Skip to content

Commit

Permalink
[sw,silicon_creator,rom] Add dummy ROM state hooks
Browse files Browse the repository at this point in the history
And define the hooks setup bazel rules for silicon creators to provide
their own ROM state hooks implementations.

Signed-off-by: Samuel Ortiz <[email protected]>
  • Loading branch information
sameo committed Dec 17, 2024
1 parent 55a25fa commit bd19b19
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 1 deletion.
9 changes: 8 additions & 1 deletion WORKSPACE.bzlmod
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ open_dice_repos()

# Setup for linking in externally managed test and provisioning customizations
# for both secure/non-secure manufacturer domains.
load("//rules:hooks_setup.bzl", "hooks_setup", "provisioning_exts_setup", "secure_hooks_setup")
load("//rules:hooks_setup.bzl", "hooks_setup", "provisioning_exts_setup", "secure_hooks_setup", "rom_hooks_setup")
hooks_setup(
name = "hooks_setup",
dummy = "sw/device/tests/closed_source",
Expand All @@ -125,16 +125,23 @@ provisioning_exts_setup(
name = "provisioning_exts_setup",
dummy = "sw/device/silicon_creator/manuf/extensions",
)
rom_hooks_setup(
name = "rom_hooks_setup",
dummy = "sw/device/silicon_creator/rom/hooks",
)

# Declare the external repositories:
# - One for both manufacturer secure and non-secure domains.
# - One for provisioning source code extensions.
# - One for ROM vendor hooks.
load("@hooks_setup//:repos.bzl", "hooks_repo")
load("@secure_hooks_setup//:repos.bzl", "secure_hooks_repo")
load("@provisioning_exts_setup//:repos.bzl", "provisioning_exts_repo")
load("@rom_hooks_setup//:repos.bzl", "rom_hooks_repo")
hooks_repo(name = "manufacturer_test_hooks")
secure_hooks_repo(name = "secure_manufacturer_test_hooks")
provisioning_exts_repo(name = "provisioning_exts")
rom_hooks_repo(name = "rom_hooks")

# The nonhermetic_repo imports environment variables needed to run vivado.
load("//rules:nonhermetic.bzl", "nonhermetic_repo")
Expand Down
24 changes: 24 additions & 0 deletions rules/hooks_setup.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ def provisioning_exts_repo(name):
)
"""

_ROM_HOOKS_TEMPLATE = """
def rom_hooks_repo(name):
native.local_repository(
name = name,
path = "{hooks_dir}",
)
"""

_BUILD = """
exports_files(glob(["**"]))
"""
Expand Down Expand Up @@ -77,3 +85,19 @@ provisioning_exts_setup = repository_rule(
},
environ = ["PROV_EXTS_DIR"],
)

def _rom_hooks_setup_impl(rctx):
rom_hooks_dir = rctx.os.environ.get("ROM_HOOKS_DIR", rctx.attr.dummy)
rctx.file("repos.bzl", _ROM_HOOKS_TEMPLATE.format(hooks_dir = rom_hooks_dir))
rctx.file("BUILD.bazel", _BUILD)

rom_hooks_setup = repository_rule(
implementation = _rom_hooks_setup_impl,
attrs = {
"dummy": attr.string(
mandatory = True,
doc = "Location of the dummy ROM extensions directory.",
),
},
environ = ["ROM_HOOKS_DIR"],
)
12 changes: 12 additions & 0 deletions sw/device/silicon_creator/rom/hooks/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright lowRISC contributors (OpenTitan project).
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

package(default_visibility = ["//visibility:public"])

cc_library(
name = "rom_hooks",
srcs = ["dummy_rom_hooks.c"],
deps = ["@//sw/device/silicon_creator/rom:rom_state"],
alwayslink = True,
)
85 changes: 85 additions & 0 deletions sw/device/silicon_creator/rom/hooks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#Silicon Creator ROM Hooks

## Overview

The OpenTitan ROM defines pre-run and post-run hooks for any defined ROM state.

When transitioning to a ROM state, the ROM state machine first executes the pre-run hook.

The state's run callback is called only if the pre-run hook does not return an error.
Finally, the post-run hook runs upon successful termination of the ROM state's run callback:

```
│ │
│ ┌──────────────┐ │
│ │Post-run Hook │ │
│ └───────┬──────┘ │
└───────────┼──────────┘
┌───────────┼──────────┐
│ ROM │ │
│ State │ │
│ ┌───────▼──────┐ │
│ │ Pre-run Hook │ │
│ └───────┬──────┘ │
│ │ │
│ │ │
│ ┌───────▽──────┐ │
│ │ Run Callback │ │
│ └───────┬──────┘ │
│ │ │
│ │ │
│ ┌───────▽──────┐ │
│ │Post-run Hook │ │
│ └───────┬──────┘ │
└───────────┼──────────┘
┌───────────┼──────────┐
│ ┌───────▼──────┐ │
│ │ Pre-run Hook │ │
│ └──────────────┘ │
│ │
```

The transition from one ROM state to the next one is defined by the current ROM state's run callback:

``` c
rom_error_t rom_state_run_cb(void *arg, rom_state_t *next_state);
```
By default, the pre-run and post-run hooks do nothing. However, they provide a mechanism for silicon creators to override them with external implementations (e.g. with closed-source, vendor-specific initialization sequences).
Each ROM state pre-run and post-run hooks are defined as weak symbols using a pre-defined naming scheme.
For example the hooks prototypes for a ROM state named `kRomStateInit` would be:
``` c
OT_WARN_UNUSED_RESULT rom_error_t rom_state_pre_kRomStateInit(void *arg);
OT_WARN_UNUSED_RESULT rom_error_t rom_state_post_kRomStateInit(void *arg);
```

## ROM State Hooks Implementation

Downstream silicon creators can override the default pre-run and post-run hooks from an external, possibly closed-source repository.

A downstream ROM hooks repository should follow the layout defined in this example.

In particular, the repository must include:

- A `WORKSPACE.bazel` file that defines a `rom_hooks` workspace.
- A `BUILD.bazel` file that defines a `rom_hooks` `cc_library` target.
- A C file implementing the desired ROM state hooks overrides.
Hooks implementations must follow the prototype defined in `rom_state.h`.
Binding a hook to a ROM state pre-run or post-run step is done through respectively the `ROM_STATE_PRE_HOOK` and `ROM_STATE_POST_HOOK` macros.
See `dummy_rom_hooks.c` in this folder for a simple example.

In order to link an OpenTitan ROM image with externally defined hooks override, `bazel` must be invoked with the `ROM_HOOKS_DIR` environment variable set to the local path of the hooks override repository.

For example:

``` bash
ROM_HOOKS_DIR=<path/to/ROM_hooks> ./bazelisk.sh test --test_output=streamed --cache_test_results=no //sw/device/silicon_creator/rom/e2e:rom_e2e_smoke_sim_verilator
```
13 changes: 13 additions & 0 deletions sw/device/silicon_creator/rom/hooks/WORKSPACE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright lowRISC contributors (OpenTitan project).
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

workspace(name = "rom_hooks")

# This is a sample workspace to demonstrate how to write custom ROM hooks.
# This bazel repository is not stand-alone project: it must be connected into
# the main OpenTitan repository by way of the `rom_hooks_setup` call in
# OpenTitan's WORKSPACE file.

# See this repository's README.md and BUILD.bazel files to understand how to
# write rules for custom ROM hooks.
15 changes: 15 additions & 0 deletions sw/device/silicon_creator/rom/hooks/dummy_rom_hooks.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// 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/rom/rom_state.h"

/**
* A dummy pre-run hook for the `kRomStateInit` ROM state.
*
* This is an example on how Silicon Creators should define a ROM state hook.
*/
OT_WARN_UNUSED_RESULT rom_error_t dummy_rom_init_pre_hook(void *arg) {
return kErrorOk;
}
ROM_STATE_PRE_HOOK(kRomStateInit, dummy_rom_init_pre_hook);

0 comments on commit bd19b19

Please sign in to comment.