10 #include "sw/device/lib/runtime/irq.h"
12 #include "sw/device/lib/testing/flash_ctrl_testutils.h"
13 #include "sw/device/lib/testing/rv_plic_testutils.h"
14 #include "sw/device/lib/testing/test_framework/check.h"
18 #include "otp_ctrl_regs.h"
19 #include "sw/device/lib/testing/autogen/isr_testutils.h"
21 #define FLASH_CTRL_NUM_IRQS 5
29 #define FLASH_CTRL_OTP_FIELD_SCRAMBLING \
30 (bitfield_field32_t) { .mask = UINT8_MAX, .index = CHAR_BIT * 0 }
31 #define FLASH_CTRL_OTP_FIELD_ECC \
32 (bitfield_field32_t) { .mask = UINT8_MAX, .index = CHAR_BIT * 1 }
33 #define FLASH_CTRL_OTP_FIELD_HE \
34 (bitfield_field32_t) { .mask = UINT8_MAX, .index = CHAR_BIT * 2 }
36 OTTF_DEFINE_TEST_CONFIG();
38 static dif_rv_plic_t plic0;
41 static dif_flash_ctrl_t flash_ctrl;
43 static plic_isr_ctx_t plic_ctx = {
48 static flash_ctrl_isr_ctx_t flash_ctx = {
49 .flash_ctrl = &flash_ctrl,
54 static uint32_t flash_bank_0_data_region;
55 static uint32_t flash_bank_1_data_region;
56 static uint32_t flash_bank_1_data_region_scr;
57 static uint32_t flash_bank_1_page_index;
58 static uint32_t flash_bank_1_page_index_scr;
61 kFlashInfoPageIdCreatorSecret = 1,
62 kFlashInfoPageIdOwnerSecret = 2,
63 kFlashInfoPageIdIsoPart = 3,
65 kRegionBaseBank0Page0Index = 0,
73 const uint32_t kRandomData1[kInfoSize] = {
74 0xb295d21b, 0xecdfbdcd, 0x67e7ab2d, 0x6f660b08, 0x273bf65c, 0xe80f1695,
75 0x586b80db, 0xc3dba27e, 0xdc124c5d, 0xb01ccd52, 0x815713e1, 0x31a141b2,
76 0x2124be3b, 0x299a6f2a, 0x1f2a4741, 0x1a073cc0,
79 const uint32_t kRandomData2[kInfoSize] = {
80 0x69e705a0, 0x65c2ec6b, 0x04b0b634, 0x59313526, 0x1858aee1, 0xd49f3ba9,
81 0x230bcd38, 0xc1eb6b3e, 0x68c15e3b, 0x024d02a9, 0x0b062ae4, 0x334dd155,
82 0x53fdbf8a, 0x3792f1e2, 0xee317161, 0x33b19bf3,
85 const uint32_t kRandomData3[kInfoSize] = {
86 0x2b78dbf5, 0x3e6e5a00, 0xbf82c6d5, 0x68d8e33f, 0x9c524bbc, 0xac5beeef,
87 0x1287ca5a, 0x12b61419, 0x872e709f, 0xf91b7c0c, 0x18312a1f, 0x325cef9a,
88 0x19fefa95, 0x4ceb421b, 0xa57d74c4, 0xaf1d723d,
91 const uint32_t kRandomData4[kDataSize] = {
92 0x0f5b84a3, 0xfa0330c3, 0xe125d174, 0x959d9779, 0xe10da3ba, 0x739e804d,
93 0xf8f8c317, 0xf236e75f, 0xa2118c37, 0x2d12fa9d, 0xa6fd72cd, 0x4b21d3dc,
94 0x6d36ca93, 0xbac514a6, 0x5f5695f8, 0xe7fdbe07, 0xde77eac9, 0x5ee7432f,
95 0xc7d26081, 0xae1d7262, 0x47d46715, 0x9da2de97, 0xa41e639d, 0x34470ce0,
96 0x8ac69175, 0x1dbcd910, 0x8193d43e, 0xe1538689, 0x166599e1, 0x0d5cc465,
97 0x86298854, 0x93121b13,
100 const uint32_t kRandomData5[kDataSize] = {
101 0xe5214227, 0x8473a570, 0xc6fc9728, 0x6110fbbe, 0xa2b4cdc8, 0x0156836a,
102 0xa0c90954, 0x23e66c9b, 0x607c9e7c, 0x40f993b6, 0x253dfc7d, 0xe0c70727,
103 0xa7b974ea, 0x0e8561c8, 0xfe8858a9, 0x36bf06bc, 0x2a734e91, 0xf0aca1e6,
104 0x6e22f4c5, 0x469cb0a2, 0x0f6bbc43, 0xc719f5cd, 0x0a129d7d, 0x9a6c171e,
105 0x1b39ff3a, 0x9644ab82, 0x5209d14c, 0x46a7e380, 0x575b1e0b, 0x4af5e8c3,
106 0xfcbbfa64, 0xe3afddf2,
109 static volatile bool expected_irqs[FLASH_CTRL_NUM_IRQS];
110 static volatile bool fired_irqs[FLASH_CTRL_NUM_IRQS];
117 void ottf_external_isr(uint32_t *exc_info) {
119 dif_flash_ctrl_irq_t irq_serviced;
121 isr_testutils_flash_ctrl_isr(plic_ctx, flash_ctx,
true, &peripheral_serviced,
124 "Interurpt from unexpected peripheral: %d", peripheral_serviced);
125 fired_irqs[irq_serviced] =
true;
131 static void clear_irq_variables(
void) {
132 for (
int i = 0; i < FLASH_CTRL_NUM_IRQS; ++i) {
133 expected_irqs[i] =
false;
134 fired_irqs[i] =
false;
141 static void flash_ctrl_init_with_event_irqs(
mmio_region_t base_addr,
143 dif_flash_ctrl_t *flash_ctrl) {
144 CHECK_DIF_OK(dif_flash_ctrl_init(base_addr, flash_ctrl));
147 for (dif_flash_ctrl_irq_t i = 0; i < FLASH_CTRL_NUM_IRQS; ++i) {
149 CHECK_DIF_OK(dif_flash_ctrl_irq_get_type(
150 flash_ctrl, kDifFlashCtrlIrqProgEmpty + i, &type));
152 CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
156 clear_irq_variables();
162 static void compare_and_clear_irq_variables(
void) {
163 for (
int i = 0; i < FLASH_CTRL_NUM_IRQS; ++i) {
164 CHECK(expected_irqs[i] == fired_irqs[i],
"expected IRQ mismatch = %d", i);
166 clear_irq_variables();
172 static void read_and_check_host_if(uint32_t addr,
const uint32_t *check_data) {
175 uint32_t host_data[kDataSize];
176 for (
int i = 0; i < kDataSize; ++i) {
178 mmio_region_read32(flash_addr, i * (ptrdiff_t)
sizeof(uint32_t));
180 CHECK_ARRAYS_EQ(host_data, check_data, kDataSize);
188 static void do_info_partition_test(uint32_t partition_number,
189 const uint32_t *test_data) {
190 uint32_t address = 0;
191 CHECK_STATUS_OK(flash_ctrl_testutils_info_region_setup(
192 &flash_state, partition_number, kFlashInfoBank, kPartitionId, &address));
197 clear_irq_variables();
199 expected_irqs[kDifFlashCtrlIrqOpDone] =
true;
200 CHECK_STATUS_OK(flash_ctrl_testutils_erase_page(
201 &flash_state, address, kPartitionId, kDifFlashCtrlPartitionTypeInfo));
202 compare_and_clear_irq_variables();
204 expected_irqs[kDifFlashCtrlIrqOpDone] =
true;
205 expected_irqs[kDifFlashCtrlIrqProgEmpty] =
true;
206 expected_irqs[kDifFlashCtrlIrqProgLvl] =
true;
211 CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
213 CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
216 flash_ctrl_testutils_write(&flash_state, address, kPartitionId, test_data,
217 kDifFlashCtrlPartitionTypeInfo, kInfoSize));
219 compare_and_clear_irq_variables();
221 uint32_t readback_data[kInfoSize];
222 expected_irqs[kDifFlashCtrlIrqOpDone] =
true;
223 expected_irqs[kDifFlashCtrlIrqRdLvl] =
true;
224 expected_irqs[kDifFlashCtrlIrqRdFull] =
true;
228 CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
230 CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
232 CHECK_STATUS_OK(flash_ctrl_testutils_read(
233 &flash_state, address, kPartitionId, readback_data,
234 kDifFlashCtrlPartitionTypeInfo, kInfoSize, 1));
236 compare_and_clear_irq_variables();
238 CHECK_ARRAYS_EQ(readback_data, test_data, kInfoSize);
253 static void do_bank0_data_partition_test(
void) {
254 uint32_t address = 0;
255 uint32_t otp_val = abs_mmio_read32(
257 OTP_CTRL_PARAM_CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG_OFFSET);
265 .erase_en = kMultiBitBool4True,
266 .prog_en = kMultiBitBool4True,
267 .rd_en = kMultiBitBool4True};
269 CHECK_STATUS_OK(flash_ctrl_testutils_data_region_setup_properties(
270 &flash_state, kRegionBaseBank0Page0Index, flash_bank_0_data_region,
271 kRegionSize, region_properties, &address));
274 clear_irq_variables();
275 expected_irqs[kDifFlashCtrlIrqOpDone] =
true;
276 expected_irqs[kDifFlashCtrlIrqRdLvl] =
true;
277 expected_irqs[kDifFlashCtrlIrqRdFull] =
true;
281 CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
283 CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
285 uint32_t readback_data[kDataSize];
286 CHECK_STATUS_OK(flash_ctrl_testutils_read(
287 &flash_state, address, kPartitionId, readback_data,
288 kDifFlashCtrlPartitionTypeData, kDataSize, 1));
290 compare_and_clear_irq_variables();
291 read_and_check_host_if(0, readback_data);
302 static void do_bank1_data_partition_test(
void) {
303 uint32_t address = 0;
308 for (
int i = 0; i < 2; ++i) {
309 uint32_t page_index =
310 (i == 0) ? flash_bank_1_page_index : flash_bank_1_page_index_scr;
311 const uint32_t *test_data = (i == 0) ? kRandomData4 : kRandomData5;
315 CHECK_STATUS_OK(flash_ctrl_testutils_data_region_setup(
316 &flash_state, page_index, flash_bank_1_data_region, kRegionSize,
320 CHECK_STATUS_OK(flash_ctrl_testutils_data_region_scrambled_setup(
321 &flash_state, page_index, flash_bank_1_data_region_scr, kRegionSize,
324 clear_irq_variables();
326 expected_irqs[kDifFlashCtrlIrqOpDone] =
true;
327 CHECK_STATUS_OK(flash_ctrl_testutils_erase_page(
328 &flash_state, address, kPartitionId, kDifFlashCtrlPartitionTypeData));
330 compare_and_clear_irq_variables();
332 expected_irqs[kDifFlashCtrlIrqOpDone] =
true;
333 expected_irqs[kDifFlashCtrlIrqProgEmpty] =
true;
334 expected_irqs[kDifFlashCtrlIrqProgLvl] =
true;
339 CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
341 CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
343 CHECK_STATUS_OK(flash_ctrl_testutils_write(
344 &flash_state, address, kPartitionId, test_data,
345 kDifFlashCtrlPartitionTypeData, kDataSize));
347 compare_and_clear_irq_variables();
349 uint32_t readback_data[kDataSize];
350 expected_irqs[kDifFlashCtrlIrqOpDone] =
true;
351 expected_irqs[kDifFlashCtrlIrqRdLvl] =
true;
352 expected_irqs[kDifFlashCtrlIrqRdFull] =
true;
356 CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
358 CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
360 CHECK_STATUS_OK(flash_ctrl_testutils_read(
361 &flash_state, address, kPartitionId, readback_data,
362 kDifFlashCtrlPartitionTypeData, kDataSize, 1));
364 compare_and_clear_irq_variables();
366 read_and_check_host_if(kPageSize * page_index, test_data);
367 CHECK_ARRAYS_EQ(readback_data, test_data, kDataSize);
373 expected_irqs[kDifFlashCtrlIrqOpDone] =
true;
375 CHECK_STATUS_OK(flash_ctrl_testutils_data_region_setup(
376 &flash_state, flash_bank_1_page_index, flash_bank_1_data_region,
377 kRegionSize, &address));
379 .byte_address = address,
381 .partition_type = kDifFlashCtrlPartitionTypeData,
385 CHECK_STATUS_OK(flash_ctrl_testutils_wait_transaction_end(&flash_state));
387 compare_and_clear_irq_variables();
390 for (
int i = 0; i < 2; ++i) {
391 uint32_t page_index =
392 (i == 0) ? flash_bank_1_page_index : flash_bank_1_page_index_scr;
394 CHECK_STATUS_OK(flash_ctrl_testutils_data_region_setup(
395 &flash_state, page_index, flash_bank_1_data_region, kRegionSize,
398 uint32_t readback_data[kDataSize];
399 expected_irqs[kDifFlashCtrlIrqOpDone] =
true;
400 expected_irqs[kDifFlashCtrlIrqRdLvl] =
true;
401 expected_irqs[kDifFlashCtrlIrqRdFull] =
true;
405 CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
407 CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
409 CHECK_STATUS_OK(flash_ctrl_testutils_read(
410 &flash_state, address, kPartitionId, readback_data,
411 kDifFlashCtrlPartitionTypeData, kDataSize, 1));
413 compare_and_clear_irq_variables();
415 uint32_t expected_data[kDataSize];
416 memset(expected_data, 0xff,
sizeof(expected_data));
418 read_and_check_host_if(kPageSize * page_index, expected_data);
419 CHECK_ARRAYS_EQ(readback_data, expected_data, kDataSize);
430 flash_bank_0_data_region = 0;
431 flash_bank_1_page_index = flash_info.
data_pages;
435 flash_bank_0_data_region = 2;
438 flash_bank_1_page_index = flash_info.
data_pages + 0x20;
440 flash_bank_1_data_region = flash_bank_0_data_region + 1;
441 flash_bank_1_data_region_scr = flash_bank_0_data_region + 2;
442 flash_bank_1_page_index_scr = flash_info.
data_pages * 2 - 1;
444 CHECK_DIF_OK(dif_rv_plic_init(
447 flash_ctrl_init_with_event_irqs(
449 &flash_state, &flash_ctrl);
450 rv_plic_testutils_irq_range_enable(&plic0, plic_ctx.hart_id,
455 irq_global_ctrl(
true);
456 irq_external_ctrl(
true);
459 do_info_partition_test(kFlashInfoPageIdCreatorSecret, kRandomData1);
460 do_info_partition_test(kFlashInfoPageIdOwnerSecret, kRandomData2);
461 do_info_partition_test(kFlashInfoPageIdIsoPart, kRandomData3);
462 do_bank0_data_partition_test();
464 do_bank1_data_partition_test();