[sw/silicon_creator] Harden flash_ctrl_info_page_enum_t
Signed-off-by: Alphan Ulusoy <alphan@google.com>
diff --git a/sw/device/silicon_creator/lib/drivers/BUILD b/sw/device/silicon_creator/lib/drivers/BUILD
index 6ee00e4..3bf7027 100644
--- a/sw/device/silicon_creator/lib/drivers/BUILD
+++ b/sw/device/silicon_creator/lib/drivers/BUILD
@@ -63,6 +63,7 @@
name = "flash_ctrl",
srcs = ["flash_ctrl.c"],
hdrs = ["flash_ctrl.h"],
+ target_compatible_with = [OPENTITAN_CPU],
deps = [
"//hw/ip/flash_ctrl/data:flash_ctrl_regs",
"//hw/ip/otp_ctrl/data:otp_ctrl_regs",
@@ -77,9 +78,15 @@
cc_test(
name = "flash_ctrl_unittest",
- srcs = ["flash_ctrl_unittest.cc"],
+ srcs = [
+ "flash_ctrl.h",
+ "flash_ctrl.c",
+ "flash_ctrl_unittest.cc",
+ ],
+ defines = [
+ "OT_OFF_TARGET_TEST",
+ ],
deps = [
- ":flash_ctrl",
"//hw/ip/flash_ctrl/data:flash_ctrl_regs",
"//hw/ip/otp_ctrl/data:otp_ctrl_regs",
"//sw/device/lib/base",
diff --git a/sw/device/silicon_creator/lib/drivers/flash_ctrl.c b/sw/device/silicon_creator/lib/drivers/flash_ctrl.c
index 23ffdb2..4988025 100644
--- a/sw/device/silicon_creator/lib/drivers/flash_ctrl.c
+++ b/sw/device/silicon_creator/lib/drivers/flash_ctrl.c
@@ -208,12 +208,19 @@
* @return Base address of the given page.
*/
static uint32_t info_page_addr(flash_ctrl_info_page_t info_page) {
- const uint32_t bank_index =
- bitfield_bit32_read(info_page, FLASH_CTRL_INFO_PAGE_BIT_BANK);
- const uint32_t page_index =
- bitfield_field32_read(info_page, FLASH_CTRL_INFO_PAGE_FIELD_PAGE);
- return kMemBase + bank_index * FLASH_CTRL_PARAM_BYTES_PER_BANK +
- page_index * FLASH_CTRL_PARAM_BYTES_PER_PAGE;
+#define INFO_PAGE_ADDR_CASE_(name_, value_, bank_, page_) \
+ case (name_): \
+ SHUTDOWN_CHECK(launder32(info_page) == (name_)); \
+ return kMemBase + (bank_)*FLASH_CTRL_PARAM_BYTES_PER_BANK + \
+ (page_)*FLASH_CTRL_PARAM_BYTES_PER_PAGE;
+
+ switch (launder32(info_page)) {
+ FLASH_CTRL_INFO_PAGES_DEFINE(INFO_PAGE_ADDR_CASE_)
+ default:
+ SHUTDOWN_CHECK(false);
+ }
+
+#undef INFO_PAGE_ADDR_CASE_
}
/**
@@ -240,28 +247,25 @@
* @return Config and config write-enable register addresses of the info page.
*/
static info_cfg_regs_t info_cfg_regs(flash_ctrl_info_page_t info_page) {
- // For each bank and info page type, there are N config regwen registers
- // followed by N config registers, where N is the number pages available for
- // the info page type. These "blocks" of registers are mapped to a contiguous
- // address space by bank number starting with config regwen registers for page
- // 0-9, type 0, bank 0, followed by config registers for page 0-9, type 0,
- // bank 0, and so on.
- enum {
- kBankOffset = FLASH_CTRL_BANK1_INFO0_PAGE_CFG_SHADOWED_0_REG_OFFSET -
- FLASH_CTRL_BANK0_INFO0_PAGE_CFG_SHADOWED_0_REG_OFFSET,
- kPageOffset = sizeof(uint32_t),
- };
- const uint32_t bank_index =
- bitfield_bit32_read(info_page, FLASH_CTRL_INFO_PAGE_BIT_BANK);
- const uint32_t page_index =
- bitfield_field32_read(info_page, FLASH_CTRL_INFO_PAGE_FIELD_PAGE);
- const uint32_t pre_addr =
- kBase + bank_index * kBankOffset + page_index * kPageOffset;
- return (info_cfg_regs_t){
- .cfg_wen_addr = pre_addr + FLASH_CTRL_BANK0_INFO0_REGWEN_0_REG_OFFSET,
- .cfg_addr =
- pre_addr + FLASH_CTRL_BANK0_INFO0_PAGE_CFG_SHADOWED_0_REG_OFFSET,
- };
+#define INFO_CFG_REGS_CASE_(name_, value_, bank_, page_) \
+ case (name_): \
+ SHUTDOWN_CHECK(launder32(info_page) == (name_)); \
+ return (info_cfg_regs_t){ \
+ .cfg_wen_addr = \
+ kBase + \
+ FLASH_CTRL_BANK##bank_##_INFO0_REGWEN_##page_##_REG_OFFSET, \
+ .cfg_addr = \
+ kBase + \
+ FLASH_CTRL_BANK##bank_##_INFO0_PAGE_CFG_SHADOWED_##page_##_REG_OFFSET, \
+ };
+
+ switch (launder32(info_page)) {
+ FLASH_CTRL_INFO_PAGES_DEFINE(INFO_CFG_REGS_CASE_)
+ default:
+ SHUTDOWN_CHECK(false);
+ }
+
+#undef INFO_CFG_REGS_CASE_
}
/**
@@ -343,12 +347,10 @@
uint32_t offset, uint32_t word_count,
uint32_t *data) {
const uint32_t addr = info_page_addr(info_page) + offset;
- const flash_ctrl_partition_t partition =
- bitfield_field32_read(info_page, FLASH_CTRL_INFO_PAGE_FIELD_PARTITION);
transaction_start((transaction_params_t){
.addr = addr,
.op_type = FLASH_CTRL_CONTROL_OP_VALUE_READ,
- .partition = partition,
+ .partition = kFlashCtrlPartitionInfo0,
.word_count = word_count,
// Does not apply to read transactions.
.erase_type = kFlashCtrlEraseTypePage,
@@ -367,9 +369,8 @@
uint32_t offset, uint32_t word_count,
const uint32_t *data) {
const uint32_t addr = info_page_addr(info_page) + offset;
- const flash_ctrl_partition_t partition =
- bitfield_field32_read(info_page, FLASH_CTRL_INFO_PAGE_FIELD_PARTITION);
- return write(addr, partition, word_count, data, kErrorFlashCtrlInfoWrite);
+ return write(addr, kFlashCtrlPartitionInfo0, word_count, data,
+ kErrorFlashCtrlInfoWrite);
}
rom_error_t flash_ctrl_data_erase(uint32_t addr,
@@ -388,13 +389,11 @@
rom_error_t flash_ctrl_info_erase(flash_ctrl_info_page_t info_page,
flash_ctrl_erase_type_t erase_type) {
const uint32_t addr = info_page_addr(info_page);
- const flash_ctrl_partition_t partition =
- bitfield_field32_read(info_page, FLASH_CTRL_INFO_PAGE_FIELD_PARTITION);
transaction_start((transaction_params_t){
.addr = addr,
.op_type = FLASH_CTRL_CONTROL_OP_VALUE_ERASE,
.erase_type = erase_type,
- .partition = partition,
+ .partition = kFlashCtrlPartitionInfo0,
// Does not apply to erase transactions.
.word_count = 1,
});
diff --git a/sw/device/silicon_creator/lib/drivers/flash_ctrl.h b/sw/device/silicon_creator/lib/drivers/flash_ctrl.h
index f6e3f33..1330883 100644
--- a/sw/device/silicon_creator/lib/drivers/flash_ctrl.h
+++ b/sw/device/silicon_creator/lib/drivers/flash_ctrl.h
@@ -57,60 +57,97 @@
((bitfield_field32_t){.mask = 0x3, .index = 1})
/**
- * Helper macro for defining the value of a `flash_ctrl_info_page_t` enumeration
- * constant for information pages of type 0.
+ * Table of flash information pages.
*
- * Each `flash_ctrl_info_page_t` enumeration constant is a bitfield with the
- * following layout:
- * - Bits 0-3: Page index ([0,9] for type 0, 0 for type 1, [0,1] for type 2).
- * - Bits 4-6: Partition type (a `flash_ctrl_partition_type_t`).
- * - Bit 7: Bank index [0,1].
+ * Columns: Name, value, bank index, page index.
+ * We use an X macro to faciliate writing enums, swtich statements, and unit
+ * tests using the contants here. All information pages in this table are of
+ * type 0 since silicon creator code does not need to access information pages
+ * of other types.
*
- * This macro assumes that all information pages are of type 0 since silicon
- * creator code does not need to access information pages of other types.
+ * Encoding generated with
+ * $ ./util/design/sparse-fsm-encode.py -d 6 -m 20 -n 32 \
+ * -s 1755363476 --language=c
*
- * @param bank_ Bank index.
- * @param page_ Page index.
+ * Hamming distance histogram:
+ *
+ * 0: --
+ * 1: --
+ * 2: --
+ * 3: --
+ * 4: --
+ * 5: --
+ * 6: --
+ * 7: --
+ * 8: --
+ * 9: (0.53%)
+ * 10: || (2.63%)
+ * 11: || (2.11%)
+ * 12: |||||| (6.84%)
+ * 13: |||||| (6.84%)
+ * 14: ||||||||||| (12.11%)
+ * 15: ||||||||||| (11.58%)
+ * 16: |||||||||||||||||||| (20.53%)
+ * 17: ||||||||| (10.00%)
+ * 18: |||||||||| (10.53%)
+ * 19: ||||||| (7.37%)
+ * 20: |||||| (6.84%)
+ * 21: | (1.05%)
+ * 22: | (1.05%)
+ * 23: --
+ * 24: --
+ * 25: --
+ * 26: --
+ * 27: --
+ * 28: --
+ * 29: --
+ * 30: --
+ * 31: --
+ * 32: --
+ *
+ * Minimum Hamming distance: 9
+ * Maximum Hamming distance: 22
+ * Minimum Hamming weight: 13
+ * Maximum Hamming weight: 25
*/
-#define INFO_PAGE_(bank_, page_) \
- ((bank_ << 7) | (kFlashCtrlPartitionInfo0 << 4) | (page_))
-
// clang-format off
#define FLASH_CTRL_INFO_PAGES_DEFINE(X) \
/**
* Bank 0 information partition type 0 pages.
*/ \
- X(kFlashCtrlInfoPageFactoryId, 0, 0), \
- X(kFlashCtrlInfoPageCreatorSecret, 0, 1), \
- X(kFlashCtrlInfoPageOwnerSecret, 0, 2), \
- X(kFlashCtrlInfoPageWaferAuthSecret, 0, 3), \
- X(kFlashCtrlInfoPageBank0Type0Page4, 0, 4), \
- X(kFlashCtrlInfoPageBank0Type0Page5, 0, 5), \
- X(kFlashCtrlInfoPageOwnerReserved0, 0, 6), \
- X(kFlashCtrlInfoPageOwnerReserved1, 0, 7), \
- X(kFlashCtrlInfoPageOwnerReserved2, 0, 8), \
- X(kFlashCtrlInfoPageOwnerReserved3, 0, 9), \
+ X(kFlashCtrlInfoPageFactoryId, 0x9dc41c33, 0, 0) \
+ X(kFlashCtrlInfoPageCreatorSecret, 0xf56af4bb, 0, 1) \
+ X(kFlashCtrlInfoPageOwnerSecret, 0x10adc6aa, 0, 2) \
+ X(kFlashCtrlInfoPageWaferAuthSecret, 0x118b5dbb, 0, 3) \
+ X(kFlashCtrlInfoPageBank0Type0Page4, 0xad3b5bee, 0, 4) \
+ X(kFlashCtrlInfoPageBank0Type0Page5, 0xa4f6f6c3, 0, 5) \
+ X(kFlashCtrlInfoPageOwnerReserved0, 0xf646f11b, 0, 6) \
+ X(kFlashCtrlInfoPageOwnerReserved1, 0x6c86d980, 0, 7) \
+ X(kFlashCtrlInfoPageOwnerReserved2, 0xdd7f34dc, 0, 8) \
+ X(kFlashCtrlInfoPageOwnerReserved3, 0x5f07277e, 0, 9) \
/**
* Bank 1 information partition type 0 pages.
*/ \
- X(kFlashCtrlInfoPageBootData0, 1, 0), \
- X(kFlashCtrlInfoPageBootData1, 1, 1), \
- X(kFlashCtrlInfoPageOwnerSlot0, 1, 2), \
- X(kFlashCtrlInfoPageOwnerSlot1, 1, 3), \
- X(kFlashCtrlInfoPageBank1Type0Page4, 1, 4), \
- X(kFlashCtrlInfoPageBank1Type0Page5, 1, 5), \
- X(kFlashCtrlInfoPageCreatorCertificate, 1, 6), \
- X(kFlashCtrlInfoPageBootServices, 1, 7), \
- X(kFlashCtrlInfoPageOwnerCerificate0, 1, 8), \
- X(kFlashCtrlInfoPageOwnerCerificate1, 1, 9), \
+ X(kFlashCtrlInfoPageBootData0, 0xfa38c9f6, 1, 0) \
+ X(kFlashCtrlInfoPageBootData1, 0x389c449e, 1, 1) \
+ X(kFlashCtrlInfoPageOwnerSlot0, 0x238cf15c, 1, 2) \
+ X(kFlashCtrlInfoPageOwnerSlot1, 0xad886d3b, 1, 3) \
+ X(kFlashCtrlInfoPageBank1Type0Page4, 0x7dfbdf9b, 1, 4) \
+ X(kFlashCtrlInfoPageBank1Type0Page5, 0xad5dd31d, 1, 5) \
+ X(kFlashCtrlInfoPageCreatorCertificate, 0xe3ffac86, 1, 6) \
+ X(kFlashCtrlInfoPageBootServices, 0xf4f48c3d, 1, 7) \
+ X(kFlashCtrlInfoPageOwnerCerificate0, 0x9fbb840e, 1, 8) \
+ X(kFlashCtrlInfoPageOwnerCerificate1, 0xec309461, 1, 9) \
// clang-format on
/**
* Helper macro for defining a `flash_ctrl_info_page_t` enumeration constant.
- * @name_ Name of the enumeration constant.
- * @value_ Value of the enumeration constant.
+ * @param name_ Name of the enumeration constant.
+ * @param value_ Value of the enumeration constant.
+ * @param bank_ Bank of the info page.
+ * @param page_ Page of the info page.
*/
-#define INFO_PAGE_ENUM_INIT_(name_, bank_, page_) name_ = INFO_PAGE_(bank_, page_)
+#define INFO_PAGE_ENUM_INIT_(name_, value_, bank_, page_) name_ = value_,
/**
* Info pages.
@@ -120,16 +157,6 @@
} flash_ctrl_info_page_t;
/**
- * Field and bit definitions to get page index, partition type, and bank index
- * from a `flash_ctrl_info_page_t`.
- */
-#define FLASH_CTRL_INFO_PAGE_FIELD_PAGE \
- ((bitfield_field32_t){.mask = 0xf, .index = 0})
-#define FLASH_CTRL_INFO_PAGE_FIELD_PARTITION \
- ((bitfield_field32_t){.mask = 0x7, .index = 4})
-#define FLASH_CTRL_INFO_PAGE_BIT_BANK 7
-
-/**
* Bitfields for `CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG` and
* `CREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG` OTP items.
*
diff --git a/sw/device/silicon_creator/lib/drivers/flash_ctrl_unittest.cc b/sw/device/silicon_creator/lib/drivers/flash_ctrl_unittest.cc
index 3a4ed1c..c29ed28 100644
--- a/sw/device/silicon_creator/lib/drivers/flash_ctrl_unittest.cc
+++ b/sw/device/silicon_creator/lib/drivers/flash_ctrl_unittest.cc
@@ -38,16 +38,16 @@
* tests.
*/
const std::map<flash_ctrl_info_page_t, InfoPage> &InfoPages() {
-#define INFO_PAGE_MAP_INIT(name_, bank_, page_) \
- { \
- name_, \
- { \
- bank_, \
- page_, \
- FLASH_CTRL_BANK##bank_##_INFO0_PAGE_CFG_SHADOWED_##page_##_REG_OFFSET, \
- FLASH_CTRL_BANK##bank_##_INFO0_REGWEN_##page_##_REG_OFFSET, \
- }, \
- }
+#define INFO_PAGE_MAP_INIT(name_, value_, bank_, page_) \
+ { \
+ name_, \
+ { \
+ bank_, \
+ page_, \
+ FLASH_CTRL_BANK##bank_##_INFO0_PAGE_CFG_SHADOWED_##page_##_REG_OFFSET, \
+ FLASH_CTRL_BANK##bank_##_INFO0_REGWEN_##page_##_REG_OFFSET, \
+ }, \
+ },
static const std::map<flash_ctrl_info_page_t, InfoPage> *const kInfoPages =
new std::map<flash_ctrl_info_page_t, InfoPage>{
@@ -70,8 +70,6 @@
std::array<uint32_t, 2> pages_per_bank = {0, 0};
for (const auto &it : InfoPages()) {
const uint32_t bank = it.second.bank;
- EXPECT_EQ(bank, static_cast<uint32_t>(bitfield_bit32_read(
- it.first, FLASH_CTRL_INFO_PAGE_BIT_BANK)));
EXPECT_LE(bank, 1);
++pages_per_bank[bank];
}
@@ -79,21 +77,9 @@
EXPECT_THAT(pages_per_bank, Each(10));
}
-TEST_F(InfoPagesTest, AllType0) {
- for (const auto &it : InfoPages()) {
- const flash_ctrl_partition_t partition =
- static_cast<flash_ctrl_partition_t>(bitfield_field32_read(
- it.first, FLASH_CTRL_INFO_PAGE_FIELD_PARTITION));
- EXPECT_EQ(partition, kFlashCtrlPartitionInfo0);
- }
-}
-
TEST_F(InfoPagesTest, PageIndices) {
for (const auto &it : InfoPages()) {
const uint32_t page = it.second.page;
-
- EXPECT_EQ(page,
- bitfield_field32_read(it.first, FLASH_CTRL_INFO_PAGE_FIELD_PAGE));
EXPECT_LE(page, 9);
}
}
diff --git a/sw/device/silicon_creator/lib/drivers/meson.build b/sw/device/silicon_creator/lib/drivers/meson.build
index 06a1188..26bed06 100644
--- a/sw/device/silicon_creator/lib/drivers/meson.build
+++ b/sw/device/silicon_creator/lib/drivers/meson.build
@@ -520,6 +520,7 @@
sw_silicon_creator_lib_base_abs_mmio,
sw_silicon_creator_lib_base_sec_mmio,
sw_silicon_creator_lib_driver_otp,
+ sw_lib_hardened,
],
),
)
@@ -536,10 +537,11 @@
sw_vendor_gtest,
sw_silicon_creator_lib_base_mock_abs_mmio,
sw_silicon_creator_lib_base_mock_sec_mmio,
+ sw_lib_testing_hardened,
],
native: true,
- c_args: ['-DMOCK_ABS_MMIO', '-DMOCK_SEC_MMIO'],
- cpp_args: ['-DMOCK_ABS_MMIO', '-DMOCK_SEC_MMIO'],
+ c_args: ['-DMOCK_ABS_MMIO', '-DMOCK_SEC_MMIO', '-DOT_OFF_TARGET_TEST'],
+ cpp_args: ['-DMOCK_ABS_MMIO', '-DMOCK_SEC_MMIO', '-DOT_OFF_TARGET_TEST'],
),
suite: 'mask_rom',
)