blob: 36067cc7a1f7d3b0c355d165112d34aa61e9254b [file] [log] [blame]
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
load(
"//rules:opentitan_test.bzl",
"DEFAULT_TEST_FAILURE_MSG",
"DEFAULT_TEST_SUCCESS_MSG",
"cw310_params",
"dv_params",
"opentitan_functest",
"verilator_params",
)
load("//rules:const.bzl", "CONST", "error_redact", "get_lc_items", "hex", "hex_digits", "lcv_hw_to_sw")
load(
"//rules:opentitan.bzl",
"bin_to_vmem",
"opentitan_flash_binary",
"opentitan_multislot_flash_binary",
"scramble_flash_vmem",
)
load("//rules:manifest.bzl", "manifest")
load("//rules:opentitan_gdb_test.bzl", "IBEX_GPRS", "gdb_commands_copy_registers", "gdb_commands_restore_registers", "gdb_commands_set_registers", "get_gdb_readable_csr_names", "get_gdb_settable_csr_names", "opentitan_gdb_fpga_cw310_test")
load("//rules:otp.bzl", "STD_OTP_OVERLAYS", "otp_alert_digest", "otp_image", "otp_json", "otp_partition")
load("//rules:rom_e2e.bzl", "maybe_skip_in_ci")
load("//rules:splice.bzl", "bitstream_splice")
load("@bazel_skylib//lib:shell.bzl", "shell")
load("@bazel_skylib//lib:structs.bzl", "structs")
package(default_visibility = ["//visibility:public"])
MSG_TEMPLATE_BFV = "{}{}\r\n(?s:.*){}{}\r\n".format(
CONST.SHUTDOWN.PREFIX.BFV,
"{0}",
CONST.SHUTDOWN.PREFIX.BFV,
"{0}",
)
MSG_TEMPLATE_BFV_LCV = "{}{}\r\n{}{}\r\n(?s:.*){}{}\r\n{}{}\r\n".format(
CONST.SHUTDOWN.PREFIX.BFV,
"{0}",
CONST.SHUTDOWN.PREFIX.LCV,
"{1}",
CONST.SHUTDOWN.PREFIX.BFV,
"{0}",
CONST.SHUTDOWN.PREFIX.LCV,
"{1}",
)
MSG_STARTING_ROM_EXT = "Starting ROM_EXT"
MSG_PASS = "PASS!"
SLOTS = {
"a": "0x0",
"b": "0x80000",
}
# list of all the production/dev/test keys, finally list of all keys
# all the keys listed must be defined in /rules/opentitan.bzl
FAKE_TEST_KEYS = ["fake_test_key_0"]
FAKE_DEV_KEYS = ["fake_dev_key_0"]
FAKE_PROD_KEYS = ["fake_prod_key_0"]
FAKE_ALL_KEYS = FAKE_TEST_KEYS + FAKE_DEV_KEYS + FAKE_PROD_KEYS
# list of all acceptable keys in each LC state
# see secure boot documentation
LC_KEY_TYPES = {
CONST.LCV.TEST_UNLOCKED0: FAKE_TEST_KEYS + FAKE_PROD_KEYS,
CONST.LCV.DEV: FAKE_DEV_KEYS + FAKE_PROD_KEYS,
CONST.LCV.PROD: FAKE_PROD_KEYS,
CONST.LCV.PROD_END: FAKE_PROD_KEYS,
CONST.LCV.RMA: FAKE_TEST_KEYS + FAKE_PROD_KEYS,
}
# Default OTP in TEST_UNLOCKED state
otp_json(
name = "otp_json_default",
partitions = [
otp_partition(
name = "OWNER_SW_CFG",
items = {
"OWNER_SW_CFG_ROM_BOOTSTRAP_EN": "0x739",
},
),
otp_partition(
name = "CREATOR_SW_CFG",
items = {
"CREATOR_SW_CFG_ROM_EXEC_EN": "0xffffffff",
# Enable use of entropy for countermeasures. See the definition
# of `hardened_bool_t` in sw/device/lib/base/hardened.h.
"CREATOR_SW_CFG_RNG_EN": "0x739",
# Entropy source health check default values. This needs to be
# populated when `CREATOR_SW_CFG_RNG_EN` is set to true.
"CREATOR_SW_CFG_RNG_REPCNT_THRESHOLDS": "0xffffffff",
"CREATOR_SW_CFG_RNG_REPCNTS_THRESHOLDS": "0xffffffff",
"CREATOR_SW_CFG_RNG_ADAPTP_HI_THRESHOLDS": "0xffffffff",
"CREATOR_SW_CFG_RNG_ADAPTP_LO_THRESHOLDS": "0x0",
"CREATOR_SW_CFG_RNG_BUCKET_THRESHOLDS": "0xffffffff",
"CREATOR_SW_CFG_RNG_MARKOV_HI_THRESHOLDS": "0xffffffff",
"CREATOR_SW_CFG_RNG_MARKOV_LO_THRESHOLDS": "0x0",
"CREATOR_SW_CFG_RNG_EXTHT_HI_THRESHOLDS": "0xffffffff",
"CREATOR_SW_CFG_RNG_EXTHT_LO_THRESHOLDS": "0x0",
"CREATOR_SW_CFG_RNG_ALERT_THRESHOLD": "0xfffd0002",
"CREATOR_SW_CFG_RNG_HEALTH_CONFIG_DIGEST": "0x8264cf75",
},
),
otp_partition(
name = "LIFE_CYCLE",
count = 1,
state = "TEST_UNLOCKED0",
),
],
)
otp_image(
name = "otp_img_default",
src = ":otp_json_default",
visibility = ["//visibility:private"],
)
bitstream_splice(
name = "bitstream_default_otp",
src = "//hw/bitstream:rom",
data = ":otp_img_default",
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"] + maybe_skip_in_ci(CONST.LCV.RMA),
update_usr_access = True,
visibility = ["//visibility:private"],
)
opentitan_functest(
name = "rom_e2e_default_otp_bootup",
srcs = ["empty_test.c"],
cw310 = cw310_params(
bitstream = ":bitstream_default_otp",
tags = ["vivado"] + maybe_skip_in_ci(CONST.LCV.RMA),
),
signed = True,
targets = [
"cw310_rom",
],
deps = [
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:otp",
],
)
[opentitan_flash_binary(
name = "empty_test_slot_{}".format(slot),
srcs = ["empty_test.c"],
devices = [
"fpga_cw310",
"sim_dv",
"sim_verilator",
],
signed = True,
deps = [
"//hw/ip/otp_ctrl/data:otp_ctrl_regs",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:lifecycle",
"//sw/device/silicon_creator/lib/drivers:otp",
"//sw/device/lib/testing/test_framework:ottf_ld_silicon_creator_slot_{}".format(slot),
],
) for slot in SLOTS]
opentitan_functest(
name = "rom_e2e_flash_ctrl_init",
srcs = ["rom_e2e_flash_ctrl_init_test.c"],
signed = True,
targets = [
"cw310_rom",
],
deps = [
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:flash_ctrl",
"//sw/device/silicon_creator/lib/drivers:otp",
],
)
opentitan_functest(
name = "rom_e2e_shutdown_exception_c",
srcs = ["rom_e2e_shutdown_exception_c_test.c"],
cw310 = cw310_params(
# Note: This test never prints a failure message so it will fail only
# when it times out.
exit_failure = "NO_FAILURE_MESSAGE",
exit_success = MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.INTERRUPT.INSTRUCTION_ACCESS)),
),
dv = dv_params(
rom = "//sw/device/silicon_creator/rom:rom_with_fake_keys",
),
signed = True,
targets = [
"dv",
"cw310_rom",
"verilator",
],
verilator = verilator_params(
timeout = "eternal",
exit_failure = "NO_FAILURE_MESSAGE",
exit_success = MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.INTERRUPT.INSTRUCTION_ACCESS)),
rom = "//sw/device/silicon_creator/rom:rom_with_fake_keys",
),
deps = [
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
"//sw/device/silicon_creator/lib:manifest_def",
"//sw/device/silicon_creator/lib/base:static_critical_boot_measurements",
"//sw/device/silicon_creator/lib/base:static_critical_epmp_state",
"//sw/device/silicon_creator/lib/base:static_critical_sec_mmio",
],
)
opentitan_functest(
name = "rom_e2e_smoke",
cw310 = cw310_params(
bitstream = "//hw/bitstream:rom",
),
dv = dv_params(
rom = "//sw/device/silicon_creator/rom:rom_with_fake_keys",
),
key = FAKE_TEST_KEYS[0],
ot_flash_binary = ":empty_test_slot_a",
targets = [
"cw310_rom",
"verilator",
"dv",
],
verilator = verilator_params(
timeout = "eternal",
rom = "//sw/device/silicon_creator/rom:rom_with_fake_keys",
),
)
opentitan_functest(
name = "rom_e2e_static_critical",
srcs = ["rom_e2e_static_critical_test.c"],
dv = dv_params(
rom = "//sw/device/silicon_creator/rom:rom_with_fake_keys",
),
signed = True,
targets = [
"dv",
"cw310_rom",
"verilator",
],
verilator = verilator_params(
timeout = "eternal",
rom = "//sw/device/silicon_creator/rom:rom_with_fake_keys",
),
deps = [
"//sw/device/lib/dif:hmac",
"//sw/device/lib/testing:hmac_testutils",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/base:sec_mmio",
],
)
opentitan_flash_binary(
name = "rom_e2e_keymgr_init_test",
srcs = [":rom_e2e_keymgr_init_test.c"],
deps = [
"//sw/device/lib/dif:keymgr",
"//sw/device/lib/testing:keymgr_testutils",
"//sw/device/lib/testing/test_framework:ottf_ld_silicon_creator_slot_a",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:otp",
],
)
rom_e2e_keymgr_init_configs = [
{
"name": "rom_ext_meas",
"value": CONST.TRUE,
},
{
"name": "rom_ext_no_meas",
"value": CONST.FALSE,
},
{
"name": "rom_ext_invalid_meas",
"value": 0,
},
]
[
otp_json(
name = "otp_json_keymgr_{}".format(config["name"]),
partitions = [
otp_partition(
name = "OWNER_SW_CFG",
items = {
"OWNER_SW_CFG_ROM_KEYMGR_ROM_EXT_MEAS_EN": "0x{}".format(hex_digits(config["value"])),
},
),
],
)
for config in rom_e2e_keymgr_init_configs
]
[
otp_image(
name = "otp_img_keymgr_{}".format(config["name"]),
src = "//hw/ip/otp_ctrl/data:otp_json_rma",
overlays = STD_OTP_OVERLAYS + [":otp_json_keymgr_{}".format(config["name"])],
visibility = ["//visibility:private"],
)
for config in rom_e2e_keymgr_init_configs
]
[
bitstream_splice(
name = "bitstream_keymgr_{}".format(config["name"]),
src = "//hw/bitstream:rom",
data = ":otp_img_keymgr_{}".format(config["name"]),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"],
visibility = ["//visibility:private"],
)
for config in rom_e2e_keymgr_init_configs
]
[
opentitan_functest(
name = "rom_e2e_keymgr_init_{}".format(config["name"]),
cw310 = cw310_params(
bitstream = ":bitstream_keymgr_{}".format(config["name"]),
tags = ["vivado"],
),
dv = dv_params(
otp = ":otp_img_keymgr_{}".format(config["name"]),
rom = "//sw/device/silicon_creator/rom:rom_with_fake_keys",
),
ot_flash_binary = ":rom_e2e_keymgr_init_test",
targets = [
"cw310_rom",
"dv",
"verilator",
],
verilator = verilator_params(
timeout = "eternal",
otp = ":otp_img_keymgr_{}".format(config["name"]),
rom = "//sw/device/silicon_creator/rom:rom_with_fake_keys",
),
)
for config in rom_e2e_keymgr_init_configs
]
test_suite(
name = "keymgr_init",
tags = ["manual"],
tests = ["rom_e2e_keymgr_init_{}".format(
config["name"],
) for config in rom_e2e_keymgr_init_configs],
)
opentitan_functest(
name = "rom_e2e_c_init",
srcs = ["rom_e2e_c_init_test.c"],
cw310 = cw310_params(
exit_failure = CONST.SHUTDOWN.PREFIX.BFV,
exit_success = MSG_PASS,
),
signed = True,
targets = [
"cw310_rom",
],
deps = [
"//hw/ip/uart/data:uart_regs",
"//hw/top_earlgrey/ip/pinmux/data/autogen:pinmux_regs",
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
"//sw/device/lib/runtime:hart",
"//sw/device/lib/runtime:log",
"//sw/device/lib/runtime:print",
"//sw/device/silicon_creator/lib:manifest_def",
"//sw/device/silicon_creator/lib/base:static_critical_boot_measurements",
"//sw/device/silicon_creator/lib/base:static_critical_epmp_state",
"//sw/device/silicon_creator/lib/base:static_critical_sec_mmio",
"//sw/device/silicon_creator/lib/drivers:otp",
"//sw/device/silicon_creator/lib/drivers:pinmux",
"//sw/device/silicon_creator/lib/drivers:uart",
],
)
# Same as `:e2e_bootup_success`, but the Dev OTP image is spliced into the
# bitstream before it's sent to the CW310 FPGA.
opentitan_functest(
name = "e2e_bootup_success_otp_dev",
cw310 = cw310_params(
bitstream = "//hw/bitstream:rom_otp_dev",
# TODO(lowRISC/opentitan#13603): Remove this "manual" tag when the
# bitstream target can fetch pre-spliced bitstream from GCP.
tags = ["manual"],
),
key = FAKE_TEST_KEYS[0],
ot_flash_binary = ":empty_test_slot_a",
targets = ["cw310_rom"],
)
[otp_image(
name = "otp_img_e2e_bootstrap_entry_{}".format(lc_state.lower()),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state.lower()),
overlays = STD_OTP_OVERLAYS,
) for lc_state in structs.to_dict(CONST.LCV)]
# Splice OTP images into bitstreams
[
bitstream_splice(
name = "bitstream_e2e_bootstrap_entry_{}".format(lc_state.lower()),
src = "//hw/bitstream:rom",
data = ":otp_img_e2e_bootstrap_entry_{}".format(lc_state.lower()),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
update_usr_access = True,
)
for lc_state, lc_state_val in structs.to_dict(CONST.LCV).items()
]
[
opentitan_functest(
name = "e2e_bootstrap_entry_{}".format(lc_state.lower()),
cw310 = cw310_params(
bitstream = ":bitstream_e2e_bootstrap_entry_{}".format(lc_state.lower()),
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
test_cmds = [
"--rom-kind=rom",
"--bitstream=\"$(location {bitstream})\"",
"--bootstrap=\"$(location {flash})\"",
],
),
ot_flash_binary = ":empty_test_slot_a",
# We don't want the `empty_test` to run, but we _also_ don't want some
# leftover flash image from a previous test to run. So, bootstrap an
# unsigned image to force a boot failure.
signed = False,
targets = ["cw310_rom"],
test_harness = "//sw/host/tests/rom/e2e_bootstrap_entry",
deps = [":bitstream_e2e_bootstrap_entry_{}".format(lc_state.lower())],
)
for lc_state, lc_state_val in structs.to_dict(CONST.LCV).items()
]
test_suite(
name = "rom_e2e_bootstrap_entry",
tags = ["manual"],
tests = [":e2e_bootstrap_entry_{}".format(lc_state.lower()) for lc_state in structs.to_dict(CONST.LCV)],
)
otp_json(
name = "otp_json_bootstrap_rma",
partitions = [
otp_partition(
name = "CREATOR_SW_CFG",
items = {
"CREATOR_SW_CFG_RMA_SPIN_EN": "0x739", # HARDENED_BOOL_TRUE
"CREATOR_SW_CFG_RMA_SPIN_CYCLES": "10",
},
),
otp_partition(
name = "SECRET2",
items = {
# This RMA token is a cSHAKE128 digest. The preimage is
# hardcoded into the test harness [0] and the tool that
# generated this token [1].
#
# [0]: //sw/host/tests/rom/e2e_bootstrap_rma
# [1]: //sw/host/tests/rom/e2e_bootstrap_rma:gen_rma_token
"RMA_TOKEN": "0x1faf9056acde66561685549803a28bec",
"CREATOR_ROOT_KEY_SHARE0": "<random>",
"CREATOR_ROOT_KEY_SHARE1": "<random>",
},
lock = True,
),
],
visibility = ["//visibility:private"],
)
# This OTP image is tightly coupled with the "rom_bootstrap_rma" testpoint.
# Despite its name ending with "rma", it actually puts the device into the PROD
# lifecycle state in order to test the transition from PROD to RMA.
otp_image(
name = "otp_img_bootstrap_rma",
src = "//hw/ip/otp_ctrl/data:otp_json_prod",
overlays = STD_OTP_OVERLAYS + [
":otp_json_bootstrap_rma",
],
visibility = ["//visibility:private"],
)
bitstream_splice(
name = "bitstream_bootstrap_rma",
src = "//hw/bitstream:rom",
data = ":otp_img_bootstrap_rma",
meminfo = "//hw/bitstream:otp_mmi",
tags = [
"vivado",
],
update_usr_access = True,
visibility = ["//visibility:private"],
)
opentitan_functest(
name = "e2e_bootstrap_rma_iteration_1",
srcs = ["rom_e2e_bootstrap_rma_test.c"],
cw310 = cw310_params(
bitstream = ":bitstream_bootstrap_rma",
tags = ["vivado"],
test_cmds = [
"--rom-kind=rom",
"--bitstream=\"$(location {bitstream})\"",
"--bootstrap=\"$(location {flash})\"",
],
),
key = LC_KEY_TYPES[CONST.LCV.PROD][0],
targets = ["cw310_rom"],
test_harness = "//sw/host/tests/rom/e2e_bootstrap_rma",
deps = [
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:retention_sram",
],
)
opentitan_functest(
name = "e2e_bootstrap_disabled",
cw310 = cw310_params(
bitstream = "//hw/bitstream:rom_otp_bootstrap_disabled",
tags = [
"vivado",
],
test_cmds = [
"--bitstream=\"$(location {bitstream})\"",
],
),
# Since the bitstream disables bootstrap, there is no firmware to
# load into the chip. However, opentitan_functest wants to build a
# binary target. We'll build an unsigned do-nothing binary.
ot_flash_binary = ":empty_test_slot_a",
signed = False,
targets = ["cw310_rom"],
test_harness = "//sw/host/tests/rom/e2e_bootstrap_disabled",
)
[
bitstream_splice(
name = "bitstream_chip_specific_startup_{}".format(lc_state.lower()),
src = "//hw/bitstream:rom",
data = ":otp_img_e2e_bootstrap_entry_{}".format(lc_state.lower()),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
update_usr_access = True,
)
for lc_state, lc_state_val in get_lc_items()
]
[
opentitan_functest(
name = "e2e_chip_specific_startup_{}".format(lc_state.lower()),
srcs = ["chip_specific_startup.c"],
args = [],
cw310 = cw310_params(
bitstream = ":bitstream_chip_specific_startup_{}".format(lc_state.lower()),
otp = ":otp_img_e2e_bootstrap_entry_{}".format(lc_state.lower()),
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
test_cmds = [
"--rom-kind=rom",
"--bitstream=\"$(location //sw/device/silicon_creator/rom/e2e:bitstream_chip_specific_startup_{})\"".format(lc_state.lower()),
"--bootstrap=\"$(location {flash})\"",
"--otp-unprogrammed",
],
),
signed = True,
targets = ["cw310_rom"],
test_harness = "//sw/host/tests/rom/e2e_chip_specific_startup",
deps = [
"//hw/ip/csrng/data:csrng_regs",
"//hw/ip/edn/data:edn_regs",
"//hw/ip/entropy_src/data:entropy_src_regs",
"//hw/ip/otp_ctrl/data:otp_ctrl_regs",
"//hw/top_earlgrey/ip/sensor_ctrl/data:sensor_ctrl_regs",
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
"//sw/device/lib/base:mmio",
"//sw/device/lib/dif:clkmgr",
"//sw/device/lib/dif:lc_ctrl",
"//sw/device/lib/dif:otp_ctrl",
"//sw/device/lib/dif:sram_ctrl",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing/json:chip_specific_startup",
"//sw/device/lib/testing/json:command",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/lib/testing/test_framework:ujson_ottf",
"//sw/device/lib/ujson",
],
)
for lc_state, lc_state_val in get_lc_items()
]
test_suite(
name = "e2e_chip_specific_startup",
tags = ["manual"],
tests = [
"e2e_chip_specific_startup_{}".format(lc_state)
for lc_state, _ in get_lc_items()
],
)
opentitan_functest(
name = "rom_ext_a_flash_a",
cw310 = cw310_params(
exit_failure = CONST.SHUTDOWN.PREFIX.BFV,
exit_success = MSG_STARTING_ROM_EXT,
),
ot_flash_binary = "//sw/device/silicon_creator/rom_ext:rom_ext_slot_a",
targets = ["cw310_rom"],
)
opentitan_multislot_flash_binary(
name = "rom_ext_b_flash_b_image",
srcs = {
"//sw/device/silicon_creator/rom_ext:rom_ext_slot_b": {
"key": FAKE_TEST_KEYS[0],
"offset": SLOTS["b"],
},
},
)
opentitan_functest(
name = "rom_ext_b_flash_b",
cw310 = cw310_params(
exit_failure = CONST.SHUTDOWN.PREFIX.BFV,
exit_success = MSG_STARTING_ROM_EXT,
),
key = "multislot",
ot_flash_binary = ":rom_ext_b_flash_b_image",
targets = ["cw310_rom"],
)
opentitan_multislot_flash_binary(
name = "rom_ext_a_flash_b_image",
srcs = {
"//sw/device/silicon_creator/rom_ext:rom_ext_slot_a": {
"key": FAKE_TEST_KEYS[0],
"offset": SLOTS["b"],
},
},
)
opentitan_functest(
name = "rom_ext_a_flash_b",
cw310 = cw310_params(
exit_failure = MSG_STARTING_ROM_EXT,
exit_success = MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.INTERRUPT.STORE_ACCESS)),
),
key = "multislot",
ot_flash_binary = ":rom_ext_a_flash_b_image",
targets = ["cw310_rom"],
)
opentitan_multislot_flash_binary(
name = "rom_ext_b_flash_a_image",
srcs = {
"//sw/device/silicon_creator/rom_ext:rom_ext_slot_b": {
"key": FAKE_TEST_KEYS[0],
"offset": SLOTS["a"],
},
},
)
opentitan_functest(
name = "rom_ext_b_flash_a",
cw310 = cw310_params(
exit_failure = MSG_STARTING_ROM_EXT,
exit_success = MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.INTERRUPT.STORE_ACCESS)),
),
key = "multislot",
ot_flash_binary = ":rom_ext_b_flash_a_image",
targets = ["cw310_rom"],
)
opentitan_functest(
name = "rom_ext_v_flash_a",
cw310 = cw310_params(
exit_failure = CONST.SHUTDOWN.PREFIX.BFV,
exit_success = MSG_STARTING_ROM_EXT,
),
ot_flash_binary = "//sw/device/silicon_creator/rom_ext:rom_ext_slot_virtual",
targets = ["cw310_rom"],
)
opentitan_multislot_flash_binary(
name = "rom_ext_v_flash_b_image",
srcs = {
"//sw/device/silicon_creator/rom_ext:rom_ext_slot_virtual": {
"key": FAKE_TEST_KEYS[0],
"offset": SLOTS["b"],
},
},
)
opentitan_functest(
name = "rom_ext_v_flash_b",
cw310 = cw310_params(
exit_failure = CONST.SHUTDOWN.PREFIX.BFV,
exit_success = MSG_STARTING_ROM_EXT,
),
key = "multislot",
ot_flash_binary = ":rom_ext_v_flash_b_image",
targets = ["cw310_rom"],
)
opentitan_functest(
name = "rom_ext_a_flash_a_bad_addr_trans",
cw310 = cw310_params(
exit_failure = MSG_STARTING_ROM_EXT,
exit_success = MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.INTERRUPT.ILLEGAL_INSTRUCTION)),
),
ot_flash_binary = "//sw/device/silicon_creator/rom_ext:rom_ext_slot_a_bad_address_translation",
targets = ["cw310_rom"],
)
test_suite(
name = "address_translation",
tags = ["manual"],
tests = [
"rom_ext_a_flash_a",
"rom_ext_a_flash_a_bad_addr_trans",
"rom_ext_a_flash_b",
"rom_ext_b_flash_a",
"rom_ext_b_flash_b",
"rom_ext_v_flash_a",
"rom_ext_v_flash_b",
],
)
opentitan_functest(
name = "sigverify_key_auth",
cw310 = cw310_params(
exit_failure = MSG_PASS,
exit_success = MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.SIGVERIFY.BAD_KEY)),
),
key = "unauthorized_0",
ot_flash_binary = ":empty_test_slot_a",
targets = ["cw310_rom"],
)
[otp_image(
name = "otp_img_shutdown_output_{}".format(lc_state),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state),
overlays = STD_OTP_OVERLAYS,
) for lc_state, _ in get_lc_items()]
# Splice OTP images into bitstreams
[
bitstream_splice(
name = "bitstream_shutdown_output_{}".format(lc_state),
src = "//hw/bitstream:rom",
data = ":otp_img_shutdown_output_{}".format(lc_state),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"],
update_usr_access = True,
)
for lc_state, _ in get_lc_items()
]
manifest({
"name": "manifest_bad_identifier",
"address_translation": hex(CONST.FALSE),
"identifier": "0",
})
[opentitan_functest(
name = "shutdown_output_{}".format(lc_state),
cw310 = cw310_params(
bitstream = ":bitstream_shutdown_output_{}".format(lc_state),
exit_failure = MSG_PASS,
exit_success = MSG_TEMPLATE_BFV_LCV.format(
hex_digits(CONST.BFV.BOOT_POLICY.BAD_IDENTIFIER),
hex_digits(lc_state_val),
),
otp = ":otp_img_shutdown_output_{}".format(lc_state),
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
dv = dv_params(
otp = ":otp_img_shutdown_output_{}".format(lc_state),
rom = "//sw/device/silicon_creator/rom:rom_with_fake_keys",
),
manifest = ":manifest_bad_identifier",
ot_flash_binary = ":empty_test_slot_a",
signed = False,
targets = [
"cw310_rom",
"dv",
],
) for lc_state, lc_state_val in get_lc_items()]
test_suite(
name = "shutdown_output",
tags = ["manual"],
tests = ["shutdown_output_{}".format(lc_state) for lc_state, _ in get_lc_items()],
)
SEC_VERS = [
0,
1,
2,
]
[manifest({
"name": "manifest_sec_ver_{}".format(sec_ver),
"address_translation": hex(CONST.FALSE),
"identifier": hex(CONST.ROM_EXT),
"security_version": hex(sec_ver),
}) for sec_ver in SEC_VERS]
[opentitan_flash_binary(
name = "empty_test_slot_{}_sec_ver_{}".format(slot, sec_ver),
srcs = ["empty_test.c"],
devices = ["fpga_cw310"],
local_defines = [
shell.quote("EMPTY_TEST_MSG=\"slot=%p, security_version=%01d, lc_state=0x%08x\", manifest_def_get(), manifest_def_get()->security_version, lifecycle_raw_state_get()"),
],
manifest = ":manifest_sec_ver_{}".format(sec_ver),
signed = True,
deps = [
"//hw/ip/otp_ctrl/data:otp_ctrl_regs",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:lifecycle",
"//sw/device/silicon_creator/lib/drivers:otp",
"//sw/device/lib/testing/test_framework:ottf_ld_silicon_creator_slot_{}".format(slot),
],
) for slot in SLOTS for sec_ver in SEC_VERS]
[opentitan_multislot_flash_binary(
name = "sec_ver_{}_{}_image".format(sec_ver_a, sec_ver_b),
srcs = {
":empty_test_slot_a_sec_ver_{}".format(sec_ver_a): {
"key": "fake_prod_key_0",
"offset": SLOTS["a"],
},
":empty_test_slot_b_sec_ver_{}".format(sec_ver_b): {
"key": "fake_prod_key_0",
"offset": SLOTS["b"],
},
},
devices = ["fpga_cw310"],
) for sec_ver_a in SEC_VERS for sec_ver_b in SEC_VERS]
BOOT_POLICY_NEWER_CASES = [
{
"a": 0,
"b": 0,
"exit_success": "slot=0x20000000, security_version=0, lc_state=0x{}",
},
{
"a": 0,
"b": 1,
"exit_success": "slot=0x20080000, security_version=1, lc_state=0x{}",
},
{
"a": 1,
"b": 0,
"exit_success": "slot=0x20000000, security_version=1, lc_state=0x{}",
},
{
"a": 1,
"b": 1,
"exit_success": "slot=0x20000000, security_version=1, lc_state=0x{}",
},
]
[otp_image(
name = "otp_img_boot_policy_newer_{}".format(lc_state.lower()),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state.lower()),
overlays = STD_OTP_OVERLAYS,
) for lc_state in structs.to_dict(CONST.LCV)]
# Splice OTP images into bitstreams
[
bitstream_splice(
name = "bitstream_boot_policy_newer_{}".format(lc_state.lower()),
src = "//hw/bitstream:rom",
data = ":otp_img_boot_policy_newer_{}".format(lc_state.lower()),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"],
update_usr_access = True,
)
for lc_state in structs.to_dict(CONST.LCV)
]
[opentitan_functest(
name = "boot_policy_newer_{}_a_{}_b_{}".format(
lc_state.lower(),
t["a"],
t["b"],
),
cw310 = cw310_params(
bitstream = ":bitstream_boot_policy_newer_{}".format(lc_state.lower()),
exit_success = t["exit_success"].format(hex_digits(lc_state_val)),
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
key = "multislot",
ot_flash_binary = ":sec_ver_{}_{}_image".format(
t["a"],
t["b"],
),
targets = ["cw310_rom"],
) for lc_state, lc_state_val in structs.to_dict(CONST.LCV).items() for t in BOOT_POLICY_NEWER_CASES]
test_suite(
name = "boot_policy_newer",
tags = ["manual"],
tests = ["boot_policy_newer_{}_a_{}_b_{}".format(
lc_state.lower(),
t["a"],
t["b"],
) for lc_state in structs.to_dict(CONST.LCV) for t in BOOT_POLICY_NEWER_CASES],
)
BOOT_POLICY_ROLLBACK_CASES = [
{
"a": 0,
"b": 0,
"exit_success": MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.BOOT_POLICY.ROLLBACK)),
},
{
"a": 0,
"b": 1,
"exit_success": "slot=0x20080000, security_version=1",
},
{
"a": 2,
"b": 0,
"exit_success": "slot=0x20000000, security_version=2",
},
{
"a": 1,
"b": 1,
"exit_success": "slot=0x20000000, security_version=1",
},
]
otp_json(
name = "otp_json_boot_policy_rollback",
partitions = [
otp_partition(
name = "CREATOR_SW_CFG",
items = {
"CREATOR_SW_CFG_MIN_SEC_VER_ROM_EXT": "1",
},
),
],
)
[otp_image(
name = "otp_img_boot_policy_rollback_{}".format(lc_state),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state),
overlays = STD_OTP_OVERLAYS + [":otp_json_boot_policy_rollback"],
visibility = ["//visibility:private"],
) for lc_state, _ in get_lc_items()]
[bitstream_splice(
name = "bitstream_boot_policy_rollback_{}".format(
lc_state,
),
src = "//hw/bitstream:rom",
data = ":otp_img_boot_policy_rollback_{}".format(
lc_state,
),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"],
update_usr_access = True,
visibility = ["//visibility:private"],
) for lc_state, _ in get_lc_items()]
[
opentitan_functest(
name = "boot_policy_rollback_{}_a_{}_b_{}".format(
lc_state,
t["a"],
t["b"],
),
cw310 = cw310_params(
bitstream = "bitstream_boot_policy_rollback_{}".format(lc_state),
exit_success = t["exit_success"],
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
key = "multislot",
ot_flash_binary = ":sec_ver_{}_{}_image".format(
t["a"],
t["b"],
),
targets = ["cw310_rom"],
)
for lc_state, lc_state_val in get_lc_items()
for t in BOOT_POLICY_ROLLBACK_CASES
]
test_suite(
name = "rom_e2e_boot_policy_rollback",
tags = ["manual"],
tests = [
"boot_policy_rollback_{}_a_{}_b_{}".format(
lc_state,
t["a"],
t["b"],
)
for lc_state, _ in get_lc_items()
for t in BOOT_POLICY_ROLLBACK_CASES
],
)
# Watchdog configuration test cases.
#
# These test cases verify the ROM correctly configures the watchdog in each life
# cycle state. Tests are run for OTP configurations that disable the watchdog
# and for OTP configurations that enable the watchdog.
# Watchdog bite threshold for the watchdog-enabled cases. This is 2 seconds,
# assuming a 200kHz clock.
WATCHDOG_BITE_THRESHOLD = "0x61a80"
# OTP overlay that enables the watchdog. The bite threshold is 2 seconds,
# assuming a 200kHz clock.
otp_json(
name = "otp_json_watchdog_enable",
partitions = [
otp_partition(
name = "OWNER_SW_CFG",
items = {"OWNER_SW_CFG_ROM_WATCHDOG_BITE_THRESHOLD_CYCLES": WATCHDOG_BITE_THRESHOLD},
),
],
)
# OTP images that enable the watchdog.
[otp_image(
name = "otp_img_watchdog_enable_{}".format(lc_state.lower()),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state.lower()),
overlays = STD_OTP_OVERLAYS + [":otp_json_watchdog_enable"],
) for lc_state in structs.to_dict(CONST.LCV)]
# Bitstreams with the watchdog-enable OTP images spliced in.
[bitstream_splice(
name = "bitstream_watchdog_enable_{}".format(lc_state.lower()),
src = "//hw/bitstream:rom",
data = ":otp_img_watchdog_enable_{}".format(lc_state.lower()),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
update_usr_access = True,
) for lc_state, lc_state_val in structs.to_dict(CONST.LCV).items()]
# Creates a binary that confirms the watchdog is enabled and a binary that
# confirms the watchdog is disabled.
[opentitan_flash_binary(
name = "test_watchdog_{}".format(watchdog_config),
srcs = ["watchdog_test.c"],
devices = [
"fpga_cw310",
"sim_verilator",
],
local_defines = [
"EXPECT_WATCHDOG_{}".format(watchdog_config.upper()),
"WATCHDOG_BITE_THRESHOLD={}".format(WATCHDOG_BITE_THRESHOLD),
],
deps = [
"//hw/ip/aon_timer/data:aon_timer_regs",
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
"//sw/device/lib/base:abs_mmio",
"//sw/device/lib/testing/test_framework:ottf_ld_silicon_creator_slot_a",
"//sw/device/lib/testing/test_framework:ottf_main",
],
) for watchdog_config in [
"disabled",
"enabled",
]]
WATCHDOG_TEST_CASES = {
"disable": {
"DEV": "disabled",
"PROD": "disabled",
"PROD_END": "disabled",
"RMA": "disabled",
"TEST_UNLOCKED0": "disabled",
},
"enable": {
"DEV": "enabled",
"PROD": "enabled",
"PROD_END": "enabled",
"RMA": "disabled",
"TEST_UNLOCKED0": "disabled",
},
}
# Bitstream targets (CW310) and otp images (verilator) for the watchdog config
# tests. The format argument should be replaced with the desired life cycle
# state.
WATCHDOG_BITSTREAM = {
"disable": "//hw/bitstream:rom_otp_{}",
"enable": ":bitstream_watchdog_enable_{}",
}
WATCHDOG_OTP = {
"disable": "//hw/ip/otp_ctrl/data:img_{}",
"enable": ":otp_img_watchdog_enable_{}",
}
[opentitan_functest(
name = "watchdog_{}_{}".format(
otp_config,
lc_state.lower(),
),
cw310 = cw310_params(
bitstream = WATCHDOG_BITSTREAM[otp_config].format(lc_state.lower()),
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
ot_flash_binary = ":test_watchdog_{}".format(WATCHDOG_TEST_CASES[otp_config][lc_state]),
targets = [
"cw310_rom",
"verilator",
],
verilator = verilator_params(
timeout = "eternal",
otp = WATCHDOG_OTP[otp_config].format(lc_state.lower()),
rom = "//sw/device/silicon_creator/rom:rom_with_fake_keys",
# Test cases that enable the watchdog time out in verilator, cause
# unknown.
tags = ["broken"] if WATCHDOG_TEST_CASES[otp_config][lc_state] == "enabled" else [],
),
) for otp_config in [
"disable",
"enable",
] for lc_state, lc_state_val in structs.to_dict(CONST.LCV).items()]
test_suite(
name = "rom_e2e_watchdog_reconfig",
tags = ["manual"],
tests = [
"watchdog_{}_{}".format(
otp_config,
lc_state.lower(),
)
for otp_config in [
"disable",
"enable",
]
for lc_state in structs.to_dict(CONST.LCV)
],
)
# Alert Handler configuration test cases.
#
# These test cases verify the ROM correctly configures the alert_handler in each
# life cycle state.
# Alert handler configuration is not checked in the TEST LC state.
ALERT_LC_STATES = get_lc_items(
CONST.LCV.PROD,
CONST.LCV.PROD_END,
CONST.LCV.DEV,
CONST.LCV.RMA,
)
[otp_image(
name = "otp_img_alert_{}".format(lc_state),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state),
overlays = STD_OTP_OVERLAYS,
) for lc_state, _ in ALERT_LC_STATES]
[bitstream_splice(
name = "bitstream_alert_{}".format(lc_state),
src = "//hw/bitstream:rom",
data = ":otp_img_alert_{}".format(lc_state),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
update_usr_access = True,
) for lc_state, lc_state_val in ALERT_LC_STATES]
[opentitan_flash_binary(
name = "rom_e2e_alert_config_test_{}".format(lc_state),
srcs = ["rom_e2e_alert_config_test.c"],
devices = [
"fpga_cw310",
],
local_defines = [
"OTP_ALERT_DIGEST=OTP_CTRL_PARAM_OWNER_SW_CFG_ROM_ALERT_DIGEST_{}_OFFSET".format(lc_state.upper()),
],
deps = [
"//hw/ip/otp_ctrl/data:otp_ctrl_regs",
"//sw/device/lib/testing/test_framework:ottf_ld_silicon_creator_slot_a",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:alert",
"//sw/device/silicon_creator/lib/drivers:lifecycle",
"//sw/device/silicon_creator/lib/drivers:otp",
],
) for lc_state, _ in ALERT_LC_STATES]
[
opentitan_functest(
name = "alert_{}".format(
lc_state,
),
cw310 = cw310_params(
bitstream = ":bitstream_alert_{}".format(lc_state),
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
key = "fake_prod_key_0",
ot_flash_binary = ":rom_e2e_alert_config_test_{}".format(lc_state),
signed = True,
targets = [
"cw310_rom",
],
)
for lc_state, lc_state_val in ALERT_LC_STATES
]
test_suite(
name = "rom_e2e_alert_config",
tags = ["manual"],
tests = [
"alert_{}".format(lc_state)
for lc_state, _ in ALERT_LC_STATES
],
)
otp_json(
name = "shutdown_alert_owner_sw_cfg",
partitions = [
otp_partition(
name = "OWNER_SW_CFG",
items = {
# Enable bootstrap.
"OWNER_SW_CFG_ROM_BOOTSTRAP_EN": hex(CONST.TRUE),
# Report errors without any redaction.
"OWNER_SW_CFG_ROM_ERROR_REPORTING": hex(CONST.SHUTDOWN.REDACT.NONE),
# Enable class A alerts.
"OWNER_SW_CFG_ROM_ALERT_CLASS_EN": hex(
CONST.ALERT.NONE << 24 |
CONST.ALERT.NONE << 16 |
CONST.ALERT.NONE << 8 |
CONST.ALERT.ENABLE,
),
# Configure class A to escalate until phase 3 and disable other classes.
"OWNER_SW_CFG_ROM_ALERT_ESCALATION": hex(
CONST.ALERT.ESC_NONE << 24 |
CONST.ALERT.ESC_NONE << 16 |
CONST.ALERT.ESC_NONE << 8 |
CONST.ALERT.ESC_PHASE_3,
),
# Classify UART0 alerts (alert source 0) as class A and leave others as unconfigured.
"OWNER_SW_CFG_ROM_ALERT_CLASSIFICATION": [
hex(
CONST.ALERT.CLASS_A << 24 |
CONST.ALERT.CLASS_A << 16 |
CONST.ALERT.CLASS_A << 8 |
CONST.ALERT.CLASS_A,
),
] + [
hex(
CONST.ALERT.CLASS_X << 24 |
CONST.ALERT.CLASS_X << 16 |
CONST.ALERT.CLASS_X << 8 |
CONST.ALERT.CLASS_X,
),
] * 79,
# Leave local alert classification as unconfigured.
"OWNER_SW_CFG_ROM_LOCAL_ALERT_CLASSIFICATION": [hex(
CONST.ALERT.CLASS_X << 24 |
CONST.ALERT.CLASS_X << 16 |
CONST.ALERT.CLASS_X << 8 |
CONST.ALERT.CLASS_X,
)] * 16,
# Set the alert accumulation thresholds to 0.
"OWNER_SW_CFG_ROM_ALERT_ACCUM_THRESH": ["0x00000000"] * 4,
# Set the alert timeout cycles to 0.
"OWNER_SW_CFG_ROM_ALERT_TIMEOUT_CYCLES": ["0x00000000"] * 4,
# Set the alert phase cycles to 0.
"OWNER_SW_CFG_ROM_ALERT_PHASE_CYCLES": ["0x00000000"] * 16,
},
),
],
)
otp_alert_digest(
name = "shutdown_alert_digest_cfg",
otp_img = ":shutdown_alert_owner_sw_cfg",
)
[otp_image(
name = "otp_img_shutdown_alert_{}".format(lc_state),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state),
overlays = STD_OTP_OVERLAYS + [
":shutdown_alert_owner_sw_cfg",
":shutdown_alert_digest_cfg",
],
) for lc_state, _ in ALERT_LC_STATES]
[bitstream_splice(
name = "bitstream_shutdown_alert_{}".format(lc_state),
src = "//hw/bitstream:rom",
data = ":otp_img_shutdown_alert_{}".format(lc_state),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
update_usr_access = True,
) for lc_state, lc_state_val in ALERT_LC_STATES]
[opentitan_flash_binary(
name = "rom_e2e_shutdown_alert_config_test_{}".format(lc_state),
srcs = ["rom_e2e_shutdown_alert_config_test.c"],
devices = [
"fpga_cw310",
],
deps = [
"//hw/ip/uart/data:uart_regs",
"//sw/device/lib/base:abs_mmio",
"//sw/device/lib/testing/test_framework:ottf_ld_silicon_creator_slot_a",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:retention_sram",
"//sw/device/silicon_creator/lib/drivers:rstmgr",
],
) for lc_state, _ in ALERT_LC_STATES]
[
opentitan_functest(
name = "shutdown_alert_{}".format(lc_state),
cw310 = cw310_params(
bitstream = ":bitstream_shutdown_alert_{}".format(lc_state),
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
key = "fake_prod_key_0",
ot_flash_binary = ":rom_e2e_shutdown_alert_config_test_{}".format(lc_state),
signed = True,
targets = [
"cw310_rom",
],
)
for lc_state, lc_state_val in ALERT_LC_STATES
]
test_suite(
name = "rom_e2e_shutdown_alert_config",
tags = ["manual"],
tests = [
"shutdown_alert_{}".format(lc_state)
for lc_state, _ in ALERT_LC_STATES
],
)
SIGVERIFY_MOD_EXP_CASES = [
{
"name": "sw",
"use_sw_rsa_verify": CONST.TRUE,
"exit_success": {lc_state: "use_sw_rsa_verify=0x00000739" for lc_state, _ in get_lc_items()},
},
{
"name": "otbn",
"use_sw_rsa_verify": CONST.FALSE,
"exit_success": {lc_state: "use_sw_rsa_verify=0x000001d4" for lc_state, _ in get_lc_items()},
},
{
"name": "invalid",
"use_sw_rsa_verify": 0,
"exit_success": {
lc_state: MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.INTERRUPT.ILLEGAL_INSTRUCTION)) if lc_state_val != CONST.LCV.TEST_UNLOCKED0 else "use_sw_rsa_verify=0x00000000"
for lc_state, lc_state_val in get_lc_items()
},
},
]
opentitan_flash_binary(
name = "empty_test_sigverify_mod_exp",
srcs = ["empty_test.c"],
devices = [
"fpga_cw310",
"sim_dv",
],
local_defines = [
shell.quote("EMPTY_TEST_MSG=\"use_sw_rsa_verify=0x%08x\", otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_SIGVERIFY_RSA_MOD_EXP_IBEX_EN_OFFSET)"),
],
signed = True,
deps = [
"//hw/ip/otp_ctrl/data:otp_ctrl_regs",
"//sw/device/lib/testing/test_framework:ottf_ld_silicon_creator_slot_a",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:lifecycle",
"//sw/device/silicon_creator/lib/drivers:otp",
],
)
[
otp_json(
name = "otp_json_sigverify_mod_exp_{}".format(t["name"]),
partitions = [
otp_partition(
name = "CREATOR_SW_CFG",
items = {"CREATOR_SW_CFG_SIGVERIFY_RSA_MOD_EXP_IBEX_EN": hex(t["use_sw_rsa_verify"])},
),
],
)
for t in SIGVERIFY_MOD_EXP_CASES
]
[
otp_image(
name = "otp_img_sigverify_mod_exp_{}_{}".format(
lc_state,
t["name"],
),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state),
overlays = STD_OTP_OVERLAYS + [":otp_json_sigverify_mod_exp_{}".format(t["name"])],
visibility = ["//visibility:private"],
)
for lc_state, _ in get_lc_items()
for t in SIGVERIFY_MOD_EXP_CASES
]
[
bitstream_splice(
name = "bitstream_sigverify_mod_exp_{}_{}".format(
lc_state,
t["name"],
),
src = "//hw/bitstream:rom",
data = ":otp_img_sigverify_mod_exp_{}_{}".format(
lc_state,
t["name"],
),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"],
update_usr_access = True,
visibility = ["//visibility:private"],
)
for lc_state, _ in get_lc_items()
for t in SIGVERIFY_MOD_EXP_CASES
]
[
opentitan_functest(
name = "sigverify_mod_exp_{}_{}".format(
lc_state,
t["name"],
),
cw310 = cw310_params(
bitstream = ":bitstream_sigverify_mod_exp_{}_{}".format(
lc_state,
t["name"],
),
exit_success = t["exit_success"][lc_state],
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
ot_flash_binary = ":empty_test_sigverify_mod_exp",
targets = ["cw310_rom"],
)
for lc_state, lc_state_val in get_lc_items()
for t in SIGVERIFY_MOD_EXP_CASES
]
test_suite(
name = "rom_e2e_sigverify_mod_exp",
tags = ["manual"],
tests = [
"sigverify_mod_exp_{}_{}".format(
lc_state,
t["name"],
)
for lc_state, _ in get_lc_items()
for t in SIGVERIFY_MOD_EXP_CASES
],
)
BOOT_POLICY_BAD_MANIFEST_CASES = [
{
"name": "bad_identifier",
"manifest": {
"identifier": "0",
},
"exit_success": MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.BOOT_POLICY.BAD_IDENTIFIER)),
},
{
"name": "too_small",
"manifest": {
"identifier": hex(CONST.ROM_EXT),
"length": hex(CONST.ROM_EXT_SIZE_MIN - 1),
},
"exit_success": MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.BOOT_POLICY.BAD_LENGTH)),
},
{
"name": "too_large",
"manifest": {
"identifier": hex(CONST.ROM_EXT),
"length": hex(CONST.ROM_EXT_SIZE_MAX + 1),
},
"exit_success": MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.BOOT_POLICY.BAD_LENGTH)),
},
{
"name": "empty_code",
"manifest": {
# Note: `length` is filled automatically unless overriden here.
"identifier": hex(CONST.ROM_EXT),
"code_start": hex(CONST.MANIFEST_SIZE + 12),
"code_end": hex(CONST.MANIFEST_SIZE + 12),
},
"exit_success": MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.MANIFEST.BAD_CODE_REGION)),
},
{
"name": "code_in_manifest",
"manifest": {
"identifier": hex(CONST.ROM_EXT),
"code_start": hex(CONST.MANIFEST_SIZE - 4),
"code_end": hex(CONST.MANIFEST_SIZE + 12),
"entry_point": hex(CONST.MANIFEST_SIZE + 8),
},
"exit_success": MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.MANIFEST.BAD_CODE_REGION)),
},
{
"name": "code_outside_image",
"manifest": {
"identifier": hex(CONST.ROM_EXT),
"code_start": hex(CONST.ROM_EXT_SIZE_MAX),
"code_end": hex(CONST.MANIFEST_SIZE + 12),
"entry_point": hex(CONST.MANIFEST_SIZE + 8),
},
"exit_success": MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.MANIFEST.BAD_CODE_REGION)),
},
{
"name": "code_start_unaligned",
"manifest": {
"identifier": hex(CONST.ROM_EXT),
"code_start": hex(CONST.MANIFEST_SIZE + 6),
"code_end": hex(CONST.MANIFEST_SIZE + 12),
"entry_point": hex(CONST.MANIFEST_SIZE + 8),
},
"exit_success": MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.MANIFEST.BAD_CODE_REGION)),
},
{
"name": "code_end_unaligned",
"manifest": {
"identifier": hex(CONST.ROM_EXT),
"code_start": hex(CONST.MANIFEST_SIZE + 8),
"code_end": hex(CONST.MANIFEST_SIZE + 10),
"entry_point": hex(CONST.MANIFEST_SIZE + 8),
},
"exit_success": MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.MANIFEST.BAD_CODE_REGION)),
},
{
"name": "entry_before_code_start",
"manifest": {
"identifier": hex(CONST.ROM_EXT),
"code_start": hex(CONST.MANIFEST_SIZE + 8),
"code_end": hex(CONST.MANIFEST_SIZE + 12),
"entry_point": hex(CONST.MANIFEST_SIZE + 4),
},
"exit_success": MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.MANIFEST.BAD_ENTRY_POINT)),
},
{
"name": "entry_at_code_end",
"manifest": {
"identifier": hex(CONST.ROM_EXT),
"code_start": hex(CONST.MANIFEST_SIZE + 8),
"code_end": hex(CONST.MANIFEST_SIZE + 12),
"entry_point": hex(CONST.MANIFEST_SIZE + 12),
},
"exit_success": MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.MANIFEST.BAD_ENTRY_POINT)),
},
{
"name": "entry_unaligned",
"manifest": {
"identifier": hex(CONST.ROM_EXT),
"code_start": hex(CONST.MANIFEST_SIZE + 8),
"code_end": hex(CONST.MANIFEST_SIZE + 12),
"entry_point": hex(CONST.MANIFEST_SIZE + 10),
},
"exit_success": MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.MANIFEST.BAD_ENTRY_POINT)),
},
{
"name": "rollback",
"manifest": {
"identifier": hex(CONST.ROM_EXT),
"code_start": hex(CONST.MANIFEST_SIZE + 8),
"code_end": hex(CONST.MANIFEST_SIZE + 12),
"entry_point": hex(CONST.MANIFEST_SIZE + 8),
"security_version": "0",
},
"exit_success": MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.BOOT_POLICY.ROLLBACK)),
"sec_ver": 1,
},
]
[opentitan_flash_binary(
name = "boot_policy_bad_manifest_{}_{}_bin".format(
t["name"],
slot,
),
srcs = ["empty_test.c"],
devices = [
"fpga_cw310",
"sim_dv",
"sim_verilator",
],
manifest = manifest(dict(
t["manifest"],
name = "{}_{}".format(
t["name"],
slot,
),
)),
signed = True,
deps = [
"//hw/ip/otp_ctrl/data:otp_ctrl_regs",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:lifecycle",
"//sw/device/silicon_creator/lib/drivers:otp",
"//sw/device/lib/testing/test_framework:ottf_ld_silicon_creator_slot_{}".format(slot),
],
) for t in BOOT_POLICY_BAD_MANIFEST_CASES for slot in SLOTS]
[opentitan_multislot_flash_binary(
name = "boot_policy_bad_manifest_{}_{}_img".format(
t["name"],
slot,
),
srcs = {
"boot_policy_bad_manifest_{}_{}_bin".format(
t["name"],
slot,
): {
"key": FAKE_TEST_KEYS[0],
"offset": offset,
},
},
devices = [
"fpga_cw310",
"sim_dv",
"sim_verilator",
],
) for t in BOOT_POLICY_BAD_MANIFEST_CASES for slot, offset in SLOTS.items()]
[
otp_json(
name = "otp_json_sec_ver_{}".format(sec_ver),
partitions = [
otp_partition(
name = "CREATOR_SW_CFG",
items = {
"CREATOR_SW_CFG_MIN_SEC_VER_ROM_EXT": "{}".format(sec_ver),
},
),
],
)
for sec_ver in [
0,
1,
]
]
[
otp_image(
name = "otp_img_boot_policy_bad_manifest_{}_sec_ver_{}".format(
lc_state,
sec_ver,
),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state),
overlays = STD_OTP_OVERLAYS + [":otp_json_sec_ver_{}".format(sec_ver)],
visibility = ["//visibility:private"],
)
for lc_state, _ in get_lc_items()
for sec_ver in [
0,
1,
]
]
[
bitstream_splice(
name = "bitstream_boot_policy_bad_manifest_{}_sec_ver_{}".format(
lc_state,
sec_ver,
),
src = "//hw/bitstream:rom",
data = ":otp_img_boot_policy_bad_manifest_{}_sec_ver_{}".format(
lc_state,
sec_ver,
),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"],
update_usr_access = True,
visibility = ["//visibility:private"],
)
for lc_state, _ in get_lc_items()
for sec_ver in [
0,
1,
]
]
[
opentitan_functest(
name = "boot_policy_bad_manifest_{}_{}_{}".format(
lc_state,
t["name"],
slot,
),
cw310 = cw310_params(
bitstream = "bitstream_boot_policy_bad_manifest_{}_sec_ver_{}".format(
lc_state,
t.get("sec_ver", 0),
),
exit_success = t["exit_success"],
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
key = "multislot",
ot_flash_binary = "boot_policy_bad_manifest_{}_{}_img".format(
t["name"],
slot,
),
targets = [
"cw310_rom",
"verilator",
],
verilator = verilator_params(
tags = [
# FIXME:#16056 Verilator fails to set up test.
"vivado",
"broken",
],
),
)
for lc_state, lc_state_val in get_lc_items()
for t in BOOT_POLICY_BAD_MANIFEST_CASES
for slot in SLOTS
]
test_suite(
name = "rom_e2e_boot_policy_bad_manifest",
tags = ["manual"],
tests = [
"boot_policy_bad_manifest_{}_{}_{}".format(
lc_state,
t["name"],
slot,
)
for lc_state, _ in get_lc_items()
for t in BOOT_POLICY_BAD_MANIFEST_CASES
for slot in SLOTS
],
)
BOOT_DATA_RECOVERY_CASES = [
{
"lc_state": "test_unlocked0",
"min_sec_ver": 0,
"default_boot_data": "nodefault",
"expected_bfv": None,
},
{
"lc_state": "dev",
"min_sec_ver": 1,
"default_boot_data": "nodefault",
"expected_bfv": None,
},
{
"lc_state": "prod",
"min_sec_ver": 1,
"default_boot_data": "default",
"expected_bfv": None,
},
{
"lc_state": "prod",
"min_sec_ver": 0,
"default_boot_data": "nodefault",
"expected_bfv": CONST.BFV.BOOT_DATA.NOT_FOUND,
},
{
"lc_state": "prod_end",
"min_sec_ver": 0,
"default_boot_data": "default",
"expected_bfv": None,
},
{
"lc_state": "prod_end",
"min_sec_ver": 1,
"default_boot_data": "nodefault",
"expected_bfv": CONST.BFV.BOOT_DATA.NOT_FOUND,
},
{
"lc_state": "rma",
"min_sec_ver": 0,
"default_boot_data": "nodefault",
"expected_bfv": None,
},
]
[otp_json(
name = "boot_data_recovery_creator_sw_cfg_{}_{}".format(
case["lc_state"],
case["default_boot_data"],
),
partitions = [
otp_partition(
name = "CREATOR_SW_CFG",
items = {
# Set the min_sec version.
"CREATOR_SW_CFG_MIN_SEC_VER_ROM_EXT": hex(case["min_sec_ver"]),
# Set allowing use of default boot data in PROD LC state.
"CREATOR_SW_CFG_DEFAULT_BOOT_DATA_IN_PROD_EN": hex(
CONST.TRUE if case["default_boot_data"] == "default" else CONST.FALSE,
),
},
),
],
) for case in BOOT_DATA_RECOVERY_CASES]
[otp_image(
name = "otp_img_boot_data_recovery_{}_{}".format(
case["lc_state"],
case["default_boot_data"],
),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(case["lc_state"]),
overlays = STD_OTP_OVERLAYS + [":boot_data_recovery_creator_sw_cfg_{}_{}".format(
case["lc_state"],
case["default_boot_data"],
)],
) for case in BOOT_DATA_RECOVERY_CASES]
[bitstream_splice(
name = "bitstream_boot_data_recovery_{}_{}".format(
case["lc_state"],
case["default_boot_data"],
),
src = "//hw/bitstream:rom",
data = ":otp_img_boot_data_recovery_{}_{}".format(
case["lc_state"],
case["default_boot_data"],
),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"] + maybe_skip_in_ci(getattr(
CONST.LCV,
case["lc_state"].upper(),
)),
update_usr_access = True,
) for case in BOOT_DATA_RECOVERY_CASES]
[opentitan_flash_binary(
name = "rom_e2e_boot_data_recovery_{}_{}".format(
case["lc_state"],
case["default_boot_data"],
),
srcs = ["empty_test.c"],
devices = [
"fpga_cw310",
],
manifest = manifest(
dict(
name = "boot_data_recovery_manifest_{}_{}".format(
case["lc_state"],
case["default_boot_data"],
),
address_translation = hex(CONST.FALSE),
identifier = hex(CONST.ROM_EXT),
security_version = hex(2),
),
),
deps = [
"//sw/device/lib/testing/test_framework:ottf_ld_silicon_creator_slot_a",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:otp",
],
) for case in BOOT_DATA_RECOVERY_CASES]
[
opentitan_functest(
name = "boot_data_recovery_{}_{}".format(
case["lc_state"],
case["default_boot_data"],
),
cw310 = cw310_params(
bitstream = ":bitstream_boot_data_recovery_{}_{}".format(
case["lc_state"],
case["default_boot_data"],
),
exit_success = MSG_TEMPLATE_BFV.format(hex_digits(case["expected_bfv"])) if case["expected_bfv"] != None else MSG_PASS,
tags = ["vivado"] + maybe_skip_in_ci(getattr(
CONST.LCV,
case["lc_state"].upper(),
)),
),
key = "fake_prod_key_0",
ot_flash_binary = ":rom_e2e_boot_data_recovery_{}_{}".format(
case["lc_state"],
case["default_boot_data"],
),
signed = True,
targets = [
"cw310_rom",
],
)
for case in BOOT_DATA_RECOVERY_CASES
]
test_suite(
name = "rom_e2e_boot_data_recovery",
tags = ["manual"],
tests = [
"boot_data_recovery_{}_{}".format(
case["lc_state"],
case["default_boot_data"],
)
for case in BOOT_DATA_RECOVERY_CASES
],
)
SHUTDOWN_WATCHDOG_BITE_THRESHOLDS = [
400000, # 2 seconds at 200 kHz
0, # Watchdog disabled
]
SHUTDOWN_WATCHDOG_CASES = [
{
"lc_state": lc_state,
"exit_success": "Returning after 1 seconds",
"bite_threshold": bite_threshold,
}
for lc_state in [
"test_unlocked0",
"rma",
]
for bite_threshold in SHUTDOWN_WATCHDOG_BITE_THRESHOLDS
] + [
{
"lc_state": lc_state,
"exit_success": "Returning after 1 seconds" if bite_threshold == 0 else "I00000[^\r\n]*\r\nROM:[0-9a-f]{8}\r\n",
"bite_threshold": bite_threshold,
}
for lc_state in [
"dev",
"prod",
"prod_end",
]
for bite_threshold in SHUTDOWN_WATCHDOG_BITE_THRESHOLDS
]
[
otp_json(
name = "otp_json_shutdown_watchdog_{}_{}".format(
t["lc_state"],
t["bite_threshold"],
),
partitions = [
otp_partition(
name = "OWNER_SW_CFG",
items = {"OWNER_SW_CFG_ROM_WATCHDOG_BITE_THRESHOLD_CYCLES": hex(t["bite_threshold"])},
),
],
)
for t in SHUTDOWN_WATCHDOG_CASES
]
[
otp_image(
name = "otp_img_shutdown_watchdog_{}_{}".format(
t["lc_state"],
t["bite_threshold"],
),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(t["lc_state"]),
overlays = STD_OTP_OVERLAYS + [
":otp_json_shutdown_watchdog_{}_{}".format(
t["lc_state"],
t["bite_threshold"],
),
],
)
for t in SHUTDOWN_WATCHDOG_CASES
]
[
bitstream_splice(
name = "bitstream_shutdown_watchdog_{}_{}".format(
t["lc_state"],
t["bite_threshold"],
),
src = "//hw/bitstream:rom",
data = ":otp_img_shutdown_watchdog_{}_{}".format(
t["lc_state"],
t["bite_threshold"],
),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"],
update_usr_access = True,
visibility = ["//visibility:private"],
)
for t in SHUTDOWN_WATCHDOG_CASES
]
[
opentitan_functest(
name = "shutdown_watchdog_{}_{}".format(
t["lc_state"],
t["bite_threshold"],
),
srcs = ["hang_test.c"],
cw310 = cw310_params(
bitstream = ":bitstream_shutdown_watchdog_{}_{}".format(
t["lc_state"],
t["bite_threshold"],
),
exit_success = t["exit_success"],
tags = ["vivado"] + maybe_skip_in_ci(getattr(
CONST.LCV,
t["lc_state"].upper(),
)),
),
local_defines = [
"HANG_SECS=1",
],
targets = ["cw310_rom"],
deps = [
"//sw/device/lib/testing/test_framework:ottf_main",
],
)
for t in SHUTDOWN_WATCHDOG_CASES
]
test_suite(
name = "rom_e2e_shutdown_watchdog",
tags = ["manual"],
tests = [
"shutdown_watchdog_{}_{}".format(
t["lc_state"],
t["bite_threshold"],
)
for t in SHUTDOWN_WATCHDOG_CASES
],
)
# list of keys that will be used to build various flash images
# it must contain at least one key of each type and contains all
# the keys used in SIGVERIFY_LCS_2_VALID_KEY
SIGVERIFY_LC_KEYS = [
FAKE_TEST_KEYS[0],
FAKE_DEV_KEYS[0],
FAKE_PROD_KEYS[0],
]
# provide a valid key for each LC state
# this key must be present in SIGVERIFY_LC_KEYS to ensure
# that the proper flush images are built
SIGVERIFY_LCS_2_VALID_KEY = {
"test_unlocked0": FAKE_TEST_KEYS[0],
"dev": FAKE_DEV_KEYS[0],
"prod": FAKE_PROD_KEYS[0],
"prod_end": FAKE_PROD_KEYS[0],
"rma": FAKE_PROD_KEYS[0],
}
[
genrule(
name = "empty_test_slot_{}_corrupted_{}_bin_signed_{}".format(slot, device, key),
testonly = True,
srcs = ["empty_test_slot_{}_{}_bin_signed_{}".format(slot, device, key)],
outs = ["empty_test_slot_{}_corrupted_{}.{}.signed.bin".format(slot, device, key)],
cmd_bash = "cat $(SRCS) > $(OUTS) && dd if=/dev/zero of=$(OUTS) bs=4 seek=7 count=1 conv=notrunc status=none".format(slot),
)
for slot in SLOTS
for device in [
"sim_dv",
"fpga_cw310",
]
for key in SIGVERIFY_LC_KEYS
]
# The below three rule sets (bin_to_vmem, scramble_flash_vmem, and filegroup)
# are needed to run `sigverify_always` test in DV.
[
bin_to_vmem(
name = "empty_test_slot_{}_corrupted_sim_dv_vmem64_signed_{}".format(slot, key),
testonly = True,
bin = "empty_test_slot_{}_corrupted_sim_dv_bin_signed_{}".format(slot, key),
word_size = 64, # Backdoor-load VMEM image uses 64-bit words
)
for slot in SLOTS
for key in SIGVERIFY_LC_KEYS
]
[
scramble_flash_vmem(
name = "empty_test_slot_{}_corrupted_sim_dv_scr_vmem64_signed_{}".format(slot, key),
testonly = True,
vmem = "empty_test_slot_{}_corrupted_sim_dv_vmem64_signed_{}".format(slot, key),
)
for slot in SLOTS
for key in SIGVERIFY_LC_KEYS
]
[
filegroup(
name = "empty_test_slot_{}_corrupted_sim_dv".format(slot),
testonly = True,
srcs = [
"empty_test_slot_{}_corrupted_sim_dv_{}_signed_{}".format(slot, file_type, key)
for file_type in [
"bin",
"vmem64",
"scr_vmem64",
]
for key in SIGVERIFY_LC_KEYS
],
)
for slot in SLOTS
]
BOOT_POLICY_VALID_CASES = [
{
"desc": "good",
"suffix": "",
},
{
"desc": "bad",
"suffix": "_corrupted",
},
]
[
opentitan_multislot_flash_binary(
name = "boot_policy_valid_img_a_{}_b_{}".format(
a["desc"],
b["desc"],
),
srcs = {
":empty_test_slot_a{}".format(a["suffix"]): {
"key": "fake_prod_key_0",
"offset": SLOTS["a"],
},
":empty_test_slot_b{}".format(b["suffix"]): {
"key": "fake_prod_key_0",
"offset": SLOTS["b"],
},
},
devices = ["fpga_cw310"],
)
for a in BOOT_POLICY_VALID_CASES
for b in BOOT_POLICY_VALID_CASES
]
[
otp_image(
name = "otp_img_boot_policy_valid_{}".format(lc_state.lower()),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state.lower()),
overlays = STD_OTP_OVERLAYS,
)
for lc_state in structs.to_dict(CONST.LCV)
]
# Splice OTP images into bitstreams
[
bitstream_splice(
name = "bitstream_boot_policy_valid_{}".format(lc_state.lower()),
src = "//hw/bitstream:rom",
data = ":otp_img_boot_policy_valid_{}".format(lc_state.lower()),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"],
update_usr_access = True,
)
for lc_state in structs.to_dict(CONST.LCV)
]
[
opentitan_functest(
name = "boot_policy_valid_{}_a_{}_b_{}".format(
lc_state,
a["desc"],
b["desc"],
),
cw310 = cw310_params(
bitstream = "bitstream_boot_policy_valid_{}".format(lc_state),
exit_failure = MSG_PASS if a["desc"] == b["desc"] and a["desc"] == "bad" else DEFAULT_TEST_FAILURE_MSG,
exit_success = MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.SIGVERIFY.BAD_ENCODED_MSG)) if a["desc"] == b["desc"] and a["desc"] == "bad" else MSG_PASS,
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
key = "multislot",
ot_flash_binary = ":boot_policy_valid_img_a_{}_b_{}".format(
a["desc"],
b["desc"],
),
targets = ["cw310_rom"],
)
for lc_state, lc_state_val in get_lc_items()
for a in BOOT_POLICY_VALID_CASES
for b in BOOT_POLICY_VALID_CASES
]
test_suite(
name = "rom_e2e_boot_policy_valid",
tags = ["manual"],
tests = [
"boot_policy_valid_{}_a_{}_b_{}".format(
lc_state,
a["desc"],
b["desc"],
)
for lc_state, _ in get_lc_items()
for a in BOOT_POLICY_VALID_CASES
for b in BOOT_POLICY_VALID_CASES
],
)
# Apply an overlay that disables ROM execution on top of the base OTP configs.
[
otp_image(
name = "img_{}_exec_disabled".format(lc_state),
src = "//hw/ip/otp_ctrl/data:otp_json_" + lc_state,
overlays = STD_OTP_OVERLAYS + ["//hw/ip/otp_ctrl/data:otp_json_exec_disabled"],
visibility = ["//visibility:private"],
)
for lc_state, _ in get_lc_items()
]
# Splice each execution-disabled OTP image into the ROM bitstream.
[
bitstream_splice(
name = "rom_otp_{}_exec_disabled".format(lc_state),
src = "//hw/bitstream:rom",
data = "img_{}_exec_disabled".format(lc_state),
meminfo = "//hw/bitstream:otp_mmi",
tags = [
"manual",
"vivado",
],
update_usr_access = True,
visibility = ["//visibility:private"],
)
for lc_state, _ in get_lc_items()
]
SRAM_JTAG_INJECTION_GDB_SCRIPT = """
target extended-remote :3333
echo :::: Send OpenOCD the 'reset halt' command.\\n
monitor reset halt
# Mitigate flakiness from the watchdog timer. Prior to connecting
# OpenOCD and GDB, the device is executing normally. The ROM has
# probably already started up and configured the watchdog timer. This is
# a problem; if the timer fires while we're connected, the interrupt
# will steal control away from the debugger and cause this test to fail.
# Thus, we need to disable the watchdog timer as quickly as possible to
# minimize the chances of it firing.
#
# The proper solution would be to disable ROM execution by provisioning
# with an OTP image that has CREATOR_SW_CFG_ROM_EXEC_EN set to zero.
#
# Initialize and disable the watchdog timer per aon_timer docs [1]. The
# hardcoded addresses were computed by adding REG_OFFSET values from
# //hw/ip/aon_timer/data:aon_timer_regs to the base address
# TOP_EARLGREY_AON_TIMER_AON_BASE_ADDR.
#
# [1]: https://docs.opentitan.org/hw/ip/aon_timer/doc/#initialization
echo :::: Disable the watchdog timer.\\n
monitor mdw 0x40470014
monitor mww 0x40470014 0
echo :::: Reset WDOG_COUNT.\\n
monitor mdw 0x40470020
monitor mww 0x40470020 0
echo :::: Clear the interrupt (if any) by writing to INTR_STATE.\\n
monitor mdw 0x40470024
monitor mww 0x40470024 0
# Before transferring the SRAM program to the device, we must configure
# the PMP unit to enable writing to and executing from SRAM. Due to
# implementation details of OpenTitan's hardware debug module, we cannot
# set pmpcfg* registers to arbitrary values [1]. However, we can safely
# modify unused PMP configuration registers. Thankfully, pmp0cfg (the
# lowest byte of CSR pmpcfg0) is unused and has the highest priority.
#
# In more detail, the problem is that our debug module implements the
# "Access Register" abstract command by assembling instructions in the
# program buffer and then executing the buffer. If one of those
# instructions clobbers the PMP configuration register that allows
# execution from the program buffer, subsequent instruction fetches will
# generate exceptions.
#
# Debug module concepts like abstract commands and the program buffer
# buffer are defined in "RISC-V External Debug Support Version 0.13.2"
# [2]. OpenTitan's (vendored-in) implementation lives in
# //hw/vendor/pulp_riscv_dbg.
#
# [1]: https://github.com/lowRISC/opentitan/issues/14978
# [2]: https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
echo :::: Configure the PMP unit.\\n
monitor reg pmpcfg0
# Write "L NAPOT X W R" to pmp{0,1,2,3}cfg in pmpcfg0. Crucially, this
# value is no less permissive than whatever the current value is.
monitor reg pmpcfg0 0x9f9f9f9f
monitor reg pmpaddr0 0xffffffff
echo :::: Value of CREATOR_SW_CFG_ROM_EXEC_EN.\\n
monitor mdw 0x40131108
echo :::: Load the SRAM program onto the device and check integrity.\\n
file sram_program.elf
load sram_program.elf
compare-sections
echo :::: Update registers before calling functions.\\n
set $sp = _stack_end
set $gp = __global_pointer$
info registers
# When testing SRAM execution, we want to be sure the code is running
# out of SRAM and not the instruction cache.
echo :::: Invalidate the icache.\\n
print icache_invalidate()
echo :::: Call sram_main().\\n
print sram_main()
echo :::: Done.\\n
"""
[
opentitan_gdb_fpga_cw310_test(
name = "sram_program_fpga_cw310_test_otp_" + lc_state,
timeout = "short",
exit_success_pattern = "sram_program\\.c:\\d+\\] PC: 0x1000[0-2][0-9a-f]{3}, SRAM: \\[0x10000000, 0x10020000\\)",
gdb_script = SRAM_JTAG_INJECTION_GDB_SCRIPT,
gdb_script_symlinks = {
"//sw/device/examples/sram_program:sram_program_fpga_cw310.elf": "sram_program.elf",
},
rom_bitstream = ":rom_otp_{}_exec_disabled".format(lc_state),
rom_kind = "Rom",
tags = [
"cw310_rom",
"vivado",
],
)
for lc_state, _ in get_lc_items(
CONST.LCV.TEST_UNLOCKED0,
CONST.LCV.DEV,
CONST.LCV.RMA,
)
]
test_suite(
name = "rom_e2e_jtag_inject_tests",
tags = ["manual"],
tests = [
"sram_program_fpga_cw310_test_otp_" + lc_state
for lc_state, _ in get_lc_items(
CONST.LCV.TEST_UNLOCKED0,
CONST.LCV.DEV,
CONST.LCV.RMA,
)
],
)
[
opentitan_functest(
name = "epmp_init_otp_" + lc_state,
srcs = ["epmp_init_test.c"],
cw310 = cw310_params(
bitstream = "//hw/bitstream:rom_otp_" + lc_state,
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
key = LC_KEY_TYPES[lc_state_val][0],
local_defines = [
"EXPECT_DEBUG={}".format(1 if lc_state_val in [
CONST.LCV.TEST_UNLOCKED0,
CONST.LCV.DEV,
CONST.LCV.RMA,
] else 0),
],
targets = [
"cw310_rom",
"verilator",
],
verilator = verilator_params(
timeout = "eternal",
otp = "//hw/ip/otp_ctrl/data:img_" + lc_state,
rom = "//sw/device/silicon_creator/rom:rom_with_fake_keys",
),
deps = [
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
"//sw/device/lib/base:csr",
"//sw/device/lib/dif:lc_ctrl",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing:lc_ctrl_testutils",
"//sw/device/lib/testing/test_framework:check",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/lib/testing/test_framework:status",
"//sw/device/silicon_creator/lib:epmp_defs",
],
)
for lc_state, lc_state_val in get_lc_items()
]
test_suite(
name = "rom_e2e_epmp_init",
tags = ["manual"],
tests = ["epmp_init_otp_" + lc_state for lc_state, _ in get_lc_items()],
)
[
opentitan_gdb_fpga_cw310_test(
name = "debug_disallowed_in_prod_fpga_cw310_test_otp_" + lc_state,
timeout = "short",
expect_debug_disallowed = lc_state_val in [
CONST.LCV.PROD,
CONST.LCV.PROD_END,
],
gdb_script = """
target extended-remote :3333
echo :::: Send OpenOCD the 'reset halt' command.\\n
monitor reset halt
echo :::: Load ROM symbols into GDB.\\n
file rom.elf
print $pc
""",
gdb_script_symlinks = {
"//sw/device/silicon_creator/rom:rom_with_fake_keys_fpga_cw310.elf": "rom.elf",
},
rom_bitstream = ":rom_otp_{}_exec_disabled".format(lc_state),
rom_kind = "Rom",
tags = [
"cw310_rom",
"vivado",
] + maybe_skip_in_ci(lc_state_val),
)
for lc_state, lc_state_val in get_lc_items(
CONST.LCV.PROD,
CONST.LCV.PROD_END,
CONST.LCV.RMA,
)
]
test_suite(
name = "rom_e2e_debug_disallowed_in_prod_tests",
tags = ["manual"],
tests = [
"debug_disallowed_in_prod_fpga_cw310_test_otp_" + lc_state
for lc_state, _ in get_lc_items(
CONST.LCV.PROD,
CONST.LCV.PROD_END,
CONST.LCV.RMA,
)
],
)
[
opentitan_gdb_fpga_cw310_test(
name = "asm_interrupt_handler_fpga_cw310_test_otp_" + lc_state,
timeout = "short",
gdb_script = """
target extended-remote :3333
echo :::: Send OpenOCD the 'reset halt' command.\\n
monitor reset halt
echo :::: Load ROM symbols into GDB.\\n
file rom.elf
echo :::: Set breakpoint on exception handler.\\n
break _asm_exception_handler
echo :::: Attempt to trigger an exception.\\n
set $pc = 0
continue
printf ":::: PC=%p. Expected PC=%p.\\n", $pc, _asm_exception_handler
if $pc == _asm_exception_handler
echo :::: Test passed!\\n
quit 0
else
echo :::: Test failed!\\n
quit 1
end
""",
gdb_script_symlinks = {
"//sw/device/silicon_creator/rom:rom_with_fake_keys_fpga_cw310.elf": "rom.elf",
},
rom_bitstream = ":rom_otp_{}_exec_disabled".format(lc_state),
rom_kind = "Rom",
tags = [
"cw310_rom",
"vivado",
] + maybe_skip_in_ci(lc_state_val),
)
for lc_state, lc_state_val in get_lc_items(
CONST.LCV.TEST_UNLOCKED0,
CONST.LCV.DEV,
CONST.LCV.RMA,
)
]
test_suite(
name = "rom_e2e_asm_interrupt_handler",
tags = ["manual"],
tests = [
"asm_interrupt_handler_fpga_cw310_test_otp_" + lc_state
for lc_state, _ in get_lc_items(
CONST.LCV.TEST_UNLOCKED0,
CONST.LCV.DEV,
CONST.LCV.RMA,
)
],
)
[
opentitan_gdb_fpga_cw310_test(
name = "shutdown_exception_asm_otp_" + lc_state,
timeout = "short",
gdb_expect_output_sequence = [
":::: About to reset.",
"unable to resume hart 0",
],
gdb_script = """
target extended-remote :3333
echo :::: Send OpenOCD the 'reset halt' command.\\n
monitor reset halt
echo :::: Load ROM symbols into GDB.\\n
file rom.elf
echo :::: Set breakpoint on exception handler.\\n
break _asm_exception_handler
echo :::: Set PC to start of main SRAM.\\n
set $pc = 0x10000000
continue
printf ":::: PC=%p. Expected PC=%p.\\n", $pc, _asm_exception_handler
if $pc != _asm_exception_handler
quit 1
end
echo :::: About to reset.\\n
continue
# Not reached.
quit 123
""",
gdb_script_symlinks = {
"//sw/device/silicon_creator/rom:rom_with_fake_keys_fpga_cw310.elf": "rom.elf",
},
rom_bitstream = ":rom_otp_{}_exec_disabled".format(lc_state),
rom_kind = "Rom",
tags = [
"cw310_rom",
"vivado",
] + maybe_skip_in_ci(lc_state_val),
)
for lc_state, lc_state_val in get_lc_items(
CONST.LCV.TEST_UNLOCKED0,
CONST.LCV.DEV,
CONST.LCV.RMA,
)
]
test_suite(
name = "rom_e2e_shutdown_exception_asm",
tags = ["manual"],
tests = [
"shutdown_exception_asm_otp_" + lc_state
for lc_state, _ in get_lc_items(
CONST.LCV.TEST_UNLOCKED0,
CONST.LCV.DEV,
CONST.LCV.RMA,
)
],
)
# Ensure that the watchdog restarts the ROM even when the bite threshold has
# been artificially inflated.
[
opentitan_gdb_fpga_cw310_test(
name = "rom_e2e_asm_watchdog_bark_fpga_cw310_test_otp_" + lc_state,
timeout = "short",
gdb_script = """
target extended-remote :3333
echo :::: Send OpenOCD the 'reset halt' command.\\n
monitor reset halt
echo :::: Load ROM symbols into GDB.\\n
file rom.elf
echo :::: Run until we check whether ROM execution is enabled.\\n
break kRomStartBootMaybeHalt
continue
printf ":::: PC=%p. Expected PC=%p.\\n", $pc, kRomStartBootMaybeHalt
if $pc != kRomStartBootMaybeHalt
quit 42
end
echo :::: Pretend execution is enabled.\\n
set $pc = kRomStartBootExecEn
break kRomStartStoreT1ToBiteThold
continue
printf ":::: PC=%p. Expected PC=%p.\\n", $pc, kRomStartStoreT1ToBiteThold
if $pc != kRomStartStoreT1ToBiteThold
quit 43
end
# Set the bite threshold to UINT32_MAX. We want to exercise that the
# bark causes control to reach the interrupt handler.
set $t1 = 0xffffffff
echo :::: Run until right after configuring the watchdog timer.\\n
break kRomStartWatchdogEnabled
continue
printf ":::: PC=%p. Expected PC=%p.\\n", $pc, kRomStartWatchdogEnabled
if $pc != kRomStartWatchdogEnabled
quit 44
end
echo :::: Set breakpoint on NMI handler.\\n
delete breakpoints
break _asm_exception_handler
echo :::: Wait for interrupt.\\n
set $pc = kRomStartBootMaybeHalt
echo :::: Continue.\\n
continue
printf ":::: PC=%p. Expected PC=%p.\\n", $pc, _asm_exception_handler
if $pc != _asm_exception_handler
quit 45
end
""",
gdb_script_symlinks = {
"//sw/device/silicon_creator/rom:rom_with_fake_keys_fpga_cw310.elf": "rom.elf",
},
rom_bitstream = ":rom_otp_{}_exec_disabled".format(lc_state),
rom_kind = "Rom",
tags = [
"cw310_rom",
"vivado",
] + maybe_skip_in_ci(lc_state_val),
)
for lc_state, lc_state_val in get_lc_items(
CONST.LCV.TEST_UNLOCKED0,
CONST.LCV.DEV,
CONST.LCV.RMA,
)
]
# Ensure that the watchdog's bite restarts the ROM.
[
opentitan_gdb_fpga_cw310_test(
name = "rom_e2e_asm_watchdog_bite_fpga_cw310_test_otp_" + lc_state,
timeout = "short",
gdb_expect_output_sequence = [
":::: Wait for interrupt.",
"Hart 0 unexpectedly reset!",
],
gdb_script = """
target extended-remote :3333
echo :::: Send OpenOCD the 'reset halt' command.\\n
monitor reset halt
echo :::: Load ROM symbols into GDB.\\n
file rom.elf
echo :::: Run until we check whether ROM execution is enabled.\\n
break kRomStartBootMaybeHalt
continue
printf ":::: PC=%p. Expected PC=%p.\\n", $pc, kRomStartBootMaybeHalt
if $pc != kRomStartBootMaybeHalt
quit 42
end
echo :::: Pretend execution is enabled.\\n
set $pc = kRomStartBootExecEn
echo :::: Run until right after configuring the watchdog timer.\\n
break kRomStartWatchdogEnabled
continue
printf ":::: PC=%p. Expected PC=%p.\\n", $pc, kRomStartWatchdogEnabled
if $pc != kRomStartWatchdogEnabled
quit 43
end
echo :::: Set breakpoint on NMI handler.\\n
delete breakpoints
break _asm_exception_handler
echo :::: Wait for interrupt.\\n
set $pc = kRomStartBootMaybeHalt
echo :::: Continue.\\n
continue
# Not reached.
quit 123
""",
gdb_script_symlinks = {
"//sw/device/silicon_creator/rom:rom_with_fake_keys_fpga_cw310.elf": "rom.elf",
},
rom_bitstream = ":rom_otp_{}_exec_disabled".format(lc_state),
rom_kind = "Rom",
tags = [
"cw310_rom",
"vivado",
] + maybe_skip_in_ci(lc_state_val),
)
for lc_state, lc_state_val in get_lc_items(
CONST.LCV.TEST_UNLOCKED0,
CONST.LCV.DEV,
CONST.LCV.RMA,
)
]
test_suite(
name = "rom_e2e_asm_watchdog",
tags = ["manual"],
tests = [
"rom_e2e_asm_watchdog_" + type + "_fpga_cw310_test_otp_" + lc_state
for lc_state, lc_state_val in get_lc_items(
CONST.LCV.TEST_UNLOCKED0,
CONST.LCV.DEV,
CONST.LCV.RMA,
)
for type in ("bite", "bark")
],
)
# Shutdown Redact Test
# Dict that also includes an invalid redaction value for test purposes.
REDACT = structs.to_dict(CONST.SHUTDOWN.REDACT)
REDACT.update({"INVALID": 0x0})
[
otp_json(
name = "otp_json_{}_overlay".format(k.lower()),
partitions = [
otp_partition(
name = "OWNER_SW_CFG",
items = {
"OWNER_SW_CFG_ROM_ERROR_REPORTING": hex(v),
},
),
],
)
for k, v in REDACT.items()
]
[
otp_image(
name = "img_{}_{}".format(
lc_state,
redact.lower(),
),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state),
overlays = STD_OTP_OVERLAYS + [":otp_json_{}_overlay".format(redact.lower())],
visibility = ["//visibility:private"],
)
for lc_state, _ in get_lc_items()
for redact in REDACT
]
[
bitstream_splice(
name = "bitstream_{}_{}".format(
lc_state,
redact.lower(),
),
src = "//hw/bitstream:rom",
data = ":img_{}_{}".format(
lc_state,
redact.lower(),
),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"],
update_usr_access = True,
visibility = ["//visibility:private"],
)
for lc_state, _ in get_lc_items()
for redact in REDACT
]
[
opentitan_functest(
name = "e2e_shutdown_redact_{}_{}".format(
lc_state,
redact.lower(),
),
srcs = ["empty_test.c"],
cw310 = cw310_params(
bitstream = "bitstream_{}_{}".format(
lc_state,
redact.lower(),
),
exit_failure = MSG_PASS,
exit_success = MSG_TEMPLATE_BFV.format(hex_digits(error_redact(
CONST.BFV.BOOT_POLICY.BAD_IDENTIFIER,
lc_state_val,
redact_val,
))),
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
signed = False,
targets = ["cw310_rom"],
deps = [
"//hw/ip/otp_ctrl/data:otp_ctrl_regs",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:lifecycle",
"//sw/device/silicon_creator/lib/drivers:otp",
],
)
for lc_state, lc_state_val in get_lc_items()
for redact, redact_val in REDACT.items()
]
test_suite(
name = "rom_e2e_shutdown_redact",
tags = ["manual"],
tests = [
"e2e_shutdown_redact_{}_{}".format(
lc_state,
redact.lower(),
)
for lc_state, _ in get_lc_items()
for redact in REDACT
],
)
[
opentitan_multislot_flash_binary(
name = "sigverify_always_img_a_{}_b_{}_{}".format(
"nothing" if slot == "b" else "bad",
"nothing" if slot == "a" else "bad",
key,
),
srcs = {
":empty_test_slot_{}_corrupted".format(slot): {
"key": key,
"offset": offset,
},
},
devices = [
"sim_dv",
"fpga_cw310",
],
)
for slot, offset in SLOTS.items()
for key in SIGVERIFY_LC_KEYS
]
[
opentitan_multislot_flash_binary(
name = "sigverify_always_img_a_bad_b_bad_{}".format(key),
srcs = {
":empty_test_slot_a_corrupted": {
"key": key,
"offset": SLOTS["a"],
},
":empty_test_slot_b_corrupted": {
"key": key,
"offset": SLOTS["b"],
},
},
devices = [
"sim_dv",
"fpga_cw310",
],
)
for key in SIGVERIFY_LC_KEYS
]
# Since we cannot feed the `assemble_flash_image` rule that is instantiated by
# the `opentitan_multislot_flash_binary` macro an empty dictionary, we create
# two images with "nothing" in them by created files of all ones, and stitching
# them together.
[
genrule(
name = "sigverify_always_img_{}_nothing_{}_bin_signed_{}".format(slot, device, key),
outs = ["sigverify_always_img_{}_all_ones_{}_bin_signed_{}".format(slot, device, key)],
cmd_bash = "touch $(OUTS)",
)
for slot in SLOTS
for device in [
"sim_dv",
"fpga_cw310",
]
for key in SIGVERIFY_LC_KEYS
]
[
opentitan_multislot_flash_binary(
name = "sigverify_always_img_a_nothing_b_nothing_{}".format(key),
srcs = {
":sigverify_always_img_a_nothing": {
"key": key,
"offset": SLOTS["a"],
},
":sigverify_always_img_b_nothing": {
"key": key,
"offset": SLOTS["b"],
},
},
devices = [
"sim_dv",
"fpga_cw310",
],
)
for key in SIGVERIFY_LC_KEYS
]
[otp_image(
name = "otp_img_sigverify_always_{}".format(lc_state),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state),
overlays = STD_OTP_OVERLAYS,
) for lc_state, _ in get_lc_items()]
# Splice OTP images into bitstreams
[
bitstream_splice(
name = "bitstream_sigverify_always_{}".format(lc_state),
src = "//hw/bitstream:rom",
data = ":otp_img_sigverify_always_{}".format(lc_state),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
update_usr_access = True,
)
for lc_state, lc_state_val in get_lc_items()
]
SIGVERIFY_BAD_CASES = [
{
"a": "nothing",
"b": "bad",
"expected_bfv": hex_digits(CONST.BFV.SIGVERIFY.BAD_ENCODED_MSG),
},
{
"a": "bad",
"b": "nothing",
"expected_bfv": hex_digits(CONST.BFV.SIGVERIFY.BAD_ENCODED_MSG),
},
{
"a": "bad",
"b": "bad",
"expected_bfv": hex_digits(CONST.BFV.SIGVERIFY.BAD_ENCODED_MSG),
},
{
"a": "nothing",
"b": "nothing",
"expected_bfv": hex_digits(CONST.BFV.BOOT_POLICY.BAD_IDENTIFIER),
},
]
[
opentitan_functest(
name = "sigverify_always_{}_a_{}_b_{}".format(
lc_state,
case["a"],
case["b"],
),
cw310 = cw310_params(
bitstream = ":bitstream_sigverify_always_{}".format(lc_state),
exit_failure = MSG_PASS,
exit_success = MSG_TEMPLATE_BFV_LCV.format(
case["expected_bfv"],
hex_digits(lc_state_val),
),
otp = ":otp_img_sigverify_always_{}".format(lc_state),
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
dv = dv_params(
otp = ":otp_img_sigverify_always_{}".format(lc_state),
rom = "//sw/device/silicon_creator/rom:rom_with_fake_keys",
),
key = "multislot",
ot_flash_binary = ":sigverify_always_img_a_{}_b_{}_{}".format(
case["a"],
case["b"],
SIGVERIFY_LCS_2_VALID_KEY[lc_state],
),
targets = [
"dv",
"cw310_rom",
],
)
for case in SIGVERIFY_BAD_CASES
for lc_state, lc_state_val in get_lc_items()
]
test_suite(
name = "sigverify_always",
tags = ["manual"],
tests = [
"sigverify_always_{}_a_{}_b_{}".format(
lc_state,
case["a"],
case["b"],
)
for case in SIGVERIFY_BAD_CASES
for lc_state, _ in get_lc_items()
],
)
[
otp_image(
name = "otp_img_sigverify_key_type_{}".format(lc_state),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state),
overlays = STD_OTP_OVERLAYS,
)
for lc_state, _ in get_lc_items()
]
[
bitstream_splice(
name = "bitstream_sigverify_key_type_{}".format(
lc_state,
),
src = "//hw/bitstream:rom",
data = ":otp_img_sigverify_key_type_{}".format(
lc_state,
),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
update_usr_access = True,
visibility = ["//visibility:private"],
)
for lc_state, lc_state_val in get_lc_items()
]
# list of the keys to test when doing a full key set test
SIGVERIFY_FULL_KEY_SET = FAKE_ALL_KEYS
[
opentitan_functest(
name = "sigverify_key_type_{}_{}".format(
lc_state,
key,
),
cw310 = cw310_params(
bitstream = ":bitstream_sigverify_key_type_{}".format(lc_state),
exit_failure = MSG_PASS if key not in LC_KEY_TYPES[lc_state_val] else MSG_TEMPLATE_BFV_LCV.format(
hex_digits(CONST.BFV.SIGVERIFY.BAD_KEY),
hex_digits(lc_state_val),
),
exit_success = MSG_PASS if key in LC_KEY_TYPES[lc_state_val] else MSG_TEMPLATE_BFV_LCV.format(
hex_digits(CONST.BFV.SIGVERIFY.BAD_KEY),
hex_digits(lc_state_val),
),
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
key = key,
ot_flash_binary = "empty_test_slot_a",
targets = [
"cw310_rom",
],
)
for lc_state, lc_state_val in get_lc_items()
for key in SIGVERIFY_FULL_KEY_SET
]
test_suite(
name = "rom_e2e_sigverify_key_type",
tags = ["manual"],
tests = [
"sigverify_key_type_{}_{}".format(
lc_state,
key,
)
for lc_state, _ in get_lc_items()
for key in SIGVERIFY_FULL_KEY_SET
],
)
otp_json(
name = "otp_json_sigverify_key_validity",
partitions = [
otp_partition(
name = "CREATOR_SW_CFG",
items = {
"CREATOR_SW_CFG_SIGVERIFY_RSA_KEY_EN": "0x4b4b4b4b4bff004b",
},
),
],
)
[
otp_image(
name = "otp_img_sigverify_key_validity_{}".format(lc_state),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state),
overlays = STD_OTP_OVERLAYS + [":otp_json_sigverify_key_validity"],
)
for lc_state, _ in get_lc_items()
]
[
bitstream_splice(
name = "bitstream_sigverify_key_validity_{}".format(
lc_state,
),
src = "//hw/bitstream:rom",
data = ":otp_img_sigverify_key_validity_{}".format(
lc_state,
),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
update_usr_access = True,
visibility = ["//visibility:private"],
)
for lc_state, lc_state_val in get_lc_items()
]
[
opentitan_functest(
name = "sigverify_key_validity_{}_{}".format(
lc_state,
key,
),
cw310 = cw310_params(
bitstream = ":bitstream_sigverify_key_validity_{}".format(lc_state),
exit_failure = MSG_PASS if lc_state_val != CONST.LCV.TEST_UNLOCKED0 else MSG_TEMPLATE_BFV_LCV.format(
hex_digits(CONST.BFV.SIGVERIFY.BAD_KEY),
hex_digits(lc_state_val),
),
exit_success = MSG_TEMPLATE_BFV_LCV.format(
hex_digits(CONST.BFV.SIGVERIFY.BAD_KEY),
hex_digits(lc_state_val),
) if lc_state_val != CONST.LCV.TEST_UNLOCKED0 else MSG_PASS,
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
key = key,
ot_flash_binary = "empty_test_slot_a",
targets = [
"cw310_rom",
],
)
for lc_state, lc_state_val in get_lc_items()
for key in LC_KEY_TYPES[lc_state_val]
]
test_suite(
name = "rom_e2e_sigverify_key_validity",
tags = ["manual"],
tests = [
"sigverify_key_validity_{}_{}".format(
lc_state,
key,
)
for lc_state, lc_state_val in get_lc_items()
for key in LC_KEY_TYPES[lc_state_val]
],
)
# Sigverify usage constraint tests
_test_device_id = [
"0xa0a1a2a3", # Least-significant word
"0x12345678",
"0x00000003",
"0xabababab",
"0xcdcdcdcd",
"0x01010101",
"0x10101010",
"0xf0f1f2f3", # Most-significant word
]
_test_manuf_states = {
"creator": "0xfedcba98",
"owner": "0x12345678",
}
# Generate OTP image with a specific device ID, creator manufacturing state,
# and owner manufacturing state
_test_device_id_joined = "0x" + "".join([word[2:] for word in reversed(_test_device_id)])
otp_json(
name = "otp_json_set_usage_constraint_params_overlay",
partitions = [
otp_partition(
name = "HW_CFG",
items = {"DEVICE_ID": _test_device_id_joined},
),
otp_partition(
name = "CREATOR_SW_CFG",
items = {"CREATOR_SW_CFG_MANUF_STATE": _test_manuf_states["creator"]},
),
otp_partition(
name = "OWNER_SW_CFG",
items = {"OWNER_SW_CFG_MANUF_STATE": _test_manuf_states["owner"]},
),
],
visibility = ["//visibility:private"],
)
[otp_image(
name = "otp_img_sigverify_usage_constraints_{}".format(lc_state),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state),
overlays = STD_OTP_OVERLAYS + [":otp_json_set_usage_constraint_params_overlay"],
visibility = ["//visibility:private"],
) for lc_state, _ in get_lc_items()]
[bitstream_splice(
name = "bitstream_sigverify_usage_constraints_{}".format(lc_state),
src = "//hw/bitstream:rom",
data = ":otp_img_sigverify_usage_constraints_{}".format(lc_state),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
update_usr_access = True,
visibility = ["//visibility:private"],
) for lc_state, lc_state_val in get_lc_items()]
_SIGVERIFY_FAIL_MSG = MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.SIGVERIFY.BAD_ENCODED_MSG))
device_id_test_cases = [
{
"name": "device_id_match",
"manifest": {
"selector_bits": "0xff",
"device_id": _test_device_id,
},
"bitstream": ":bitstream_sigverify_usage_constraints_rma",
"exit_success": DEFAULT_TEST_SUCCESS_MSG,
"exit_failure": _SIGVERIFY_FAIL_MSG,
"lc_state_val": CONST.LCV.RMA,
},
{
"name": "device_id_no_match",
"manifest": {
"selector_bits": "0xff",
"device_id": ["0xbad"] * 8,
},
"bitstream": ":bitstream_sigverify_usage_constraints_rma",
"exit_success": _SIGVERIFY_FAIL_MSG,
"exit_failure": DEFAULT_TEST_SUCCESS_MSG,
"lc_state_val": CONST.LCV.RMA,
},
{
"name": "device_id_family_match",
"manifest": {
# Select words 0, 3, and 5 to match on:
# 0b0010_1001 = 0x29
"selector_bits": "0x29",
"device_id": [
_test_device_id[0],
hex(CONST.DEFAULT_USAGE_CONSTRAINTS),
hex(CONST.DEFAULT_USAGE_CONSTRAINTS),
_test_device_id[3],
hex(CONST.DEFAULT_USAGE_CONSTRAINTS),
_test_device_id[5],
hex(CONST.DEFAULT_USAGE_CONSTRAINTS),
hex(CONST.DEFAULT_USAGE_CONSTRAINTS),
],
},
"bitstream": ":bitstream_sigverify_usage_constraints_rma",
"exit_success": DEFAULT_TEST_SUCCESS_MSG,
"exit_failure": _SIGVERIFY_FAIL_MSG,
"lc_state_val": CONST.LCV.RMA,
},
{
"name": "device_id_family_no_match",
"manifest": {
# Select words 0, 3, and 5 to match on:
# 0b0010_1001 = 0x29
"selector_bits": "0x29",
"device_id": [
"0xbad",
hex(CONST.DEFAULT_USAGE_CONSTRAINTS),
hex(CONST.DEFAULT_USAGE_CONSTRAINTS),
"0xbad",
hex(CONST.DEFAULT_USAGE_CONSTRAINTS),
"0xbad",
hex(CONST.DEFAULT_USAGE_CONSTRAINTS),
hex(CONST.DEFAULT_USAGE_CONSTRAINTS),
],
},
"bitstream": ":bitstream_sigverify_usage_constraints_rma",
"exit_success": _SIGVERIFY_FAIL_MSG,
"exit_failure": DEFAULT_TEST_SUCCESS_MSG,
"lc_state_val": CONST.LCV.RMA,
},
]
lc_state_test_cases = [
{
"name": "lc_state_{}_{}".format(
lc_state,
"match" if match_case else "no_match",
),
# Note: the manifest value for a given life-cycle state is determined
# by CONST.LCV_SW instead of CONST.LCV. These two structs have slightly
# different mappings for the TEST_* LC state, so lc_hw_to_sw is used to
# convert from the names in CONST.LCV to those in CONST.LCV_SW before
# performing the lookup.
"manifest": {
"selector_bits": "0x400",
"life_cycle_state": hex(lcv_hw_to_sw(lc_state_val)) if match_case else "0",
},
"bitstream": ":bitstream_sigverify_usage_constraints_{}".format(lc_state),
"exit_success": DEFAULT_TEST_SUCCESS_MSG if match_case else _SIGVERIFY_FAIL_MSG,
"exit_failure": _SIGVERIFY_FAIL_MSG if match_case else DEFAULT_TEST_SUCCESS_MSG,
"lc_state_val": lc_state_val,
}
for lc_state, lc_state_val in get_lc_items()
for match_case in (True, False)
]
manuf_state_test_cases = [
{
"name": "manuf_state_{}_{}".format(
entity,
"match" if match_case else "no_match",
),
"manifest": {
"selector_bits": "0x100" if entity == "creator" else "0x200",
"manuf_state_{}".format(entity): "{}".format(_test_manuf_states[entity]) if match_case else "0",
},
"bitstream": ":bitstream_sigverify_usage_constraints_rma",
"exit_success": DEFAULT_TEST_SUCCESS_MSG if match_case else _SIGVERIFY_FAIL_MSG,
"exit_failure": _SIGVERIFY_FAIL_MSG if match_case else DEFAULT_TEST_SUCCESS_MSG,
"lc_state_val": CONST.LCV.RMA,
}
for entity in ("creator", "owner")
for match_case in (True, False)
]
# The all-constraints case is tested against all LC states. For each LC state,
# we try all 5 LC state settings in the manifest and ensure that only one
# boots successfully.
all_constr_test_cases = [
{
"name": "all_constraints_mf_lc_{}_bs_lc_{}".format(
mf_lc_state.lower(),
bs_lc_state,
),
"manifest": {
"selector_bits": "0x7ff",
"device_id": _test_device_id,
"life_cycle_state": hex(mf_lc_val),
"manuf_state_creator": _test_manuf_states["creator"],
"manuf_state_owner": _test_manuf_states["owner"],
},
"bitstream": ":bitstream_sigverify_usage_constraints_{}".format(bs_lc_state),
"exit_success": DEFAULT_TEST_SUCCESS_MSG if mf_lc_val == lcv_hw_to_sw(bs_lc_val) else _SIGVERIFY_FAIL_MSG,
"exit_failure": _SIGVERIFY_FAIL_MSG if mf_lc_val == lcv_hw_to_sw(bs_lc_val) else DEFAULT_TEST_SUCCESS_MSG,
"lc_state_val": bs_lc_val,
}
for mf_lc_state, mf_lc_val in structs.to_dict(CONST.LCV_SW).items()
for bs_lc_state, bs_lc_val in get_lc_items()
]
# Usage constraints that are not selected by the selector_bits must be set to
# MANIFEST_USAGE_CONSTRAINT_UNSELECTED_WORD. These tests check for a failure if
# they are not by setting various fields to otherwise valid values while
# setting the selector_bits to 0.
invalid_unselected_word_cases = [
{
"name": "invalid_unselected_{}".format(field),
"manifest": {
field: field_val,
"selector_bits": "0",
"selector_mismatch_is_failure": False,
},
"bitstream": ":bitstream_sigverify_usage_constraints_rma",
"exit_success": _SIGVERIFY_FAIL_MSG,
"exit_failure": DEFAULT_TEST_SUCCESS_MSG,
"lc_state_val": CONST.LCV.RMA,
}
for field, field_val in [
("device_id", _test_device_id),
(
"life_cycle_state",
hex(CONST.LCV_SW.RMA),
),
(
"manuf_state_creator",
_test_manuf_states["creator"],
),
(
"manuf_state_owner",
_test_manuf_states["owner"],
),
]
]
test_cases = device_id_test_cases + lc_state_test_cases + manuf_state_test_cases + all_constr_test_cases + invalid_unselected_word_cases
[opentitan_functest(
name = "sigverify_usage_constraint_{}".format(t["name"]),
srcs = ["empty_test.c"],
cw310 = cw310_params(
bitstream = t["bitstream"],
exit_failure = t["exit_failure"],
exit_success = t["exit_success"],
tags = ["vivado"] + maybe_skip_in_ci(t["lc_state_val"]),
),
manifest = manifest(
dict(
t["manifest"],
name = "sigverify_usage_constraint_manifest_{}".format(t["name"]),
address_translation = hex(CONST.FALSE),
identifier = hex(CONST.ROM_EXT),
),
),
signed = True,
targets = ["cw310_rom"],
deps = [
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib/drivers:otp",
],
) for t in test_cases]
test_suite(
name = "rom_e2e_sigverify_usage_constraints",
tags = ["manual"],
tests = ["sigverify_usage_constraint_{}".format(t["name"]) for t in test_cases],
)
[
opentitan_gdb_fpga_cw310_test(
name = "rom_e2e_debug_test_otp_" + lc_state,
timeout = "short",
exit_success_pattern = "OK!GDB-OK(?s:.*)BFV:0142500d",
gdb_expect_output_sequence = [
":::: GDB script complete.",
"Hart 0 unexpectedly reset!",
],
gdb_script = """
define assert_pc
printf ":::: PC=%p. Expected PC=%p.\\n", $pc, $arg0
if $pc != $arg0
quit 1
end
end
target extended-remote :3333
echo :::: Send OpenOCD the 'reset halt' command.\\n
monitor reset halt
echo :::: Load ROM symbols into GDB.\\n
file rom.elf
# Immediately after reset, we should be sitting on the Ibex reset
# handler, the 33rd entry in the interrupt vector.
set $ibex_reset_handler = _rom_interrupt_vector_asm + 32 * 4
assert_pc $ibex_reset_handler
# Executing the `j _rom_start_boot` instruction should take us
# to _rom_start_boot.
stepi
assert_pc _rom_start_boot
echo :::: Run until we check whether ROM execution is enabled.\\n
break kRomStartBootMaybeHalt
continue
assert_pc kRomStartBootMaybeHalt
# Use three of four hardware breakpoints. Leave one unused so we can
# use `call` and `finish`. (See RvCoreIbexDbgHwBreakNum in
# hw/top_earlgrey/data/top_earlgrey.hjson.)
echo :::: Set all but one available breakpoints.\\n
# Set a breakpoint at the actual address of rom_main(), without
# trying to skip the function prologue.
break *rom_main
break *uart_init
echo :::: Pretend execution is enabled.\\n
set $pc = kRomStartBootExecEn
echo :::: Continue until watchdog config.\\n
break kRomStartWatchdogEnabled
continue
echo :::: Disable watchdog config.\\n
set {{int}}{watchdog_ctrl_reg_addr} = 0
delete 4
echo :::: Continue until rom_main.\\n
continue
assert_pc rom_main
echo :::: Continue until uart_init.\\n
continue
assert_pc uart_init
echo :::: Finish uart_init.\\n
finish
echo :::: Read and write GPRs.\\n
{gpr_copy_commands}
{gpr_set_commands}
{gpr_restore_commands}
echo :::: Read selected CSRs.\\n
{csr_copy_commands}
{csr_set_commands}
{csr_restore_commands}
echo :::: Read and write memory (both SRAM and device).\\n
# See hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
set $sram_base = 0x10000000
set $sram_len = 0x00008000
x/16xb $sram_base
x/16xb $sram_base + ($sram_len / 2)
x/16xb $sram_base + $sram_len - 16
echo :::: Manually write bytes to UART0.\\n
set $uart0_base = 0x40000000
set $uart_wdata = 0x1c
print *(uint32_t*)($uart0_base + $uart_wdata) = 'O'
print *(uint32_t*)($uart0_base + $uart_wdata) = 'K'
print *(uint32_t*)($uart0_base + $uart_wdata) = '!'
echo :::: Execute code from GDB with `call` command.\\n
call uart_putchar('G')
call uart_putchar('D')
call uart_putchar('B')
call uart_putchar('-')
call uart_putchar('O')
call uart_putchar('K')
call uart_putchar('\\r')
call uart_putchar('\\n')
echo :::: GDB script complete.\\n
continue
""".format(
csr_copy_commands = gdb_commands_copy_registers(get_gdb_readable_csr_names()),
csr_restore_commands = gdb_commands_restore_registers(get_gdb_settable_csr_names()),
csr_set_commands = gdb_commands_set_registers(
"0x89abcdef",
get_gdb_settable_csr_names(),
),
gpr_copy_commands = gdb_commands_copy_registers(IBEX_GPRS),
gpr_restore_commands = gdb_commands_restore_registers(IBEX_GPRS),
gpr_set_commands = gdb_commands_set_registers("0x89abcdef", IBEX_GPRS),
watchdog_ctrl_reg_addr = "0x40470014",
),
gdb_script_symlinks = {
"//sw/device/silicon_creator/rom:rom_with_fake_keys_fpga_cw310.elf": "rom.elf",
},
rom_bitstream = ":rom_otp_{}_exec_disabled".format(lc_state),
rom_kind = "Rom",
tags = [
"cw310_rom",
"exclusive",
"vivado",
] + maybe_skip_in_ci(lc_state_val),
)
for lc_state, lc_state_val in get_lc_items(
CONST.LCV.TEST_UNLOCKED0,
CONST.LCV.DEV,
CONST.LCV.RMA,
)
]
test_suite(
name = "rom_e2e_debug_test",
tags = ["manual"],
tests = [
"rom_e2e_debug_test_otp_" + lc_state
for lc_state, _ in get_lc_items(
CONST.LCV.TEST_UNLOCKED0,
CONST.LCV.DEV,
CONST.LCV.RMA,
)
],
)
opentitan_flash_binary(
name = "rom_ext_upgrade_test",
srcs = ["rom_ext_upgrade_test.c"],
devices = [
"fpga_cw310",
],
deps = [
"//hw/ip/otp_ctrl/data:otp_ctrl_regs",
"//sw/device/lib/testing/test_framework:ottf_ld_silicon_creator_slot_a",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib:boot_data",
"//sw/device/silicon_creator/lib/drivers:lifecycle",
"//sw/device/silicon_creator/lib/drivers:otp",
"//sw/device/silicon_creator/lib/drivers:rstmgr",
],
)
opentitan_functest(
name = "rom_ext_upgrade",
cw310 = cw310_params(
# Fail if we see version 3, because the test has updated twice, FAIL, version 0 twice, or PASS
exit_failure = "(min_security_version_rom_ext:[^01])|(FAIL)|((min_security_version_rom_ext:0(?s:.*)){2,})|(PASS)",
exit_success = "min_security_version_rom_ext:0(?s:.*)min_security_version_rom_ext:1(?s:.*)" + MSG_TEMPLATE_BFV.format(hex_digits(CONST.BFV.BOOT_POLICY.ROLLBACK)),
test_cmds = [
"--exec=\"fpga load-bitstream --rom-kind=rom $(rootpath {bitstream})\"",
"--exec=\"bootstrap --clear-uart=true $(rootpath {flash})\"",
"--exec=\"console --exit-success={exit_success} --exit-failure={exit_failure}\"",
"fpga",
"load-bitstream",
"$(rootpath {bitstream})", # This test should clean up after itself
],
),
ot_flash_binary = "rom_ext_upgrade_test",
targets = [
"cw310_rom",
],
)
otp_json(
name = "otp_json_reset_ret_ram_overlay",
partitions = [
otp_partition(
name = "CREATOR_SW_CFG",
# Set the mask to 1 << kRstmgrReasonSoftwareRequest to trigger a
# retention RAM reset after a SW-requested reset
items = {"CREATOR_SW_CFG_RET_RAM_RESET_MASK": "0x4"},
),
],
)
otp_image(
name = "otp_img_reset_ret_ram",
src = "//hw/ip/otp_ctrl/data:otp_json_rma",
overlays = STD_OTP_OVERLAYS + [":otp_json_reset_ret_ram_overlay"],
visibility = ["//visibility:private"],
)
bitstream_splice(
name = "bitstream_reset_ret_ram",
src = "//hw/bitstream:rom",
data = ":otp_img_reset_ret_ram",
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"] + maybe_skip_in_ci(CONST.LCV.RMA),
update_usr_access = True,
visibility = ["//visibility:private"],
)
opentitan_functest(
name = "rom_e2e_ret_ram_init",
srcs = ["rom_e2e_ret_ram_init_test.c"],
cw310 = cw310_params(
bitstream = ":bitstream_reset_ret_ram",
tags = ["vivado"] + maybe_skip_in_ci(CONST.LCV.RMA),
),
signed = True,
targets = [
"cw310_rom",
],
deps = [
"//sw/device/lib/base:memory",
"//sw/device/lib/dif:rstmgr",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib:test_main",
"//sw/device/silicon_creator/lib/drivers:retention_sram",
"//sw/device/silicon_creator/lib/drivers:rstmgr",
],
)
opentitan_functest(
name = "rom_e2e_ret_ram_keep",
srcs = ["rom_e2e_ret_ram_keep_test.c"],
cw310 = cw310_params(
bitstream = "//hw/bitstream:rom",
tags = ["vivado"] + maybe_skip_in_ci(CONST.LCV.RMA),
),
signed = True,
targets = [
"cw310_rom",
],
deps = [
"//hw/top_earlgrey/ip/pwrmgr/data/autogen:pwrmgr_regs",
"//sw/device/lib/base:memory",
"//sw/device/lib/dif:aon_timer",
"//sw/device/lib/dif:pwrmgr",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing:aon_timer_testutils",
"//sw/device/lib/testing:pwrmgr_testutils",
"//sw/device/lib/testing/test_framework:check",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib:test_main",
"//sw/device/silicon_creator/lib/drivers:retention_sram",
"//sw/device/silicon_creator/lib/drivers:rstmgr",
],
)
manifest({
"name": "manifest_rom_ext_upgrade_interrupt",
"address_translation": hex(CONST.FALSE),
"identifier": hex(CONST.ROM_EXT),
"security_version": hex(10),
})
otp_json(
name = "otp_json_rom_ext_upgrade_interrupt",
partitions = [
otp_partition(
name = "CREATOR_SW_CFG",
items = {
"CREATOR_SW_CFG_DEFAULT_BOOT_DATA_IN_PROD_EN": hex(CONST.TRUE),
},
),
],
)
[
otp_image(
name = "otp_img_rom_ext_upgrade_interrupt_{}".format(lc_state),
src = "//hw/ip/otp_ctrl/data:otp_json_{}".format(lc_state),
overlays = STD_OTP_OVERLAYS + [":otp_json_rom_ext_upgrade_interrupt"],
visibility = ["//visibility:private"],
)
for lc_state, _ in get_lc_items()
]
[
bitstream_splice(
name = "bitstream_rom_ext_upgrade_interrupt_{}".format(
lc_state,
),
src = "//hw/bitstream:rom",
data = ":otp_img_rom_ext_upgrade_interrupt_{}".format(
lc_state,
),
meminfo = "//hw/bitstream:otp_mmi",
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
update_usr_access = True,
visibility = ["//visibility:private"],
)
for lc_state, lc_state_val in get_lc_items()
]
[
opentitan_functest(
name = "rom_ext_upgrade_interrupt_{}".format(lc_state),
srcs = ["rom_ext_upgrade_interrupt.c"],
cw310 = cw310_params(
bitstream = ":bitstream_rom_ext_upgrade_interrupt_{}".format(lc_state),
clear_bitstream = True,
tags = ["vivado"] + maybe_skip_in_ci(lc_state_val),
),
manifest = ":manifest_rom_ext_upgrade_interrupt",
targets = [
"cw310_rom",
],
deps = [
"//sw/device/lib/testing:flash_ctrl_testutils",
"//sw/device/lib/testing/test_framework:check",
"//sw/device/lib/testing/test_framework:ottf_main",
"//sw/device/silicon_creator/lib:boot_data",
"//sw/device/silicon_creator/lib:test_main",
"//sw/device/silicon_creator/lib/drivers:lifecycle",
"//sw/device/silicon_creator/lib/drivers:rstmgr",
],
)
for lc_state, lc_state_val in get_lc_items()
]
test_suite(
name = "rom_e2e_rom_ext_upgrade_interrupt",
tags = ["manual"],
tests = ["rom_ext_upgrade_interrupt_{}".format(lc_state) for lc_state, _ in get_lc_items()],
)