From 8110d695637f20b2b11b2761857b14ee6b7c62bc Mon Sep 17 00:00:00 2001 From: Yi-Hsuan Deng Date: Wed, 18 Dec 2024 01:44:47 +0000 Subject: [PATCH] [rom_ext] Enable Oz to reduce firmware size This change enables Oz for rom_ext to reduce code size (43084B -> 41868B). Since some targets can't be built with LLD, this commit introduces a new attribute, `with_features`, to the `opentitan_binary` rule to allow specifying additional features for the target. LTO is also ready to be enabled for those targets, but we found no size improvement (41868B v.s. 41896B), so we keep it off at the moment. Change-Id: I5a8e7e7fcbb7d1e435b987d955a3e5ff8e4b7383 Signed-off-by: Yi-Hsuan Deng --- rules/rv.bzl | 5 ++++- .../lib/sigverify/sphincsplus/utils.c | 13 +++++++++++- sw/device/silicon_creator/rom_ext/BUILD | 20 +++++++++++++++++++ sw/device/silicon_creator/rom_ext/rom_ext.c | 4 ++++ sw/device/silicon_creator/rom_ext/sival/BUILD | 16 +++++++++++++++ third_party/crt/repos.bzl | 6 +++--- 6 files changed, 59 insertions(+), 5 deletions(-) diff --git a/rules/rv.bzl b/rules/rv.bzl index 48368231fb30b..cbb39f01729e8 100644 --- a/rules/rv.bzl +++ b/rules/rv.bzl @@ -19,10 +19,11 @@ PER_DEVICE_DEPS = { } def _opentitan_transition_impl(settings, attr): + features = settings["//command_line_option:features"] + attr.with_features return { "//command_line_option:platforms": attr.platform, "//command_line_option:copt": settings["//command_line_option:copt"], - "//command_line_option:features": settings["//command_line_option:features"], + "//command_line_option:features": features, "//hw/bitstream/universal:rom": "//hw/bitstream/universal:none", "//hw/bitstream/universal:otp": "//hw/bitstream/universal:none", "//hw/bitstream/universal:env": "//hw/bitstream/universal:none", @@ -58,6 +59,8 @@ def rv_rule(**kwargs): attrs = kwargs.pop("attrs", {}) if "platform" not in attrs: attrs["platform"] = attr.string(default = OPENTITAN_PLATFORM) + if "with_features" not in attrs: + attrs["with_features"] = attr.string_list(default = []) attrs["_allowlist_function_transition"] = attr.label( default = "@bazel_tools//tools/allowlists/function_transition_allowlist", ) diff --git a/sw/device/silicon_creator/lib/sigverify/sphincsplus/utils.c b/sw/device/silicon_creator/lib/sigverify/sphincsplus/utils.c index ff28b63a2b350..79aaf6688708f 100644 --- a/sw/device/silicon_creator/lib/sigverify/sphincsplus/utils.c +++ b/sw/device/silicon_creator/lib/sigverify/sphincsplus/utils.c @@ -17,7 +17,18 @@ uint64_t spx_utils_bytes_to_u64(const uint8_t *in, size_t inlen) { uint64_t retval = 0; for (size_t i = 0; i < inlen; i++) { - retval |= ((uint64_t)in[i]) << (8 * (inlen - 1 - i)); + // Perform native shift on u32 first to avoid __ashldi3 polyfill. + // + // The following code is equivalent to: + // retval |= ((uint64_t)in[i]) << (8 * (inlen - 1 - i)); + // + // See also pull #11451. + size_t offset = 8 * (inlen - 1 - i); + if (offset < 32) { + retval |= ((uint32_t)in[i]) << offset; + } else { + retval |= ((uint64_t)(((uint32_t)in[i]) << (offset - 32))) << 32; + } } return retval; } diff --git a/sw/device/silicon_creator/rom_ext/BUILD b/sw/device/silicon_creator/rom_ext/BUILD index 3de879f2099df..98f3cb063e040 100644 --- a/sw/device/silicon_creator/rom_ext/BUILD +++ b/sw/device/silicon_creator/rom_ext/BUILD @@ -290,6 +290,10 @@ opentitan_binary( linker_script = ":ld_slot_a", manifest = ":manifest", spx_key = {"//sw/device/silicon_creator/rom/keys/fake/spx:prod_key_0_spx": "prod_key_0"}, + with_features = [ + "minsize", + "use_lld", + ], deps = [ ":rom_ext", "//sw/device/lib/crt", @@ -314,6 +318,10 @@ opentitan_binary( linker_script = ":ld_slot_b", manifest = ":manifest", spx_key = {"//sw/device/silicon_creator/rom/keys/fake/spx:prod_key_0_spx": "prod_key_0"}, + with_features = [ + "minsize", + "use_lld", + ], deps = [ ":rom_ext", "//sw/device/lib/crt", @@ -337,6 +345,10 @@ opentitan_binary( ], linker_script = ":ld_slot_virtual", manifest = ":manifest", + with_features = [ + "minsize", + "use_lld", + ], deps = [ ":rom_ext", "//sw/device/lib/crt", @@ -360,6 +372,10 @@ opentitan_binary( ], linker_script = ":ld_slot_virtual", manifest = ":manifest", + with_features = [ + "minsize", + "use_lld", + ], deps = [ ":rom_ext", "//sw/device/lib/crt", @@ -390,6 +406,10 @@ opentitan_binary( ], linker_script = ":ld_slot_a", manifest = ":manifest_bad_address_translation", + with_features = [ + "minsize", + "use_lld", + ], deps = [ ":rom_ext", "//sw/device/lib/crt", diff --git a/sw/device/silicon_creator/rom_ext/rom_ext.c b/sw/device/silicon_creator/rom_ext/rom_ext.c index 212fe2a797e6f..c9df0d54c3cad 100644 --- a/sw/device/silicon_creator/rom_ext/rom_ext.c +++ b/sw/device/silicon_creator/rom_ext/rom_ext.c @@ -619,19 +619,23 @@ void rom_ext_main(void) { shutdown_finalize(error); } +OT_USED void rom_ext_interrupt_handler(void) { shutdown_finalize(rom_ext_irq_error()); } // We only need a single handler for all ROM_EXT interrupts, but we want to // keep distinct symbols to make writing tests easier. In the ROM_EXT, // alias all interrupt handler symbols to the single handler. +OT_USED OT_ALIAS("rom_ext_interrupt_handler") void rom_ext_exception_handler(void); +OT_USED OT_ALIAS("rom_ext_interrupt_handler") void rom_ext_nmi_handler(void); // A no-op immutable rom_ext fallback to avoid breaking tests before the // proper bazel target is ready. // TODO(opentitan#24368): Remove this nop fallback. +OT_USED OT_SECTION(".rom_ext_immutable.fallback") void imm_rom_ext_placeholder(void) {} diff --git a/sw/device/silicon_creator/rom_ext/sival/BUILD b/sw/device/silicon_creator/rom_ext/sival/BUILD index b47c28d5cf73e..f1b0837d624d2 100644 --- a/sw/device/silicon_creator/rom_ext/sival/BUILD +++ b/sw/device/silicon_creator/rom_ext/sival/BUILD @@ -49,6 +49,10 @@ opentitan_binary( linkopts = LINK_ORDER, manifest = ":manifest_sival", spx_key = {"//sw/device/silicon_creator/rom/keys/fake/spx:prod_key_0_spx": "prod_key_0"}, + with_features = [ + "minsize", + "use_lld", + ], deps = [ "//sw/device/lib/crt", "//sw/device/silicon_creator/lib:manifest_def", @@ -71,6 +75,10 @@ opentitan_binary( linkopts = LINK_ORDER, manifest = ":manifest_sival", spx_key = {"//sw/device/silicon_creator/rom/keys/fake/spx:prod_key_0_spx": "prod_key_0"}, + with_features = [ + "minsize", + "use_lld", + ], deps = [ "//sw/device/lib/crt", "//sw/device/silicon_creator/lib:manifest_def", @@ -87,6 +95,10 @@ opentitan_binary( ], linker_script = "//sw/device/silicon_creator/rom_ext:ld_slot_a", linkopts = LINK_ORDER, + with_features = [ + "minsize", + "use_lld", + ], deps = [ "//sw/device/lib/crt", "//sw/device/silicon_creator/lib:manifest_def", @@ -103,6 +115,10 @@ opentitan_binary( ], linker_script = "//sw/device/silicon_creator/rom_ext:ld_slot_b", linkopts = LINK_ORDER, + with_features = [ + "minsize", + "use_lld", + ], deps = [ "//sw/device/lib/crt", "//sw/device/silicon_creator/lib:manifest_def", diff --git a/third_party/crt/repos.bzl b/third_party/crt/repos.bzl index df14dd639e60c..47d51cd2b35ce 100644 --- a/third_party/crt/repos.bzl +++ b/third_party/crt/repos.bzl @@ -15,7 +15,7 @@ def crt_repos(local = None): maybe( http_archive, name = "crt", - url = "https://github.com/lowRISC/crt/archive/refs/tags/v0.4.13.tar.gz", - strip_prefix = "crt-0.4.13", - sha256 = "9813c8a3aeb72c3951d305e19a69dbbd17a3a6313bef938c20b1e214eb51e6e6", + url = "https://github.com/lowRISC/crt/archive/refs/tags/v0.4.16.tar.gz", + strip_prefix = "crt-0.4.16", + integrity = "sha256-25pTbQERCq1+X5rEudAIIVvxlm3ylMP4svFhOKx4WS0=", )