Software APIs
dif_flash_ctrl_unittest.cc
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 
6 
7 #include "gtest/gtest.h"
9 #include "sw/device/lib/base/mock_mmio.h"
10 #include "sw/device/lib/base/multibits.h"
13 
14 #include "flash_ctrl_regs.h" // Generated.
15 
16 namespace dif_flash_ctrl_unittest {
17 namespace {
20 using testing::Test;
21 
22 class FlashCtrlTest : public Test, public MmioTest {
23  protected:
24  void SetUp() {
25  ASSERT_DIF_OK(dif_flash_ctrl_init_state(&dif_flash_ctrl_, dev().region()));
26  }
27 
28  dif_flash_ctrl_state_t dif_flash_ctrl_;
29 };
30 
31 TEST_F(FlashCtrlTest, NullArgs) {
32  dif_toggle_t toggle_arg{};
36  dif_flash_ctrl_get_flash_enablement(&dif_flash_ctrl_, nullptr));
37 
42  dif_flash_ctrl_get_exec_enablement(&dif_flash_ctrl_, nullptr));
43 
45 
46  dif_flash_ctrl_status_t status_arg{};
47  EXPECT_DIF_BADARG(dif_flash_ctrl_get_status(nullptr, &status_arg));
48  EXPECT_DIF_BADARG(dif_flash_ctrl_get_status(&dif_flash_ctrl_, nullptr));
49 
53  dif_flash_ctrl_get_allowed_prog_types(&dif_flash_ctrl_, nullptr));
55 
58 
59  bool bool_arg = false;
62  dif_flash_ctrl_get_erase_suspend_status(&dif_flash_ctrl_, nullptr));
64  dif_flash_ctrl_get_erase_suspend_status(nullptr, &bool_arg));
65 
66  uint32_t data_arg = 0;
68  dif_flash_ctrl_prog_fifo_push_unsafe(nullptr, 1, &data_arg));
70  dif_flash_ctrl_prog_fifo_push_unsafe(&dif_flash_ctrl_, 1, nullptr));
71  EXPECT_DIF_BADARG(dif_flash_ctrl_prog_fifo_push(nullptr, 1, &data_arg));
73  dif_flash_ctrl_prog_fifo_push(&dif_flash_ctrl_, 1, nullptr));
76  dif_flash_ctrl_read_fifo_pop_unsafe(&dif_flash_ctrl_, 1, nullptr));
77  EXPECT_DIF_BADARG(dif_flash_ctrl_read_fifo_pop(nullptr, 1, &data_arg));
78  EXPECT_DIF_BADARG(dif_flash_ctrl_read_fifo_pop(&dif_flash_ctrl_, 1, nullptr));
79 
80  dif_flash_ctrl_error_t error_arg{};
82  EXPECT_DIF_BADARG(dif_flash_ctrl_get_error_codes(&dif_flash_ctrl_, nullptr));
84 
85  dif_flash_ctrl_output_t output_arg{};
86  EXPECT_DIF_BADARG(dif_flash_ctrl_end(nullptr, &output_arg));
87  EXPECT_DIF_BADARG(dif_flash_ctrl_end(&dif_flash_ctrl_, nullptr));
88 
90  nullptr, /*region=*/0, toggle_arg));
92  nullptr, /*region=*/0, &toggle_arg));
94  /*region=*/0,
95  nullptr));
96 
98  dif_flash_ctrl_set_info_region_enablement(nullptr, {}, toggle_arg));
100  dif_flash_ctrl_get_info_region_enablement(nullptr, {}, &toggle_arg));
102  dif_flash_ctrl_get_info_region_enablement(&dif_flash_ctrl_, {}, nullptr));
103 
110  dif_flash_ctrl_get_default_region_properties(&dif_flash_ctrl_, nullptr));
111 
114  dif_flash_ctrl_set_data_region_properties(nullptr, 0, data_mp_arg));
116  dif_flash_ctrl_get_data_region_properties(nullptr, 0, &data_mp_arg));
118  dif_flash_ctrl_get_data_region_properties(&dif_flash_ctrl_, 0, nullptr));
119 
121  dif_flash_ctrl_set_info_region_properties(nullptr, {}, mp_arg));
123  dif_flash_ctrl_get_info_region_properties(nullptr, {}, &mp_arg));
125  dif_flash_ctrl_get_info_region_properties(&dif_flash_ctrl_, {}, nullptr));
126 
129 
131  dif_flash_ctrl_data_region_is_locked(nullptr, 0, &bool_arg));
133  dif_flash_ctrl_data_region_is_locked(&dif_flash_ctrl_, 0, nullptr));
135  dif_flash_ctrl_info_region_is_locked(nullptr, {}, &bool_arg));
137  dif_flash_ctrl_info_region_is_locked(&dif_flash_ctrl_, {}, nullptr));
138 
140  nullptr, /*region=*/0, toggle_arg));
142  nullptr, /*region=*/0, &toggle_arg));
144  /*region=*/0,
145  nullptr));
146 
149  dif_flash_ctrl_bank_configuration_is_locked(nullptr, &bool_arg));
151  dif_flash_ctrl_bank_configuration_is_locked(&dif_flash_ctrl_, nullptr));
152 
156  dif_flash_ctrl_get_fifo_watermarks(nullptr, nullptr, nullptr));
157 
159 
160  dif_flash_ctrl_faults_t faults_arg{};
161  EXPECT_DIF_BADARG(dif_flash_ctrl_get_faults(nullptr, &faults_arg));
162  EXPECT_DIF_BADARG(dif_flash_ctrl_get_faults(&dif_flash_ctrl_, nullptr));
163 
164  dif_flash_ctrl_ecc_errors_t ecc_errors_arg{};
165  EXPECT_DIF_BADARG(dif_flash_ctrl_get_ecc_errors(nullptr, 0, &ecc_errors_arg));
167  dif_flash_ctrl_get_ecc_errors(&dif_flash_ctrl_, 0, nullptr));
168 
169  dif_flash_ctrl_phy_status_t phy_status_arg{};
170  EXPECT_DIF_BADARG(dif_flash_ctrl_get_phy_status(nullptr, &phy_status_arg));
171  EXPECT_DIF_BADARG(dif_flash_ctrl_get_phy_status(&dif_flash_ctrl_, nullptr));
172 
173  uint32_t scratch_arg = 0;
174  EXPECT_DIF_BADARG(dif_flash_ctrl_set_scratch(nullptr, scratch_arg));
175  EXPECT_DIF_BADARG(dif_flash_ctrl_get_scratch(nullptr, &scratch_arg));
176  EXPECT_DIF_BADARG(dif_flash_ctrl_get_scratch(&dif_flash_ctrl_, nullptr));
177 }
178 
179 TEST_F(FlashCtrlTest, EnableFlash) {
180  dif_toggle_t toggle;
181  EXPECT_WRITE32(FLASH_CTRL_DIS_REG_OFFSET, kMultiBitBool4True);
184  EXPECT_READ32(FLASH_CTRL_DIS_REG_OFFSET, kMultiBitBool4True);
185  EXPECT_DIF_OK(dif_flash_ctrl_get_flash_enablement(&dif_flash_ctrl_, &toggle));
186  EXPECT_EQ(toggle, kDifToggleDisabled);
187 
188  EXPECT_WRITE32(FLASH_CTRL_DIS_REG_OFFSET, kMultiBitBool4False);
191  EXPECT_READ32(FLASH_CTRL_DIS_REG_OFFSET, kMultiBitBool4False);
192  EXPECT_DIF_OK(dif_flash_ctrl_get_flash_enablement(&dif_flash_ctrl_, &toggle));
193  EXPECT_EQ(toggle, kDifToggleEnabled);
194 }
195 
196 TEST_F(FlashCtrlTest, EnableFetch) {
197  dif_toggle_t toggle;
198  EXPECT_WRITE32(FLASH_CTRL_EXEC_REG_OFFSET, 0);
201  EXPECT_READ32(FLASH_CTRL_EXEC_REG_OFFSET, 0);
202  EXPECT_DIF_OK(dif_flash_ctrl_get_exec_enablement(&dif_flash_ctrl_, &toggle));
203  EXPECT_EQ(toggle, kDifToggleDisabled);
204 
205  EXPECT_WRITE32(FLASH_CTRL_EXEC_REG_OFFSET, FLASH_CTRL_PARAM_EXEC_EN);
208  EXPECT_READ32(FLASH_CTRL_EXEC_REG_OFFSET, FLASH_CTRL_PARAM_EXEC_EN);
209  EXPECT_DIF_OK(dif_flash_ctrl_get_exec_enablement(&dif_flash_ctrl_, &toggle));
210  EXPECT_EQ(toggle, kDifToggleEnabled);
211 }
212 
213 TEST_F(FlashCtrlTest, ControllerInit) {
214  EXPECT_READ32(FLASH_CTRL_INIT_REG_OFFSET, 0);
215  EXPECT_WRITE32(FLASH_CTRL_INIT_REG_OFFSET, {{FLASH_CTRL_INIT_VAL_BIT, 1}});
217 
218  EXPECT_READ32(FLASH_CTRL_INIT_REG_OFFSET, {{FLASH_CTRL_INIT_VAL_BIT, 1}});
219  EXPECT_EQ(dif_flash_ctrl_start_controller_init(&dif_flash_ctrl_), kDifError);
220 
222  EXPECT_READ32(FLASH_CTRL_STATUS_REG_OFFSET,
223  {
224  {FLASH_CTRL_STATUS_INIT_WIP_BIT, 1},
225  });
226  EXPECT_DIF_OK(dif_flash_ctrl_get_status(&dif_flash_ctrl_, &status));
227  EXPECT_EQ(status.controller_init_wip, 1);
228 
229  EXPECT_READ32(FLASH_CTRL_STATUS_REG_OFFSET,
230  {
231  {FLASH_CTRL_STATUS_INIT_WIP_BIT, 0},
232  });
233  EXPECT_DIF_OK(dif_flash_ctrl_get_status(&dif_flash_ctrl_, &status));
234  EXPECT_EQ(status.controller_init_wip, 0);
235 }
236 
237 TEST_F(FlashCtrlTest, SetProgPermissions) {
239  .normal_prog_type = 0,
240  .repair_prog_type = 1,
241  };
242 
243  EXPECT_READ32(FLASH_CTRL_CTRL_REGWEN_REG_OFFSET,
244  {{FLASH_CTRL_CTRL_REGWEN_EN_BIT, 1}});
245 
246  EXPECT_WRITE32(FLASH_CTRL_PROG_TYPE_EN_REG_OFFSET,
247  {
248  {FLASH_CTRL_PROG_TYPE_EN_NORMAL_BIT, 1},
249  {FLASH_CTRL_PROG_TYPE_EN_REPAIR_BIT, 0},
250  });
252  dif_flash_ctrl_disallow_prog_types(&dif_flash_ctrl_, prog_caps));
253  EXPECT_READ32(FLASH_CTRL_PROG_TYPE_EN_REG_OFFSET,
254  {
255  {FLASH_CTRL_PROG_TYPE_EN_NORMAL_BIT, 1},
256  {FLASH_CTRL_PROG_TYPE_EN_REPAIR_BIT, 0},
257  });
259  dif_flash_ctrl_get_allowed_prog_types(&dif_flash_ctrl_, &prog_caps));
260  EXPECT_EQ(prog_caps.normal_prog_type, 1);
261  EXPECT_EQ(prog_caps.repair_prog_type, 0);
262 
263  prog_caps.normal_prog_type = 1;
264  prog_caps.repair_prog_type = 0;
265 
266  EXPECT_READ32(FLASH_CTRL_CTRL_REGWEN_REG_OFFSET,
267  {{FLASH_CTRL_CTRL_REGWEN_EN_BIT, 1}});
268 
269  EXPECT_WRITE32(FLASH_CTRL_PROG_TYPE_EN_REG_OFFSET,
270  {
271  {FLASH_CTRL_PROG_TYPE_EN_NORMAL_BIT, 0},
272  {FLASH_CTRL_PROG_TYPE_EN_REPAIR_BIT, 1},
273  });
275  dif_flash_ctrl_disallow_prog_types(&dif_flash_ctrl_, prog_caps));
276  EXPECT_READ32(FLASH_CTRL_PROG_TYPE_EN_REG_OFFSET,
277  {
278  {FLASH_CTRL_PROG_TYPE_EN_NORMAL_BIT, 0},
279  {FLASH_CTRL_PROG_TYPE_EN_REPAIR_BIT, 1},
280  });
282  dif_flash_ctrl_get_allowed_prog_types(&dif_flash_ctrl_, &prog_caps));
283  EXPECT_EQ(prog_caps.normal_prog_type, 0);
284  EXPECT_EQ(prog_caps.repair_prog_type, 1);
285 }
286 
287 TEST_F(FlashCtrlTest, ReadTransaction) {
288  dif_flash_ctrl_transaction_t transaction = {
289  .op = kDifFlashCtrlOpRead,
290  .partition_type = kDifFlashCtrlPartitionTypeInfo,
291  .partition_id = 1,
292  .byte_address = 0x80,
293  .word_count = 0x20,
294  };
295 
296  // Read FIFO not empty
297  EXPECT_READ32(FLASH_CTRL_STATUS_REG_OFFSET,
298  {
299  {FLASH_CTRL_STATUS_RD_FULL_BIT, 0},
300  {FLASH_CTRL_STATUS_RD_EMPTY_BIT, 0},
301  {FLASH_CTRL_STATUS_PROG_EMPTY_BIT, 1},
302  });
303  EXPECT_EQ(dif_flash_ctrl_start(&dif_flash_ctrl_, transaction),
305 
306  // Control register not writable
307  EXPECT_READ32(FLASH_CTRL_STATUS_REG_OFFSET,
308  {
309  {FLASH_CTRL_STATUS_RD_FULL_BIT, 0},
310  {FLASH_CTRL_STATUS_RD_EMPTY_BIT, 1},
311  {FLASH_CTRL_STATUS_PROG_EMPTY_BIT, 1},
312  });
313  EXPECT_READ32(FLASH_CTRL_CTRL_REGWEN_REG_OFFSET,
314  {{FLASH_CTRL_CTRL_REGWEN_EN_BIT, 0}});
315  EXPECT_EQ(dif_flash_ctrl_start(&dif_flash_ctrl_, transaction),
317 
318  // Read transaction setup is successful
319  EXPECT_READ32(FLASH_CTRL_STATUS_REG_OFFSET,
320  {
321  {FLASH_CTRL_STATUS_RD_FULL_BIT, 0},
322  {FLASH_CTRL_STATUS_RD_EMPTY_BIT, 1},
323  {FLASH_CTRL_STATUS_PROG_EMPTY_BIT, 1},
324  });
325  EXPECT_READ32(FLASH_CTRL_CTRL_REGWEN_REG_OFFSET,
326  {{FLASH_CTRL_CTRL_REGWEN_EN_BIT, 1}});
327  EXPECT_WRITE32(
328  FLASH_CTRL_CONTROL_REG_OFFSET,
329  {
330  {FLASH_CTRL_CONTROL_OP_OFFSET, FLASH_CTRL_CONTROL_OP_VALUE_READ},
331  {FLASH_CTRL_CONTROL_PARTITION_SEL_BIT, 1},
332  {FLASH_CTRL_CONTROL_INFO_SEL_OFFSET, 1},
333  {FLASH_CTRL_CONTROL_NUM_OFFSET, 0x20 - 1},
334  });
335  EXPECT_WRITE32(FLASH_CTRL_ADDR_REG_OFFSET, 0x80);
336  EXPECT_WRITE32(
337  FLASH_CTRL_CONTROL_REG_OFFSET,
338  {
339  {FLASH_CTRL_CONTROL_START_BIT, 1},
340  {FLASH_CTRL_CONTROL_OP_OFFSET, FLASH_CTRL_CONTROL_OP_VALUE_READ},
341  {FLASH_CTRL_CONTROL_PARTITION_SEL_BIT, 1},
342  {FLASH_CTRL_CONTROL_INFO_SEL_OFFSET, 1},
343  {FLASH_CTRL_CONTROL_NUM_OFFSET, 0x20 - 1},
344  });
345  EXPECT_DIF_OK(dif_flash_ctrl_start(&dif_flash_ctrl_, transaction));
346  EXPECT_TRUE(dif_flash_ctrl_.transaction_pending);
347 
348  // Read the data
349  uint32_t data[0x20];
350  EXPECT_READ32(
351  FLASH_CTRL_CONTROL_REG_OFFSET,
352  {
353  {FLASH_CTRL_CONTROL_START_BIT, 1},
354  {FLASH_CTRL_CONTROL_OP_OFFSET, FLASH_CTRL_CONTROL_OP_VALUE_READ},
355  {FLASH_CTRL_CONTROL_PARTITION_SEL_BIT, 1},
356  {FLASH_CTRL_CONTROL_INFO_SEL_OFFSET, 1},
357  {FLASH_CTRL_CONTROL_NUM_OFFSET, 0x20 - 1},
358  });
359  for (uint32_t i = 0; i < 0x20; ++i) {
360  EXPECT_READ32(FLASH_CTRL_RD_FIFO_REG_OFFSET, i);
361  }
362  EXPECT_DIF_OK(dif_flash_ctrl_read_fifo_pop(&dif_flash_ctrl_, 0x20, data));
363  for (uint32_t i = 0; i < 0x20; i++) {
364  EXPECT_EQ(data[i], i);
365  }
366 
367  // Complete the transaction (with meaningless error code return)
369  EXPECT_READ32(FLASH_CTRL_OP_STATUS_REG_OFFSET,
370  {
371  {FLASH_CTRL_OP_STATUS_DONE_BIT, 0},
372  {FLASH_CTRL_OP_STATUS_ERR_BIT, 0},
373  });
374  EXPECT_EQ(dif_flash_ctrl_end(&dif_flash_ctrl_, &output), kDifUnavailable);
375  EXPECT_READ32(FLASH_CTRL_OP_STATUS_REG_OFFSET,
376  {
377  {FLASH_CTRL_OP_STATUS_DONE_BIT, 1},
378  {FLASH_CTRL_OP_STATUS_ERR_BIT, 0},
379  });
380  EXPECT_READ32(FLASH_CTRL_ERR_CODE_REG_OFFSET,
381  {
382  {FLASH_CTRL_ERR_CODE_MP_ERR_BIT, 1},
383  {FLASH_CTRL_ERR_CODE_RD_ERR_BIT, 0},
384  {FLASH_CTRL_ERR_CODE_PROG_WIN_ERR_BIT, 1},
385  {FLASH_CTRL_ERR_CODE_PROG_TYPE_ERR_BIT, 0},
386  {FLASH_CTRL_ERR_CODE_UPDATE_ERR_BIT, 0},
387  });
388  EXPECT_READ32(FLASH_CTRL_ERR_ADDR_REG_OFFSET, 0x12345678u);
389  EXPECT_WRITE32(FLASH_CTRL_OP_STATUS_REG_OFFSET, 0);
390  EXPECT_DIF_OK(dif_flash_ctrl_end(&dif_flash_ctrl_, &output));
391  EXPECT_FALSE(dif_flash_ctrl_.transaction_pending);
392  EXPECT_EQ(output.operation_done, 1);
393  EXPECT_EQ(output.operation_error, 0);
394  EXPECT_EQ(output.error_code.address, 0x12345678u);
395  EXPECT_EQ(output.error_code.codes.memory_properties_error, 1);
396  EXPECT_EQ(output.error_code.codes.read_error, 0);
397  EXPECT_EQ(output.error_code.codes.prog_window_error, 1);
398  EXPECT_EQ(output.error_code.codes.prog_type_error, 0);
399  EXPECT_EQ(output.error_code.codes.shadow_register_error, 0);
400 }
401 
402 TEST_F(FlashCtrlTest, ProgramTransaction) {
403  dif_flash_ctrl_transaction_t transaction = {
405  .partition_type = kDifFlashCtrlPartitionTypeData,
406  .partition_id = 0,
407  .byte_address = 0x1800,
408  .word_count = 0x16,
409  };
410 
411  // Prog FIFO not empty
412  EXPECT_READ32(FLASH_CTRL_STATUS_REG_OFFSET,
413  {
414  {FLASH_CTRL_STATUS_RD_EMPTY_BIT, 1},
415  {FLASH_CTRL_STATUS_PROG_FULL_BIT, 0},
416  {FLASH_CTRL_STATUS_PROG_EMPTY_BIT, 0},
417  });
418  EXPECT_EQ(dif_flash_ctrl_start(&dif_flash_ctrl_, transaction),
420  // Control register not writable
421  EXPECT_READ32(FLASH_CTRL_STATUS_REG_OFFSET,
422  {
423  {FLASH_CTRL_STATUS_RD_EMPTY_BIT, 1},
424  {FLASH_CTRL_STATUS_PROG_FULL_BIT, 0},
425  {FLASH_CTRL_STATUS_PROG_EMPTY_BIT, 1},
426  });
427  EXPECT_READ32(FLASH_CTRL_CTRL_REGWEN_REG_OFFSET,
428  {{FLASH_CTRL_CTRL_REGWEN_EN_BIT, 0}});
429  EXPECT_EQ(dif_flash_ctrl_start(&dif_flash_ctrl_, transaction),
431 
432  // Prog transaction setup is successful
433  EXPECT_READ32(FLASH_CTRL_STATUS_REG_OFFSET,
434  {
435  {FLASH_CTRL_STATUS_RD_EMPTY_BIT, 1},
436  {FLASH_CTRL_STATUS_PROG_FULL_BIT, 0},
437  {FLASH_CTRL_STATUS_PROG_EMPTY_BIT, 1},
438  });
439  EXPECT_READ32(FLASH_CTRL_CTRL_REGWEN_REG_OFFSET,
440  {{FLASH_CTRL_CTRL_REGWEN_EN_BIT, 1}});
441  EXPECT_WRITE32(
442  FLASH_CTRL_CONTROL_REG_OFFSET,
443  {
444  {FLASH_CTRL_CONTROL_OP_OFFSET, FLASH_CTRL_CONTROL_OP_VALUE_PROG},
445  {FLASH_CTRL_CONTROL_PARTITION_SEL_BIT, 0},
446  {FLASH_CTRL_CONTROL_PROG_SEL_BIT, 1},
447  {FLASH_CTRL_CONTROL_NUM_OFFSET, 0x16 - 1},
448  });
449  EXPECT_WRITE32(FLASH_CTRL_ADDR_REG_OFFSET, 0x1800);
450  EXPECT_WRITE32(
451  FLASH_CTRL_CONTROL_REG_OFFSET,
452  {
453  {FLASH_CTRL_CONTROL_START_BIT, 1},
454  {FLASH_CTRL_CONTROL_OP_OFFSET, FLASH_CTRL_CONTROL_OP_VALUE_PROG},
455  {FLASH_CTRL_CONTROL_PARTITION_SEL_BIT, 0},
456  {FLASH_CTRL_CONTROL_PROG_SEL_BIT, 1},
457  {FLASH_CTRL_CONTROL_NUM_OFFSET, 0x16 - 1},
458  });
459  EXPECT_DIF_OK(dif_flash_ctrl_start(&dif_flash_ctrl_, transaction));
460  EXPECT_TRUE(dif_flash_ctrl_.transaction_pending);
461 
462  // Write out the data
463  uint32_t data[0x16];
464  EXPECT_READ32(
465  FLASH_CTRL_CONTROL_REG_OFFSET,
466  {
467  {FLASH_CTRL_CONTROL_START_BIT, 1},
468  {FLASH_CTRL_CONTROL_OP_OFFSET, FLASH_CTRL_CONTROL_OP_VALUE_PROG},
469  {FLASH_CTRL_CONTROL_PARTITION_SEL_BIT, 0},
470  {FLASH_CTRL_CONTROL_PROG_SEL_BIT, 1},
471  {FLASH_CTRL_CONTROL_NUM_OFFSET, 0x16 - 1},
472  });
473  for (uint32_t i = 0; i < 0x16; ++i) {
474  data[i] = i;
475  EXPECT_WRITE32(FLASH_CTRL_PROG_FIFO_REG_OFFSET, i);
476  }
477  EXPECT_DIF_OK(dif_flash_ctrl_prog_fifo_push(&dif_flash_ctrl_, 0x16, data));
478 
479  // Complete the transaction (with meaningless error code return)
481  EXPECT_READ32(FLASH_CTRL_OP_STATUS_REG_OFFSET,
482  {
483  {FLASH_CTRL_OP_STATUS_DONE_BIT, 0},
484  {FLASH_CTRL_OP_STATUS_ERR_BIT, 0},
485  });
486  EXPECT_EQ(dif_flash_ctrl_end(&dif_flash_ctrl_, &output), kDifUnavailable);
487  EXPECT_READ32(FLASH_CTRL_OP_STATUS_REG_OFFSET,
488  {
489  {FLASH_CTRL_OP_STATUS_DONE_BIT, 1},
490  {FLASH_CTRL_OP_STATUS_ERR_BIT, 0},
491  });
492  EXPECT_READ32(FLASH_CTRL_ERR_CODE_REG_OFFSET,
493  {
494  {FLASH_CTRL_ERR_CODE_MP_ERR_BIT, 0},
495  {FLASH_CTRL_ERR_CODE_RD_ERR_BIT, 0},
496  {FLASH_CTRL_ERR_CODE_PROG_WIN_ERR_BIT, 1},
497  {FLASH_CTRL_ERR_CODE_PROG_TYPE_ERR_BIT, 1},
498  {FLASH_CTRL_ERR_CODE_UPDATE_ERR_BIT, 1},
499  });
500  EXPECT_READ32(FLASH_CTRL_ERR_ADDR_REG_OFFSET, 0x87654321u);
501  EXPECT_WRITE32(FLASH_CTRL_OP_STATUS_REG_OFFSET, 0);
502  EXPECT_DIF_OK(dif_flash_ctrl_end(&dif_flash_ctrl_, &output));
503  EXPECT_FALSE(dif_flash_ctrl_.transaction_pending);
504  EXPECT_EQ(output.operation_done, 1);
505  EXPECT_EQ(output.operation_error, 0);
506  EXPECT_EQ(output.error_code.address, 0x87654321u);
507  EXPECT_EQ(output.error_code.codes.memory_properties_error, 0);
508  EXPECT_EQ(output.error_code.codes.read_error, 0);
509  EXPECT_EQ(output.error_code.codes.prog_window_error, 1);
510  EXPECT_EQ(output.error_code.codes.prog_type_error, 1);
511  EXPECT_EQ(output.error_code.codes.shadow_register_error, 1);
512 }
513 
514 TEST_F(FlashCtrlTest, SuspendErase) {
515  EXPECT_WRITE32(FLASH_CTRL_ERASE_SUSPEND_REG_OFFSET,
516  {
517  {FLASH_CTRL_ERASE_SUSPEND_REQ_BIT, 1},
518  });
519  EXPECT_DIF_OK(dif_flash_ctrl_suspend_erase(&dif_flash_ctrl_));
520 
521  bool erase_suspend_status;
522  EXPECT_READ32(FLASH_CTRL_ERASE_SUSPEND_REG_OFFSET,
523  {
524  {FLASH_CTRL_ERASE_SUSPEND_REQ_BIT, 1},
525  });
527  &erase_suspend_status));
528  EXPECT_TRUE(erase_suspend_status);
529 
530  EXPECT_READ32(FLASH_CTRL_ERASE_SUSPEND_REG_OFFSET,
531  {
532  {FLASH_CTRL_ERASE_SUSPEND_REQ_BIT, 0},
533  });
535  &erase_suspend_status));
536  EXPECT_FALSE(erase_suspend_status);
537 }
538 
539 TEST_F(FlashCtrlTest, ConfigureDataRegion) {
540  // Uses a few different regions throughout to test the addressing
541 
542  // Check whether the region is enabled
543  dif_toggle_t toggle;
544  EXPECT_READ32(
545  FLASH_CTRL_MP_REGION_CFG_4_REG_OFFSET,
546  {
547  {FLASH_CTRL_MP_REGION_CFG_4_EN_4_OFFSET, kMultiBitBool4False},
548  });
550  dif_flash_ctrl_get_data_region_enablement(&dif_flash_ctrl_, 4, &toggle));
551  EXPECT_EQ(toggle, kDifToggleDisabled);
552 
553  // Check if the region is locked
554  bool locked;
555  EXPECT_READ32(FLASH_CTRL_REGION_CFG_REGWEN_3_REG_OFFSET,
556  {{FLASH_CTRL_REGION_CFG_REGWEN_3_REGION_3_BIT, 1}});
558  dif_flash_ctrl_data_region_is_locked(&dif_flash_ctrl_, 3, &locked));
559  EXPECT_FALSE(locked);
560 
561  // Configure the region
563  .base = 0x48,
564  .size = 0x9a,
565  .properties =
566  {
567  .rd_en = kMultiBitBool4False,
568  .prog_en = kMultiBitBool4True,
569  .erase_en = kMultiBitBool4True,
570  .scramble_en = kMultiBitBool4False,
571  .ecc_en = kMultiBitBool4False,
572  .high_endurance_en = kMultiBitBool4False,
573  },
574  };
575  EXPECT_READ32(FLASH_CTRL_REGION_CFG_REGWEN_2_REG_OFFSET,
576  {{FLASH_CTRL_REGION_CFG_REGWEN_2_REGION_2_BIT, 1}});
577 
578  EXPECT_READ32(
579  FLASH_CTRL_MP_REGION_CFG_2_REG_OFFSET,
580  {{FLASH_CTRL_MP_REGION_CFG_2_EN_2_OFFSET, kMultiBitBool4False}});
581 
582  EXPECT_WRITE32(
583  FLASH_CTRL_MP_REGION_CFG_2_REG_OFFSET,
584  {
585  {FLASH_CTRL_MP_REGION_CFG_2_EN_2_OFFSET, kMultiBitBool4False},
586  {FLASH_CTRL_MP_REGION_CFG_2_RD_EN_2_OFFSET, kMultiBitBool4False},
587  {FLASH_CTRL_MP_REGION_CFG_2_PROG_EN_2_OFFSET, kMultiBitBool4True},
588  {FLASH_CTRL_MP_REGION_CFG_2_ERASE_EN_2_OFFSET, kMultiBitBool4True},
589  {FLASH_CTRL_MP_REGION_CFG_2_SCRAMBLE_EN_2_OFFSET,
590  kMultiBitBool4False},
591  {FLASH_CTRL_MP_REGION_CFG_2_ECC_EN_2_OFFSET, kMultiBitBool4False},
592  {FLASH_CTRL_MP_REGION_CFG_2_HE_EN_2_OFFSET, kMultiBitBool4False},
593  });
594 
595  EXPECT_WRITE32(FLASH_CTRL_MP_REGION_2_REG_OFFSET,
596  {
597  {FLASH_CTRL_MP_REGION_2_BASE_2_OFFSET, 0x48},
598  {FLASH_CTRL_MP_REGION_2_SIZE_2_OFFSET, 0x9a},
599  });
600 
602  dif_flash_ctrl_set_data_region_properties(&dif_flash_ctrl_, 2, data_mp));
603 
604  // Enable the region
605  EXPECT_READ32(FLASH_CTRL_REGION_CFG_REGWEN_3_REG_OFFSET,
606  {{FLASH_CTRL_REGION_CFG_REGWEN_3_REGION_3_BIT, 1}});
607  EXPECT_READ32(
608  FLASH_CTRL_MP_REGION_CFG_3_REG_OFFSET,
609  {
610  {FLASH_CTRL_MP_REGION_CFG_3_EN_3_OFFSET, kMultiBitBool4False},
611  {FLASH_CTRL_MP_REGION_CFG_3_RD_EN_3_OFFSET, kMultiBitBool4False},
612  {FLASH_CTRL_MP_REGION_CFG_3_PROG_EN_3_OFFSET, kMultiBitBool4True},
613  {FLASH_CTRL_MP_REGION_CFG_3_ERASE_EN_3_OFFSET, kMultiBitBool4True},
614  {FLASH_CTRL_MP_REGION_CFG_3_SCRAMBLE_EN_3_OFFSET,
615  kMultiBitBool4False},
616  {FLASH_CTRL_MP_REGION_CFG_3_ECC_EN_3_OFFSET, kMultiBitBool4False},
617  {FLASH_CTRL_MP_REGION_CFG_3_HE_EN_3_OFFSET, kMultiBitBool4False},
618  });
619 
620  EXPECT_WRITE32(
621  FLASH_CTRL_MP_REGION_CFG_3_REG_OFFSET,
622  {
623  {FLASH_CTRL_MP_REGION_CFG_3_EN_3_OFFSET, kMultiBitBool4True},
624  {FLASH_CTRL_MP_REGION_CFG_3_RD_EN_3_OFFSET, kMultiBitBool4False},
625  {FLASH_CTRL_MP_REGION_CFG_3_PROG_EN_3_OFFSET, kMultiBitBool4True},
626  {FLASH_CTRL_MP_REGION_CFG_3_ERASE_EN_3_OFFSET, kMultiBitBool4True},
627  {FLASH_CTRL_MP_REGION_CFG_3_SCRAMBLE_EN_3_OFFSET,
628  kMultiBitBool4False},
629  {FLASH_CTRL_MP_REGION_CFG_3_ECC_EN_3_OFFSET, kMultiBitBool4False},
630  {FLASH_CTRL_MP_REGION_CFG_3_HE_EN_3_OFFSET, kMultiBitBool4False},
631  });
632 
635 
636  // Read out the region's configuration
637  EXPECT_READ32(
638  FLASH_CTRL_MP_REGION_CFG_3_REG_OFFSET,
639  {
640  {FLASH_CTRL_MP_REGION_CFG_3_RD_EN_3_OFFSET, kMultiBitBool4False},
641  {FLASH_CTRL_MP_REGION_CFG_3_PROG_EN_3_OFFSET, kMultiBitBool4True},
642  {FLASH_CTRL_MP_REGION_CFG_3_ERASE_EN_3_OFFSET, kMultiBitBool4True},
643  {FLASH_CTRL_MP_REGION_CFG_3_SCRAMBLE_EN_3_OFFSET,
644  kMultiBitBool4False},
645  {FLASH_CTRL_MP_REGION_CFG_3_ECC_EN_3_OFFSET, kMultiBitBool4False},
646  {FLASH_CTRL_MP_REGION_CFG_3_HE_EN_3_OFFSET, kMultiBitBool4False},
647  });
648 
649  EXPECT_READ32(FLASH_CTRL_MP_REGION_3_REG_OFFSET,
650  {
651  {FLASH_CTRL_MP_REGION_3_BASE_3_OFFSET, 0x48},
652  {FLASH_CTRL_MP_REGION_3_SIZE_3_OFFSET, 0x9a},
653  });
654 
656  dif_flash_ctrl_get_data_region_properties(&dif_flash_ctrl_, 3, &data_mp));
657  EXPECT_EQ(data_mp.properties.rd_en, kMultiBitBool4False);
658  EXPECT_EQ(data_mp.properties.prog_en, kMultiBitBool4True);
659  EXPECT_EQ(data_mp.properties.erase_en, kMultiBitBool4True);
660  EXPECT_EQ(data_mp.properties.scramble_en, kMultiBitBool4False);
661  EXPECT_EQ(data_mp.properties.ecc_en, kMultiBitBool4False);
662  EXPECT_EQ(data_mp.properties.high_endurance_en, kMultiBitBool4False);
663  EXPECT_EQ(data_mp.base, 0x48);
664  EXPECT_EQ(data_mp.size, 0x9a);
665 
666  // Lock the region
667  EXPECT_READ32(FLASH_CTRL_REGION_CFG_REGWEN_3_REG_OFFSET,
668  {{FLASH_CTRL_REGION_CFG_REGWEN_3_REGION_3_BIT, 1}});
670  dif_flash_ctrl_data_region_is_locked(&dif_flash_ctrl_, 3, &locked));
671  EXPECT_FALSE(locked);
672 
673  EXPECT_READ32(FLASH_CTRL_REGION_CFG_REGWEN_3_REG_OFFSET,
674  {{FLASH_CTRL_REGION_CFG_REGWEN_3_REGION_3_BIT, 1}});
675  EXPECT_WRITE32(FLASH_CTRL_REGION_CFG_REGWEN_3_REG_OFFSET,
676  {{FLASH_CTRL_REGION_CFG_REGWEN_3_REGION_3_BIT, 0}});
678  dif_flash_ctrl_lock_data_region_properties(&dif_flash_ctrl_, 3));
679 
680  EXPECT_READ32(FLASH_CTRL_REGION_CFG_REGWEN_3_REG_OFFSET,
681  {{FLASH_CTRL_REGION_CFG_REGWEN_3_REGION_3_BIT, 0}});
683  dif_flash_ctrl_data_region_is_locked(&dif_flash_ctrl_, 3, &locked));
684  EXPECT_TRUE(locked);
685  EXPECT_READ32(FLASH_CTRL_REGION_CFG_REGWEN_3_REG_OFFSET,
686  {{FLASH_CTRL_REGION_CFG_REGWEN_3_REGION_3_BIT, 0}});
687  EXPECT_EQ(
688  dif_flash_ctrl_set_data_region_properties(&dif_flash_ctrl_, 3, data_mp),
689  kDifLocked);
690 }
691 
692 TEST_F(FlashCtrlTest, SimpleQueries) {
694  EXPECT_READ32(FLASH_CTRL_STATUS_REG_OFFSET,
695  {
696  {FLASH_CTRL_STATUS_RD_FULL_BIT, 0},
697  {FLASH_CTRL_STATUS_RD_EMPTY_BIT, 1},
698  {FLASH_CTRL_STATUS_PROG_FULL_BIT, 1},
699  {FLASH_CTRL_STATUS_PROG_EMPTY_BIT, 0},
700  {FLASH_CTRL_STATUS_INIT_WIP_BIT, 0},
701  });
702  EXPECT_DIF_OK(dif_flash_ctrl_get_status(&dif_flash_ctrl_, &status));
703  EXPECT_EQ(status.read_fifo_full, 0);
704  EXPECT_EQ(status.read_fifo_empty, 1);
705  EXPECT_EQ(status.prog_fifo_full, 1);
706  EXPECT_EQ(status.prog_fifo_empty, 0);
707  EXPECT_EQ(status.controller_init_wip, 0);
708 
709  dif_flash_ctrl_error_t error_value;
710  EXPECT_READ32(FLASH_CTRL_ERR_CODE_REG_OFFSET,
711  {
712  {FLASH_CTRL_ERR_CODE_MP_ERR_BIT, 1},
713  {FLASH_CTRL_ERR_CODE_RD_ERR_BIT, 0},
714  {FLASH_CTRL_ERR_CODE_PROG_WIN_ERR_BIT, 0},
715  {FLASH_CTRL_ERR_CODE_PROG_TYPE_ERR_BIT, 1},
716  {FLASH_CTRL_ERR_CODE_UPDATE_ERR_BIT, 1},
717  });
718  EXPECT_READ32(FLASH_CTRL_ERR_ADDR_REG_OFFSET, 0x1effe0u);
719  EXPECT_DIF_OK(dif_flash_ctrl_get_error_codes(&dif_flash_ctrl_, &error_value));
720  EXPECT_EQ(error_value.codes.memory_properties_error, 1);
721  EXPECT_EQ(error_value.codes.read_error, 0);
722  EXPECT_EQ(error_value.codes.prog_window_error, 0);
723  EXPECT_EQ(error_value.codes.prog_type_error, 1);
724  EXPECT_EQ(error_value.codes.shadow_register_error, 1);
725  EXPECT_EQ(error_value.address, 0x1effe0u);
726 
727  dif_toggle_t toggle;
728  dif_flash_ctrl_info_region_t info_region = {
729  .bank = 1,
730  .partition_id = 0,
731  .page = 3,
732  };
733  EXPECT_READ32(
734  FLASH_CTRL_BANK1_INFO0_PAGE_CFG_3_REG_OFFSET,
735  {
736  {FLASH_CTRL_MP_REGION_CFG_0_EN_0_OFFSET, kMultiBitBool4True},
737  });
739  &dif_flash_ctrl_, info_region, &toggle));
740  EXPECT_EQ(toggle, kDifToggleEnabled);
741 
743  EXPECT_READ32(
744  FLASH_CTRL_DEFAULT_REGION_REG_OFFSET,
745  {
746  {FLASH_CTRL_DEFAULT_REGION_RD_EN_OFFSET, kMultiBitBool4True},
747  {FLASH_CTRL_DEFAULT_REGION_PROG_EN_OFFSET, kMultiBitBool4True},
748  {FLASH_CTRL_DEFAULT_REGION_ERASE_EN_OFFSET, kMultiBitBool4False},
749  {FLASH_CTRL_DEFAULT_REGION_SCRAMBLE_EN_OFFSET, kMultiBitBool4False},
750  {FLASH_CTRL_DEFAULT_REGION_ECC_EN_OFFSET, kMultiBitBool4True},
751  {FLASH_CTRL_DEFAULT_REGION_HE_EN_OFFSET, kMultiBitBool4False},
752  });
754  dif_flash_ctrl_get_default_region_properties(&dif_flash_ctrl_, &mp));
755  EXPECT_EQ(mp.rd_en, kMultiBitBool4True);
756  EXPECT_EQ(mp.prog_en, kMultiBitBool4True);
757  EXPECT_EQ(mp.erase_en, kMultiBitBool4False);
758  EXPECT_EQ(mp.scramble_en, kMultiBitBool4False);
759  EXPECT_EQ(mp.ecc_en, kMultiBitBool4True);
760  EXPECT_EQ(mp.high_endurance_en, kMultiBitBool4False);
761 
762  info_region.bank = 0;
763  info_region.partition_id = 2;
764  info_region.page = 1;
765  EXPECT_READ32(FLASH_CTRL_BANK0_INFO2_PAGE_CFG_1_REG_OFFSET,
766  {
767  {FLASH_CTRL_BANK0_INFO2_PAGE_CFG_1_RD_EN_1_OFFSET,
768  kMultiBitBool4True},
769  {FLASH_CTRL_BANK0_INFO2_PAGE_CFG_1_PROG_EN_1_OFFSET,
770  kMultiBitBool4False},
771  {FLASH_CTRL_BANK0_INFO2_PAGE_CFG_1_ERASE_EN_1_OFFSET,
772  kMultiBitBool4True},
773  {FLASH_CTRL_BANK0_INFO2_PAGE_CFG_1_SCRAMBLE_EN_1_OFFSET,
774  kMultiBitBool4False},
775  {FLASH_CTRL_BANK0_INFO2_PAGE_CFG_1_ECC_EN_1_OFFSET,
776  kMultiBitBool4True},
777  {FLASH_CTRL_BANK0_INFO2_PAGE_CFG_1_HE_EN_1_OFFSET,
778  kMultiBitBool4False},
779  });
781  info_region, &mp));
782  EXPECT_EQ(mp.rd_en, kMultiBitBool4True);
783  EXPECT_EQ(mp.prog_en, kMultiBitBool4False);
784  EXPECT_EQ(mp.erase_en, kMultiBitBool4True);
785  EXPECT_EQ(mp.scramble_en, kMultiBitBool4False);
786  EXPECT_EQ(mp.ecc_en, kMultiBitBool4True);
787  EXPECT_EQ(mp.high_endurance_en, kMultiBitBool4False);
788 
789  bool locked;
790  info_region.bank = 0;
791  info_region.partition_id = 0;
792  info_region.page = 2;
793  EXPECT_READ32(FLASH_CTRL_BANK0_INFO0_REGWEN_2_REG_OFFSET,
794  {{FLASH_CTRL_BANK0_INFO0_REGWEN_2_REGION_2_BIT, 1}});
796  info_region, &locked));
797  EXPECT_FALSE(locked);
798 
799  EXPECT_READ32(FLASH_CTRL_MP_BANK_CFG_SHADOWED_REG_OFFSET,
800  {
801  {FLASH_CTRL_MP_BANK_CFG_SHADOWED_ERASE_EN_0_BIT, 0},
802  {FLASH_CTRL_MP_BANK_CFG_SHADOWED_ERASE_EN_1_BIT, 1},
803  });
805  dif_flash_ctrl_get_bank_erase_enablement(&dif_flash_ctrl_, 1, &toggle));
806  EXPECT_EQ(toggle, kDifToggleEnabled);
807 
808  EXPECT_READ32(FLASH_CTRL_BANK_CFG_REGWEN_REG_OFFSET,
809  {{FLASH_CTRL_BANK_CFG_REGWEN_BANK_BIT, 1}});
811  dif_flash_ctrl_bank_configuration_is_locked(&dif_flash_ctrl_, &locked));
812  EXPECT_FALSE(locked);
813 
814  uint32_t prog_level, read_level;
815  EXPECT_READ32(FLASH_CTRL_FIFO_LVL_REG_OFFSET,
816  {
817  {FLASH_CTRL_FIFO_LVL_PROG_OFFSET, 9},
818  {FLASH_CTRL_FIFO_LVL_RD_OFFSET, 13},
819  });
821  &prog_level, &read_level));
822  EXPECT_EQ(prog_level, 9);
823  EXPECT_EQ(read_level, 13);
824 
826  EXPECT_READ32(FLASH_CTRL_FAULT_STATUS_REG_OFFSET,
827  {
828  {FLASH_CTRL_FAULT_STATUS_MP_ERR_BIT, 1},
829  {FLASH_CTRL_FAULT_STATUS_RD_ERR_BIT, 0},
830  {FLASH_CTRL_FAULT_STATUS_PROG_WIN_ERR_BIT, 1},
831  {FLASH_CTRL_FAULT_STATUS_PROG_TYPE_ERR_BIT, 0},
832  });
833  EXPECT_READ32(FLASH_CTRL_STD_FAULT_STATUS_REG_OFFSET,
834  {
835  {FLASH_CTRL_STD_FAULT_STATUS_REG_INTG_ERR_BIT, 0},
836  {FLASH_CTRL_STD_FAULT_STATUS_PROG_INTG_ERR_BIT, 1},
837  {FLASH_CTRL_STD_FAULT_STATUS_LCMGR_ERR_BIT, 0},
838  {FLASH_CTRL_STD_FAULT_STATUS_STORAGE_ERR_BIT, 1},
839  });
840  EXPECT_DIF_OK(dif_flash_ctrl_get_faults(&dif_flash_ctrl_, &faults));
841  EXPECT_EQ(faults.memory_properties_error, 1);
842  EXPECT_EQ(faults.read_error, 0);
843  EXPECT_EQ(faults.prog_window_error, 1);
844  EXPECT_EQ(faults.prog_type_error, 0);
845  EXPECT_EQ(faults.register_integrity_error, 0);
846  EXPECT_EQ(faults.phy_integrity_error, 1);
847  EXPECT_EQ(faults.lifecycle_manager_error, 0);
848  EXPECT_EQ(faults.shadow_storage_error, 1);
849 
850  dif_flash_ctrl_ecc_errors_t ecc_errors;
851  EXPECT_READ32(
852  FLASH_CTRL_ECC_SINGLE_ERR_CNT_REG_OFFSET,
853  {
854  {FLASH_CTRL_ECC_SINGLE_ERR_CNT_ECC_SINGLE_ERR_CNT_0_OFFSET, 7},
855  {FLASH_CTRL_ECC_SINGLE_ERR_CNT_ECC_SINGLE_ERR_CNT_1_OFFSET, 11},
856  });
857  EXPECT_READ32(FLASH_CTRL_ECC_SINGLE_ERR_ADDR_1_REG_OFFSET, 0x16487590u);
859  dif_flash_ctrl_get_ecc_errors(&dif_flash_ctrl_, 1, &ecc_errors));
860  EXPECT_EQ(ecc_errors.single_bit_error_count, 11);
861  EXPECT_EQ(ecc_errors.last_error_address, 0x16487590u);
862 
863  dif_flash_ctrl_phy_status_t phy_status;
864  EXPECT_READ32(FLASH_CTRL_PHY_STATUS_REG_OFFSET,
865  {
866  {FLASH_CTRL_PHY_STATUS_INIT_WIP_BIT, 0},
867  {FLASH_CTRL_PHY_STATUS_PROG_NORMAL_AVAIL_BIT, 1},
868  {FLASH_CTRL_PHY_STATUS_PROG_REPAIR_AVAIL_BIT, 0},
869  });
870  EXPECT_DIF_OK(dif_flash_ctrl_get_phy_status(&dif_flash_ctrl_, &phy_status));
871  EXPECT_EQ(phy_status.phy_init_wip, 0);
872  EXPECT_EQ(phy_status.prog_normal_available, 1);
873  EXPECT_EQ(phy_status.prog_repair_available, 0);
874 
875  uint32_t scratch;
876  EXPECT_READ32(FLASH_CTRL_SCRATCH_REG_OFFSET, 0x89abcdefu);
877  EXPECT_DIF_OK(dif_flash_ctrl_get_scratch(&dif_flash_ctrl_, &scratch));
878  EXPECT_EQ(scratch, 0x89abcdefu);
879 }
880 
881 } // namespace
882 } // namespace dif_flash_ctrl_unittest