Software APIs
rom_e2e_flash_ctrl_init_test.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
7 #include "sw/device/lib/testing/test_framework/check.h"
9 #include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
10 #include "sw/device/silicon_creator/lib/drivers/otp.h"
11 #include "sw/device/silicon_creator/lib/manifest_def.h"
12 
13 #include "flash_ctrl_regs.h"
15 #include "otp_ctrl_regs.h"
16 
17 OTTF_DEFINE_TEST_CONFIG();
18 
19 #define RUN_TEST(test_) \
20  LOG_INFO("Starting test " #test_ "..."); \
21  test_(); \
22  LOG_INFO("Finished test " #test_ ": ok.");
23 
24 enum {
25  /**
26  * Base address of the flash_ctrl registers.
27  */
29 };
30 
31 typedef struct flash_cfg_reg {
32  /**
33  * Full register value.
34  */
35  uint32_t reg_value;
36  /**
37  * Bitfield for scrambling enable.
38  */
40  /**
41  * Bitfield for ECC enable.
42  */
44  /**
45  * Bitfield for HE enable.
46  */
49 
50 /**
51  * Check that an info page is in the expected bank.
52  */
53 static void check_info_page_bank(const flash_ctrl_info_page_t *info_page,
54  uint32_t expected_bank) {
55 #define INFO_PAGE_BANK_CASE_(name_, bank_, page_) \
56  if (&name_ == info_page) { \
57  CHECK(bank_ == expected_bank); \
58  return; \
59  }
60 
61  FLASH_CTRL_INFO_PAGES_DEFINE(INFO_PAGE_BANK_CASE_);
62  CHECK(false);
63 
64 #undef INFO_PAGE_BANK_CASE_
65 }
66 
67 /**
68  * Check that an info page has the expected page number.
69  */
70 static void check_info_page_pagenum(const flash_ctrl_info_page_t *info_page,
71  uint32_t expected_pagenum) {
72 #define INFO_PAGE_PAGENUM_CASE_(name_, bank_, page_) \
73  if (&name_ == info_page) { \
74  CHECK(page_ == expected_pagenum); \
75  return; \
76  }
77 
78  FLASH_CTRL_INFO_PAGES_DEFINE(INFO_PAGE_PAGENUM_CASE_);
79  CHECK(false);
80 
81 #undef INFO_PAGE_PAGENUM_CASE_
82 }
83 
84 /**
85  * Check that the configurations match.
86  *
87  * Compares the scrambling, ECC, and HE enable fields for equality and ensures
88  * they are all valid multibit booleans.
89  *
90  * @param actual Actual configuration register.
91  * @param expected Expected configuration register.
92  */
93 static void check_cfg_match(flash_cfg_reg_t actual, flash_cfg_reg_t expected) {
94  // Check that the values match.
95  CHECK(bitfield_field32_read(actual.reg_value, actual.scrambling_en) ==
96  bitfield_field32_read(expected.reg_value, expected.scrambling_en));
97  CHECK(bitfield_field32_read(actual.reg_value, actual.ecc_en) ==
98  bitfield_field32_read(expected.reg_value, expected.ecc_en));
99  CHECK(bitfield_field32_read(actual.reg_value, actual.he_en) ==
100  bitfield_field32_read(expected.reg_value, expected.he_en));
101 }
102 
103 /**
104  * Check that default data partition configurations match OTP.
105  *
106  * The `CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG` OTP value should match the
107  * default scrambling, ecc, and he settings for the data partitions as
108  * described in the `DEFAULT_REGION` flash controller register.
109  */
110 static void default_cfg_test(void) {
111  // Extract expected values from OTP.
112  uint32_t otp_default_cfg_value =
113  otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG_OFFSET);
114  flash_cfg_reg_t otp_default_cfg = {
115  .reg_value = otp_default_cfg_value,
116  .scrambling_en = FLASH_CTRL_OTP_FIELD_SCRAMBLING,
117  .ecc_en = FLASH_CTRL_OTP_FIELD_ECC,
118  .he_en = FLASH_CTRL_OTP_FIELD_HE,
119  };
120 
121  // Read actual values from the flash controller.
122  uint32_t default_cfg_value =
123  abs_mmio_read32(kBase + FLASH_CTRL_DEFAULT_REGION_REG_OFFSET);
124  flash_cfg_reg_t default_cfg = {
125  .reg_value = default_cfg_value,
126  .scrambling_en = FLASH_CTRL_DEFAULT_REGION_SCRAMBLE_EN_FIELD,
127  .ecc_en = FLASH_CTRL_DEFAULT_REGION_ECC_EN_FIELD,
128  .he_en = FLASH_CTRL_DEFAULT_REGION_HE_EN_FIELD,
129  };
130 
131  // Check that the two match.
132  check_cfg_match(default_cfg, otp_default_cfg);
133 }
134 
135 /**
136  * Check that boot partition info pages match OTP.
137  *
138  * The `CREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG` OTP value should match the
139  * scrambling, ecc, and he settings in info0 for the boot partitions
140  * `kFlashCtrlInfoPageBootData0` (bank 1, page 0) and
141  * `kFlashCtrlInfoPageBootData1` (bank 1, page 1).
142  */
143 static void boot_info_cfg_test(void) {
144  // Double-check the expected bank and page number for the boot info pages.
145  // These numbers are hardcoded below to mitigate risk from errors in macros
146  // that construct the page-specific constants.
147  //
148  // Expected values:
149  // * kFlashCtrlInfoPageBootData0 -> bank 1, page 0
150  // * kFlashCtrlInfoPageBootData1 -> bank 1, page 1
151  check_info_page_bank(&kFlashCtrlInfoPageBootData0, 1);
152  check_info_page_pagenum(&kFlashCtrlInfoPageBootData0, 0);
153  check_info_page_bank(&kFlashCtrlInfoPageBootData1, 1);
154  check_info_page_pagenum(&kFlashCtrlInfoPageBootData1, 1);
155 
156  // Extract expected values from OTP.
157  uint32_t otp_boot_info_cfg_value =
158  otp_read32(OTP_CTRL_PARAM_CREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG_OFFSET);
159  flash_cfg_reg_t otp_boot_info_cfg = {
160  .reg_value = otp_boot_info_cfg_value,
161  .scrambling_en = FLASH_CTRL_OTP_FIELD_SCRAMBLING,
162  .ecc_en = FLASH_CTRL_OTP_FIELD_ECC,
163  .he_en = FLASH_CTRL_OTP_FIELD_HE,
164  };
165 
166  // Check the configuration for bank 1, page 0.
167  uint32_t page0_cfg_value =
168  abs_mmio_read32(kBase + FLASH_CTRL_BANK1_INFO0_PAGE_CFG_0_REG_OFFSET);
169  flash_cfg_reg_t page0_cfg = {
170  .reg_value = page0_cfg_value,
171  .scrambling_en = FLASH_CTRL_BANK1_INFO0_PAGE_CFG_0_SCRAMBLE_EN_0_FIELD,
172  .ecc_en = FLASH_CTRL_BANK1_INFO0_PAGE_CFG_0_ECC_EN_0_FIELD,
173  .he_en = FLASH_CTRL_BANK1_INFO0_PAGE_CFG_0_HE_EN_0_FIELD,
174  };
175  check_cfg_match(page0_cfg, otp_boot_info_cfg);
176 
177  // Check the configuration for bank 1, page 1.
178  uint32_t page1_cfg_value =
179  abs_mmio_read32(kBase + FLASH_CTRL_BANK1_INFO0_PAGE_CFG_1_REG_OFFSET);
180  flash_cfg_reg_t page1_cfg = {
181  .reg_value = page1_cfg_value,
182  .scrambling_en = FLASH_CTRL_BANK1_INFO0_PAGE_CFG_1_SCRAMBLE_EN_1_FIELD,
183  .ecc_en = FLASH_CTRL_BANK1_INFO0_PAGE_CFG_1_ECC_EN_1_FIELD,
184  .he_en = FLASH_CTRL_BANK1_INFO0_PAGE_CFG_1_HE_EN_1_FIELD,
185  };
186  check_cfg_match(page1_cfg, otp_boot_info_cfg);
187 }
188 
189 /**
190  * Verify that the flash controller is initialized.
191  */
192 static void is_initialized_test(void) {
193  // Check that the `INIT` register is nonzero, indicating that the flash
194  // controller received the signal to initialize on startup.
195  uint32_t init = abs_mmio_read32(kBase + FLASH_CTRL_INIT_REG_OFFSET);
196  CHECK(bitfield_bit32_read(init, FLASH_CTRL_INIT_VAL_BIT) == true);
197 
198  // Check that the physical status register does not say flash controller is
199  // still initializing.
200  uint32_t phy_status =
201  abs_mmio_read32(kBase + FLASH_CTRL_PHY_STATUS_REG_OFFSET);
202  CHECK(bitfield_bit32_read(phy_status, FLASH_CTRL_PHY_STATUS_INIT_WIP_BIT) ==
203  false);
204 
205  // Check that the general status register does not say flash controller is
206  // still initializing, and that the FIFOs are empty.
207  uint32_t status = abs_mmio_read32(kBase + FLASH_CTRL_STATUS_REG_OFFSET);
208  CHECK(bitfield_bit32_read(status, FLASH_CTRL_STATUS_INIT_WIP_BIT) == false);
209  CHECK(bitfield_bit32_read(status, FLASH_CTRL_STATUS_RD_EMPTY_BIT) == true);
210  CHECK(bitfield_bit32_read(status, FLASH_CTRL_STATUS_PROG_EMPTY_BIT) == true);
211 }
212 
213 bool test_main(void) {
214  RUN_TEST(default_cfg_test);
215  RUN_TEST(boot_info_cfg_test);
216  RUN_TEST(is_initialized_test);
217  return true;
218 }