[sw/silicon_creator] Update lifecyle_state_t
This change
* Reduces the number of `lifecycle_state_t` variants to 5, i.e. to the
ones that we use in mask rom,
* Adds `lifecycle_raw_state_get()` to get the unprocessed life cycle
state from hardware (mostly for debug purposes),
* Removes `lifecycle_state_name_get()`,
* Updates `mock_lifecycle.h`, and
* Updates call sites and existing tests.
Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/silicon_creator/lib/boot_data.c b/sw/device/silicon_creator/lib/boot_data.c
index d6f6b1e..15f489a 100644
--- a/sw/device/silicon_creator/lib/boot_data.c
+++ b/sw/device/silicon_creator/lib/boot_data.c
@@ -472,14 +472,7 @@
boot_data_t *boot_data) {
// TODO(#8778): Default boot data.
switch (lc_state) {
- case kLcStateTestUnlocked0:
- case kLcStateTestUnlocked1:
- case kLcStateTestUnlocked2:
- case kLcStateTestUnlocked3:
- case kLcStateTestUnlocked4:
- case kLcStateTestUnlocked5:
- case kLcStateTestUnlocked6:
- case kLcStateTestUnlocked7:
+ case kLcStateTest:
case kLcStateDev:
case kLcStateRma:
*boot_data = kBootDataDefault;
diff --git a/sw/device/silicon_creator/lib/boot_data_functest.c b/sw/device/silicon_creator/lib/boot_data_functest.c
index e209c1c..a720097 100644
--- a/sw/device/silicon_creator/lib/boot_data_functest.c
+++ b/sw/device/silicon_creator/lib/boot_data_functest.c
@@ -190,7 +190,7 @@
erase_boot_data_pages();
boot_data_t boot_data;
- RETURN_IF_ERROR(boot_data_read(kLcStateTestUnlocked0, &boot_data));
+ RETURN_IF_ERROR(boot_data_read(kLcStateTest, &boot_data));
RETURN_IF_ERROR(check_boot_data(&boot_data, 5));
return kErrorOk;
}
diff --git a/sw/device/silicon_creator/lib/drivers/keymgr_functest.c b/sw/device/silicon_creator/lib/drivers/keymgr_functest.c
index a83dcd6..3d7d541 100644
--- a/sw/device/silicon_creator/lib/drivers/keymgr_functest.c
+++ b/sw/device/silicon_creator/lib/drivers/keymgr_functest.c
@@ -272,8 +272,7 @@
rom_error_t result = kErrorOk;
// This test is expected to run in DEV, PROD or PROD_END states.
- lifecycle_state_t lc_state = lifecycle_state_get();
- LOG_INFO("lifecycle state: %s", lifecycle_state_name_get(lc_state));
+ LOG_INFO("lifecycle state: 0x%x", lifecycle_raw_state_get());
// Initialize pwrmgr
dif_pwrmgr_t pwrmgr;
diff --git a/sw/device/silicon_creator/lib/drivers/lifecycle.c b/sw/device/silicon_creator/lib/drivers/lifecycle.c
index f925b2b..34eb31d 100644
--- a/sw/device/silicon_creator/lib/drivers/lifecycle.c
+++ b/sw/device/silicon_creator/lib/drivers/lifecycle.c
@@ -8,91 +8,67 @@
#include <stdint.h>
#include "sw/device/lib/base/bitfield.h"
+#include "sw/device/lib/base/hardened.h"
#include "sw/device/lib/base/macros.h"
#include "sw/device/silicon_creator/lib/base/sec_mmio.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
#include "lc_ctrl_regs.h"
-static const char *const kStateNames[] = {
- // clang-format off
- "RAW",
- "TEST_UNLOCKED0",
- "TEST_LOCKED0",
- "TEST_UNLOCKED1",
- "TEST_LOCKED1",
- "TEST_UNLOCKED2",
- "TEST_LOCKED2",
- "TEST_UNLOCKED3",
- "TEST_LOCKED3",
- "TEST_UNLOCKED4",
- "TEST_LOCKED4",
- "TEST_UNLOCKED5",
- "TEST_LOCKED5",
- "TEST_UNLOCKED6",
- "TEST_LOCKED6",
- "TEST_UNLOCKED7",
- "DEV",
- "PROD",
- "PROD_END",
- "RMA",
- "SCRAP",
- "POST_TRANSITION",
- "ESCALATE",
- "INVALID",
- // clang-format on
-};
-
-static_assert(ARRAYSIZE(kStateNames) == kLcStateNumStates,
- "length of the kStateNames array doesn't match the "
- "number of states.");
-
-#define LC_ASSERT(a, b) static_assert(a == b, "Bad value for " #a)
-LC_ASSERT(kLcStateRaw, LC_CTRL_LC_STATE_STATE_VALUE_RAW);
-LC_ASSERT(kLcStateTestUnlocked0, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED0);
-LC_ASSERT(kLcStateTestLocked0, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED0);
-LC_ASSERT(kLcStateTestUnlocked1, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED1);
-LC_ASSERT(kLcStateTestLocked1, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED1);
-LC_ASSERT(kLcStateTestUnlocked2, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED2);
-LC_ASSERT(kLcStateTestLocked2, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED2);
-LC_ASSERT(kLcStateTestUnlocked3, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED3);
-LC_ASSERT(kLcStateTestLocked3, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED3);
-LC_ASSERT(kLcStateTestUnlocked4, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED4);
-LC_ASSERT(kLcStateTestLocked4, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED4);
-LC_ASSERT(kLcStateTestUnlocked5, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED5);
-LC_ASSERT(kLcStateTestLocked5, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED5);
-LC_ASSERT(kLcStateTestUnlocked6, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED6);
-LC_ASSERT(kLcStateTestLocked6, LC_CTRL_LC_STATE_STATE_VALUE_TEST_LOCKED6);
-LC_ASSERT(kLcStateTestUnlocked7, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED7);
-LC_ASSERT(kLcStateDev, LC_CTRL_LC_STATE_STATE_VALUE_DEV);
-LC_ASSERT(kLcStateProd, LC_CTRL_LC_STATE_STATE_VALUE_PROD);
-LC_ASSERT(kLcStateProdEnd, LC_CTRL_LC_STATE_STATE_VALUE_PROD_END);
-LC_ASSERT(kLcStateRma, LC_CTRL_LC_STATE_STATE_VALUE_RMA);
-LC_ASSERT(kLcStateScrap, LC_CTRL_LC_STATE_STATE_VALUE_SCRAP);
-LC_ASSERT(kLcStatePostTransition, LC_CTRL_LC_STATE_STATE_VALUE_POST_TRANSITION);
-LC_ASSERT(kLcStateEscalate, LC_CTRL_LC_STATE_STATE_VALUE_ESCALATE);
-LC_ASSERT(kLcStateInvalid, LC_CTRL_LC_STATE_STATE_VALUE_INVALID);
-
enum {
kBase = TOP_EARLGREY_LC_CTRL_BASE_ADDR,
};
lifecycle_state_t lifecycle_state_get(void) {
+ uint32_t raw_state = lifecycle_raw_state_get();
+
+ switch (launder32(raw_state)) {
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED0:
+ HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED0);
+ return kLcStateTest;
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED1:
+ HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED1);
+ return kLcStateTest;
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED2:
+ HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED2);
+ return kLcStateTest;
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED3:
+ HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED3);
+ return kLcStateTest;
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED4:
+ HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED4);
+ return kLcStateTest;
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED5:
+ HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED5);
+ return kLcStateTest;
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED6:
+ HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED6);
+ return kLcStateTest;
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED7:
+ HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED7);
+ return kLcStateTest;
+ case LC_CTRL_LC_STATE_STATE_VALUE_DEV:
+ HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_DEV);
+ return kLcStateDev;
+ case LC_CTRL_LC_STATE_STATE_VALUE_PROD:
+ HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_PROD);
+ return kLcStateProd;
+ case LC_CTRL_LC_STATE_STATE_VALUE_PROD_END:
+ HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_PROD_END);
+ return kLcStateProdEnd;
+ case LC_CTRL_LC_STATE_STATE_VALUE_RMA:
+ HARDENED_CHECK_EQ(raw_state, LC_CTRL_LC_STATE_STATE_VALUE_RMA);
+ return kLcStateRma;
+ default:
+ HARDENED_UNREACHABLE();
+ }
+}
+
+uint32_t lifecycle_raw_state_get(void) {
uint32_t value = bitfield_field32_read(
sec_mmio_read32(kBase + LC_CTRL_LC_STATE_REG_OFFSET),
LC_CTRL_LC_STATE_STATE_FIELD);
- return (lifecycle_state_t)value;
-}
-
-const char *lifecycle_state_name_get(lifecycle_state_t lc_state) {
- // Life cycle state value (`lc_state`) is a 32-bit value that repeats the
- // 5-bit life cycle state index 6 times.
- enum { kStateIndexMask = 0x1f };
- size_t state_index = (uint32_t)lc_state & kStateIndexMask;
- if (state_index >= kLcStateNumStates) {
- state_index = kLcStateInvalid & kStateIndexMask;
- }
- return kStateNames[state_index];
+ return value;
}
void lifecycle_device_id_get(lifecycle_device_id_t *device_id) {
diff --git a/sw/device/silicon_creator/lib/drivers/lifecycle.h b/sw/device/silicon_creator/lib/drivers/lifecycle.h
index adaf609..664ca21 100644
--- a/sw/device/silicon_creator/lib/drivers/lifecycle.h
+++ b/sw/device/silicon_creator/lib/drivers/lifecycle.h
@@ -12,111 +12,81 @@
#endif
/**
- * Lifecycle States.
+ * Lifecycle states.
+ *
+ * This is a condensed version of the 24 possible life cycle states where
+ * TEST_UNLOCKED_* states are mapped to `kLcStateTest` and invalid states where
+ * CPU execution is disabled are omitted.
+ *
+ * Encoding generated with
+ * $ ./util/design/sparse-fsm-encode.py -d 6 -m 5 -n 32 \
+ * -s 2447090565 --language=c
+ *
+ * Hamming distance histogram:
+ *
+ * 0: --
+ * 1: --
+ * 2: --
+ * 3: --
+ * 4: --
+ * 5: --
+ * 6: --
+ * 7: --
+ * 8: --
+ * 9: --
+ * 10: --
+ * 11: --
+ * 12: --
+ * 13: ||||| (10.00%)
+ * 14: ||||| (10.00%)
+ * 15: --
+ * 16: |||||||||| (20.00%)
+ * 17: |||||||||||||||||||| (40.00%)
+ * 18: ||||| (10.00%)
+ * 19: ||||| (10.00%)
+ * 20: --
+ * 21: --
+ * 22: --
+ * 23: --
+ * 24: --
+ * 25: --
+ * 26: --
+ * 27: --
+ * 28: --
+ * 29: --
+ * 30: --
+ * 31: --
+ * 32: --
+ *
+ * Minimum Hamming distance: 13
+ * Maximum Hamming distance: 19
+ * Minimum Hamming weight: 15
+ * Maximum Hamming weight: 20
*/
-typedef enum LcState {
- /**
- * Raw life cycle state after fabrication where all functions are disabled.
- */
- kLcStateRaw = 0x0,
+typedef enum lifecycle_state {
/**
* Unlocked test state where debug functions are enabled.
+ *
+ * Corresponds to TEST_UNLOCKED_* life cycle states.
*/
- kLcStateTestUnlocked0 = 1 * 0x2108421,
- /**
- * Locked test state where where all functions are disabled.
- */
- kLcStateTestLocked0 = 2 * 0x2108421,
- /**
- * Unlocked test state where debug functions are enabled.
- */
- kLcStateTestUnlocked1 = 3 * 0x2108421,
- /**
- * Locked test state where where all functions are disabled.
- */
- kLcStateTestLocked1 = 4 * 0x2108421,
- /**
- * Unlocked test state where debug functions are enabled.
- */
- kLcStateTestUnlocked2 = 5 * 0x2108421,
- /**
- * Locked test state where debug all functions are disabled.
- */
- kLcStateTestLocked2 = 6 * 0x2108421,
- /**
- * Unlocked test state where debug functions are enabled.
- */
- kLcStateTestUnlocked3 = 7 * 0x2108421,
- /**
- * Locked test state where debug all functions are disabled.
- */
- kLcStateTestLocked3 = 8 * 0x2108421,
- /**
- * Unlocked test state where debug functions are enabled.
- */
- kLcStateTestUnlocked4 = 9 * 0x2108421,
- /**
- * Locked test state where debug all functions are disabled.
- */
- kLcStateTestLocked4 = 10 * 0x2108421,
- /**
- * Unlocked test state where debug functions are enabled.
- */
- kLcStateTestUnlocked5 = 11 * 0x2108421,
- /**
- * Locked test state where debug all functions are disabled.
- */
- kLcStateTestLocked5 = 12 * 0x2108421,
- /**
- * Unlocked test state where debug functions are enabled.
- */
- kLcStateTestUnlocked6 = 13 * 0x2108421,
- /**
- * Locked test state where debug all functions are disabled.
- */
- kLcStateTestLocked6 = 14 * 0x2108421,
- /**
- * Unlocked test state where debug functions are enabled.
- */
- kLcStateTestUnlocked7 = 15 * 0x2108421,
+ kLcStateTest = 0xb2865fbb,
/**
* Development life cycle state where limited debug functionality is
* available.
*/
- kLcStateDev = 16 * 0x2108421,
+ kLcStateDev = 0x0b5a75e0,
/**
* Production life cycle state.
*/
- kLcStateProd = 17 * 0x2108421,
+ kLcStateProd = 0x65f2520f,
/**
* Same as PROD, but transition into RMA is not possible from this state.
*/
- kLcStateProdEnd = 18 * 0x2108421,
+ kLcStateProdEnd = 0x91b9b68a,
/**
* RMA life cycle state.
*/
- kLcStateRma = 19 * 0x2108421,
- /**
- * SCRAP life cycle state where all functions are disabled.
- */
- kLcStateScrap = 20 * 0x2108421,
- /**
- * This state is temporary and behaves the same way as SCRAP.
- */
- kLcStatePostTransition = 21 * 0x2108421,
- /**
- * This state is temporary and behaves the same way as SCRAP.
- */
- kLcStateEscalate = 22 * 0x2108421,
- /**
- * This state is reported when the life cycle state encoding is invalid.
- * This state is temporary and behaves the same way as SCRAP.
- */
- kLcStateInvalid = 23 * 0x2108421,
- /**
- * This is not a state - it is the total number of states.
- */
- kLcStateNumStates = 24,
+ kLcStateRma = 0xcf8cfaab,
} lifecycle_state_t;
enum {
@@ -136,17 +106,21 @@
/**
* Get the life cycle state.
*
+ * This function checks the value read from the hardware and returns a
+ * `life_cycle_state_t`. See `life_cyle_state_t` for more details.
+ *
* @return Life cycle state.
*/
lifecycle_state_t lifecycle_state_get(void);
/**
- * Get the human-readable name for a life cycle state.
+ * Get the unprocessed life cycle state value read from the hardware.
*
- * @param lc_state Life cycle state.
- * @return Name of the given state.
+ * This function directly returns the `uint32_t` value read from the hardware.
+ *
+ * @return Life cycle state.
*/
-const char *lifecycle_state_name_get(lifecycle_state_t lc_state);
+uint32_t lifecycle_raw_state_get(void);
/**
* Get the device identifier.
diff --git a/sw/device/silicon_creator/lib/drivers/mock_lifecycle.h b/sw/device/silicon_creator/lib/drivers/mock_lifecycle.h
index fca4782..b1ced9a 100644
--- a/sw/device/silicon_creator/lib/drivers/mock_lifecycle.h
+++ b/sw/device/silicon_creator/lib/drivers/mock_lifecycle.h
@@ -17,6 +17,7 @@
class MockLifecycle : public GlobalMock<MockLifecycle> {
public:
MOCK_METHOD(lifecycle_state_t, State, ());
+ MOCK_METHOD(uint32_t, RawState, ());
MOCK_METHOD(void, DeviceId, (lifecycle_device_id_t * device_id));
};
@@ -30,6 +31,10 @@
return MockLifecycle::Instance().State();
}
+uint32_t lifecycle_raw_state_get(void) {
+ return MockLifecycle::Instance().RawState();
+}
+
void lifecycle_device_id_get(lifecycle_device_id_t *device_id) {
MockLifecycle::Instance().DeviceId(device_id);
}
diff --git a/sw/device/silicon_creator/lib/shutdown.c b/sw/device/silicon_creator/lib/shutdown.c
index 5c9274e..fa24236 100644
--- a/sw/device/silicon_creator/lib/shutdown.c
+++ b/sw/device/silicon_creator/lib/shutdown.c
@@ -71,14 +71,7 @@
// Are we in a lifecycle state which needs alert configuration?
uint32_t lc_shift;
switch (lc_state) {
- case kLcStateTestUnlocked0:
- case kLcStateTestUnlocked1:
- case kLcStateTestUnlocked2:
- case kLcStateTestUnlocked3:
- case kLcStateTestUnlocked4:
- case kLcStateTestUnlocked5:
- case kLcStateTestUnlocked6:
- case kLcStateTestUnlocked7:
+ case kLcStateTest:
// Don't configure alerts during manufacturing as OTP may not have been
// programmed yet.
return kErrorOk;
@@ -226,25 +219,25 @@
//
// 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 kLcStateTestUnlocked0:
- case kLcStateTestUnlocked1:
- case kLcStateTestUnlocked2:
- case kLcStateTestUnlocked3:
- case kLcStateTestUnlocked4:
- case kLcStateTestUnlocked5:
- case kLcStateTestUnlocked6:
- case kLcStateTestUnlocked7:
- case kLcStateRma:
+ uint32_t raw_state =
+ 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 (raw_state) {
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED0:
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED1:
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED2:
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED3:
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED4:
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED5:
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED6:
+ case LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED7:
+ case LC_CTRL_LC_STATE_STATE_VALUE_RMA:
// No error redaction in TEST_UNLOCKED and RMA states.
return kShutdownErrorRedactNone;
- case kLcStateProd:
- case kLcStateProdEnd:
- case kLcStateDev:
+ case LC_CTRL_LC_STATE_STATE_VALUE_DEV:
+ case LC_CTRL_LC_STATE_STATE_VALUE_PROD:
+ case LC_CTRL_LC_STATE_STATE_VALUE_PROD_END:
// 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 +
diff --git a/sw/device/silicon_creator/lib/shutdown_unittest.cc b/sw/device/silicon_creator/lib/shutdown_unittest.cc
index 7068993..288ffb0 100644
--- a/sw/device/silicon_creator/lib/shutdown_unittest.cc
+++ b/sw/device/silicon_creator/lib/shutdown_unittest.cc
@@ -505,10 +505,17 @@
TEST_F(ShutdownTest, RedactPolicyManufacturing) {
// Devices in manufacturing or RMA states should not redact errors regardless
// of the redaction level set by OTP.
- constexpr std::array<lifecycle_state_t, 9> kManufacturingStates = {
- kLcStateTestUnlocked0, kLcStateTestUnlocked1, kLcStateTestUnlocked2,
- kLcStateTestUnlocked3, kLcStateTestUnlocked4, kLcStateTestUnlocked5,
- kLcStateTestUnlocked6, kLcStateTestUnlocked7, kLcStateRma};
+ constexpr std::array<uint32_t, 9> kManufacturingStates = {
+ LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED0,
+ LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED1,
+ LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED2,
+ LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED3,
+ LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED4,
+ LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED5,
+ LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED6,
+ LC_CTRL_LC_STATE_STATE_VALUE_TEST_UNLOCKED7,
+ LC_CTRL_LC_STATE_STATE_VALUE_RMA,
+ };
for (const auto state : kManufacturingStates) {
EXPECT_ABS_READ32(
TOP_EARLGREY_LC_CTRL_BASE_ADDR + LC_CTRL_LC_STATE_REG_OFFSET,
@@ -519,8 +526,11 @@
TEST_F(ShutdownTest, RedactPolicyProduction) {
// Production states should read redaction level from OTP.
- constexpr std::array<lifecycle_state_t, 3> kProductionStates = {
- kLcStateProd, kLcStateProdEnd, kLcStateDev};
+ constexpr std::array<uint32_t, 3> kProductionStates = {
+ LC_CTRL_LC_STATE_STATE_VALUE_DEV,
+ LC_CTRL_LC_STATE_STATE_VALUE_PROD,
+ LC_CTRL_LC_STATE_STATE_VALUE_PROD_END,
+ };
for (const auto state : kProductionStates) {
EXPECT_ABS_READ32(
TOP_EARLGREY_LC_CTRL_BASE_ADDR + LC_CTRL_LC_STATE_REG_OFFSET,
@@ -536,51 +546,25 @@
TEST_F(ShutdownTest, RedactPolicyInvalid) {
// Invalid states should result in the highest redaction level regardless of
// the redaction level set by OTP.
- constexpr std::array<lifecycle_state_t, 11> kInvalidStates = {
- kLcStateTestLocked0, kLcStateTestLocked1, kLcStateTestLocked2,
- kLcStateTestLocked3, kLcStateTestLocked4, kLcStateTestLocked5,
- kLcStateTestLocked6, kLcStateScrap, kLcStatePostTransition,
- kLcStateEscalate, kLcStateInvalid};
- for (const auto state : kInvalidStates) {
- EXPECT_ABS_READ32(
- TOP_EARLGREY_LC_CTRL_BASE_ADDR + LC_CTRL_LC_STATE_REG_OFFSET,
- static_cast<uint32_t>(state));
- EXPECT_EQ(shutdown_redact_policy(), kShutdownErrorRedactAll);
- }
+ EXPECT_ABS_READ32(
+ TOP_EARLGREY_LC_CTRL_BASE_ADDR + LC_CTRL_LC_STATE_REG_OFFSET, 0);
+ EXPECT_EQ(shutdown_redact_policy(), kShutdownErrorRedactAll);
}
TEST_F(ShutdownTest, InitializeManufacturing) {
// OTP reads and alert setup should be skipped in the TEST_UNLOCKED lifecycle
// states.
- constexpr std::array<lifecycle_state_t, 8> kManufacturingStates = {
- kLcStateTestUnlocked0, kLcStateTestUnlocked1, kLcStateTestUnlocked2,
- kLcStateTestUnlocked3, kLcStateTestUnlocked4, kLcStateTestUnlocked5,
- kLcStateTestUnlocked6, kLcStateTestUnlocked7,
- };
- for (auto state : kManufacturingStates) {
- EXPECT_EQ(shutdown_init(state), kErrorOk);
- }
+ EXPECT_EQ(shutdown_init(kLcStateTest), kErrorOk);
}
TEST_F(ShutdownTest, InitializeInvalid) {
- // Invalid states (such as the INVALID lifecycle state itself) should be
- // treated as PROD.
- constexpr std::array<lifecycle_state_t, 12> kInvalidStates = {
- kLcStateRaw, kLcStateTestLocked0,
- kLcStateTestLocked1, kLcStateTestLocked2,
- kLcStateTestLocked3, kLcStateTestLocked4,
- kLcStateTestLocked5, kLcStateTestLocked6,
- kLcStateScrap, kLcStatePostTransition,
- kLcStateEscalate, kLcStateInvalid,
- };
- for (auto state : kInvalidStates) {
- SetupOtpReads();
- ExpectFinalize(kErrorShutdownBadLcState);
+ SetupOtpReads();
+ ExpectFinalize(kErrorShutdownBadLcState);
- // Note: the unmocked implementation of `shutdown_finalize` will never
- // return and therefore `shutdown_init` will not return.
- EXPECT_EQ(shutdown_init(state), kErrorShutdownBadLcState);
- }
+ // Note: the unmocked implementation of `shutdown_finalize` will never
+ // return and therefore `shutdown_init` will not return.
+ EXPECT_EQ(shutdown_init(static_cast<lifecycle_state_t>(0)),
+ kErrorShutdownBadLcState);
}
TEST(ShutdownModule, RedactErrors) {
diff --git a/sw/device/silicon_creator/lib/sigverify.c b/sw/device/silicon_creator/lib/sigverify.c
index 9713f02..db22db0 100644
--- a/sw/device/silicon_creator/lib/sigverify.c
+++ b/sw/device/silicon_creator/lib/sigverify.c
@@ -207,14 +207,7 @@
static rom_error_t sigverify_use_sw_rsa_verify(lifecycle_state_t lc_state,
hardened_bool_t *use_sw) {
switch (lc_state) {
- case kLcStateTestUnlocked0:
- case kLcStateTestUnlocked1:
- case kLcStateTestUnlocked2:
- case kLcStateTestUnlocked3:
- case kLcStateTestUnlocked4:
- case kLcStateTestUnlocked5:
- case kLcStateTestUnlocked6:
- case kLcStateTestUnlocked7:
+ case kLcStateTest:
// Don't read from OTP during manufacturing. Use software
// implementation by default.
*use_sw = kHardenedBoolTrue;
diff --git a/sw/device/silicon_creator/lib/sigverify_unittest.cc b/sw/device/silicon_creator/lib/sigverify_unittest.cc
index 6600888..9adf452d 100644
--- a/sw/device/silicon_creator/lib/sigverify_unittest.cc
+++ b/sw/device/silicon_creator/lib/sigverify_unittest.cc
@@ -95,12 +95,6 @@
* Life cycle states used in parameterized tests.
*/
-constexpr std::array<lifecycle_state_t, 8> kLcStatesTest{
- kLcStateTestUnlocked0, kLcStateTestUnlocked1, kLcStateTestUnlocked2,
- kLcStateTestUnlocked3, kLcStateTestUnlocked4, kLcStateTestUnlocked5,
- kLcStateTestUnlocked6, kLcStateTestUnlocked7,
-};
-
constexpr std::array<lifecycle_state_t, 4> kLcStatesNonTestOperational{
kLcStateDev,
kLcStateProd,
@@ -108,33 +102,6 @@
kLcStateRma,
};
-constexpr std::array<lifecycle_state_t, 12> kLcStatesNonOperational{
- kLcStateRaw, kLcStateTestLocked0,
- kLcStateTestLocked1, kLcStateTestLocked2,
- kLcStateTestLocked3, kLcStateTestLocked4,
- kLcStateTestLocked5, kLcStateTestLocked6,
- kLcStateScrap, kLcStatePostTransition,
- kLcStateEscalate, kLcStateInvalid,
-};
-
-const std::unordered_set<lifecycle_state_t> &LcStatesAll() {
- static const std::unordered_set<lifecycle_state_t> *const kLcStatesAll =
- []() {
- auto states = new std::unordered_set<lifecycle_state_t>();
- states->insert(kLcStatesTest.begin(), kLcStatesTest.end());
- states->insert(kLcStatesNonTestOperational.begin(),
- kLcStatesNonTestOperational.end());
- states->insert(kLcStatesNonOperational.begin(),
- kLcStatesNonOperational.end());
- return states;
- }();
- return *kLcStatesAll;
-}
-
-TEST(LcStateCount, IsCorrect) {
- EXPECT_EQ(kLcStateNumStates, LcStatesAll().size());
-}
-
class SigverifyInLcState
: public mask_rom_test::MaskRomTest,
public testing::WithParamInterface<lifecycle_state_t> {
@@ -223,18 +190,18 @@
class SigverifyInTestStates : public SigverifyInLcState {};
-TEST_P(SigverifyInTestStates, GoodSignatureIbex) {
+TEST_F(SigverifyInTestStates, GoodSignatureIbex) {
EXPECT_CALL(sigverify_mod_exp_ibex_, mod_exp(&key_, &kSignature, NotNull()))
.WillOnce(DoAll(SetArgPointee<2>(kEncMsg), Return(kErrorOk)));
uint32_t flash_exec = 0;
- EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam(),
+ EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, kLcStateTest,
&flash_exec),
kErrorOk);
EXPECT_EQ(flash_exec, kSigverifyFlashExec);
}
-TEST_P(SigverifyInTestStates, BadSignatureIbex) {
+TEST_F(SigverifyInTestStates, BadSignatureIbex) {
// Corrupt the words of the encoded message by flipping their bits and check
// that signature verification fails.
for (size_t i = 0; i < kSigVerifyRsaNumWords; ++i) {
@@ -245,29 +212,24 @@
.WillOnce(DoAll(SetArgPointee<2>(bad_enc_msg), Return(kErrorOk)));
uint32_t flash_exec = 0;
- EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam(),
- &flash_exec),
+ EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest,
+ kLcStateTest, &flash_exec),
kErrorSigverifyBadEncodedMessage);
EXPECT_EQ(flash_exec, std::numeric_limits<uint32_t>::max());
}
}
-INSTANTIATE_TEST_SUITE_P(TestStates, SigverifyInTestStates,
- testing::ValuesIn(kLcStatesTest));
-
class SigverifyInInvalidStates : public SigverifyInLcState {};
-TEST_P(SigverifyInInvalidStates, BadLcState) {
+TEST_F(SigverifyInInvalidStates, BadLcState) {
uint32_t flash_exec = 0;
- EXPECT_EQ(sigverify_rsa_verify(&kSignature, &key_, &kTestDigest, GetParam(),
- &flash_exec),
- kErrorSigverifyBadLcState);
+ EXPECT_EQ(
+ sigverify_rsa_verify(&kSignature, &key_, &kTestDigest,
+ static_cast<lifecycle_state_t>(0), &flash_exec),
+ kErrorSigverifyBadLcState);
EXPECT_EQ(flash_exec, std::numeric_limits<uint32_t>::max());
}
-INSTANTIATE_TEST_SUITE_P(NonOperationalStates, SigverifyInInvalidStates,
- testing::ValuesIn(kLcStatesNonOperational));
-
struct UsageConstraintsTestCase {
uint32_t selector_bits;
lifecycle_device_id_t exp_device_id;
diff --git a/sw/device/silicon_creator/mask_rom/mask_rom.c b/sw/device/silicon_creator/mask_rom/mask_rom.c
index bca705e..440a8d0 100644
--- a/sw/device/silicon_creator/mask_rom/mask_rom.c
+++ b/sw/device/silicon_creator/mask_rom/mask_rom.c
@@ -199,7 +199,7 @@
// TODO(lowrisc/opentitan#7894): What (if anything) should we print at
// startup?
log_printf("OpenTitan: \"version-tag\"\r\n");
- log_printf("lc_state: %s\r\n", lifecycle_state_name_get(lc_state));
+ log_printf("lc_state: 0x%x\r\n", (unsigned int)lifecycle_raw_state_get());
// TODO(lowrisc/opentitan#1513): Switch to EEPROM SPI device bootstrap
// protocol.
diff --git a/sw/device/silicon_creator/mask_rom/sigverify_keys.c b/sw/device/silicon_creator/mask_rom/sigverify_keys.c
index b604ee9..5df248e 100644
--- a/sw/device/silicon_creator/mask_rom/sigverify_keys.c
+++ b/sw/device/silicon_creator/mask_rom/sigverify_keys.c
@@ -185,29 +185,8 @@
static rom_error_t key_is_valid(sigverify_key_type_t key_type,
lifecycle_state_t lc_state, size_t key_index) {
switch (launder32(lc_state)) {
- case kLcStateTestUnlocked0:
- HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked0);
- return key_is_valid_in_lc_state_test(key_type);
- case kLcStateTestUnlocked1:
- HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked1);
- return key_is_valid_in_lc_state_test(key_type);
- case kLcStateTestUnlocked2:
- HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked2);
- return key_is_valid_in_lc_state_test(key_type);
- case kLcStateTestUnlocked3:
- HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked3);
- return key_is_valid_in_lc_state_test(key_type);
- case kLcStateTestUnlocked4:
- HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked4);
- return key_is_valid_in_lc_state_test(key_type);
- case kLcStateTestUnlocked5:
- HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked5);
- return key_is_valid_in_lc_state_test(key_type);
- case kLcStateTestUnlocked6:
- HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked6);
- return key_is_valid_in_lc_state_test(key_type);
- case kLcStateTestUnlocked7:
- HARDENED_CHECK_EQ(lc_state, kLcStateTestUnlocked7);
+ case kLcStateTest:
+ HARDENED_CHECK_EQ(lc_state, kLcStateTest);
return key_is_valid_in_lc_state_test(key_type);
case kLcStateProd:
HARDENED_CHECK_EQ(lc_state, kLcStateProd);
diff --git a/sw/device/silicon_creator/mask_rom/sigverify_keys_unittest.cc b/sw/device/silicon_creator/mask_rom/sigverify_keys_unittest.cc
index d5fa82c..9493b80 100644
--- a/sw/device/silicon_creator/mask_rom/sigverify_keys_unittest.cc
+++ b/sw/device/silicon_creator/mask_rom/sigverify_keys_unittest.cc
@@ -82,12 +82,6 @@
* Life cycle states used in parameterized tests.
*/
-constexpr std::array<lifecycle_state_t, 8> kLcStatesTest{
- kLcStateTestUnlocked0, kLcStateTestUnlocked1, kLcStateTestUnlocked2,
- kLcStateTestUnlocked3, kLcStateTestUnlocked4, kLcStateTestUnlocked5,
- kLcStateTestUnlocked6, kLcStateTestUnlocked7,
-};
-
constexpr std::array<lifecycle_state_t, 4> kLcStatesNonTestOperational{
kLcStateDev,
kLcStateProd,
@@ -95,33 +89,16 @@
kLcStateRma,
};
-constexpr std::array<lifecycle_state_t, 12> kLcStatesNonOperational{
- kLcStateRaw, kLcStateTestLocked0,
- kLcStateTestLocked1, kLcStateTestLocked2,
- kLcStateTestLocked3, kLcStateTestLocked4,
- kLcStateTestLocked5, kLcStateTestLocked6,
- kLcStateScrap, kLcStatePostTransition,
- kLcStateEscalate, kLcStateInvalid,
+constexpr std::array<lifecycle_state_t, 6> kLcStatesAll{
+ kLcStateTest,
+ kLcStateDev,
+ kLcStateProd,
+ kLcStateProdEnd,
+ kLcStateRma,
+ // An invalid state
+ static_cast<lifecycle_state_t>(0),
};
-const std::unordered_set<lifecycle_state_t> &LcStatesAll() {
- static const std::unordered_set<lifecycle_state_t> *const kLcStatesAll =
- []() {
- auto states = new std::unordered_set<lifecycle_state_t>();
- states->insert(kLcStatesTest.begin(), kLcStatesTest.end());
- states->insert(kLcStatesNonTestOperational.begin(),
- kLcStatesNonTestOperational.end());
- states->insert(kLcStatesNonOperational.begin(),
- kLcStatesNonOperational.end());
- return states;
- }();
- return *kLcStatesAll;
-}
-
-TEST(LcStateCount, IsCorrect) {
- EXPECT_EQ(kLcStateNumStates, LcStatesAll().size());
-}
-
class SigverifyKeys : public mask_rom_test::MaskRomTest {
protected:
/**
@@ -180,7 +157,7 @@
}
INSTANTIATE_TEST_SUITE_P(AllLcStates, BadKeyIdTypeTest,
- testing::ValuesIn(LcStatesAll()));
+ testing::ValuesIn(kLcStatesAll));
class BadKeyIdTypeDeathTest : public BadKeyIdTypeTest {};
@@ -205,7 +182,7 @@
}
INSTANTIATE_TEST_SUITE_P(AllLcStates, BadKeyIdTypeDeathTest,
- testing::ValuesIn(LcStatesAll()));
+ testing::ValuesIn(kLcStatesAll));
/**
* Base class for paramaterized tests below.
@@ -235,7 +212,7 @@
INSTANTIATE_TEST_SUITE_P(
AllKeysAndNonOperationalStates, NonOperationalStateDeathTest,
testing::Combine(testing::Range<size_t>(0, kNumMockKeys),
- testing::ValuesIn(kLcStatesNonOperational)));
+ testing::Values(static_cast<lifecycle_state_t>(0))));
class ValidBasedOnOtp : public KeyValidityTest {};
@@ -310,13 +287,13 @@
ProdKeysInTestStates, ValidInState,
testing::Combine(
testing::ValuesIn(MockKeyIndicesOfType(kSigverifyKeyTypeProd)),
- testing::ValuesIn(kLcStatesTest)));
+ testing::Values(kLcStateTest)));
INSTANTIATE_TEST_SUITE_P(
TestKeysInTestStates, ValidInState,
testing::Combine(
testing::ValuesIn(MockKeyIndicesOfType(kSigverifyKeyTypeTest)),
- testing::ValuesIn(kLcStatesTest)));
+ testing::Values(kLcStateTest)));
class InvalidInState : public KeyValidityTest {};
@@ -344,7 +321,7 @@
DevKeysAndTestStates, InvalidInState,
testing::Combine(
testing::ValuesIn(MockKeyIndicesOfType(kSigverifyKeyTypeDev)),
- testing::ValuesIn(kLcStatesTest)));
+ testing::Values(kLcStateTest)));
INSTANTIATE_TEST_SUITE_P(
DevKeysAndNonDevOperStates, InvalidInState,