[bazel] Restructure `opentitan_binary` and `opentitan_functest` macros
Verilator simulations can take as input either a scrambled VMEM file or
an ELF file to load the simulated flash memory with. However, the
existing signing tool, can only sign BIN files, and BIN files can only
be converted to VMEM files (since ELF section header info is lost).
Therefore, in order to run Verilator simulations with signed flash
images, for mask ROM testing, the bazel `opentitan_binary` macro must
be able to convert singed BIN files into scrambled VMEM files.
Currently, the `opentitan_binary` macro is used to generate both ROM and
flash images for simulations, since the simulated ROM takes as input a
scrambled VMEM file, that can be generated from an ELF file (so the
same macro could generate ELFs for either ROM or flash, and if the image
was destined for ROM, it could just be processed further).
Unfortunately, the scrambled VMEM format used for ROM, is different from
that used for flash (i.e., 32 vs. 64 bit words), and, using the
same bazel macro (i.e., `opentitan_binary`) to generate two different
scrambled VMEM files (one for ROM and one for flash) adds too much
complexity to the macro.
Therefore, this commit, brakes the original `opentitan_binary` macro
intro three macros, to simplify the implementation of each, while
maximizing code reuse. These include:
1. `opentitan_binary`: a macro used to generate ".elf", ".bin", and
".dis" files for RV32I targets,
2. `opentitan_rom_binary`: a macro that invokes `opentitan_binary`
under the hood, and then translates the resulting ".elf" into a
scrambled 32-bit VMEM file (required for ROM), and
3. `opentitan_flash_binary`: a macro that invokes `opentitan_binary`
under the hood, and then (optionally) signs, and translates the
resulting ".bin" files into scrambled 64-bit VMEM files (required
for flash).
This fixes #10876, and enables running `opentitan_functest`s with mask
ROM (and test ROM) on both Verilator and CW310 hardware targets.
Signed-off-by: Timothy Trippel <ttrippel@google.com>
diff --git a/rules/autogen.bzl b/rules/autogen.bzl
index 0006ae8..579badb 100644
--- a/rules/autogen.bzl
+++ b/rules/autogen.bzl
@@ -87,6 +87,6 @@
attrs = {
"src": attr.label(allow_files = True),
"deps": attr.label_list(allow_files = True),
- "_tool": attr.label(default = "//util:design/gen-otp-img.py", allow_files = True),
+ "_tool": attr.label(default = "//util/design:gen-otp-img.py", allow_files = True),
},
)
diff --git a/rules/opentitan.bzl b/rules/opentitan.bzl
index cd75050..9c00581 100644
--- a/rules/opentitan.bzl
+++ b/rules/opentitan.bzl
@@ -15,6 +15,17 @@
OPENTITAN_PLATFORM: [OPENTITAN_CPU],
}
+# This constant holds a dictionary of per-device dependencies which are used to
+# generate slightly different binaries for each hardware target, including two
+# simulation platforms (DV and Verilator), and two FPGA platforms (NexysVideo
+# and CW310).
+PER_DEVICE_DEPS = {
+ "sim_verilator": ["//sw/device/lib/arch:sim_verilator"],
+ "sim_dv": ["//sw/device/lib/arch:sim_dv"],
+ "fpga_nexysvideo": ["//sw/device/lib/arch:fpga_nexysvideo"],
+ "fpga_cw310": ["//sw/device/lib/arch:fpga_cw310"],
+}
+
def _opentitan_transition_impl(settings, attr):
return {"//command_line_option:platforms": attr.platform}
@@ -24,7 +35,7 @@
outputs = ["//command_line_option:platforms"],
)
-def _obj_transform(ctx):
+def _obj_transform_impl(ctx):
cc_toolchain = find_cc_toolchain(ctx)
outputs = []
for src in ctx.files.srcs:
@@ -44,7 +55,7 @@
return [DefaultInfo(files = depset(outputs), data_runfiles = ctx.runfiles(files = outputs))]
obj_transform = rule(
- implementation = _obj_transform,
+ implementation = _obj_transform_impl,
cfg = opentitan_transition,
attrs = {
"srcs": attr.label_list(allow_files = True),
@@ -59,11 +70,12 @@
toolchains = ["@rules_cc//cc:toolchain_type"],
)
-def _sign_image_impl(ctx):
+def _sign_bin_impl(ctx):
outputs = []
signed_image = ctx.actions.declare_file(
"{0}.{1}.signed.bin".format(
- ctx.file.bin.basename.rstrip(".bin"),
+ # Remove ".bin" from file basename.
+ ctx.file.bin.basename.replace("." + ctx.file.bin.extension, ""),
ctx.attr.key_name,
),
)
@@ -90,8 +102,8 @@
data_runfiles = ctx.runfiles(files = outputs),
)]
-sign_image = rule(
- implementation = _sign_image_impl,
+sign_bin = rule(
+ implementation = _sign_bin_impl,
cfg = opentitan_transition,
attrs = {
"bin": attr.label(allow_single_file = True),
@@ -101,6 +113,8 @@
allow_single_file = True,
),
"key_name": attr.string(),
+ # TODO(lowRISC/opentitan:#11199): explore other options to side-step the
+ # need for this transition, in order to build the ROM_EXT signer tool.
"platform": attr.string(default = "@local_config_platform//:host"),
"_tool": attr.label(
default = "//sw/host/rom_ext_image_tools/signer:rom_ext_signer",
@@ -112,7 +126,7 @@
},
)
-def _elf_to_disassembly(ctx):
+def _elf_to_disassembly_impl(ctx):
cc_toolchain = find_cc_toolchain(ctx)
outputs = []
for src in ctx.files.srcs:
@@ -131,7 +145,7 @@
return [DefaultInfo(files = depset(outputs), data_runfiles = ctx.runfiles(files = outputs))]
elf_to_disassembly = rule(
- implementation = _elf_to_disassembly,
+ implementation = _elf_to_disassembly_impl,
cfg = opentitan_transition,
attrs = {
"srcs": attr.label_list(allow_files = True),
@@ -145,10 +159,15 @@
incompatible_use_toolchain_transition = True,
)
-def _elf_to_scrambled(ctx):
+def _elf_to_scrambled_rom_impl(ctx):
outputs = []
for src in ctx.files.srcs:
- scrambled = ctx.actions.declare_file("{}.scr.40.vmem".format(src.basename))
+ scrambled = ctx.actions.declare_file(
+ "{}.scr.39.vmem".format(
+ # Remove ".elf" from file basename.
+ src.basename.replace("." + src.extension, ""),
+ ),
+ )
outputs.append(scrambled)
ctx.actions.run(
outputs = [scrambled],
@@ -166,14 +185,122 @@
)
return [DefaultInfo(files = depset(outputs), data_runfiles = ctx.runfiles(files = outputs))]
-elf_to_scrambled = rule(
- implementation = _elf_to_scrambled,
+elf_to_scrambled_rom_vmem = rule(
+ implementation = _elf_to_scrambled_rom_impl,
cfg = opentitan_transition,
attrs = {
"srcs": attr.label_list(allow_files = True),
"platform": attr.string(default = OPENTITAN_PLATFORM),
- "_tool": attr.label(default = "//hw/ip/rom_ctrl/util:scramble_image.py", allow_files = True),
- "_config": attr.label(default = "//hw/top_earlgrey/data:autogen/top_earlgrey.gen.hjson", allow_files = True),
+ "_tool": attr.label(
+ default = "//hw/ip/rom_ctrl/util:scramble_image.py",
+ allow_files = True,
+ ),
+ "_config": attr.label(
+ default = "//hw/top_earlgrey/data:autogen/top_earlgrey.gen.hjson",
+ allow_files = True,
+ ),
+ "_allowlist_function_transition": attr.label(
+ default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
+ ),
+ },
+)
+
+def _bin_to_flash_vmem_impl(ctx):
+ outputs = []
+ vmem = ctx.actions.declare_file("{}.{}.vmem".format(
+ # Remove ".bin" from file basename.
+ ctx.file.bin.basename[:-4],
+ ctx.attr.word_size,
+ ))
+ outputs.append(vmem)
+ ctx.actions.run(
+ outputs = [vmem],
+ inputs = [
+ ctx.file.bin,
+ ],
+ arguments = [
+ ctx.file.bin.path,
+ "--binary",
+ # Reverse the endianness of every word.
+ "--offset",
+ "0x0",
+ "--byte-swap",
+ str(ctx.attr.word_size // 8),
+ # Pad to word alignment.
+ "--fill",
+ "0xff",
+ "-within",
+ ctx.file.bin.path,
+ "-binary",
+ "-range-pad",
+ str(ctx.attr.word_size // 8),
+ # Output a VMEM file with specified word size
+ "--output",
+ vmem.path,
+ "--vmem",
+ str(ctx.attr.word_size),
+ ],
+ # This this executable is expected to be installed (as required by the
+ # srecord package in apt-requirements.txt).
+ executable = "srec_cat",
+ )
+ return [DefaultInfo(
+ files = depset(outputs),
+ data_runfiles = ctx.runfiles(files = outputs),
+ )]
+
+bin_to_flash_vmem = rule(
+ implementation = _bin_to_flash_vmem_impl,
+ cfg = opentitan_transition,
+ attrs = {
+ "bin": attr.label(allow_single_file = True),
+ "platform": attr.string(default = OPENTITAN_PLATFORM),
+ "word_size": attr.int(
+ default = 64,
+ doc = "Word size of VMEM file.",
+ mandatory = True,
+ values = [32, 64],
+ ),
+ "_allowlist_function_transition": attr.label(
+ default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
+ ),
+ },
+)
+
+def _scramble_flash_vmem_impl(ctx):
+ outputs = []
+ scrambled_vmem = ctx.actions.declare_file("{}.scr.vmem".format(
+ # Remove ".vmem" from file basename.
+ ctx.file.vmem.basename[:-4],
+ ))
+ outputs.append(scrambled_vmem)
+ ctx.actions.run(
+ outputs = [scrambled_vmem],
+ inputs = [
+ ctx.file.vmem,
+ ctx.file._tool,
+ ],
+ arguments = [
+ ctx.file.vmem.path,
+ scrambled_vmem.path,
+ ],
+ executable = ctx.file._tool.path,
+ )
+ return [DefaultInfo(
+ files = depset(outputs),
+ data_runfiles = ctx.runfiles(files = outputs),
+ )]
+
+scramble_flash_vmem = rule(
+ implementation = _scramble_flash_vmem_impl,
+ cfg = opentitan_transition,
+ attrs = {
+ "vmem": attr.label(allow_single_file = True),
+ "platform": attr.string(default = OPENTITAN_PLATFORM),
+ "_tool": attr.label(
+ default = "//util/design:gen-flash-img.py",
+ allow_single_file = True,
+ ),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
@@ -183,44 +310,28 @@
def opentitan_binary(
name,
platform = OPENTITAN_PLATFORM,
- per_device_deps = {
- "verilator": ["//sw/device/lib/arch:sim_verilator"],
- "dv": ["//sw/device/lib/arch:sim_dv"],
- "fpga_nexysvideo": ["//sw/device/lib/arch:fpga_nexysvideo"],
- "cw310": ["//sw/device/lib/arch:fpga_cw310"],
- },
- signing_keys = {
- "test_key_0": "//sw/device/silicon_creator/mask_rom/keys:test_private_key_0",
- },
output_bin = True,
output_disassembly = True,
- output_signed = False,
- output_scrambled = False,
**kwargs):
"""A helper macro for generating OpenTitan binary artifacts.
+
This macro is mostly a wrapper around cc_binary, but creates artifacts
- for each of the keys in `per_device_deps`. The actual artifacts
- created are an ELF file, a BIN file, the disassembly and the scrambled
- ROM image. Each of these output targets performs a bazel transition to
- the RV32I toolchain to build the target under the correct compiler.
+ compatible with OpenTitan binaries. The actual artifacts created are an ELF
+ file, a BIN file, and the disassembly. Each of these output targets performs
+ a bazel transition to the RV32I toolchain to build the target under the
+ correct compiler.
Args:
@param name: The name of this rule.
@param platform: The target platform for the artifacts.
- @param per_device_deps: The deps for each of the execution environments.
@param output_bin: Whether or not to emit a BIN file.
@param output_disassembly: Whether or not to emit a disassembly file.
- @param output_signed: Whether or not to emit a signed binary.
- @param output_scrambled: Whether or not to emit a SCR file.
@param **kwargs: Arguments to forward to `cc_binary`.
Emits rules:
- For each device in per_device_deps entry:
- cc_binary named: name_device
- obj_transform named: name_device_elf
- optionally:
- obj_transform named: name_device_bin
- elf_to_dissassembly named: name_device_dis
- elf_to_scrambled named: name_device_scr
- filegroup named: name
+ cc_binary named: <name>
+ optionally:
+ obj_transform named: <name>_bin
+ elf_to_dissassembly named: <name>_dis
+ filegroup named: <name>
with all the generated rules
"""
@@ -234,65 +345,210 @@
]
deps = kwargs.pop("deps", [])
targets = []
- for (device, dev_deps) in per_device_deps.items():
- devname = "{}_{}".format(name, device)
- native.cc_binary(
- name = devname,
- deps = deps + dev_deps,
- target_compatible_with = _targets_compatible_with[platform],
- copts = copts,
- linkopts = linkopts,
- **kwargs
- )
- targets.append(":" + devname + "_elf")
+
+ # Generate ELF
+ native.cc_binary(
+ name = name,
+ deps = deps,
+ target_compatible_with = _targets_compatible_with[platform],
+ copts = copts,
+ linkopts = linkopts,
+ **kwargs
+ )
+ elf_name = "{}_{}".format(name, "elf")
+ targets.append(":" + elf_name)
+ obj_transform(
+ name = elf_name,
+ srcs = [name],
+ format = "elf32-little",
+ suffix = "elf",
+ platform = platform,
+ )
+
+ # Generate Binary
+ if output_bin:
+ bin_name = "{}_{}".format(name, "bin")
+ targets.append(":" + bin_name)
obj_transform(
- name = devname + "_elf",
- srcs = [devname],
- format = "elf32-little",
- suffix = "elf",
+ name = bin_name,
+ srcs = [name],
platform = platform,
)
- if output_bin:
- targets.append(":" + devname + "_bin")
- obj_transform(
- name = devname + "_bin",
- srcs = [devname],
- platform = platform,
- )
- if output_disassembly:
- targets.append(":" + devname + "_dis")
- elf_to_disassembly(
- name = devname + "_dis",
- srcs = [devname],
- platform = platform,
- )
- if output_scrambled:
- targets.append(":" + devname + "_scr")
- elf_to_scrambled(
- name = devname + "_scr",
- srcs = [devname],
- platform = platform,
- )
+ # Generate Disassembly
+ if output_disassembly:
+ dis_name = "{}_{}".format(name, "dis")
+ targets.append(":" + dis_name)
+ elf_to_disassembly(
+ name = dis_name,
+ srcs = [name],
+ platform = platform,
+ )
+
+ native.filegroup(
+ name = name + "_base_bins",
+ srcs = targets,
+ )
+
+ return targets
+
+def opentitan_rom_binary(
+ name,
+ platform = OPENTITAN_PLATFORM,
+ per_device_deps = PER_DEVICE_DEPS,
+ **kwargs):
+ """A helper macro for generating OpenTitan binary artifacts for ROM.
+
+ This macro is mostly a wrapper around a opentitan_binary macro, which itself
+ is a wrapper around cc_binary, but also creates artifacts for each of the
+ keys in `per_device_deps`. The actual artifacts created are an ELF file, a
+ BIN file, the disassembly, and the scrambled (ROM) VMEM file. Each of these
+ output targets performs a bazel transition to the RV32I toolchain to build
+ the target under the correct compiler.
+ Args:
+ @param name: The name of this rule.
+ @param platform: The target platform for the artifacts.
+ @param per_device_deps: The deps for each of the hardware target.
+ @param **kwargs: Arguments to forward to `opentitan_binary`.
+ Emits rules:
+ For each device in per_device_deps entry:
+ cc_binary named: <name>_<device>
+ obj_transform named: <name>_<device>_elf
+ obj_transform named: <name>_<device>_bin
+ elf_to_dissassembly named: <name>_<device>_dis
+ elf_to_scrambled_rom_vmem named: <name>_<device>_scr_vmem
+ filegroup named: <name>
+ with all the generated rules
+ """
+
+ deps = kwargs.pop("deps", [])
+ targets = []
+ for (device, dev_deps) in per_device_deps.items():
+ devname = "{}_{}".format(name, device)
+
+ # Generate ELF, Binary, and Disassembly
+ targets.extend(opentitan_binary(
+ name = devname,
+ deps = deps + dev_deps,
+ **kwargs
+ ))
+ elf_name = "{}_{}".format(devname, "elf")
+
+ # Generate Scrambled ROM VMEM
+ scr_vmem_name = "{}_scr_vmem".format(devname)
+ targets.append(":" + scr_vmem_name)
+ elf_to_scrambled_rom_vmem(
+ name = scr_vmem_name,
+ srcs = [elf_name],
+ platform = platform,
+ )
+
+ native.filegroup(
+ name = name,
+ srcs = targets,
+ )
+
+def opentitan_flash_binary(
+ name,
+ platform = OPENTITAN_PLATFORM,
+ signing_keys = {
+ "test_key_0": "//sw/device/silicon_creator/mask_rom/keys:test_private_key_0",
+ },
+ per_device_deps = PER_DEVICE_DEPS,
+ output_signed = False,
+ **kwargs):
+ """A helper macro for generating OpenTitan binary artifacts for flash.
+
+ This macro is mostly a wrapper around a opentitan_binary macro, which itself
+ is a wrapper around cc_binary, but also creates artifacts for each of the
+ keys in `per_device_deps`, and if signing is enabled, each of the keys in
+ `signing_keys`. The actual artifacts created are an ELF file, a (signed and)
+ unsigned BIN file, a (signed and) unsigned flash VMEM file, and a (signed
+ and) unsigned scrambled flash VMEM file. Some of these output targets
+ perform a bazel transition to the RV32I toolchain to build the target under
+ the correct compiler.
+ Args:
+ @param name: The name of this rule.
+ @param platform: The target platform for the artifacts.
+ @param signing_keys: The signing keys for to sign each BIN file with.
+ @param per_device_deps: The deps for each of the hardware target.
+ @param output_signed: Whether or not to emit signed binary/VMEM files.
+ @param **kwargs: Arguments to forward to `opentitan_binary`.
+ Emits rules:
+ For each device in per_device_deps entry:
+ cc_binary named: <name>_<device>
+ obj_transform named: <name>_<device>_elf
+ obj_transform named: <name>_<device>_bin
+ elf_to_dissassembly named: <name>_<device>_dis
+ bin_to_flash_vmem named: <name>_<device>_flash_vmem
+ scrambled_flash_vmem named: <name>_<device>_scr_flash_vmem
+ optionally:
+ sign_bin named: <name>_<device>_bin_signed_<key_name>
+ bin_to_flash_vmem named: <name>_<device>_flash_vmem_signed_<key_name>
+ scrambled_flash_vmem named: <name>_<device>_scr_flash_vmem_signed_<key_name>
+ filegroup named: <name>
+ with all the generated rules
+ """
+
+ deps = kwargs.pop("deps", [])
+ targets = []
+ for (device, dev_deps) in per_device_deps.items():
+ devname = "{}_{}".format(name, device)
+
+ # Generate ELF, Binary, and Disassembly
+ targets.extend(opentitan_binary(
+ name = devname,
+ deps = deps + dev_deps,
+ **kwargs
+ ))
+ elf_name = "{}_{}".format(devname, "elf")
+ bin_name = "{}_{}".format(devname, "bin")
if output_signed:
for (key_name, key) in signing_keys.items():
- targets.append(":" + devname + "_bin_signed_" + key_name)
- sign_image(
- name = devname + "_bin_signed_" + key_name,
- bin = devname + "_bin",
- elf = devname + "_elf",
+ # Sign the Binary.
+ signed_bin_name = "{}_bin_signed_{}".format(devname, key_name)
+ targets.append(":" + signed_bin_name)
+ sign_bin(
+ name = signed_bin_name,
+ bin = bin_name,
+ elf = elf_name,
key = key,
key_name = key_name,
)
+ # Generate a VMEM64 from the signed binary.
+ signed_vmem_name = "{}_vmem64_signed_{}".format(
+ devname,
+ key_name,
+ )
+ targets.append(":" + signed_vmem_name)
+ bin_to_flash_vmem(
+ name = signed_vmem_name,
+ bin = signed_bin_name,
+ platform = platform,
+ word_size = 64,
+ )
+
+ # Scramble signed VMEM64.
+ scr_signed_vmem_name = "{}_scr_vmem64_signed_{}".format(
+ devname,
+ key_name,
+ )
+ targets.append(":" + scr_signed_vmem_name)
+ scramble_flash_vmem(
+ name = scr_signed_vmem_name,
+ vmem = signed_vmem_name,
+ platform = platform,
+ )
+
native.filegroup(
name = name,
srcs = targets,
)
def verilator_params(
- rom = "//sw/device/lib/testing/test_rom:test_rom_verilator_scr",
+ rom = "//sw/device/lib/testing/test_rom:test_rom_sim_verilator_scr_vmem",
otp = "//hw/ip/otp_ctrl/data:rma_image_verilator",
tags = [
"cpu:4",
@@ -318,10 +574,18 @@
@param tags: The test tags to apply to the test rule.
@param timeout: The timeout to apply to the test rule.
@param local: Whether the test should be run locally and without sandboxing.
- @param args: Arguments to pass to the test.
+ @param args: Extra arguments to pass to `opentitantool`.
@param data: Data dependencies of the test.
"""
- kwargs.update(rom = rom, otp = otp, tags = tags + ["verilator"], timeout = timeout, local = local, args = args, data = data)
+ kwargs.update(
+ rom = rom,
+ otp = otp,
+ tags = tags + ["verilator"],
+ timeout = timeout,
+ local = local,
+ args = args,
+ data = data,
+ )
return kwargs
def cw310_params(
@@ -347,10 +611,16 @@
@param tags: The test tags to apply to the test rule.
@param timeout: The timeout to apply to the test rule.
@param local: Whether the test should be run locally and without sandboxing.
- @param args: Arguments to pass to the test.
+ @param args: Extra arguments to pass to `opentitantool`.
@param data: Data dependencies of the test.
"""
- kwargs.update(tags = tags + ["cw310", "exclusive"], timeout = timeout, local = local, args = args, data = data)
+ kwargs.update(
+ tags = tags + ["cw310", "exclusive"],
+ timeout = timeout,
+ local = local,
+ args = args,
+ data = data,
+ )
return kwargs
def _format_list(name, list1, datadict, **kwargs):
@@ -389,41 +659,55 @@
def opentitan_functest(
name,
- platform = OPENTITAN_PLATFORM,
targets = ["verilator", "cw310"],
args = [],
data = [],
ottf = _OTTF_DEPS,
+ test_in_rom = False,
+ signed = False,
+ key = "test_key_0",
verilator = None,
cw310 = None,
**kwargs):
"""A helper macro for generating OpenTitan functional tests.
- This macro is mostly a wrapper around opentitan_binary, but creates
- testing artifacts for each of the keys in `per_device_deps`.
- The testing artifacts are then given to an `sh_test` rule which
- dispatches the test via opentitantool.
+
+ This macro is mostly a wrapper around opentitan_flash_binary, but creates
+ testing artifacts for each of the hardware targets in `targets`. The testing
+ artifacts are then given to an `sh_test` rule which dispatches the test to
+ the corresponding hardware target via opentitantool.
Args:
@param name: The name of this rule.
- @param platform: The target platform for the artifacts.
- @param targets: A list of targets on which to dispatch tests.
+ @param targets: A list of hardware targets on which to dispatch tests.
@param args: Extra arguments to pass to `opentitantool`.
@param data: Extra data dependencies needed while executing the test.
- @param ottf: Default dependencies for OTTF tests. Set to empty list if
+ @param ottf: Default dependencies for OTTF tests. Set to empty list if
your test doesn't use the OTTF.
- @param **kwargs: Arguments to forward to `opentitan_binary`.
+ @param test_in_rom: Whether to run the test from ROM, Runs from flash by
+ default.
+ @param signed: Whether to sign the test image. Unsigned by default.
+ @param key: Which signed test image (by key) to use.
+ @param verilator: Verilator test parameters.
+ @param cw310: CW310 test parameters.
+ @param **kwargs: Arguments to forward to `opentitan_flash_binary`.
This macro emits the following rules:
- opentitan_binary named: {name}_prog (and all of its emitted rules).
- sh_test named: verilator_{name}
- sh_test named: cw310_{name}
- test_suite named: {name}
+ opentitan_flash_binary named: {name}_prog (and all emitted rules).
+ sh_test named: verilator_{name}
+ sh_test named: cw310_{name}
+ test_suite named: {name}
"""
+ # Generate flash artifacts for test.
deps = _unique_deps(kwargs.pop("deps", []), ottf)
- opentitan_binary(
+ if test_in_rom:
+ opentitan_rom_binary(
+ name = name + "_rom_prog",
+ deps = deps,
+ **kwargs
+ )
+ opentitan_flash_binary(
name = name + "_prog",
- platform = platform,
- output_disassembly = True,
+ output_signed = signed,
deps = deps,
**kwargs
)
@@ -432,11 +716,24 @@
if "verilator" in targets:
test_name = "verilator_{}".format(name)
- test_bin = "{}_prog_verilator_elf".format(name)
+
+ # If the test is unsigned, the Verilator sim can use the ELF.
+ test_bin = "{}_prog_sim_verilator_elf".format(name)
+
+ # If the test is signed, the Verilator sim must use the scrambled VMEM,
+ # since only the BIN can be signed by the ROM_EXT signer tool, and this
+ # is converted to a scrambled (64-bit) VMEM.
+ if signed:
+ test_bin = "{}_prog_sim_verilator_scr_vmem64_signed_{}".format(
+ name,
+ key,
+ )
if verilator == None:
verilator = verilator_params()
rom = verilator.pop("rom")
+ if test_in_rom:
+ rom = name + "_rom_prog_sim_verilator_scr_vmem"
otp = verilator.pop("otp")
vargs = _format_list("args", args, verilator, test_bin = test_bin)
vdata = _format_list("data", data, verilator, test_bin = test_bin)
@@ -468,8 +765,12 @@
)
if "cw310" in targets:
+ if test_in_rom:
+ fail("test_in_rom only valid on Verilator target.")
test_name = "cw310_{}".format(name)
- test_bin = "{}_prog_cw310_bin".format(name)
+ test_bin = "{}_prog_fpga_cw310_bin".format(name)
+ if signed:
+ test_bin = "{}_prog_fpga_cw310_bin_signed_{}".format(name, key)
if cw310 == None:
cw310 = cw310_params()
diff --git a/sw/device/examples/hello_usbdev/BUILD b/sw/device/examples/hello_usbdev/BUILD
index 60e4cd6..171e2db 100644
--- a/sw/device/examples/hello_usbdev/BUILD
+++ b/sw/device/examples/hello_usbdev/BUILD
@@ -2,9 +2,9 @@
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
-load("//rules:opentitan.bzl", "OPENTITAN_CPU", "opentitan_binary")
+load("//rules:opentitan.bzl", "OPENTITAN_CPU", "opentitan_flash_binary")
-opentitan_binary(
+opentitan_flash_binary(
name = "hello_usbdev",
srcs = [
"hello_usbdev.c",
diff --git a/sw/device/examples/hello_world/BUILD b/sw/device/examples/hello_world/BUILD
index 80de671..c0489bd 100644
--- a/sw/device/examples/hello_world/BUILD
+++ b/sw/device/examples/hello_world/BUILD
@@ -2,9 +2,9 @@
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
-load("//rules:opentitan.bzl", "OPENTITAN_CPU", "opentitan_binary")
+load("//rules:opentitan.bzl", "OPENTITAN_CPU", "opentitan_flash_binary")
-opentitan_binary(
+opentitan_flash_binary(
name = "hello_world",
srcs = [
"hello_world.c",
diff --git a/sw/device/lib/testing/test_rom/BUILD b/sw/device/lib/testing/test_rom/BUILD
index 80ca2bd..2bf9a0d 100644
--- a/sw/device/lib/testing/test_rom/BUILD
+++ b/sw/device/lib/testing/test_rom/BUILD
@@ -2,7 +2,7 @@
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
-load("//rules:opentitan.bzl", "OPENTITAN_CPU", "opentitan_binary", "opentitan_functest")
+load("//rules:opentitan.bzl", "OPENTITAN_CPU", "opentitan_functest", "opentitan_rom_binary")
load("//rules:autogen.bzl", "autogen_chip_info")
package(default_visibility = ["//visibility:public"])
@@ -11,12 +11,11 @@
name = "chip_info",
)
-opentitan_binary(
+opentitan_rom_binary(
name = "test_rom",
linkopts = [
"-T $(location test_rom.ld)",
],
- output_scrambled = True,
deps = [
"test_rom.ld",
":test_rom_lib",
diff --git a/sw/device/silicon_creator/lib/drivers/BUILD b/sw/device/silicon_creator/lib/drivers/BUILD
index 87425ce..539a53d 100644
--- a/sw/device/silicon_creator/lib/drivers/BUILD
+++ b/sw/device/silicon_creator/lib/drivers/BUILD
@@ -2,9 +2,9 @@
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
-package(default_visibility = ["//visibility:public"])
+load("//rules:opentitan.bzl", "OPENTITAN_CPU", "opentitan_functest", "verilator_params")
-load("//rules:opentitan.bzl", "OPENTITAN_CPU", "opentitan_binary", "opentitan_functest", "verilator_params")
+package(default_visibility = ["//visibility:public"])
cc_library(
name = "alert",
@@ -37,8 +37,8 @@
cc_test(
name = "alert_unittest",
srcs = [
- "alert.h",
"alert.c",
+ "alert.h",
"alert_unittest.cc",
],
deps = [
@@ -178,9 +178,9 @@
cc_test(
name = "keymgr_unittest",
srcs = [
- "keymgr.h",
"keymgr.c",
- "keymgr_unittest.cc"
+ "keymgr.h",
+ "keymgr_unittest.cc",
],
deps = [
"//hw/ip/keymgr/data:keymgr_regs",
@@ -237,7 +237,7 @@
"mock_lifecycle.h",
],
deps = [
- "//sw/device/lib/base/testing:global_mock",
+ "//sw/device/lib/base/testing:global_mock",
"//sw/device/silicon_creator/testing:mask_rom_test",
"@googletest//:gtest",
],
@@ -283,7 +283,7 @@
srcs = [
"otbn.c",
"otbn.h",
- "otbn_unittest.cc"
+ "otbn_unittest.cc",
],
defines = [
"OT_OFF_TARGET_TEST",
@@ -321,7 +321,7 @@
"otp.h",
],
deps = [
- "//sw/device/lib/base/testing:global_mock",
+ "//sw/device/lib/base/testing:global_mock",
"//sw/device/silicon_creator/testing:mask_rom_test",
"@googletest//:gtest",
],
@@ -330,8 +330,8 @@
cc_test(
name = "otp_unittest",
srcs = [
- "otp.h",
"otp.c",
+ "otp.h",
"otp_unittest.cc",
],
deps = [
@@ -528,8 +528,8 @@
"//hw/top_earlgrey/sw/autogen:top_earlgrey",
"//sw/device/lib/base:abs_mmio",
"//sw/device/silicon_creator/lib/base:sec_mmio",
- "//sw/device/silicon_creator/lib/drivers:otp",
"//sw/device/silicon_creator/lib/drivers:lifecycle",
+ "//sw/device/silicon_creator/lib/drivers:otp",
],
)
diff --git a/sw/device/silicon_creator/mask_rom/BUILD b/sw/device/silicon_creator/mask_rom/BUILD
index 74c33b7..859d12d 100644
--- a/sw/device/silicon_creator/mask_rom/BUILD
+++ b/sw/device/silicon_creator/mask_rom/BUILD
@@ -2,7 +2,7 @@
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
-load("//rules:opentitan.bzl", "OPENTITAN_CPU", "opentitan_binary", "opentitan_functest", "verilator_params")
+load("//rules:opentitan.bzl", "OPENTITAN_CPU", "opentitan_functest", "opentitan_rom_binary", "verilator_params")
package(default_visibility = ["//visibility:public"])
@@ -53,7 +53,7 @@
],
)
-opentitan_binary(
+opentitan_rom_binary(
name = "mask_rom",
srcs = [
"mask_rom.c",
@@ -63,7 +63,6 @@
linkopts = [
"-T $(location mask_rom.ld)",
],
- output_scrambled = True,
deps = [
"mask_rom.ld",
":boot_policy",
@@ -136,11 +135,13 @@
],
# This test doesn't use the OTTF.
ottf = [],
- output_scrambled = True,
targets = ["verilator"], # Can only run in verilator right now.
- verilator = verilator_params(
- rom = ":mask_rom_epmp_test_prog_verilator_scr",
- ),
+ # This test is designed to run and complete entirely in the ROM boot stage.
+ # Setting the `test_in_rom` flag makes the `opentitan_functest` rule aware
+ # of this, and instructs it to load the test image into ROM (rather than
+ # loading the default test ROM, or any other ROM that may be specified via
+ # Verilator or CW310 params).
+ test_in_rom = True,
deps = [
"mask_rom.ld",
":mask_rom_epmp",
@@ -264,14 +265,9 @@
srcs = [
"mask_rom_test.c",
],
- targets = ["verilator"], # Can only run in verilator right now.
+ signed = True,
verilator = verilator_params(
- args = [
- "console",
- # This test program is not signed, so a boot fault is the expected behavior.
- "--exit-success='boot_fault: 0x0142500d'",
- ],
- rom = ":mask_rom_verilator_scr",
+ rom = ":mask_rom_sim_verilator_scr_vmem",
tags = [
"cpu:4",
"failing_verilator",
diff --git a/sw/device/tests/crypto/BUILD b/sw/device/tests/crypto/BUILD
index fdf1d93..a7ba754 100644
--- a/sw/device/tests/crypto/BUILD
+++ b/sw/device/tests/crypto/BUILD
@@ -2,9 +2,9 @@
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
-package(default_visibility = ["//visibility:public"])
+load("//rules:opentitan.bzl", "opentitan_functest")
-load("//rules:opentitan.bzl", "opentitan_functest", "OPENTITAN_CPU")
+package(default_visibility = ["//visibility:public"])
opentitan_functest(
name = "ecdsa_p256_functest",
@@ -14,8 +14,8 @@
"//sw/device/lib/crypto/drivers:hmac",
"//sw/device/lib/crypto/drivers:otbn",
"//sw/device/lib/crypto/ecdsa_p256",
- "//sw/device/lib/testing:entropy_testutils",
"//sw/device/lib/runtime:log",
+ "//sw/device/lib/testing:entropy_testutils",
],
)
diff --git a/util/design/BUILD b/util/design/BUILD
new file mode 100644
index 0000000..3b76e7c
--- /dev/null
+++ b/util/design/BUILD
@@ -0,0 +1,10 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+package(default_visibility = ["//visibility:public"])
+
+exports_files([
+ "gen-flash-img.py",
+ "gen-otp-img.py",
+])