[dif_sram_ctrl] Refactor and extend the header Since SRAM header was merged there was a number of HW changes that made some of the API absolete. In practice, scrambling/wiping C routines don't make sense, unless C runtime is set up in retention RAM, which would make it possible to use the above mentioned API. Signed-off-by: Silvestrs Timofejevs <silvestrst@lowrisc.org>
diff --git a/sw/device/lib/dif/autogen/dif_sram_ctrl_autogen.c b/sw/device/lib/dif/autogen/dif_sram_ctrl_autogen.c new file mode 100644 index 0000000..79a68a4 --- /dev/null +++ b/sw/device/lib/dif/autogen/dif_sram_ctrl_autogen.c
@@ -0,0 +1,9 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This file is auto-generated. + +#include "sw/device/lib/dif/dif_sram_ctrl.h" + +#include "sram_ctrl_regs.h" // Generated.
diff --git a/sw/device/lib/dif/autogen/dif_sram_ctrl_autogen.h b/sw/device/lib/dif/autogen/dif_sram_ctrl_autogen.h new file mode 100644 index 0000000..f2aed1a --- /dev/null +++ b/sw/device/lib/dif/autogen/dif_sram_ctrl_autogen.h
@@ -0,0 +1,43 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#ifndef OPENTITAN_SW_DEVICE_LIB_DIF_AUTOGEN_DIF_SRAM_CTRL_AUTOGEN_H_ +#define OPENTITAN_SW_DEVICE_LIB_DIF_AUTOGEN_DIF_SRAM_CTRL_AUTOGEN_H_ + +// This file is auto-generated. + +/** + * @file + * @brief <a href="/hw/ip/sram_ctrl/doc/">SRAM_CTRL</a> Device Interface + * Functions + */ + +#include <stdbool.h> +#include <stdint.h> + +#include "sw/device/lib/base/macros.h" +#include "sw/device/lib/base/mmio.h" +#include "sw/device/lib/dif/dif_base.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * A handle to sram_ctrl. + * + * This type should be treated as opaque by users. + */ +typedef struct dif_sram_ctrl { + /** + * The base address for the sram_ctrl hardware registers. + */ + mmio_region_t base_addr; +} dif_sram_ctrl_t; + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif // OPENTITAN_SW_DEVICE_LIB_DIF_AUTOGEN_DIF_SRAM_CTRL_AUTOGEN_H_
diff --git a/sw/device/lib/dif/autogen/dif_sram_ctrl_autogen_unittest.cc b/sw/device/lib/dif/autogen/dif_sram_ctrl_autogen_unittest.cc new file mode 100644 index 0000000..b4bcb34 --- /dev/null +++ b/sw/device/lib/dif/autogen/dif_sram_ctrl_autogen_unittest.cc
@@ -0,0 +1,27 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This file is auto-generated. + +#include "sw/device/lib/dif/dif_sram_ctrl.h" + +#include "gtest/gtest.h" +#include "sw/device/lib/base/mmio.h" +#include "sw/device/lib/base/testing/mock_mmio.h" + +#include "sram_ctrl_regs.h" // Generated. + +namespace dif_sram_ctrl_autogen_unittest { +namespace { +using ::mock_mmio::MmioTest; +using ::mock_mmio::MockDevice; +using ::testing::Test; + +class SramCtrlTest : public Test, public MmioTest { + protected: + dif_sram_ctrl_t sram_ctrl_ = {.base_addr = dev().region()}; +}; + +} // namespace +} // namespace dif_sram_ctrl_autogen_unittest
diff --git a/sw/device/lib/dif/dif_sram_ctrl.h b/sw/device/lib/dif/dif_sram_ctrl.h index 011d674..7f23dc6 100644 --- a/sw/device/lib/dif/dif_sram_ctrl.h +++ b/sw/device/lib/dif/dif_sram_ctrl.h
@@ -11,256 +11,262 @@ * Functions */ -/** - * The SRAM Controller can perform destructive operations on data in memory. - * These operations invalidate the stack and other data that the C runtime - * requires. Such functionality has been intentionally left out of this library - * and will need to be triggered by assembly code that does not require a valid - * stack or initialized static data. Such functionality includes: - * - * - Requesting a new scrambling key. - * - Initializing the contents of memory. - * - * For the same reason there is no accessor function in this library for the - * `status.ESCALATED` bit. If that bit is set then memory is inaccessible. - */ - -#include <stdbool.h> #include <stdint.h> -#include "sw/device/lib/base/macros.h" -#include "sw/device/lib/base/mmio.h" +#include "sw/device/lib/dif/autogen/dif_sram_ctrl_autogen.h" #ifdef __cplusplus extern "C" { #endif // __cplusplus /** - * Hardware instantiation parameters for SRAM Controller. - * - * This struct describes information about the underlying hardware that is - * not determined until the hardware design is used as part of a top-level - * design. + * SRAM Controller status information bitfield. */ -typedef struct dif_sram_ctrl_params { - /** - * The base address for the SRAM Controller hardware registers. - */ - mmio_region_t base_addr; -} dif_sram_ctrl_params_t; +typedef uint32_t dif_sram_ctrl_status_bitfield_t; /** - * A handle to SRAM Controller. + * SRAM Controller status flags. * - * This type should be treated as opaque by users. + * Invariants are used to extract information encoded in + * `dif_sram_ctrl_status_bitfield_t`. + * + * More than one status flag can be set at the same time, and a caller may use + * these invariants to look-up individual or a group of flags. + * + * Note: these must match the autogenerated register definition bit offsets. */ -typedef struct dif_sram_ctrl { - dif_sram_ctrl_params_t params; -} dif_sram_ctrl_t; +typedef enum dif_sram_ctrl_status { + /** + * Bus integrity fault is detected. This error triggers a fatal_error alert. + * This condition is terminal. + */ + kDifSramCtrlStatusBusIntegErr = 0x1, + /** + * Initialization counter has reached an invalid state. This error triggers + * a fatal_error alert. This condition is terminal. + */ + kDifSramCtrlStatusInitErr = (0x1 << 1), + /** + * SRAM Controller has received an escalate request, the scrambling keys have + * been reset to the default values and all subsequent memory requests will + * be blocked. This condition is terminal. + */ + kDifSramCtrlStatusEscalated = (0x1 << 2), + /** + * New scrambling key has been successfully obtained from OTP. If the flag is + * not set, the SRAM contents are still scrambled, but a default all-zero key + * and nonce are used to do so. + */ + kDifSramCtrlStatusScrKeyValid = (0x1 << 3), + /** + * Scrambling key has been derived from a valid key seed in OTP. When + * `kDifSramCtrlStatusScrKeyValid` is set, but this flag is unset - the + * scrambling key is still ephemeral (i.e., it is derived using entropy from + * CSRNG), but a default all-zero value is used as the key seed. This could + * happen when the scrambling key seeds have not yet been provisioned to OTP. + */ + kDifSramCtrlStatusScrKeySeedValid = (0x1 << 4), + /** + * Hardware initialization triggered via `dif_sram_ctrl_scramble` or + * `dif_sram_ctrl_wipe` has completed. + */ + kDifSramCtrlStatusInitDone = (0x1 << 5), +} dif_sram_ctrl_status_t; /** - * The result of a SRAM Controller operation. + * SRAM Controller lockable functionality. */ -typedef enum dif_sram_ctrl_result { +typedef enum dif_sram_ctrl_lock { /** - * Indicates that the operation succeeded. + * SRAM scrambling key renewal and "wiping" lock, which includes the following + * API: `dif_sram_ctrl_scramble`, `dif_sram_ctrl_request_new_key` + * and `dif_sram_ctrl_wipe`. */ - kDifSramCtrlOk = 0, + kDifSramCtrlLockCtrl = 0, /** - * Indicates some unspecified failure. - */ - kDifSramCtrlError, - /** - * Indicates that some parameter passed into a function failed a - * precondition. + * Code execution from SRAM lock, which includes the following API: + * `dif_sram_ctrl_exec_set_enabled`. * - * When this value is returned, no hardware operations occurred. + * Note: this setting may not be available depending on the OTP configuration + * of the chip (EN_SRAM_IFETCH fuse). */ - kDifSramCtrlBadArg, -} dif_sram_ctrl_result_t; - -/** - * A toggle state: enabled, or disabled. - * - * This enum may be used instead of a `bool` when describing an enabled/disabled - * state. - */ -typedef enum dif_sram_ctrl_toggle { - /** - * The "enabled" state. - */ - kDifSramCtrlToggleEnabled, - /** - * The "disabled" state. - */ - kDifSramCtrlToggleDisabled, -} dif_sram_ctrl_toggle_t; + kDifSramCtrlLockExec, +} dif_sram_ctrl_lock_t; /** * Creates a new handle for SRAM Controller. * * This function does not actuate the hardware. * - * @param params Hardware instantiation parameters. - * @param[out] handle Out param for the initialized handle. + * @param base_addr The MMIO base address of the IP. + * @param[out] sram_ctrl Out param for the initialized handle. * @return The result of the operation. */ OT_WARN_UNUSED_RESULT -dif_sram_ctrl_result_t dif_sram_ctrl_init(dif_sram_ctrl_params_t params, - dif_sram_ctrl_t *handle); +dif_result_t dif_sram_ctrl_init(mmio_region_t base_addr, + dif_sram_ctrl_t *sram_ctrl); /** - * Trigger one alert event. + * Performs SRAM scrambling. + * + * This function should only be called when the data is no longer used. + * + * This is a compound operation covering both data and address "scrambling". + * In other words logical re-mapping of the physical addresses and data + * scrambling, followed by the entire SRAM overwriting with a pseudo-random + * data. + * + * The intention of this operation is to ensure that there is no predefined + * values or predictable data that could potentially make "unscrambling" + * easier. + * + * This operation is expected to take a significant amount of CPU cycles. The + * status can be checked via `dif_sram_ctrl_scramble_is_busy`, which is useful + * when a non-blocking work flow is desirable. Otherwise any SRAM access will + * automatically block until this operation has finished. + * + * The equivalent effect can be achieved by calling + * `dif_sram_ctrl_request_new_key`, followed by `dif_sram_ctrl_wipe`. + * + * Note: when dealing with the Main RAM, additional implication is that the + * C runtime can be invalidated by the call to this function, and must be + * re-configured prior to any C code execution. * * @param sram_ctrl A SRAM Controller handle. * @return The result of the operation. */ OT_WARN_UNUSED_RESULT -dif_sram_ctrl_result_t dif_sram_ctrl_force_alert( - const dif_sram_ctrl_t *sram_ctrl); +dif_result_t dif_sram_ctrl_scramble(const dif_sram_ctrl_t *sram_ctrl); /** - * Lock execution enable register. + * Checks whether SRAM scramble is still progress. * - * This function prevents any further writes to the - * execution enable register. Future attempts to enable or disable - * execution from SRAM will fail. + * Useful when a non-blocking work flow is desirable. + * + * @param sram_ctrl A SRAM Controller handle. + * @param[out] is_busy Out-param for the busy state. + * @return The result of the operation. + */ +OT_WARN_UNUSED_RESULT +dif_result_t dif_sram_ctrl_scramble_is_busy(const dif_sram_ctrl_t *sram_ctrl, + bool *is_busy); + +/** + * Requests a new scrambling key. + * + * This function should only be called when the data is no longer used. + * + * On successful completion SRAM addresses (due to different logical mapping of + * the physical addresses) and the data are scrambled. However, it is + * recommended to additionally overwrite SRAM with pseudo-random data by calling + * `dif_sram_ctrl_wipe`. This should minimize the chances of revealing the XOR + * key-stream. + * + * This operation is expected to take a significant amount of CPU cycles. The + * status can be checked via `kDifSramCtrlStatusScrKeyValid`, which is useful + * when a non-blocking work flow is desirable. Otherwise any SRAM access will + * automatically block until this operation has finished. + * + * Note: when dealing with the Main RAM, additional implication is that the + * C runtime can be invalidated by the call to this function, and must be + * re-configured prior to any C code execution. * * @param sram_ctrl A SRAM Controller handle. * @return The result of the operation. */ OT_WARN_UNUSED_RESULT -dif_sram_ctrl_result_t dif_sram_ctrl_exec_lock( - const dif_sram_ctrl_t *sram_ctrl); +dif_result_t dif_sram_ctrl_request_new_key(const dif_sram_ctrl_t *sram_ctrl); /** - * Reports whether the execution enable register is locked or not. + * Overwrites "wipes" the entire SRAM with pseudo-random data. * - * If the execution enable register is locked then it is no longer possible to - * enable or disable execution from SRAM. + * This function should only be called when the data is no longer used. + * + * This operation is expected to take a significant amount of CPU cycles. The + * status can be checked via `kDifSramCtrlStatusInitDone`, which is useful when + * a non-blocking work flow is desirable. Otherwise any SRAM access will + * automatically block until this operation has finished. + * + * Note: when dealing with the Main RAM, additional implication is that the + * C runtime can be invalidated by the call to this function, and must be + * re-configured prior to any C code execution. * * @param sram_ctrl A SRAM Controller handle. - * @param state[out] Enabled if locked, disabled if unlocked. * @return The result of the operation. */ OT_WARN_UNUSED_RESULT -dif_sram_ctrl_result_t dif_sram_ctrl_exec_is_locked( - const dif_sram_ctrl_t *sram_ctrl, dif_sram_ctrl_toggle_t *state); +dif_result_t dif_sram_ctrl_wipe(const dif_sram_ctrl_t *sram_ctrl); /** - * Reports whether the control register is locked or not. - * - * If the control register is locked then it is no longer possible to request a - * new scrambling key. + * Checks whether execution from SRAM is currently enabled or disabled. * * @param sram_ctrl A SRAM Controller handle. - * @param state[out] Enabled if locked, disabled if unlocked. + * @param[out] state Out-param toggle state of the SRAM execution. * @return The result of the operation. */ OT_WARN_UNUSED_RESULT -dif_sram_ctrl_result_t dif_sram_ctrl_control_is_locked( - const dif_sram_ctrl_t *sram_ctrl, dif_sram_ctrl_toggle_t *state); +dif_result_t dif_sram_ctrl_exec_get_enabled(const dif_sram_ctrl_t *sram_ctrl, + dif_toggle_t *state); /** - * The result of an attempt to enable or disable execution from SRAM. - */ -typedef enum dif_sram_ctrl_exec_result { - /** - * Indicates that the operation succeeded. - */ - kDifSramCtrlExecOk = kDifSramCtrlOk, - /** - * Indicates some unspecified failure. - */ - kDifSramCtrlExecError = kDifSramCtrlError, - /** - * Indicates that some parameter passed into a function failed a - * precondition. - * - * When this value is returned, no hardware operations occured. - */ - kDifSramCtrlExecBadArg = kDifSramCtrlBadArg, - /** - * Indicates that this operation has been locked out, and can never - * succeed until hardware reset. - */ - kDifSramCtrlExecLocked, -} dif_sram_ctrl_exec_result_t; - -/** - * Enable or disable execution from SRAM. + * Sets whether execution from SRAM enabled or disabled. * * @param sram_ctrl A SRAM Controller handle. - * @param state Enable or disable SRAM execution. + * @param state The new toggle state for the SRAM execution. * @return The result of the operation. */ OT_WARN_UNUSED_RESULT -dif_sram_ctrl_exec_result_t dif_sram_ctrl_exec_set_enabled( - const dif_sram_ctrl_t *sram_ctrl, dif_sram_ctrl_toggle_t state); +dif_result_t dif_sram_ctrl_exec_set_enabled(const dif_sram_ctrl_t *sram_ctrl, + dif_toggle_t state); /** - * Report whether execution from SRAM is currently enabled or disabled. + * Queries the SRAM Controller status. + * + * `dif_sram_ctrl_status_t` is used to then extract individual status bits. * * @param sram_ctrl A SRAM Controller handle. - * @param[out] state State of SRAM execution (enabled or disabled). + * @param[out] SRAM Controller status bitfield. * @return The result of the operation. */ OT_WARN_UNUSED_RESULT -dif_sram_ctrl_result_t dif_sram_ctrl_exec_get_enabled( - const dif_sram_ctrl_t *sram_ctrl, dif_sram_ctrl_toggle_t *state); +dif_result_t dif_sram_ctrl_get_status(const dif_sram_ctrl_t *sram_ctrl, + dif_sram_ctrl_status_bitfield_t *status); /** - * Retrieve the error state from the SRAM controller. - * - * This function will return `kDifSramCtrlOk` if the error state of the - * SRAM controller was successfully fetched regardless of whether the SRAM - * controller has experienced an uncorrectable parity error or not. The `error` - * argument must be checked to see if a uncorrectable parity error has actually - * occurred. + * Forces a fatal error. * * @param sram_ctrl A SRAM Controller handle. - * @param[out] error Whether an uncorrectable parity error has occurred. - * @param[out] address The byte address of the last parity error (optional). * @return The result of the operation. */ OT_WARN_UNUSED_RESULT -dif_sram_ctrl_result_t dif_sram_ctrl_get_error(const dif_sram_ctrl_t *sram_ctrl, - bool *error, uintptr_t *address); +dif_result_t dif_sram_ctrl_alert_test(const dif_sram_ctrl_t *sram_ctrl); /** - * SRAM controller scrambling status. - */ -typedef struct dif_sram_ctrl_scrambling_status { - /** - * The validity of the scrambling key. If the key is valid then SRAM is - * scrambled using a key from OTP. Otherwise SRAM is scrambled using the - * default all-zero key and nonce. - */ - bool key_valid; - - /** - * The validity of the seed used to derive the scrambling key in OTP. If the - * seed is not valid then the scrambling key was derived using the default - * all-zero seed. - */ - bool key_seed_valid; -} dif_sram_ctrl_scrambling_status_t; - -/** - * Retrieve the scrambling status from the SRAM controller. + * Locks out requested SRAM Controller functionality. * - * If `key_valid` is set to true then SRAM is scrambled using a valid key from - * OTP. Otherwise SRAM is scrambled using a default all-zero key and all-zero - * nonce. + * This function is reentrant: calling it while functionality is locked will + * have no effect and return `kDifSramCtrlOk`. * * @param sram_ctrl A SRAM Controller handle. - * @param[out] status Information about the scrambling key in use. + * @param lock SRAM functionality to lock. * @return The result of the operation. */ OT_WARN_UNUSED_RESULT -dif_sram_ctrl_result_t dif_sram_ctrl_get_scrambling_status( - const dif_sram_ctrl_t *sram_ctrl, - dif_sram_ctrl_scrambling_status_t *status); +dif_result_t dif_sram_ctrl_lock(const dif_sram_ctrl_t *sram_ctrl, + dif_sram_ctrl_lock_t lock); + +/** + * Checks whether requested SRAM Controller functionality is locked. + * + * @param sram_ctrl A SRAM Controller handle. + * @param lock SRAM functionality to query locked state for. + * @param[out] is_locked Out-param for the locked state. + * @return The result of the operation. + */ +OT_WARN_UNUSED_RESULT +dif_result_t dif_sram_ctrl_is_locked(const dif_sram_ctrl_t *sram_ctrl, + dif_sram_ctrl_lock_t lock, + bool *is_locked); #ifdef __cplusplus } // extern "C"
diff --git a/sw/device/lib/dif/dif_sram_ctrl.md b/sw/device/lib/dif/dif_sram_ctrl.md index 6a2bf84..eddbcaa 100644 --- a/sw/device/lib/dif/dif_sram_ctrl.md +++ b/sw/device/lib/dif/dif_sram_ctrl.md
@@ -2,6 +2,8 @@ title: "SRAM Controller DIF Checklist" --- + + <!-- NOTE: This is a template checklist document that is required to be copied over to `sw/device/lib/dif/dif_sram_ctrl.md` for a new DIF that transitions @@ -36,7 +38,6 @@ Documentation | [DIF_DOC_API][] | Not Started | Code Quality | [DIF_CODE_STYLE][] | Not Started | Coordination | [DIF_DV_TESTS][] | Not Started | -Implementation | [DIF_USED_TOCK][] | Not Started | Review | HW IP Usage Reviewer(s) | Not Started | [DIF_FEATURES]: {{< relref "/doc/project/checklist.md#dif_features" >}} @@ -47,7 +48,6 @@ [DIF_DOC_API]: {{< relref "/doc/project/checklist.md#dif_doc_api" >}} [DIF_CODE_STYLE]: {{< relref "/doc/project/checklist.md#dif_code_style" >}} [DIF_DV_TESTS]: {{< relref "/doc/project/checklist.md#dif_dv_tests" >}} -[DIF_USED_TOCK]: {{< relref "/doc/project/checklist.md#dif_used_tock" >}} Type | Item | Resolution | Note/Collaterals @@ -57,7 +57,6 @@ Review | [DIF_REVIEW_C_STABLE][] | Not Started | Tests | [DIF_TEST_UNIT_COMPLETE][] | Not Started | Review | [DIF_TODO_COMPLETE][] | Not Started | -Review | [DIF_REVIEW_TOCK_STABLE][] | Not Started | Review | Reviewer(s) | Not Started | Review | Signoff date | Not Started | @@ -66,4 +65,3 @@ [DIF_REVIEW_C_STABLE]: {{< relref "/doc/project/checklist.md#dif_review_c_stable" >}} [DIF_TEST_UNIT_COMPLETE]: {{< relref "/doc/project/checklist.md#dif_test_unit_complete" >}} [DIF_TODO_COMPLETE]: {{< relref "/doc/project/checklist.md#dif_todo_complete" >}} -[DIF_REVIEW_TOCK_STABLE]: {{< relref "/doc/project/checklist.md#dif_review_tock_stable" >}}