Skip to content

Commit

Permalink
[imm_rom_ext] Add hello world IM_EXT
Browse files Browse the repository at this point in the history
* 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.
* Reuse the rule `opentitan_binary` to build IM_EXT and add a attribute
  to skip the signing stage to the rule. The manifest given as None will
  turn into the default manifest and keep the signing operation so we
  need to skip it explicitly.
* 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 <[email protected]>
  • Loading branch information
lchiawei committed Nov 20, 2024
1 parent d46f270 commit bfd47a2
Show file tree
Hide file tree
Showing 10 changed files with 298 additions and 52 deletions.
4 changes: 3 additions & 1 deletion rules/opentitan/cc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ def _build_binary(ctx, exec_env, name, deps, kind):
if manifest and ctx.attr.immutable_rom_ext_enabled:
manifest = update_manifest(ctx, manifest, elf, exec_env._update_manifest_json)

if (manifest or rsa_key) and kind != "ram":
if (manifest or rsa_key) and kind != "ram" and not ctx.attr.skip_signing:
if not (manifest and (rsa_key or ecdsa_key)):
fail("Signing requires a manifest and an rsa_key or ecdsa_key, and optionally an spx_key")
signed = sign_binary(
Expand Down Expand Up @@ -339,6 +339,7 @@ opentitan_binary = rv_rule(
doc = "List of execution environments for this target.",
),
"_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
"skip_signing": attr.bool(default = False),
}.items()),
fragments = ["cpp"],
toolchains = ["@rules_cc//cc:toolchain_type"],
Expand Down Expand Up @@ -445,6 +446,7 @@ opentitan_test = rv_rule(
doc = "OpenOCD adapter configuration override for this test",
),
"_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
"skip_signing": attr.bool(default = False),
}.items()),
fragments = ["cpp"],
toolchains = ["@rules_cc//cc:toolchain_type"],
Expand Down
54 changes: 54 additions & 0 deletions sw/device/silicon_creator/imm_rom_ext/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright lowRISC contributors (OpenTitan project).
# 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"])

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",
skip_signing = True,
deps = [
":hello_world",
],
)

imm_rom_ext_section(
name = "hello_world_section",
srcs = [":hello_world_binaries"],
)
9 changes: 9 additions & 0 deletions sw/device/silicon_creator/imm_rom_ext/defs.bzl
Original file line number Diff line number Diff line change
@@ -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",
}
25 changes: 25 additions & 0 deletions sw/device/silicon_creator/imm_rom_ext/hello_world.c
Original file line number Diff line number Diff line change
@@ -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;
}
18 changes: 18 additions & 0 deletions sw/device/silicon_creator/imm_rom_ext/hello_world.h
Original file line number Diff line number Diff line change
@@ -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_
46 changes: 46 additions & 0 deletions sw/device/silicon_creator/imm_rom_ext/hello_world.ld
Original file line number Diff line number Diff line change
@@ -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
}
14 changes: 14 additions & 0 deletions sw/device/silicon_creator/imm_rom_ext/hello_world_start.S
Original file line number Diff line number Diff line change
@@ -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
55 changes: 55 additions & 0 deletions sw/device/silicon_creator/imm_rom_ext/utils.bzl
Original file line number Diff line number Diff line change
@@ -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,
)
54 changes: 31 additions & 23 deletions sw/device/silicon_creator/rom_ext/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -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"])

Expand Down Expand Up @@ -335,29 +339,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",
Expand Down
Loading

0 comments on commit bfd47a2

Please sign in to comment.