Software APIs
flash_ctrl_clock_freqs_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 
11 #include "sw/device/lib/testing/flash_ctrl_testutils.h"
12 #include "sw/device/lib/testing/rand_testutils.h"
13 #include "sw/device/lib/testing/test_framework/check.h"
15 
17 #include "otp_ctrl_regs.h"
18 
19 /**
20  * Bitfields for `CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG` and
21  * `CREATOR_SW_CFG_FLASH_INFO_BOOT_DATA_CFG` OTP items.
22  *
23  * Defined here to be able to use in tests.
24  */
25 #define FLASH_CTRL_OTP_FIELD_SCRAMBLING \
26  (bitfield_field32_t) { .mask = UINT8_MAX, .index = CHAR_BIT * 0 }
27 #define FLASH_CTRL_OTP_FIELD_ECC \
28  (bitfield_field32_t) { .mask = UINT8_MAX, .index = CHAR_BIT * 1 }
29 #define FLASH_CTRL_OTP_FIELD_HE \
30  (bitfield_field32_t) { .mask = UINT8_MAX, .index = CHAR_BIT * 2 }
31 
32 OTTF_DEFINE_TEST_CONFIG();
33 
34 enum {
35  kFlashInfoPageIdCreatorSecret = 1,
36  kFlashInfoPageIdOwnerSecret = 2,
37  kFlashInfoPageIdIsoPart = 3,
38  kFlashInfoBank = 0,
39  kFlashDataBank0 = 0,
40  kFlashDataBank1 = 1,
41  kRegionBaseBank0Page0Index = 0,
42  kPartitionId = 0,
43  kRegionSize = 1,
44  kDataSize = 16,
45  kPageSize = 2048,
46  kNumLoops = 10,
47 };
48 
49 static dif_flash_ctrl_device_info_t flash_info;
50 static dif_flash_ctrl_state_t flash_state;
51 static uint32_t test_data[kDataSize];
52 
53 static uint32_t flash_bank_0_data_region;
54 static uint32_t flash_bank_1_data_region;
55 static uint32_t flash_bank_1_page_index;
56 static uint32_t flash_bank_1_page_index_last;
57 
58 /**
59  * Check data read from host interface against known data.
60  */
61 static void read_and_check_host_if(uint32_t addr, const uint32_t *check_data) {
62  mmio_region_t flash_addr =
64  uint32_t host_data[kDataSize];
65  for (int i = 0; i < kDataSize; ++i) {
66  host_data[i] =
67  mmio_region_read32(flash_addr, i * (ptrdiff_t)sizeof(uint32_t));
68  }
69  CHECK_ARRAYS_EQ(host_data, check_data, kDataSize);
70 }
71 
72 /**
73  * Tests the erase, write and
74  * read of the specified information partition.
75  * Confirms that the written data is read back correctly.
76  */
77 static void do_info_partition_test(uint32_t partition_number) {
78  uint32_t address = 0;
79  CHECK_STATUS_OK(flash_ctrl_testutils_info_region_setup(
80  &flash_state, partition_number, kFlashInfoBank, kPartitionId, &address));
81 
82  for (int i = 0; i < kDataSize; ++i) {
83  test_data[i] = rand_testutils_gen32();
84  }
85 
86  CHECK_STATUS_OK(flash_ctrl_testutils_erase_page(
87  &flash_state, address, kPartitionId, kDifFlashCtrlPartitionTypeInfo));
88  CHECK_STATUS_OK(
89  flash_ctrl_testutils_write(&flash_state, address, kPartitionId, test_data,
90  kDifFlashCtrlPartitionTypeInfo, kDataSize));
91 
92  uint32_t readback_data[kDataSize];
93  CHECK_STATUS_OK(flash_ctrl_testutils_read(
94  &flash_state, address, kPartitionId, readback_data,
95  kDifFlashCtrlPartitionTypeInfo, kDataSize, 0));
96 
97  CHECK_ARRAYS_EQ(readback_data, test_data, kDataSize);
98 }
99 
100 /**
101  * Tests the erase, write and read of the lowest and highest page of
102  * bank 1 data partition or the reads for the lowest page of bank 0.
103  * For bank 1 confirms that the written data is read back correctly.
104  */
105 static void do_data_partition_test(uint32_t bank_number) {
106  if (bank_number == 0) {
107  // Bank 0 contains the program data so can only be read and checked
108  // against the host interface read.
109  uint32_t address = 0;
110  uint32_t otp_val = abs_mmio_read32(
112  OTP_CTRL_SW_CFG_WINDOW_REG_OFFSET +
113  OTP_CTRL_PARAM_CREATOR_SW_CFG_FLASH_DATA_DEFAULT_CFG_OFFSET);
114 
115  dif_flash_ctrl_region_properties_t region_properties = {
116  .ecc_en = bitfield_field32_read(otp_val, FLASH_CTRL_OTP_FIELD_ECC),
117  .high_endurance_en =
118  bitfield_field32_read(otp_val, FLASH_CTRL_OTP_FIELD_HE),
119  .scramble_en =
120  bitfield_field32_read(otp_val, FLASH_CTRL_OTP_FIELD_SCRAMBLING),
121  .erase_en = kMultiBitBool4True,
122  .prog_en = kMultiBitBool4True,
123  .rd_en = kMultiBitBool4True};
124 
125  CHECK_STATUS_OK(flash_ctrl_testutils_data_region_setup_properties(
126  &flash_state, kRegionBaseBank0Page0Index, flash_bank_0_data_region,
127  kRegionSize, region_properties, &address));
128 
129  uint32_t readback_data[kDataSize];
130  CHECK_STATUS_OK(flash_ctrl_testutils_read(
131  &flash_state, address, kPartitionId, readback_data,
132  kDifFlashCtrlPartitionTypeData, kDataSize, 0));
133 
134  read_and_check_host_if(kRegionBaseBank0Page0Index, readback_data);
135  } else if (bank_number == 1) {
136  for (int i = 0; i < 2; ++i) {
137  uint32_t page_index =
138  (i == 0) ? flash_bank_1_page_index : flash_bank_1_page_index_last;
139  for (int j = 0; j < kDataSize; ++j) {
140  test_data[i] = rand_testutils_gen32();
141  }
142  uint32_t address = 0;
143  CHECK_STATUS_OK(flash_ctrl_testutils_data_region_setup(
144  &flash_state, page_index, flash_bank_1_data_region, kRegionSize,
145  &address));
146  CHECK_STATUS_OK(flash_ctrl_testutils_erase_page(
147  &flash_state, address, kPartitionId, kDifFlashCtrlPartitionTypeData));
148  CHECK_STATUS_OK(flash_ctrl_testutils_write(
149  &flash_state, address, kPartitionId, test_data,
150  kDifFlashCtrlPartitionTypeData, kDataSize));
151 
152  uint32_t readback_data[kDataSize];
153  CHECK_STATUS_OK(flash_ctrl_testutils_read(
154  &flash_state, address, kPartitionId, readback_data,
155  kDifFlashCtrlPartitionTypeData, kDataSize, 1));
156  read_and_check_host_if(kPageSize * page_index, test_data);
157  CHECK_ARRAYS_EQ(readback_data, test_data, kDataSize);
158  }
159  } else {
160  LOG_ERROR("Unexpected bank number, only 0 and 1 are valid.");
161  }
162 }
163 
164 bool test_main(void) {
165  flash_info = dif_flash_ctrl_get_device_info();
166 
167  // Determine the region index and page index to use for tests.
168  // Test data page used for flash bank 1 should be the lowest and highest
169  // usable page.
170  if (kBootStage != kBootStageOwner) {
171  flash_bank_0_data_region = 0;
172  flash_bank_1_page_index = flash_info.data_pages;
173  } else {
174  // If we boot up in owner stage, the first 2 regions will be used by
175  // ROM_EXT.
176  flash_bank_0_data_region = 2;
177  // First 0x20 pages are configured by ROM_EXT. To avoid conflicts, skip over
178  // these pages.
179  flash_bank_1_page_index = flash_info.data_pages + 0x20;
180  }
181  flash_bank_1_data_region = flash_bank_0_data_region + 1;
182  flash_bank_1_page_index_last = flash_info.data_pages * 2 - 1;
183 
184  dif_clkmgr_t clkmgr;
185  CHECK_DIF_OK(dif_clkmgr_init(
187 
188  CHECK_DIF_OK(dif_clkmgr_jitter_set_enabled(&clkmgr, kDifToggleEnabled));
189 
190  CHECK_DIF_OK(dif_flash_ctrl_init_state(
191  &flash_state,
193 
194  for (int i = 0; i < kNumLoops; ++i) {
195  if (kBootStage != kBootStageOwner) {
196  do_info_partition_test(kFlashInfoPageIdCreatorSecret);
197  do_info_partition_test(kFlashInfoPageIdOwnerSecret);
198  do_info_partition_test(kFlashInfoPageIdIsoPart);
199  do_data_partition_test(kFlashDataBank0);
200  }
201  do_data_partition_test(kFlashDataBank1);
202  }
203 
204  return true;
205 }