From 1fc69c6abb07cab1e3a85ea7e7ec8a82691e2914 Mon Sep 17 00:00:00 2001 From: Chia-Wei Liu Date: Mon, 11 Nov 2024 19:29:29 +0800 Subject: [PATCH] [imm_rom_ext] Add hello world IM_EXT * Add minimized C code, startup asm and linker script for a standalone IM_EXT build target. * Add a bazel rule `imm_rom_ext_section`, which will transform binaries into object files and turn it to a target that can be directly used as deps of ROM_EXT's bazel targets. * Add a map for all IM_EXT target that can be used and make the ROM_EXT targets iterate the map to generate multiple targets. * Update the ROM_EXT to use in e2e verified boot test. Test: String `Immutable` appears in the UART output of the test target `verified_boot:position_romext_virtual_a_with_hello_world_imm_romext_enabled_fpga_cw340_rom_ext`: ``` OpenTitan:4001-0002-01 ROM:0a7a997f bootstrap:1 OpenTitan:4001-0002-01 ROM:0a7a997f Immutable Starting ROM_EXT 0.1 ``` Signed-off-by: Chia-Wei Liu --- sw/device/silicon_creator/imm_rom_ext/BUILD | 48 +++++++++++++ .../silicon_creator/imm_rom_ext/defs.bzl | 9 +++ .../silicon_creator/imm_rom_ext/hello_world.c | 25 +++++++ .../silicon_creator/imm_rom_ext/hello_world.h | 18 +++++ .../imm_rom_ext/hello_world.ld | 46 ++++++++++++ .../imm_rom_ext/hello_world_start.S | 14 ++++ .../silicon_creator/imm_rom_ext/utils.bzl | 55 ++++++++++++++ sw/device/silicon_creator/rom_ext/BUILD | 54 ++++++++------ .../rom_ext/e2e/verified_boot/BUILD | 71 +++++++++++-------- 9 files changed, 289 insertions(+), 51 deletions(-) create mode 100644 sw/device/silicon_creator/imm_rom_ext/defs.bzl create mode 100644 sw/device/silicon_creator/imm_rom_ext/hello_world.c create mode 100644 sw/device/silicon_creator/imm_rom_ext/hello_world.h create mode 100644 sw/device/silicon_creator/imm_rom_ext/hello_world.ld create mode 100644 sw/device/silicon_creator/imm_rom_ext/hello_world_start.S create mode 100644 sw/device/silicon_creator/imm_rom_ext/utils.bzl diff --git a/sw/device/silicon_creator/imm_rom_ext/BUILD b/sw/device/silicon_creator/imm_rom_ext/BUILD index 71cf2fe68cc2a..f91e44b8afbff 100644 --- a/sw/device/silicon_creator/imm_rom_ext/BUILD +++ b/sw/device/silicon_creator/imm_rom_ext/BUILD @@ -2,6 +2,11 @@ # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 +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") + package(default_visibility = ["//visibility:public"]) cc_library( @@ -9,3 +14,46 @@ cc_library( srcs = ["imm_rom_ext.c"], hdrs = ["imm_rom_ext.h"], ) + +ld_library( + name = "ld_hello_world", + script = "hello_world.ld", + deps = [ + "//hw/top_earlgrey/sw/autogen:top_earlgrey_memory", + "//sw/device:info_sections", + ], +) + +cc_library( + name = "hello_world", + srcs = [ + "hello_world.c", + "hello_world_start.S", + ], + hdrs = ["hello_world.h"], + target_compatible_with = [OPENTITAN_CPU], + deps = [ + "//sw/device/silicon_creator/lib/drivers:uart", + ], +) + +opentitan_binary( + name = "hello_world_binaries", + # TODO(#22780): Integrate real keys for A1 flows. + # 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", + ], + linker_script = ":ld_hello_world", + deps = [ + ":hello_world", + ], +) + +imm_rom_ext_section( + name = "hello_world_section", + srcs = [":hello_world_binaries"], +) diff --git a/sw/device/silicon_creator/imm_rom_ext/defs.bzl b/sw/device/silicon_creator/imm_rom_ext/defs.bzl new file mode 100644 index 0000000000000..04ada7e14b651 --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/defs.bzl @@ -0,0 +1,9 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +# 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", +} diff --git a/sw/device/silicon_creator/imm_rom_ext/hello_world.c b/sw/device/silicon_creator/imm_rom_ext/hello_world.c new file mode 100644 index 0000000000000..81b350269f418 --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/hello_world.c @@ -0,0 +1,25 @@ +// 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 new file mode 100644 index 0000000000000..2932989cb8e76 --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/hello_world.h @@ -0,0 +1,18 @@ +// 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 new file mode 100644 index 0000000000000..47b757cded97d --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/hello_world.ld @@ -0,0 +1,46 @@ +/* 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 new file mode 100644 index 0000000000000..f90d7a861da8c --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/hello_world_start.S @@ -0,0 +1,14 @@ +// 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/utils.bzl b/sw/device/silicon_creator/imm_rom_ext/utils.bzl new file mode 100644 index 0000000000000..e5a55923ce671 --- /dev/null +++ b/sw/device/silicon_creator/imm_rom_ext/utils.bzl @@ -0,0 +1,55 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain") +load("@lowrisc_opentitan//rules:rv.bzl", "rv_rule") + +def _bin_to_imm_rom_ext_object_impl(ctx): + cc_toolchain = find_cc_toolchain(ctx) + outputs = [] + for src in ctx.files.srcs: + if src.extension != "bin": + continue + object = ctx.actions.declare_file( + "{}.{}".format( + src.basename.replace("." + src.extension, ""), + "o", + ), + ) + ctx.actions.run( + outputs = [object], + inputs = [src] + cc_toolchain.all_files.to_list(), + arguments = [ + "-I", + "binary", + "-O", + "elf32-littleriscv", + "--rename-section", + ".data=.rom_ext_immutable,alloc,load,readonly,data,contents", + src.path, + object.path, + ], + executable = cc_toolchain.objcopy_executable, + ) + outputs.append(object) + 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), + "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), + }, + 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) + native.cc_import( + name = 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 187f5dab662f2..05126f0c69f74 100644 --- a/sw/device/silicon_creator/rom_ext/BUILD +++ b/sw/device/silicon_creator/rom_ext/BUILD @@ -12,6 +12,10 @@ load( "//sw/device/silicon_creator/rom_ext:defs.bzl", "ROM_EXT_VERSION", ) +load( + "//sw/device/silicon_creator/imm_rom_ext:defs.bzl", + "IMM_ROM_EXT_TARGETS", +) package(default_visibility = ["//visibility:public"]) @@ -327,29 +331,33 @@ opentitan_binary( ], ) -opentitan_binary( - name = "rom_ext_with_nop_imm_slot_virtual", - testonly = True, - # TODO(#22780): Integrate real keys for A1 flows. - ecdsa_key = {"//sw/device/silicon_creator/rom/keys/fake/ecdsa:prod_key_0_ecdsa_p256": "prod_key_0"}, - 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", - ], - linker_script = ":ld_slot_virtual", - manifest = ":manifest", - deps = [ - ":rom_ext", - "//sw/device/lib/crt", - "//sw/device/silicon_creator/imm_rom_ext/prebuilts:nop_imm_rom_ext", - "//sw/device/silicon_creator/lib:manifest_def", - "//sw/device/silicon_creator/lib/ownership:test_owner", - "//sw/device/silicon_creator/lib/ownership/keys/fake", - ], -) +[ + opentitan_binary( + name = "rom_ext_with_{}_imm_slot_virtual".format(name), + testonly = True, + # TODO(#22780): Integrate real keys for A1 flows. + ecdsa_key = {"//sw/device/silicon_creator/rom/keys/fake/ecdsa:prod_key_0_ecdsa_p256": "prod_key_0"}, + 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", + ], + linker_script = ":ld_slot_virtual", + manifest = ":manifest", + deps = [ + ":rom_ext", + "//sw/device/lib/crt", + "//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() +] manifest(d = { "name": "manifest_bad_address_translation", 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 9058ca970a528..0616c75df464a 100644 --- a/sw/device/silicon_creator/rom_ext/e2e/verified_boot/BUILD +++ b/sw/device/silicon_creator/rom_ext/e2e/verified_boot/BUILD @@ -20,6 +20,10 @@ load( "otp_json_immutable_rom_ext", "otp_partition", ) +load( + "//sw/device/silicon_creator/imm_rom_ext:defs.bzl", + "IMM_ROM_EXT_TARGETS", +) package(default_visibility = ["//visibility:public"]) @@ -28,31 +32,37 @@ filegroup( srcs = ["boot_test.c"], ) -otp_json_immutable_rom_ext( - name = "otp_json_with_nop_imm_romext_enabled", - testonly = True, - partitions = [ - otp_partition( - name = "CREATOR_SW_CFG", - items = { - "CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN": otp_hex(CONST.HARDENED_TRUE), - }, - ), - ], - rom_ext = "//sw/device/silicon_creator/rom_ext:rom_ext_with_nop_imm_slot_virtual", - visibility = ["//visibility:private"], -) +[ + otp_json_immutable_rom_ext( + name = "otp_json_with_{}_imm_romext_enabled".format(name), + testonly = True, + partitions = [ + otp_partition( + name = "CREATOR_SW_CFG", + items = { + "CREATOR_SW_CFG_IMMUTABLE_ROM_EXT_EN": otp_hex(CONST.HARDENED_TRUE), + }, + ), + ], + 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 +] -otp_image( - name = "otp_img_with_nop_imm_romext_enabled", - testonly = True, - src = "//hw/ip/otp_ctrl/data:otp_json_prod", - overlays = STD_OTP_OVERLAYS + [ - "//sw/device/silicon_creator/rom_ext/e2e:otp_json_secret2_locked", - ":otp_json_with_nop_imm_romext_enabled", - ], - visibility = ["//visibility:private"], -) +[ + otp_image( + name = "otp_img_with_{}_imm_romext_enabled".format(name), + testonly = True, + src = "//hw/ip/otp_ctrl/data:otp_json_prod", + overlays = STD_OTP_OVERLAYS + [ + "//sw/device/silicon_creator/rom_ext/e2e:otp_json_secret2_locked", + ":otp_json_with_{}_imm_romext_enabled".format(name), + ], + visibility = ["//visibility:private"], + ) + for name in IMM_ROM_EXT_TARGETS +] _POSITIONS = { "owner_slot_a": { @@ -119,14 +129,16 @@ _POSITIONS = { "success": "rom_ext_slot = __BB\r\n", "otp_img": None, }, - "romext_virtual_a_with_nop_imm_romext_enabled": { - "romext": "//sw/device/silicon_creator/rom_ext:rom_ext_with_nop_imm_slot_virtual", +} | { + "romext_virtual_a_with_{}_imm_romext_enabled".format(name): { + "romext": "//sw/device/silicon_creator/rom_ext:rom_ext_with_{}_imm_slot_virtual".format(name), "romext_offset": "0", "linker_script": "//sw/device/lib/testing/test_framework:ottf_ld_silicon_owner_slot_a", "owner_offset": "0x10000", "success": "rom_ext_slot = AA__\r\n", - "otp_img": ":otp_img_with_nop_imm_romext_enabled", - }, + "otp_img": ":otp_img_with_{}_imm_romext_enabled".format(name), + } + for name in IMM_ROM_EXT_TARGETS } [ @@ -135,6 +147,7 @@ _POSITIONS = { srcs = [":boot_test"], exec_env = { "//hw/top_earlgrey:fpga_cw310_rom_ext": None, + "//hw/top_earlgrey:fpga_cw340_rom_ext": None, }, fpga = fpga_params( assemble = "{romext}@{romext_offset} {firmware}@{owner_offset}", @@ -176,6 +189,7 @@ opentitan_test( srcs = [":boot_test"], exec_env = { "//hw/top_earlgrey:fpga_cw310_rom_ext": None, + "//hw/top_earlgrey:fpga_cw340_rom_ext": None, }, fpga = fpga_params( exit_failure = "PASS|FAIL|FAULT|BFV:.{8}", @@ -221,6 +235,7 @@ _KEYS = { srcs = [":boot_test"], exec_env = { "//hw/top_earlgrey:fpga_cw310_rom_ext": None, + "//hw/top_earlgrey:fpga_cw340_rom_ext": None, }, fpga = fpga_params( exit_failure = keyinfo["exit_failure"],