[sw/silicon_creator] Constrain otp_read to aligned reads Update the signature for otp_read as a follow-up to https://github.com/lowRISC/opentitan/pull/7000/files#r652890537 Signed-off-by: Jon Flatley <jflat@google.com>
diff --git a/sw/device/silicon_creator/lib/drivers/otp.c b/sw/device/silicon_creator/lib/drivers/otp.c index 155e584..ebcac8e 100644 --- a/sw/device/silicon_creator/lib/drivers/otp.c +++ b/sw/device/silicon_creator/lib/drivers/otp.c
@@ -28,18 +28,9 @@ return value; } -rom_error_t otp_read(uint32_t address, void *data, size_t len) { - // TODO Update to use alignment utility functions. - // https://github.com/lowRISC/opentitan/issues/6112 - if (address % alignof(uint32_t) != 0 || len % sizeof(uint32_t) != 0) { - return kErrorOtpBadAlignment; - } - +void otp_read(uint32_t address, uint32_t *data, size_t num_words) { uint32_t reg_offset = OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET + address; - for (size_t i = 0; i < len; i += sizeof(uint32_t)) { - uint32_t word = sec_mmio_read32(kBase + reg_offset + i); - memcpy(data + i, &word, sizeof(uint32_t)); + for (size_t i = 0; i < num_words; ++i) { + data[i] = sec_mmio_read32(kBase + reg_offset + i * sizeof(uint32_t)); } - - return kErrorOk; }
diff --git a/sw/device/silicon_creator/lib/drivers/otp.h b/sw/device/silicon_creator/lib/drivers/otp.h index f444c5d..8b3de4a 100644 --- a/sw/device/silicon_creator/lib/drivers/otp.h +++ b/sw/device/silicon_creator/lib/drivers/otp.h
@@ -37,18 +37,14 @@ uint64_t otp_read64(uint32_t address); /** - * Perform a blocking read of `len` bytes from the memory mapped software config - * partitions. It is required that both `address` and `address` + `len` be - * word-aligned. + * Perform a blocking read of `num_words` 32-bit words from the memory mapped + * software config partitions. * * @param address The address to read from offset from the start of OTP memory. - * @param data The output buffer of at least length `len`. - * @param len The number of bytes to read from OTP. - * @return `kErrorOtpBadAlignment` if `address` or `address` + `len` are - * misaligned, `kErrorOk` otherwise. + * @param data The output buffer of at least length `num_words`. + * @param num_words The number of 32-bit words to read from OTP. */ -OTP_WARN_UNUSED_RESULT -rom_error_t otp_read(uint32_t address, void *data, size_t len); +void otp_read(uint32_t address, uint32_t *data, size_t num_words); #ifdef __cplusplus }
diff --git a/sw/device/silicon_creator/lib/drivers/otp_unittest.cc b/sw/device/silicon_creator/lib/drivers/otp_unittest.cc index 3f707b6..6611425 100644 --- a/sw/device/silicon_creator/lib/drivers/otp_unittest.cc +++ b/sw/device/silicon_creator/lib/drivers/otp_unittest.cc
@@ -4,6 +4,8 @@ #include "sw/device/silicon_creator/lib/drivers/otp.h" +#include <array> + #include "gtest/gtest.h" #include "sw/device/lib/base/mmio.h" #include "sw/device/lib/testing/mask_rom_test.h" @@ -15,6 +17,7 @@ namespace otp_unittest { namespace { +using ::testing::ElementsAre; using ::testing::ElementsAreArray; class OtpTest : public mask_rom_test::MaskRomTest { @@ -45,7 +48,7 @@ EXPECT_SEC_READ32(mmio_, base_ + offset_, 0x08090A0B); uint32_t value = 0; - EXPECT_EQ(otp_read(0, &value, sizeof(value)), kErrorOk); + otp_read(0, &value, 1); EXPECT_EQ(value, 0x08090A0B); } @@ -53,9 +56,9 @@ EXPECT_SEC_READ32(mmio_, base_ + offset_, 0x0C0D0E0F); EXPECT_SEC_READ32(mmio_, base_ + offset_ + 4, 0x08090A0B); - uint64_t value = 0; - EXPECT_EQ(otp_read(0, &value, sizeof(value)), kErrorOk); - EXPECT_EQ(value, 0x08090A0B0C0D0E0F); + std::array<uint32_t, 2> buf; + otp_read(0, buf.data(), 2); + EXPECT_THAT(buf, ElementsAre(0x0C0D0E0F, 0x08090A0B)); } TEST_F(OtpReadTest, ReadLenN) { @@ -63,21 +66,13 @@ EXPECT_SEC_READ32(mmio_, base_ + offset_ + val * sizeof(uint32_t), val); } - std::vector<uint32_t> arr(16); - EXPECT_EQ(otp_read(0, &arr[0], arr.size() * sizeof(uint32_t)), kErrorOk); + std::array<uint32_t, 16> arr; + otp_read(0, arr.data(), arr.size()); - std::vector<uint32_t> expected(arr.size()); + std::array<uint32_t, 16> expected; std::iota(expected.begin(), expected.end(), 0); EXPECT_THAT(arr, ElementsAreArray(expected)); } -TEST_F(OtpReadTest, ReadLenNMisaligned) { - std::vector<uint32_t> arr(16); - EXPECT_EQ(otp_read(1, &arr[0], arr.size() * sizeof(uint32_t)), - kErrorOtpBadAlignment); - EXPECT_EQ(otp_read(0, &arr[0], arr.size() * sizeof(uint32_t) - 1), - kErrorOtpBadAlignment); -} - } // namespace } // namespace otp_unittest