[sw/silicon_creator] Use OTP library in shutdown module
1. Follow the redaction policy in #7353 (no redaction in RMA and
test unlocked lifecycle states).
2. Use the OTP library to read from OTP.
The OTP and lifecycle libraries use sec_mmio underneath the hood.
Since sec_mmio can trigger a call to shutdown_finalize we need to
avoid calling it from shutdown_finalize. To acheive this a new
shutdown_redact_policy function has been added that determines
the redaction policy to apply without using either library.
This change required an increase in the number of registers that
`sec_mmio_ctx` has capacity to track. I've bumped it up to 200 for
now.
Signed-off-by: Michael Munday <mike.munday@lowrisc.org>
diff --git a/sw/device/silicon_creator/lib/shutdown.c b/sw/device/silicon_creator/lib/shutdown.c
index 170aec2..d4546bb 100644
--- a/sw/device/silicon_creator/lib/shutdown.c
+++ b/sw/device/silicon_creator/lib/shutdown.c
@@ -14,11 +14,13 @@
#include "sw/device/silicon_creator/lib/base/abs_mmio.h"
#include "sw/device/silicon_creator/lib/drivers/alert.h"
#include "sw/device/silicon_creator/lib/drivers/lifecycle.h"
+#include "sw/device/silicon_creator/lib/drivers/otp.h"
#include "alert_handler_regs.h"
#include "flash_ctrl_regs.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
#include "keymgr_regs.h"
+#include "lc_ctrl_regs.h"
#include "otp_ctrl_regs.h"
#include "sram_ctrl_regs.h"
@@ -46,16 +48,6 @@
static ALWAYS_INLINE modifiers_ void name_
#endif
-// TODO: use the real OTP driver after it's converted to abs_mmio.
-#ifdef OT_OFF_TARGET_TEST
-extern uint32_t otp_read32(uint32_t address);
-#else
-inline uint32_t otp_read32(uint32_t address) {
- return abs_mmio_read32(TOP_EARLGREY_OTP_CTRL_CORE_BASE_ADDR +
- OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET + address);
-}
-#endif
-
// Convert the alert class to an index.
// This is required because I expect to change the constant definitions in
// alert_class_t to have reasonable hamming distances.
@@ -174,7 +166,13 @@
return error;
}
-uint32_t shutdown_redact(rom_error_t reason, shutdown_error_redact_t severity) {
+/**
+ * Implementation of `shutdown_redact` that is guaranteed to be inlined.
+ *
+ * This function must be inlined because it is called from `shutdown_finalize`.
+ */
+static ALWAYS_INLINE uint32_t
+shutdown_redact_inline(rom_error_t reason, shutdown_error_redact_t severity) {
uint32_t redacted = (uint32_t)reason;
if (reason == kErrorOk) {
return 0;
@@ -196,6 +194,70 @@
return redacted;
}
+uint32_t shutdown_redact(rom_error_t reason, shutdown_error_redact_t severity) {
+ return shutdown_redact_inline(reason, severity);
+}
+
+/**
+ * Implementation of `shutdown_redact_policy` that is guaranteed to be inlined.
+ *
+ * This function must be inlined because it is called from `shutdown_finalize`.
+ */
+static ALWAYS_INLINE shutdown_error_redact_t
+shutdown_redact_policy_inline(void) {
+ // Determine the error code redaction policy to apply according to the
+ // lifecycle state and OTP configuration.
+ //
+ // Note that we cannot use the lifecycle or OTP libraries since an error
+ // may trigger a call to `shutdown_finalize`.
+ lifecycle_state_t lc_state = (lifecycle_state_t)bitfield_field32_read(
+ abs_mmio_read32(TOP_EARLGREY_LC_CTRL_BASE_ADDR +
+ LC_CTRL_LC_STATE_REG_OFFSET),
+ LC_CTRL_LC_STATE_STATE_FIELD);
+ switch (lc_state) {
+ case kLcStateRaw:
+ case kLcStateTestUnlocked0:
+ case kLcStateTestUnlocked1:
+ case kLcStateTestUnlocked2:
+ case kLcStateTestUnlocked3:
+ case kLcStateTestUnlocked4:
+ case kLcStateTestUnlocked5:
+ case kLcStateTestUnlocked6:
+ case kLcStateTestUnlocked7:
+ case kLcStateRma:
+ // No error redaction in RAW, TEST_UNLOCKED and RMA states.
+ return kShutdownErrorRedactNone;
+ case kLcStateProd:
+ case kLcStateProdEnd:
+ case kLcStateDev:
+ // In production states use the redaction level specified in OTP.
+ return (shutdown_error_redact_t)abs_mmio_read32(
+ TOP_EARLGREY_OTP_CTRL_CORE_BASE_ADDR +
+ OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET +
+ OTP_CTRL_PARAM_ROM_ERROR_REPORTING_OFFSET);
+ default:
+ // Redact everything if in an unexpected lifecycle state.
+ return kShutdownErrorRedactAll;
+ }
+}
+
+shutdown_error_redact_t shutdown_redact_policy(void) {
+ return shutdown_redact_policy_inline();
+}
+
+SHUTDOWN_FUNC(NO_MODIFIERS, shutdown_report_error(rom_error_t reason)) {
+ // Call the inline variant of `shutdown_redact_policy` because we want to
+ // guarantee that we won't jump to a different function.
+ shutdown_error_redact_t policy = shutdown_redact_policy_inline();
+
+ // Call the inline variant of `shutdown_redact` because we want to guarantee
+ // that we won't jump to a different function.
+ uint32_t redacted_error = shutdown_redact_inline(reason, policy);
+
+ // TODO(lowRISC/opentitan#8236): base_printf is in the .text section.
+ base_printf("boot_fault: 0x%08x\n", redacted_error);
+}
+
SHUTDOWN_FUNC(NO_MODIFIERS, shutdown_software_escalate(void)) {
// TODO(lowRISC/opentitan#7148): Use a software alert when available.
// For now, signal a fatal_intg_error from SRAM.
@@ -265,12 +327,7 @@
__attribute__((section(".shutdown")))
#endif
void shutdown_finalize(rom_error_t reason) {
- uint32_t redacted_error = shutdown_redact(
- reason, otp_read32(OTP_CTRL_PARAM_ROM_ERROR_REPORTING_OFFSET));
-
- // TODO(lowRISC/opentitan#8236): base_printf is in the .text section.
- base_printf("boot_fault: 0x%08x\n", redacted_error);
-
+ shutdown_report_error(reason);
shutdown_software_escalate();
shutdown_keymgr_kill();
shutdown_flash_kill();