12 #include "sw/device/lib/testing/flash_ctrl_testutils.h"
13 #include "sw/device/lib/testing/test_framework/check.h"
18 #define CHECK_EQZ(x) CHECK((x) == 0)
19 #define CHECK_NEZ(x) CHECK((x) != 0)
22 #define FLASH_WORD_SZ flash_info.bytes_per_word
23 #define FLASH_PAGE_SZ flash_info.bytes_per_page
24 #define FLASH_UINT32_WORDS_PER_PAGE \
25 (FLASH_PAGE_SZ / FLASH_WORD_SZ) * (FLASH_WORD_SZ / sizeof(uint32_t))
26 #define FLASH_PAGES_PER_BANK flash_info.data_pages
30 static uint32_t flash_region_index;
31 static uint32_t flash_page_to_test;
37 static void test_basic_io(
void) {
42 .
bank = 1, .partition_id = 0, .page = 5};
44 .
rd_en = kMultiBitBool4True,
45 .prog_en = kMultiBitBool4True,
46 .erase_en = kMultiBitBool4True,
47 .scramble_en = kMultiBitBool4True,
48 .ecc_en = kMultiBitBool4True,
49 .high_endurance_en = kMultiBitBool4False};
57 region_properties.
rd_en = kMultiBitBool4True;
58 region_properties.
prog_en = kMultiBitBool4True;
59 region_properties.
erase_en = kMultiBitBool4True;
62 .
base = flash_page_to_test, .size = 0x1, .properties = region_properties};
65 &flash, flash_region_index, data_region));
69 uint32_t flash_test_page_addr = data_region.
base * FLASH_PAGE_SZ;
70 uint32_t bank1_info5_addr =
71 FLASH_PAGES_PER_BANK * FLASH_PAGE_SZ + FLASH_PAGE_SZ * 5;
78 CHECK_STATUS_OK(flash_ctrl_testutils_erase_page(
79 &flash, flash_test_page_addr,
80 0, kDifFlashCtrlPartitionTypeData));
82 for (
int i = 0; i < FLASH_UINT32_WORDS_PER_PAGE; ++i) {
84 ~mmio_region_read32(flash_test_page, i * (ptrdiff_t)
sizeof(uint32_t)));
88 CHECK_STATUS_OK(flash_ctrl_testutils_erase_page(
89 &flash, bank1_info5_addr,
90 0, kDifFlashCtrlPartitionTypeInfo));
93 uint32_t input_page[FLASH_UINT32_WORDS_PER_PAGE];
94 uint32_t output_page[FLASH_UINT32_WORDS_PER_PAGE];
96 "Unexpected buffer size. got: %d, want: %d",
sizeof(input_page),
99 "Unexpected buffer size. got: %d, want: %d",
sizeof(input_page),
101 memset(input_page, 0xa5, FLASH_UINT32_WORDS_PER_PAGE *
sizeof(uint32_t));
102 for (
int i = 0; i < FLASH_UINT32_WORDS_PER_PAGE; i += 2) {
103 input_page[i] ^= 0xffffffff;
108 CHECK_STATUS_OK(flash_ctrl_testutils_erase_and_write_page(
109 &flash, flash_test_page_addr, 0, input_page,
110 kDifFlashCtrlPartitionTypeData, FLASH_UINT32_WORDS_PER_PAGE));
111 CHECK_STATUS_OK(flash_ctrl_testutils_read(
112 &flash, flash_test_page_addr, 0, output_page,
113 kDifFlashCtrlPartitionTypeData, FLASH_UINT32_WORDS_PER_PAGE,
115 CHECK_ARRAYS_EQ(output_page, input_page, FLASH_UINT32_WORDS_PER_PAGE);
118 for (
int i = 0; i < FLASH_UINT32_WORDS_PER_PAGE; i++) {
120 mmio_region_read32(flash_test_page, i * (ptrdiff_t)
sizeof(uint32_t));
122 CHECK_ARRAYS_EQ(output_page, input_page, FLASH_UINT32_WORDS_PER_PAGE);
125 CHECK_STATUS_OK(flash_ctrl_testutils_erase_and_write_page(
126 &flash, bank1_info5_addr, 0, input_page,
127 kDifFlashCtrlPartitionTypeInfo, FLASH_UINT32_WORDS_PER_PAGE));
128 CHECK_STATUS_OK(flash_ctrl_testutils_read(
129 &flash, bank1_info5_addr, 0, output_page,
130 kDifFlashCtrlPartitionTypeInfo, FLASH_UINT32_WORDS_PER_PAGE,
132 CHECK_ARRAYS_EQ(output_page, input_page, FLASH_UINT32_WORDS_PER_PAGE);
138 CHECK_STATUS_OK(flash_ctrl_testutils_default_region_access(
139 &flash,
true,
true,
true,
142 CHECK_STATUS_OK(flash_ctrl_testutils_default_region_access(
143 &flash,
true,
true,
true,
144 false,
false,
false));
148 uint32_t flash_bank_0_last_page_addr =
149 (FLASH_PAGES_PER_BANK - 1) * FLASH_PAGE_SZ;
152 (uintptr_t)flash_bank_0_last_page_addr);
153 CHECK_STATUS_OK(flash_ctrl_testutils_erase_page(
154 &flash, flash_bank_0_last_page_addr,
155 0, kDifFlashCtrlPartitionTypeData));
156 for (
int i = 0; i < FLASH_UINT32_WORDS_PER_PAGE; ++i) {
157 CHECK_EQZ(~mmio_region_read32(flash_bank_0_last_page,
158 i * (ptrdiff_t)
sizeof(uint32_t)));
161 CHECK_STATUS_OK(flash_ctrl_testutils_write(
162 &flash, flash_bank_0_last_page_addr, 0, input_page,
163 kDifFlashCtrlPartitionTypeData, FLASH_UINT32_WORDS_PER_PAGE));
164 CHECK_STATUS_OK(flash_ctrl_testutils_read(
165 &flash, flash_bank_0_last_page_addr,
166 0, output_page, kDifFlashCtrlPartitionTypeData,
167 FLASH_UINT32_WORDS_PER_PAGE, 0));
169 CHECK_ARRAYS_EQ(output_page, input_page, FLASH_UINT32_WORDS_PER_PAGE);
172 static void test_memory_protection(
void) {
182 CHECK_STATUS_OK(flash_ctrl_testutils_default_region_access(
183 &flash,
true,
true,
true,
186 CHECK_STATUS_OK(flash_ctrl_testutils_default_region_access(
187 &flash,
true,
true,
true,
188 false,
false,
false));
193 .
rd_en = kMultiBitBool4True,
194 .prog_en = kMultiBitBool4True,
195 .erase_en = kMultiBitBool4True,
196 .scramble_en = kMultiBitBool4False,
197 .ecc_en = kMultiBitBool4True,
198 .high_endurance_en = kMultiBitBool4False};
201 .
base = flash_page_to_test,
203 .properties = protected_properties};
206 (protected_region.
base * FLASH_PAGE_SZ);
207 uintptr_t ok_region_end =
208 ok_region_start + (protected_region.
size * FLASH_PAGE_SZ);
211 uintptr_t bad_region_start = ok_region_end;
214 CHECK_STATUS_OK(flash_ctrl_testutils_erase_page(
215 &flash, ok_region_start,
216 0, kDifFlashCtrlPartitionTypeData));
217 CHECK_STATUS_OK(flash_ctrl_testutils_erase_page(
218 &flash, bad_region_start,
219 0, kDifFlashCtrlPartitionTypeData));
223 CHECK_STATUS_OK(flash_ctrl_testutils_default_region_access(
224 &flash,
false,
false,
false,
227 CHECK_STATUS_OK(flash_ctrl_testutils_default_region_access(
228 &flash,
false,
false,
false,
229 false,
false,
false));
234 &flash, flash_region_index, protected_region));
237 uintptr_t region_boundary_start = bad_region_start - (FLASH_WORD_SZ * 2);
241 uint32_t words[(FLASH_WORD_SZ * 2 * 2) /
sizeof(uint32_t)];
243 for (uint32_t i = 0; i <
ARRAYSIZE(words); ++i) {
248 CHECK(status_err(flash_ctrl_testutils_write(
249 &flash, region_boundary_start, 0, words,
250 kDifFlashCtrlPartitionTypeData,
ARRAYSIZE(words))));
253 for (
int i = 0; i <
ARRAYSIZE(words); ++i) {
254 uint32_t expected = 0xffffffff;
258 CHECK(mmio_region_read32(region_boundary,
259 i * (ptrdiff_t)
sizeof(uint32_t)) == expected);
263 CHECK(status_err(flash_ctrl_testutils_erase_page(
264 &flash, bad_region_start,
265 0, kDifFlashCtrlPartitionTypeData)));
268 CHECK_STATUS_OK(flash_ctrl_testutils_erase_page(
269 &flash, ok_region_start,
270 0, kDifFlashCtrlPartitionTypeData));
271 for (
int i = 0; i < FLASH_UINT32_WORDS_PER_PAGE; i++) {
272 CHECK_EQZ(~mmio_region_read32(ok_region, i * (ptrdiff_t)
sizeof(uint32_t)));
276 OTTF_DEFINE_TEST_CONFIG();
284 flash_region_index = 2;
285 flash_page_to_test = FLASH_PAGES_PER_BANK + 0x20;
287 flash_region_index = 0;
288 flash_page_to_test = FLASH_PAGES_PER_BANK;
293 CHECK_STATUS_OK(flash_ctrl_testutils_wait_for_init(&flash));
302 test_memory_protection();