8 #include "dt/dt_rstmgr.h"
9 #include "dt/dt_sram_ctrl.h"
12 #include "sw/device/lib/base/multibits.h"
16 #include "sw/device/lib/testing/rand_testutils.h"
17 #include "sw/device/lib/testing/rstmgr_testutils.h"
18 #include "sw/device/lib/testing/sram_ctrl_testutils.h"
19 #include "sw/device/lib/testing/test_framework/check.h"
21 #include "sw/device/lib/testing/test_framework/ottf_utils.h"
23 #include "rstmgr_regs.h"
24 #include "sram_ctrl_regs.h"
26 OTTF_DEFINE_TEST_CONFIG();
32 #if defined(OPENTITAN_IS_EARLGREY)
36 #elif defined(OPENTITAN_IS_DARJEELING)
37 kRetSramBaseAddr = TOP_DARJEELING_SRAM_CTRL_RET_AON_RAM_BASE_ADDR,
39 kRetSramBaseAddr + TOP_DARJEELING_SRAM_CTRL_RET_AON_RAM_SIZE_BYTES - 1,
41 #error Unsupported top
45 kRetSramOwnerAddr = kRetSramBaseAddr + 4 + 2048,
47 kTestBufferSizeWords = 16,
48 kTestBufferSizeBytes = kTestBufferSizeWords *
sizeof(uint32_t),
94 kEccErrorsFalsePositiveFloorLimit = 3,
97 static_assert(kTestBufferSizeWords == 16,
98 "kBackdoorTestWords changed, so "
99 "kEccErrorsFalsePositiveFloorLimit should be "
103 uint32_t pattern[kTestBufferSizeWords];
104 uint32_t backdoor[kTestBufferSizeWords];
105 uint32_t ecc_error_counter;
111 static dif_sram_ctrl_t ret_sram;
112 static dif_rstmgr_t rstmgr;
117 static const uint32_t kRamTestPattern1[kTestBufferSizeWords] = {
118 0xA5A5A5A5, 0xA23DE94C, 0xD82A4FB0, 0xE3CA4D62, 0xA5A5A5A5, 0xA23DE94C,
119 0xD82A4FB0, 0xE3CA4D62, 0xA5A5A5A5, 0xA23DE94C, 0xD82A4FB0, 0xE3CA4D62,
120 0xA5A5A5A5, 0xA23DE94C, 0xD82A4FB0, 0xE3CA4D62,
126 static const uint32_t kRamTestPattern2[kTestBufferSizeWords] = {
127 0x5A5A5A5A, 0x3CFB4A77, 0x304C6528, 0xFAEFD5CC, 0x5A5A5A5A, 0x3CFB4A77,
128 0x304C6528, 0xFAEFD5CC, 0x5A5A5A5A, 0x3CFB4A77, 0x304C6528, 0xFAEFD5CC,
129 0x5A5A5A5A, 0x3CFB4A77, 0x304C6528, 0xFAEFD5CC,
135 static const uint8_t kBackdoorExpectedBytes[kTestBufferSizeBytes];
149 static noreturn
void main_sram_scramble(
void) {
151 uint32_t copy_len =
sizeof(reference_frame->pattern);
156 copy_len +=
sizeof(reference_frame->backdoor);
161 "lw a2, 0(%[mainFrame]) \n"
162 "lw a3, 0(%[retFrame]) \n"
165 "sw t0, %[kSramCtrlOffset](%[kSramCtrlRegsBase]) \n"
168 ".L_scrambling_busy_loop: \n"
169 " lw t0, %[kSramCtrlStatusOffset](%[kSramCtrlRegsBase]) \n"
170 " andi t0, t0, %[kSramCtrlKeyScrDone] \n"
171 " beqz t0, .L_scrambling_busy_loop \n"
174 "sw a2, 0(%[mainFrame]) \n"
175 "sw a3, 0(%[retFrame]) \n"
178 "add t1, a3, %[kCopyLen] \n"
179 ".L_buffer_copy_loop: \n"
184 " blt a3, t1, .L_buffer_copy_loop \n"
187 "li t0, %[kMultiBitTrue] \n"
188 "sw t0, %[kRstMgrResetReq](%[kRstMgrRegsBase]) \n"
191 ".L_infinite_loop: \n"
193 " j .L_infinite_loop"
195 : [kMultiBitTrue]
"I"(kMultiBitBool4True),
197 [kSramCtrlRegsBase]
"r"(
198 dt_sram_ctrl_primary_reg_block(kDtSramCtrlMain)),
199 [kSramCtrlOffset]
"I"(SRAM_CTRL_CTRL_REG_OFFSET),
200 [kSramCtrlStatusOffset]
"I"(SRAM_CTRL_STATUS_REG_OFFSET),
202 [kSramCtrlKeyScrDone]
"I"(0x1 << SRAM_CTRL_STATUS_SCR_KEY_VALID_BIT),
204 [mainFrame]
"r"(&scrambling_frame), [retFrame]
"r"(&reference_frame),
205 [kCopyLen]
"r"(copy_len),
207 [kRstMgrRegsBase]
"r"(dt_rstmgr_primary_reg_block(kDtRstmgrAon)),
208 [kRstMgrResetReq]
"I"(RSTMGR_RESET_REQ_REG_OFFSET)
209 :
"t0",
"t1",
"a2",
"a3");
220 static void prepare_sram_for_scrambling(
void) {
221 LOG_INFO(
"Writing to addr 0x%x", scrambling_frame->pattern);
223 sram_ctrl_testutils_write(
224 (uint32_t)scrambling_frame->pattern,
226 .len = kTestBufferSizeWords});
227 sram_ctrl_testutils_write(
228 (uint32_t)scrambling_frame->pattern,
230 .len = kTestBufferSizeWords});
232 LOG_INFO(
"Checking addr 0x%x", scrambling_frame->pattern);
233 CHECK_ARRAYS_EQ(scrambling_frame->pattern, kRamTestPattern1,
234 kTestBufferSizeWords);
236 LOG_INFO(
"Writing to addr 0x%x", reference_frame->pattern);
238 sram_ctrl_testutils_write(
239 (uint32_t)reference_frame->pattern,
241 .len = kTestBufferSizeWords});
242 sram_ctrl_testutils_write(
243 (uint32_t)reference_frame->pattern,
245 .len = kTestBufferSizeWords});
246 LOG_INFO(
"Checking addr 0x%x", reference_frame->pattern);
247 CHECK_ARRAYS_EQ(reference_frame->pattern, kRamTestPattern2,
248 kTestBufferSizeWords);
251 static void execute_main_sram_test(
void) {
252 LOG_INFO(
"ut_backdoor: %x,ut_pattern: %x,ut_ecc_error_counter: %x",
253 scrambling_frame->backdoor, scrambling_frame->pattern,
254 &scrambling_frame->ecc_error_counter);
255 LOG_INFO(
"ref_backdoor: %x,ref_pattern: %x,ref_ecc_error_counter: %x",
256 reference_frame->backdoor, reference_frame->pattern,
257 &reference_frame->ecc_error_counter);
259 reference_frame->ecc_error_counter = 0;
262 prepare_sram_for_scrambling();
264 main_sram_scramble();
268 LOG_INFO(
"Checking addr 0x%x", mem_frame->pattern);
269 uint32_t tmp_buffer[kTestBufferSizeWords];
270 memcpy(tmp_buffer, (
const uint8_t *)mem_frame->pattern,
sizeof(tmp_buffer));
272 CHECK_ARRAYS_NE((uint32_t *)tmp_buffer, kRamTestPattern1,
273 kTestBufferSizeWords);
274 CHECK_ARRAYS_NE((uint32_t *)tmp_buffer, kRamTestPattern2,
275 kTestBufferSizeWords);
283 bool check_ecc_errors =
false;
287 check_ecc_errors =
false;
293 check_ecc_errors =
true;
296 CHECK(
false,
"Device type not handled: %d",
kDeviceType);
300 if (check_ecc_errors) {
301 LOG_INFO(
"Checking ECC error count of %d",
302 reference_frame->ecc_error_counter);
303 CHECK(reference_frame->ecc_error_counter <= kTestBufferSizeWords);
308 uint32_t false_positives =
309 kTestBufferSizeWords - reference_frame->ecc_error_counter;
311 CHECK(false_positives <= kEccErrorsFalsePositiveFloorLimit,
312 "Too many expected ECC errors failed to trigger (%d > %d)",
313 false_positives, kEccErrorsFalsePositiveFloorLimit);
315 if (false_positives > 0) {
316 LOG_INFO(
"Passing with remark: %d words didn't give expected ECC errors",
324 LOG_INFO(
"Checking backdoor 0x%x", mem_frame->backdoor);
325 uint32_t kBackdoorExpectedWords[kTestBufferSizeWords];
326 memcpy(kBackdoorExpectedWords, kBackdoorExpectedBytes,
327 kTestBufferSizeBytes);
329 CHECK_ARRAYS_EQ(mem_frame->backdoor, kBackdoorExpectedWords,
330 kTestBufferSizeWords);
333 CHECK_ARRAYS_NE(mem_frame->pattern, kRamTestPattern2, kTestBufferSizeWords);
337 static void execute_retention_sram_test(
void) {
338 LOG_INFO(
"Wiping retention sram...");
342 prepare_sram_for_scrambling();
345 CHECK_STATUS_OK(sram_ctrl_testutils_scramble(&ret_sram));
352 void ottf_internal_isr(uint32_t *exc_info) {
353 reference_frame->ecc_error_counter++;
356 typedef enum test_phases {
358 kTestPhaseMainSramScramble,
359 kTestPhaseMainSramCheck,
360 kTestPhaseRetSramScramble,
361 kTestPhaseRetSramCheck,
366 static volatile const uint8_t kTestPhase = kTestPhaseSetup;
367 const uint32_t kTestPhaseTimeoutUsec = 2500;
379 static status_t sync_testbench(uint8_t prior_phase, uint8_t next_phase) {
383 test_status_set(kTestStatusInWfi);
384 test_status_set(kTestStatusInTest);
387 kTestPhaseTimeoutUsec);
389 TRY_CHECK(kTestPhase == next_phase);
445 uint32_t main_sram_addr;
446 uint32_t ret_sram_addr;
448 extern uint8_t _stack_start[];
449 extern uint8_t _freertos_heap_start[];
452 CHECK_DIF_OK(dif_rstmgr_init_from_dt(kDtRstmgrAon, &rstmgr));
454 CHECK_DIF_OK(dif_sram_ctrl_init_from_dt(kDtSramCtrlRetAon, &ret_sram));
456 main_sram_addr =
OT_ALIGN_MEM(rand_testutils_gen32_range(
457 (uintptr_t)_freertos_heap_start,
468 uint8_t current_phase = kTestPhase;
470 LOG_INFO(
"RET_SRAM addr: %x MAIN_SRAM addr: %x", ret_sram_addr,
472 CHECK_STATUS_OK(sync_testbench(current_phase, kTestPhaseMainSramScramble));
473 LOG_INFO(
"First boot, testing main sram");
475 execute_main_sram_test();
478 CHECK_STATUS_OK(sync_testbench(current_phase, kTestPhaseMainSramCheck));
479 LOG_INFO(
"Second boot, checking main sram");
481 check_sram_data(reference_frame);
484 ret_sram_addr =
OT_ALIGN_MEM(rand_testutils_gen32_range(
486 LOG_INFO(
"RET_SRAM addr: %x MAIN_SRAM addr: %x", ret_sram_addr,
488 CHECK_STATUS_OK(sync_testbench(current_phase, kTestPhaseRetSramScramble));
493 execute_retention_sram_test();
495 CHECK_STATUS_OK(sync_testbench(current_phase, kTestPhaseRetSramCheck));
496 LOG_INFO(
"Checking retention sram");
499 reference_frame->ecc_error_counter = 0;
500 check_sram_data(scrambling_frame);