diff --git a/hw/top_earlgrey/BUILD b/hw/top_earlgrey/BUILD index 1b2288c35271d..e2ae56c5a1249 100644 --- a/hw/top_earlgrey/BUILD +++ b/hw/top_earlgrey/BUILD @@ -2,6 +2,10 @@ # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 +load( + "//rules:manifest.bzl", + "manifest", +) load( "//rules/opentitan:defs.bzl", "CLEAR_KEY_SET", @@ -27,6 +31,14 @@ filegroup( ], ) +# The following definition is used to define a null manifest in the signing +# configuration for execution environments (exec_env) and opentitan_test +# and opentitan_binary rules. When building the binaries, if the manifest equals +# to this null manifest, then the signing will be skipped. +CLEAR_MANIFEST = manifest(d = { + "name": "none_manifest", +}) + ########################################################################### # FPGA CW310 Environments ########################################################################### diff --git a/rules/opentitan/cc.bzl b/rules/opentitan/cc.bzl index 96047ee8b55dc..e29e993f4f1a7 100644 --- a/rules/opentitan/cc.bzl +++ b/rules/opentitan/cc.bzl @@ -182,6 +182,9 @@ def _build_binary(ctx, exec_env, name, deps, kind): ) manifest = get_fallback(ctx, "file.manifest", exec_env) + if manifest and str(manifest.owner) == "@@//hw/top_earlgrey:none_manifest": + manifest = None + ecdsa_key = get_fallback(ctx, "attr.ecdsa_key", exec_env) rsa_key = get_fallback(ctx, "attr.rsa_key", exec_env) spx_key = get_fallback(ctx, "attr.spx_key", exec_env) @@ -226,10 +229,20 @@ def _opentitan_binary(ctx): providers = [] default_info = [] groups = {} - for exec_env in ctx.attr.exec_env: - exec_env = exec_env[ExecEnvInfo] + for exec_env_target in ctx.attr.exec_env: + exec_env = exec_env_target[ExecEnvInfo] name = _binary_name(ctx, exec_env) deps = ctx.attr.deps + exec_env.libs + + imm_rom_ext_deps = [] + for dep in ctx.attr.immutable_rom_ext_sections: + if exec_env_target.label.name not in dep.label.name: + continue + imm_rom_ext_deps.append(dep) + if ctx.attr.immutable_rom_ext_sections and len(imm_rom_ext_deps) != 1: + fail("When building for exec_env {}, found zero or more than one immutable ROM_EXT sections to link: {}".format(imm_rom_ext_deps, exec_env_target)) + deps += imm_rom_ext_deps + kind = ctx.attr.kind provides, signed = _build_binary(ctx, exec_env, name, deps, kind) providers.append(exec_env.provider(kind = kind, **provides)) @@ -329,6 +342,10 @@ common_binary_attrs = { doc = "Indicates whether the binary is intended for a chip with the immutable ROM_EXT feature enabled.", default = False, ), + "immutable_rom_ext_sections": attr.label_list( + providers = [CcInfo], + doc = "The list of immutable ROM_EXT sections to be linked in to the binary target. Only the deps matched with the specific exec_env will be kept.", + ), } opentitan_binary = rv_rule( diff --git a/sw/device/silicon_creator/imm_rom_ext/BUILD b/sw/device/silicon_creator/imm_rom_ext/BUILD index 86d8cb1f26b6e..a55fefff49c26 100644 --- a/sw/device/silicon_creator/imm_rom_ext/BUILD +++ b/sw/device/silicon_creator/imm_rom_ext/BUILD @@ -2,17 +2,26 @@ # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 +load("@lowrisc_opentitan//rules/opentitan:exec_env.bzl", "ExecEnvInfo") load("@lowrisc_opentitan//rules/opentitan:transform.bzl", "obj_transform") load("//rules/opentitan:defs.bzl", "OPENTITAN_CPU", "opentitan_binary") load("//rules:linker.bzl", "ld_library") -load("//sw/device/silicon_creator/imm_rom_ext:utils.bzl", "imm_rom_ext_section") +load("//sw/device/silicon_creator/imm_rom_ext:defs.bzl", "DEFAULT_EXEC_ENV") +load( + "//sw/device/silicon_creator/imm_rom_ext:utils.bzl", + "create_imm_rom_ext_targets", +) package(default_visibility = ["//visibility:public"]) cc_library( name = "main_lib", - srcs = ["imm_rom_ext.c"], + srcs = [ + "imm_rom_ext.c", + "imm_rom_ext_start.S", + ], hdrs = ["imm_rom_ext.h"], + target_compatible_with = [OPENTITAN_CPU], deps = [ ":imm_rom_ext_epmp", "//hw/top:flash_ctrl_c_regs", @@ -52,43 +61,110 @@ cc_library( ) ld_library( - name = "ld_hello_world", - script = "hello_world.ld", + name = "ld_common", + includes = ["imm_rom_ext_common.ld"], deps = [ "//hw/top_earlgrey/sw/autogen:top_earlgrey_memory", "//sw/device:info_sections", + "//sw/device/silicon_creator/lib/base:static_critical_sections", ], ) -cc_library( - name = "hello_world", - srcs = [ - "hello_world.c", - "hello_world_start.S", +ld_library( + name = "ld_slot_a", + script = "imm_rom_ext_slot_a.ld", + deps = [ + ":ld_common", + "//hw/top_earlgrey/sw/autogen:top_earlgrey_memory", ], - hdrs = ["hello_world.h"], - target_compatible_with = [OPENTITAN_CPU], +) + +ld_library( + name = "ld_slot_b", + script = "imm_rom_ext_slot_b.ld", deps = [ - "//sw/device/silicon_creator/lib/drivers:uart", + ":ld_common", + "//hw/top_earlgrey/sw/autogen:top_earlgrey_memory", + ], +) + +ld_library( + name = "ld_slot_virtual", + script = "imm_rom_ext_slot_virtual.ld", + deps = [ + ":ld_common", + "//hw/top_earlgrey/sw/autogen:top_earlgrey_memory", ], ) opentitan_binary( - name = "hello_world_binaries", - # TODO(#24368): Support multiple executing environments. Currently all - # environments derive the same binary so only one environment is kept here, - # but we need to support multiple executing environments and make sure - # ROM_EXT targets choose the matched environment when linking IMM_ROM_EXT. - exec_env = [ - "//hw/top_earlgrey:fpga_cw340", + name = "main_binaries_slot_a", + exec_env = DEFAULT_EXEC_ENV, + extra_bazel_features = [ + "minsize", + "use_lld", ], - linker_script = ":ld_hello_world", + linker_script = ":ld_slot_a", + manifest = "//hw/top_earlgrey:none_manifest", deps = [ - ":hello_world", + ":main_lib", + "//sw/device/lib/crt", ], ) -imm_rom_ext_section( - name = "hello_world_section", - srcs = [":hello_world_binaries"], +[ + create_imm_rom_ext_targets( + src = ":main_binaries_slot_a", + base_name = "main_section_slot_a", + exec_env = env, + ) + for env in DEFAULT_EXEC_ENV +] + +opentitan_binary( + name = "main_binaries_slot_b", + exec_env = DEFAULT_EXEC_ENV, + extra_bazel_features = [ + "minsize", + "use_lld", + ], + linker_script = ":ld_slot_b", + manifest = "//hw/top_earlgrey:none_manifest", + deps = [ + ":main_lib", + "//sw/device/lib/crt", + ], ) + +[ + create_imm_rom_ext_targets( + src = ":main_binaries_slot_b", + base_name = "main_section_slot_b", + exec_env = env, + ) + for env in DEFAULT_EXEC_ENV +] + +opentitan_binary( + name = "main_binaries_slot_virtual", + exec_env = DEFAULT_EXEC_ENV, + extra_bazel_features = [ + "minsize", + "use_lld", + ], + linker_script = ":ld_slot_virtual", + manifest = "//hw/top_earlgrey:none_manifest", + deps = [ + ":main_lib", + "//sw/device/lib/crt", + ], +) + +[ + create_imm_rom_ext_targets( + src = ":main_binaries_slot_virtual", + base_name = "main_section_slot_virtual", + exec_env = env, + ) + for env in DEFAULT_EXEC_ENV +] diff --git a/sw/device/silicon_creator/imm_rom_ext/defs.bzl b/sw/device/silicon_creator/imm_rom_ext/defs.bzl index 04ada7e14b651..01d2937c42a5b 100644 --- a/sw/device/silicon_creator/imm_rom_ext/defs.bzl +++ b/sw/device/silicon_creator/imm_rom_ext/defs.bzl @@ -2,8 +2,41 @@ # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 +DEFAULT_EXEC_ENV = [ + "//hw/top_earlgrey:fpga_cw310", + "//hw/top_earlgrey:fpga_cw340", + "//hw/top_earlgrey:sim_dv_base", + "//hw/top_earlgrey:sim_verilator_base", + "//hw/top_earlgrey:silicon_creator", +] + # The target list should contian prebuilt artifacts and run-time build targets. -IMM_ROM_EXT_TARGETS = { - "nop": "//sw/device/silicon_creator/imm_rom_ext/prebuilts:nop_imm_rom_ext", - "hello_world": "//sw/device/silicon_creator/imm_rom_ext:hello_world_section", +SLOT_A_IMM_ROM_EXT_SECTIONS = { + "main": [ + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_a_fpga_cw310", + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_a_fpga_cw340", + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_a_sim_dv_base", + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_a_sim_verilator_base", + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_a_silicon_creator", + ], +} + +SLOT_B_IMM_ROM_EXT_SECTIONS = { + "main": [ + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_b_fpga_cw310", + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_b_fpga_cw340", + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_b_sim_dv_base", + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_b_sim_verilator_base", + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_b_silicon_creator", + ], +} + +SLOT_VIRTUAL_IMM_ROM_EXT_SECTIONS = { + "main": [ + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_virtual_fpga_cw310", + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_virtual_fpga_cw340", + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_virtual_sim_dv_base", + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_virtual_sim_verilator_base", + "//sw/device/silicon_creator/imm_rom_ext:main_section_slot_virtual_silicon_creator", + ], } diff --git a/sw/device/silicon_creator/imm_rom_ext/hello_world.c b/sw/device/silicon_creator/imm_rom_ext/hello_world.c deleted file mode 100644 index 81b350269f418..0000000000000 --- a/sw/device/silicon_creator/imm_rom_ext/hello_world.c +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -#include "sw/device/silicon_creator/imm_rom_ext/hello_world.h" - -#include "sw/device/silicon_creator/lib/drivers/uart.h" - -void imm_rom_ext_main(void) { - // Print "Immutable" to the UART console. - // l b a t u m m I - const uint64_t kStr1 = 0x6c626174756d6d49; - // e - const uint32_t kStr2 = 0x65; - const uint32_t kNewline = 0x0a0d; - uart_write_imm(kStr1); - uart_write_imm(kStr2); - uart_write_imm(kNewline); - - // Wait until the UART is done transmitting. - while (!uart_tx_idle()) { - } - - return; -} diff --git a/sw/device/silicon_creator/imm_rom_ext/hello_world.h b/sw/device/silicon_creator/imm_rom_ext/hello_world.h deleted file mode 100644 index 2932989cb8e76..0000000000000 --- a/sw/device/silicon_creator/imm_rom_ext/hello_world.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_IMM_ROM_EXT_HELLO_WORLD_H_ -#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_IMM_ROM_EXT_HELLO_WORLD_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -void imm_rom_ext_main(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_IMM_ROM_EXT_HELLO_WORLD_H_ diff --git a/sw/device/silicon_creator/imm_rom_ext/hello_world.ld b/sw/device/silicon_creator/imm_rom_ext/hello_world.ld deleted file mode 100644 index 47b757cded97d..0000000000000 --- a/sw/device/silicon_creator/imm_rom_ext/hello_world.ld +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright lowRISC contributors (OpenTitan project). */ -/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ -/* SPDX-License-Identifier: Apache-2.0 */ - -/** - * TODO(#24368): Adapt the linker script for real IMM_ROM_EXT. This linker - * script only works for hello-world IMM_ROM_EXT. - */ -OUTPUT_ARCH(riscv) - -/** - * Indicate that there are no dynamic libraries, whatsoever. - */ -__DYNAMIC = 0; - -/* DV Log offset (has to be different to other boot stages). */ -_dv_log_offset = 0x10000; - -ENTRY(_imm_rom_ext_start_boot) - -SECTIONS { - .rom_ext_immutable : ALIGN(4) { - /* Ibex */ - *(.vectors) - . = ALIGN(256); - /* CRT */ - *(.crt) - . = ALIGN(4); - /* Text */ - *(.text) - *(.text.*) - . = ALIGN(4); - /* Read-only Data */ - *(.srodata) - *(.srodata.*) - *(.rodata) - *(.rodata.*) - . = ALIGN(4); - *(.data) - . = ALIGN(4); - *(.bss) - . = ALIGN(4); - } - - INCLUDE sw/device/info_sections.ld -} diff --git a/sw/device/silicon_creator/imm_rom_ext/hello_world_start.S b/sw/device/silicon_creator/imm_rom_ext/hello_world_start.S deleted file mode 100644 index f90d7a861da8c..0000000000000 --- a/sw/device/silicon_creator/imm_rom_ext/hello_world_start.S +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright lowRISC contributors (OpenTitan project). -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// TODO(#24368): Adapt the startup assembly for real IMM_ROM_EXT. This startup -// assembly only works for hello-world IMM_ROM_EXT. -#include "hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h" - - .balign 4 - .global _imm_rom_ext_start_boot - .type _imm_rom_ext_start_boot, @function -_imm_rom_ext_start_boot: - tail imm_rom_ext_main - .size _imm_rom_ext_start_boot, .-_imm_rom_ext_start_boot diff --git a/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_common.ld b/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_common.ld new file mode 100644 index 0000000000000..03731afd856fd --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_common.ld @@ -0,0 +1,150 @@ +/* Copyright lowRISC contributors (OpenTitan project). */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +/** + * TODO(#24368): Adapt the linker script for real IMM_ROM_EXT. This linker + * script only works for hello-world IMM_ROM_EXT. + */ + +OUTPUT_ARCH(riscv) + +/** + * Indicate that there are no dynamic libraries, whatsoever. + */ +__DYNAMIC = 0; + +/* DV Log offset (has to be different to other boot stages). */ +_dv_log_offset = 0x10000; + +ENTRY(_imm_rom_ext_start_boot) + +SECTIONS { + /** + * Ibex interrupt vector. + * + * This has to be set up at a 256-byte offset, so that we can use it with + * Ibex. + */ + .vectors : ALIGN(256) { + _text_start = .; + _rom_ext_immutable_start = .; + KEEP(*(.vectors)) + } > rom_ext_flash + + /** + * C runtime (CRT) section, containing program initialization code. + */ + .crt : ALIGN(4) { + KEEP(*(.crt)) + } > rom_ext_flash + + /** + * Standard text section, containing program code. + */ + .text : ALIGN(4) { + *(.text) + *(.text.*) + + /* Ensure section end is word-aligned. */ + . = ALIGN(4); + } > rom_ext_flash + + /** + * Shutdown text section, containing shutdown function(s). + * + * This must be the last executable section in the ROM_EXT flash image. + */ + .shutdown : ALIGN(4) { + *(.shutdown) + *(.shutdown.*) + + /* Ensure section end is word-aligned. */ + . = ALIGN(4); + _text_end = .; + } > rom_ext_flash + + /** + * Read-only data section, containing all large compile-time constants, like + * strings. + */ + .rodata : ALIGN(4) { + /* Small read-only data comes before regular read-only data for the same + * reasons as in the data section */ + *(.srodata) + *(.srodata.*) + *(.rodata) + *(.rodata.*) + } > rom_ext_flash + + /** + * Critical static data that is accessible by both the ROM and the ROM + * extension. + */ + INCLUDE sw/device/silicon_creator/lib/base/static_critical.ld + + /** + * Mutable data section, at the bottom of ram_main. This will be initialized + * from flash at runtime by the CRT. + * + * Load this by copying the bytes from [_data_init_start, _data_init_end] into + * the range [_data_start, _data_end]. + */ + .data : ALIGN(4) { + _data_start = .; + _data_init_start = LOADADDR(.data); + + /* This will get loaded into `gp`, and the linker will use that register for + * accessing data within [-2048,2047] of `__global_pointer$`. + * + * This is much cheaper (for small data) than materializing the + * address and loading from that (which will take one extra instruction). + */ + __global_pointer$ = . + 2048; + + /* Small data should come before larger data. This helps to ensure small + * globals are within 2048 bytes of the value of `gp`, making their accesses + * hopefully only take one instruction. */ + *(.sdata) + *(.sdata.*) + + /* Other data will likely need multiple instructions to load, so we're less + * concerned about address materialisation taking more than one instruction. + */ + *(.data) + *(.data.*) + + /* Ensure section end is word-aligned. */ + . = ALIGN(4); + _data_end = .; + _data_init_end = LOADADDR(.data) + SIZEOF(.data); + _rom_ext_immutable_end = LOADADDR(.data) + SIZEOF(.data); + + /* This puts it in ram_main at runtime (for the VMA), but puts the section + * into flash for load time (for the LMA). This is why `_data_init_*` uses + * `LOADADDR`. + * + * Using `AT>` means we don't have to keep track of the next free part of + * flash, as we do in our other linker scripts. */ + } > ram_main AT> rom_ext_flash + + /** + * Standard BSS section. This will be zeroed at runtime by the CRT. + */ + .bss : ALIGN(4) { + _bss_start = .; + + /* Small BSS comes before regular BSS for the same reasons as in the data + * section */ + *(.sbss) + *(.sbss.*) + *(.bss) + *(.bss.*) + + /* Ensure section end is word-aligned. */ + . = ALIGN(4); + _bss_end = .; + } > ram_main + + INCLUDE sw/device/info_sections.ld +} diff --git a/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_slot_a.ld b/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_slot_a.ld new file mode 100644 index 0000000000000..e7751d59bf4fc --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_slot_a.ld @@ -0,0 +1,27 @@ +/* Copyright lowRISC contributors (OpenTitan project). */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +/** + * Linker script for an OpenTitan IMM_ROM_EXT. + * + * Portions of this file are Ibex-specific. + * + * The IMM_ROM_EXT is kept in the .rom_ext_immutable section in ROM, after the + * .manifest section. This linker script targets to use slot A address, and + * the addresses are similar to the linker script rom_ext_slot_a.ld that ROM_EXT + * is using. + */ + +INCLUDE hw/top_earlgrey/sw/autogen/top_earlgrey_memory.ld + +/** + * Symbols to be used in the setup of the address translation for IMM_ROM_EXT. + */ + +MEMORY { + imm_rom_ext_slot_a(rx) : ORIGIN = ORIGIN(eflash) + 0x400, LENGTH = LENGTH(eflash) / 2 - 0x400 +} +REGION_ALIAS("rom_ext_flash", imm_rom_ext_slot_a); + +INCLUDE sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_common.ld diff --git a/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_slot_b.ld b/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_slot_b.ld new file mode 100644 index 0000000000000..35540731a9888 --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_slot_b.ld @@ -0,0 +1,28 @@ +/* Copyright lowRISC contributors (OpenTitan project). */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +/** + * Linker script for an OpenTitan IMM_ROM_EXT. + * + * Portions of this file are Ibex-specific. + * + * The IMM_ROM_EXT is kept in the .rom_ext_immutable section in ROM, after the + * .manifest section. This linker script targets to use slot B address, and + * the addresses are similar to the linker script rom_ext_slot_b.ld that ROM_EXT + * is using. + */ + +INCLUDE hw/top_earlgrey/sw/autogen/top_earlgrey_memory.ld + +/** + * Symbols to be used in the setup of the address translation for IMM_ROM_EXT. + */ + +/* Slot B starts at the half-size mark of the eFlash. */ +MEMORY { + imm_rom_ext_slot_b(rx) : ORIGIN = ORIGIN(eflash) + LENGTH(eflash) / 2 + 0x400, LENGTH = LENGTH(eflash) / 2 - 0x400 +} +REGION_ALIAS("rom_ext_flash", imm_rom_ext_slot_b); + +INCLUDE sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_common.ld diff --git a/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_slot_virtual.ld b/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_slot_virtual.ld new file mode 100644 index 0000000000000..47d3dcd372bfd --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_slot_virtual.ld @@ -0,0 +1,27 @@ +/* Copyright lowRISC contributors (OpenTitan project). */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +/** + * Linker script for an OpenTitan IMM_ROM_EXT. + * + * Portions of this file are Ibex-specific. + * + * The IMM_ROM_EXT is kept in the .rom_ext_immutable section in ROM, after the + * .manifest section. This linker script targets to use virtual address, and + * the addresses are similar to the linker script rom_ext_slot_virtual.ld that + * ROM_EXT is using. + */ + +INCLUDE hw/top_earlgrey/sw/autogen/top_earlgrey_memory.ld + +/** + * Symbols to be used in the setup of the address translation for IMM_ROM_EXT. + */ + +MEMORY { + imm_rom_ext_virtual(rx) : ORIGIN = ORIGIN(rom_ext_virtual) + 0x400, LENGTH = 0x80000 - 0x400 +} +REGION_ALIAS("rom_ext_flash", imm_rom_ext_virtual); + +INCLUDE sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_common.ld diff --git a/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_start.S b/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_start.S new file mode 100644 index 0000000000000..cf382cf8cd5ae --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/imm_rom_ext_start.S @@ -0,0 +1,91 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#include "hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h" +#include "sw/device/lib/base/hardened_asm.h" + + /** + * NOTE: The "ax" flag below is necessary to ensure that this section + * is allocated executable space in ROM by the linker. + */ + .section .crt, "ax" + + /** + * Entry point. + * + * This symbol is jumped to from `rom_boot` using the `entry_point` field + * of the manifest. + */ + .balign 4 + .global _imm_rom_ext_start_boot + .type _imm_rom_ext_start_boot, @function +_imm_rom_ext_start_boot: + + .option push + .option norelax + + /** + * Set up the global pointer `gp`. + */ + la gp, __global_pointer$ + + .option pop + + /** + * Save registers. + */ + addi sp, sp, -8 + sw ra, 4(sp) + + /** + * Disable Interrupts. + * + * We cannot disable exceptions, or Ibex's non-maskable interrupts (interrupt + * 31), so we still need to be careful. + */ + + // Clear `MIE` field of `mstatus` (disable interrupts globally). + csrci mstatus, 0x8 + + /** + * Clear all the machine-defined interrupts, `MEIE`, `MTIE`, and `MSIE` fields + * of `mie`. + */ + li t0, 0xFFFF0888 + csrc mie, t0 + + /** + * Setup C Runtime + */ + /** + * Initialize the `.data` section in RAM from ROM. + */ + la a0, _data_start + la a1, _data_end + la a2, _data_init_start + jal ra, crt_section_copy + + /** + * Initialize the `.bss` section. + * + * We do this despite zeroing all of SRAM above, so that we still zero `.bss` + * once we've enabled SRAM scrambling. + */ + la a0, _bss_start + la a1, _bss_end + jal ra, crt_section_clear + + + /** + * Restore registers. + */ + lw ra, 4(sp) + addi sp, sp, 8 + + /** + * Jump to IMM_ROM_EXT. + */ + tail imm_rom_ext_main + + .size _imm_rom_ext_start_boot, .-_imm_rom_ext_start_boot diff --git a/sw/device/silicon_creator/imm_rom_ext/utils.bzl b/sw/device/silicon_creator/imm_rom_ext/utils.bzl index 1c881c2860ae2..d013047f20f72 100644 --- a/sw/device/silicon_creator/imm_rom_ext/utils.bzl +++ b/sw/device/silicon_creator/imm_rom_ext/utils.bzl @@ -5,6 +5,7 @@ load("@rules_cc//cc:action_names.bzl", "OBJ_COPY_ACTION_NAME") load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain") load("@lowrisc_opentitan//rules:rv.bzl", "rv_rule") +load("@lowrisc_opentitan//rules/opentitan:exec_env.bzl", "ExecEnvInfo") def _bin_to_imm_rom_ext_object_impl(ctx): cc_toolchain = find_cc_toolchain(ctx) @@ -20,9 +21,8 @@ def _bin_to_imm_rom_ext_object_impl(ctx): ) outputs = [] - for src in ctx.files.srcs: - if src.extension != "bin": - continue + exec_env_name = ctx.attr.exec_env[ExecEnvInfo].exec_env + for src in ctx.attr.src.output_groups[exec_env_name + "_binary"].to_list(): object = ctx.actions.declare_file( "{}.{}".format( src.basename.replace("." + src.extension, ""), @@ -45,23 +45,40 @@ def _bin_to_imm_rom_ext_object_impl(ctx): executable = objcopy, ) outputs.append(object) - return [DefaultInfo(files = depset(outputs), runfiles = ctx.runfiles(files = outputs))] + if len(outputs) != 1: + fail("Generated zero or more than one binary: {}".format(outputs)) + return [ + DefaultInfo( + files = depset(outputs), + runfiles = ctx.runfiles(files = outputs), + ), + ] bin_to_imm_rom_ext_object = rv_rule( implementation = _bin_to_imm_rom_ext_object_impl, attrs = { - "srcs": attr.label_list(allow_files = True), + "src": attr.label(allow_files = True), + "exec_env": attr.label( + providers = [ExecEnvInfo], + doc = "The execution environment for this target.", + ), "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), }, fragments = ["cpp"], toolchains = ["@rules_cc//cc:toolchain_type"], ) -def imm_rom_ext_section(name, srcs): - object_target_name = name + "_object" - bin_to_imm_rom_ext_object(name = object_target_name, srcs = srcs) +def create_imm_rom_ext_targets(src, exec_env, base_name): + exec_env_name = Label(exec_env).name + object_target_name = "{}_{}_object".format(base_name, exec_env_name) + cc_import_name = "{}_{}".format(base_name, exec_env_name) + bin_to_imm_rom_ext_object( + name = object_target_name, + src = src, + exec_env = exec_env, + ) native.cc_import( - name = name, + name = cc_import_name, objects = [object_target_name], data = [object_target_name], alwayslink = 1, diff --git a/sw/device/silicon_creator/rom_ext/BUILD b/sw/device/silicon_creator/rom_ext/BUILD index 97b9bc066606f..1e145f06a9279 100644 --- a/sw/device/silicon_creator/rom_ext/BUILD +++ b/sw/device/silicon_creator/rom_ext/BUILD @@ -14,7 +14,9 @@ load( ) load( "//sw/device/silicon_creator/imm_rom_ext:defs.bzl", - "IMM_ROM_EXT_TARGETS", + "SLOT_A_IMM_ROM_EXT_SECTIONS", + "SLOT_B_IMM_ROM_EXT_SECTIONS", + "SLOT_VIRTUAL_IMM_ROM_EXT_SECTIONS", ) package(default_visibility = ["//visibility:public"]) @@ -233,7 +235,6 @@ cc_library( "//sw/device/lib/base:memory", "//sw/device/lib/base:stdasm", "//sw/device/lib/runtime:hart", - "//sw/device/silicon_creator/imm_rom_ext:main_lib", "//sw/device/silicon_creator/lib:boot_data", "//sw/device/silicon_creator/lib:boot_log", "//sw/device/silicon_creator/lib:dbg_print", @@ -291,6 +292,7 @@ opentitan_binary( "minsize", "use_lld", ], + immutable_rom_ext_sections = SLOT_A_IMM_ROM_EXT_SECTIONS["main"], linker_script = ":ld_slot_a", manifest = ":manifest", spx_key = {"//sw/device/silicon_creator/rom/keys/fake/spx:prod_key_0_spx": "prod_key_0"}, @@ -319,6 +321,7 @@ opentitan_binary( "minsize", "use_lld", ], + immutable_rom_ext_sections = SLOT_B_IMM_ROM_EXT_SECTIONS["main"], linker_script = ":ld_slot_b", manifest = ":manifest", spx_key = {"//sw/device/silicon_creator/rom/keys/fake/spx:prod_key_0_spx": "prod_key_0"}, @@ -347,6 +350,7 @@ opentitan_binary( "minsize", "use_lld", ], + immutable_rom_ext_sections = SLOT_VIRTUAL_IMM_ROM_EXT_SECTIONS["main"], linker_script = ":ld_slot_virtual", manifest = ":manifest", deps = [ @@ -374,6 +378,7 @@ opentitan_binary( "minsize", "use_lld", ], + immutable_rom_ext_sections = imm_rom_ext_sections, linker_script = ":ld_slot_virtual", manifest = ":manifest", deps = [ @@ -382,11 +387,9 @@ opentitan_binary( "//sw/device/silicon_creator/lib:manifest_def", "//sw/device/silicon_creator/lib/ownership:test_owner", "//sw/device/silicon_creator/lib/ownership/keys/fake", - ] + [ - imm_rom_ext_target, ], ) - for name, imm_rom_ext_target in IMM_ROM_EXT_TARGETS.items() + for name, imm_rom_ext_sections in SLOT_VIRTUAL_IMM_ROM_EXT_SECTIONS.items() ] manifest(d = { diff --git a/sw/device/silicon_creator/rom_ext/e2e/verified_boot/BUILD b/sw/device/silicon_creator/rom_ext/e2e/verified_boot/BUILD index a25d750ab8c4a..bb69b14a06d69 100644 --- a/sw/device/silicon_creator/rom_ext/e2e/verified_boot/BUILD +++ b/sw/device/silicon_creator/rom_ext/e2e/verified_boot/BUILD @@ -23,7 +23,7 @@ load( ) load( "//sw/device/silicon_creator/imm_rom_ext:defs.bzl", - "IMM_ROM_EXT_TARGETS", + "SLOT_VIRTUAL_IMM_ROM_EXT_SECTIONS", ) package(default_visibility = ["//visibility:public"]) @@ -48,7 +48,7 @@ filegroup( rom_ext = "//sw/device/silicon_creator/rom_ext:rom_ext_with_{}_imm_slot_virtual".format(name), visibility = ["//visibility:private"], ) - for name in IMM_ROM_EXT_TARGETS + for name in SLOT_VIRTUAL_IMM_ROM_EXT_SECTIONS ] [ @@ -62,7 +62,7 @@ filegroup( ], visibility = ["//visibility:private"], ) - for name in IMM_ROM_EXT_TARGETS + for name in SLOT_VIRTUAL_IMM_ROM_EXT_SECTIONS ] _POSITIONS = { @@ -139,7 +139,7 @@ _POSITIONS = { "success": "rom_ext_slot = AA__\r\n", "otp_img": ":otp_img_with_{}_imm_romext_enabled".format(name), } - for name in IMM_ROM_EXT_TARGETS + for name in SLOT_VIRTUAL_IMM_ROM_EXT_SECTIONS } [ diff --git a/sw/device/silicon_creator/rom_ext/rom_ext.c b/sw/device/silicon_creator/rom_ext/rom_ext.c index c9df0d54c3cad..1cd63a1f2ee09 100644 --- a/sw/device/silicon_creator/rom_ext/rom_ext.c +++ b/sw/device/silicon_creator/rom_ext/rom_ext.c @@ -10,7 +10,6 @@ #include "sw/device/lib/base/memory.h" #include "sw/device/lib/base/stdasm.h" #include "sw/device/lib/runtime/hart.h" -#include "sw/device/silicon_creator/imm_rom_ext/imm_rom_ext.h" #include "sw/device/silicon_creator/lib/base/boot_measurements.h" #include "sw/device/silicon_creator/lib/base/chip.h" #include "sw/device/silicon_creator/lib/base/sec_mmio.h" @@ -602,11 +601,6 @@ static rom_error_t rom_ext_start(boot_data_t *boot_data, boot_log_t *boot_log) { } void rom_ext_main(void) { - // TODO(opentitan#24368): Call immutable main in .rom_ext_immutable. - // The immutable rom_ext startup code is not ready yet, so we call it here - // to avoid breaking tests. - imm_rom_ext_main(); - rom_ext_check_rom_expectations(); boot_data_t boot_data; boot_log_t *boot_log = &retention_sram_get()->creator.boot_log; @@ -632,10 +626,3 @@ 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 7db34c0cd79df..ac2a597615e20 100644 --- a/sw/device/silicon_creator/rom_ext/sival/BUILD +++ b/sw/device/silicon_creator/rom_ext/sival/BUILD @@ -11,6 +11,11 @@ load( "ROM_EXT_VERSION", ) load("@rules_pkg//pkg:tar.bzl", "pkg_tar") +load( + "//sw/device/silicon_creator/imm_rom_ext:defs.bzl", + "SLOT_A_IMM_ROM_EXT_SECTIONS", + "SLOT_B_IMM_ROM_EXT_SECTIONS", +) package(default_visibility = ["//visibility:public"]) @@ -49,6 +54,7 @@ opentitan_binary( "minsize", "use_lld", ], + immutable_rom_ext_sections = SLOT_A_IMM_ROM_EXT_SECTIONS["main"], linker_script = "//sw/device/silicon_creator/rom_ext:ld_slot_a", linkopts = LINK_ORDER, manifest = ":manifest_sival", @@ -75,6 +81,7 @@ opentitan_binary( "minsize", "use_lld", ], + immutable_rom_ext_sections = SLOT_B_IMM_ROM_EXT_SECTIONS["main"], linker_script = "//sw/device/silicon_creator/rom_ext:ld_slot_b", linkopts = LINK_ORDER, manifest = ":manifest_sival", @@ -97,6 +104,7 @@ opentitan_binary( "minsize", "use_lld", ], + immutable_rom_ext_sections = SLOT_A_IMM_ROM_EXT_SECTIONS["main"], linker_script = "//sw/device/silicon_creator/rom_ext:ld_slot_a", linkopts = LINK_ORDER, deps = [ @@ -117,6 +125,7 @@ opentitan_binary( "minsize", "use_lld", ], + immutable_rom_ext_sections = SLOT_B_IMM_ROM_EXT_SECTIONS["main"], linker_script = "//sw/device/silicon_creator/rom_ext:ld_slot_b", linkopts = LINK_ORDER, deps = [