From e30d7a453531dea36ada784f0d2fa01841251ed7 Mon Sep 17 00:00:00 2001 From: Michael Schaffner Date: Fri, 19 Jan 2024 17:40:56 -0800 Subject: [PATCH] [sram_ctrl/dif] Implement DIF for SCR_KEY_ROTATED CSR Signed-off-by: Michael Schaffner --- sw/device/lib/dif/dif_sram_ctrl.c | 21 +++++++++++ sw/device/lib/dif/dif_sram_ctrl.h | 22 ++++++++++++ sw/device/lib/dif/dif_sram_ctrl_unittest.cc | 39 +++++++++++++++++++++ 3 files changed, 82 insertions(+) diff --git a/sw/device/lib/dif/dif_sram_ctrl.c b/sw/device/lib/dif/dif_sram_ctrl.c index 87b7a9e5ad2a23..d71da1a69eac65 100644 --- a/sw/device/lib/dif/dif_sram_ctrl.c +++ b/sw/device/lib/dif/dif_sram_ctrl.c @@ -214,3 +214,24 @@ dif_result_t dif_sram_ctrl_is_locked(const dif_sram_ctrl_t *sram_ctrl, return kDifOk; } + +dif_result_t dif_sram_ctrl_scr_key_rotated(const dif_sram_ctrl_t *sram_ctrl, + multi_bit_bool_t *success, + multi_bit_bool_t clear) { + if (sram_ctrl == NULL || success == NULL) { + return kDifBadArg; + } + + *success = mmio_region_read32(sram_ctrl->base_addr, + SRAM_CTRL_SCR_KEY_ROTATED_REG_OFFSET); + // We do not use any control flow statements to determine whether to clear the + // reg or not. Rather, the register is always written and the MuBi logic + // determines whether the register is cleared or not. I.e., the register is + // specified as W1C in which case a clear opeartion only takes place if clear + // is set to kMultiBitBool4True. If it is set to kMultiBitBool4False, the + // current state will persist. + mmio_region_write32(sram_ctrl->base_addr, + SRAM_CTRL_SCR_KEY_ROTATED_REG_OFFSET, clear); + + return kDifOk; +} diff --git a/sw/device/lib/dif/dif_sram_ctrl.h b/sw/device/lib/dif/dif_sram_ctrl.h index 9bfdb9f3b3112e..cdf974c9616295 100644 --- a/sw/device/lib/dif/dif_sram_ctrl.h +++ b/sw/device/lib/dif/dif_sram_ctrl.h @@ -13,6 +13,8 @@ #include +#include "sw/device/lib/base/multibits.h" + #include "sw/device/lib/dif/autogen/dif_sram_ctrl_autogen.h" #ifdef __cplusplus @@ -230,6 +232,26 @@ dif_result_t dif_sram_ctrl_is_locked(const dif_sram_ctrl_t *sram_ctrl, dif_sram_ctrl_lock_t lock, bool *is_locked); +/** + * Checks whether requested SRAM Controller successfully obtained a new key. + * + * success is set to kMultiBitBool4True if a key rotation was successful. + * + * The clear parameter can be set to kMultiBitBool4True in order to clear + * the key rotation state back to kMultiBitBool4False after reading it. + * If the state should not be cleared, set clear to kMultiBitBool4False. + * + * @param sram_ctrl A SRAM Controller handle. + * @param[out] success Outparam for the success state. + * @param clear Parameter indicating whether to CSR should be cleared after + * reading. + * @return The result of the operation. + */ +OT_WARN_UNUSED_RESULT +dif_result_t dif_sram_ctrl_scr_key_rotated(const dif_sram_ctrl_t *sram_ctrl, + multi_bit_bool_t *success, + multi_bit_bool_t clear); + #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/sw/device/lib/dif/dif_sram_ctrl_unittest.cc b/sw/device/lib/dif/dif_sram_ctrl_unittest.cc index b4b19b87e0bdaa..b7fe0eac3563ab 100644 --- a/sw/device/lib/dif/dif_sram_ctrl_unittest.cc +++ b/sw/device/lib/dif/dif_sram_ctrl_unittest.cc @@ -296,5 +296,44 @@ TEST_F(IsLockedTest, Exec) { EXPECT_EQ(is_locked, true); } +class RotatedTest : public SramCtrlTest {}; + +TEST_F(RotatedTest, NullArgs) { + multi_bit_bool_t success; + EXPECT_DIF_BADARG( + dif_sram_ctrl_scr_key_rotated(nullptr, &success, kMultiBitBool4False)); + EXPECT_DIF_BADARG( + dif_sram_ctrl_scr_key_rotated(nullptr, nullptr, kMultiBitBool4False)); + EXPECT_DIF_BADARG( + dif_sram_ctrl_scr_key_rotated(&sram_ctrl_, nullptr, kMultiBitBool4False)); +} + +TEST_F(IsLockedTest, Rotated0) { + multi_bit_bool_t success = kMultiBitBool4True; + EXPECT_READ32(SRAM_CTRL_SCR_KEY_ROTATED_REG_OFFSET, kMultiBitBool4False); + EXPECT_WRITE32(SRAM_CTRL_SCR_KEY_ROTATED_REG_OFFSET, kMultiBitBool4False); + EXPECT_DIF_OK(dif_sram_ctrl_scr_key_rotated(&sram_ctrl_, &success, + kMultiBitBool4False)); + EXPECT_EQ(success, kMultiBitBool4False); +} + +TEST_F(IsLockedTest, Rotated1) { + multi_bit_bool_t success = kMultiBitBool4False; + EXPECT_READ32(SRAM_CTRL_SCR_KEY_ROTATED_REG_OFFSET, kMultiBitBool4True); + EXPECT_WRITE32(SRAM_CTRL_SCR_KEY_ROTATED_REG_OFFSET, kMultiBitBool4True); + EXPECT_DIF_OK( + dif_sram_ctrl_scr_key_rotated(&sram_ctrl_, &success, kMultiBitBool4True)); + EXPECT_EQ(success, kMultiBitBool4True); +} + +TEST_F(IsLockedTest, Rotated2) { + multi_bit_bool_t success = kMultiBitBool4False; + EXPECT_READ32(SRAM_CTRL_SCR_KEY_ROTATED_REG_OFFSET, kMultiBitBool4True); + EXPECT_WRITE32(SRAM_CTRL_SCR_KEY_ROTATED_REG_OFFSET, kMultiBitBool4False); + EXPECT_DIF_OK(dif_sram_ctrl_scr_key_rotated(&sram_ctrl_, &success, + kMultiBitBool4False)); + EXPECT_EQ(success, kMultiBitBool4True); +} + } // namespace } // namespace dif_sram_ctrl_autogen_unittest