Software APIs
flash_ctrl_rma_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 
6 #include "sw/device/lib/base/status.h"
12 #include "sw/device/lib/testing/flash_ctrl_testutils.h"
13 #include "sw/device/lib/testing/otp_ctrl_testutils.h"
14 #include "sw/device/lib/testing/pinmux_testutils.h"
15 #include "sw/device/lib/testing/test_framework/check.h"
16 #include "sw/device/lib/testing/test_framework/ottf_console.h"
17 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
18 #include "sw/device/lib/testing/test_framework/ottf_utils.h"
19 
21 
22 OTTF_DEFINE_TEST_CONFIG(.enable_uart_flow_control = true);
23 
24 volatile uint32_t kTestPhase;
25 volatile uint32_t kEndTest;
26 
27 static dif_pinmux_t pinmux;
28 static dif_flash_ctrl_state_t flash;
29 static dif_otp_ctrl_t otp_ctrl;
30 
31 enum {
32  kFlashInfoBankId = 0,
33  kFlashInfoPartitionId = 0,
34  kFlashInfoPageIdCreatorSecret = 1,
35  kFlashInfoPageIdOwnerSecret = 2,
36  kFlashInfoPageIdIsoPart = 3,
37  kTestPhase0 = 0,
38  kTestPhase1 = 1,
39  kTestPhaseInit = 2,
40  kCommandTimeout = 5000000, // usec
41 };
42 
43 // Hardcoded secret data for flash info partition.
44 static const uint32_t kRandomData[2] = {
45  0xbab0bab1,
46  0xdeadbeef,
47 };
48 
49 static status_t write_info_page(dif_flash_ctrl_state_t *flash, uint32_t page_id,
50  const uint32_t *data, bool scramble) {
51  uint32_t address = 0;
52  if (scramble) {
53  TRY(flash_ctrl_testutils_info_region_scrambled_setup(
54  flash, page_id, kFlashInfoBankId, kFlashInfoPartitionId, &address));
55  } else {
56  TRY(flash_ctrl_testutils_info_region_setup(
57  flash, page_id, kFlashInfoBankId, kFlashInfoPartitionId, &address));
58  }
59 
60  TRY(flash_ctrl_testutils_erase_and_write_page(
61  flash, address, kFlashInfoPartitionId, data,
62  kDifFlashCtrlPartitionTypeInfo, 1));
63 
64  LOG_INFO("wr_info: data:0x%x", *data);
65  return OK_STATUS();
66 }
67 
68 static status_t read_info_page(dif_flash_ctrl_state_t *flash, uint32_t page_id,
69  uint32_t *data, bool scramble) {
70  uint32_t address = 0;
71  if (scramble) {
72  TRY(flash_ctrl_testutils_info_region_scrambled_setup(
73  flash, page_id, kFlashInfoBankId, kFlashInfoPartitionId, &address));
74  } else {
75  TRY(flash_ctrl_testutils_info_region_setup(
76  flash, page_id, kFlashInfoBankId, kFlashInfoPartitionId, &address));
77  }
78 
79  TRY(flash_ctrl_testutils_read(flash, address, kFlashInfoPartitionId, data,
80  kDifFlashCtrlPartitionTypeInfo, 1, 1));
81 
82  return OK_STATUS();
83 }
84 
85 static status_t read_and_check_info(bool match) {
86  uint32_t readback_data[2];
87  read_info_page(&flash, kFlashInfoPageIdOwnerSecret, readback_data, true);
88  read_info_page(&flash, kFlashInfoPageIdIsoPart, readback_data + 1, true);
89  LOG_INFO("readdata0: %x", *readback_data);
90  LOG_INFO("readdata1: %x", *(readback_data + 1));
91  if (match) {
92  // iso partition cannot be accessed in dev state.
93  // check owner partition only
94  CHECK_ARRAYS_EQ(readback_data, kRandomData, 1);
95  } else {
96  CHECK_ARRAYS_NE(readback_data, kRandomData, 2);
97  }
98  LOG_INFO("read_and_check is done");
99  return OK_STATUS();
100 }
101 
102 bool test_main(void) {
103  // Initialize dif handles and pinmux
104  CHECK_DIF_OK(dif_pinmux_init(
106  pinmux_testutils_init(&pinmux);
107  CHECK_DIF_OK(dif_flash_ctrl_init_state(
109  CHECK_DIF_OK(dif_otp_ctrl_init(
111 
112  ottf_console_init();
113 
114  kEndTest = 0;
115  kTestPhase = kTestPhaseInit;
116 
117  // Waiting for uart input from the host.
118  LOG_INFO("Starting test ");
119  OTTF_WAIT_FOR(kEndTest, kCommandTimeout);
120 
121  switch (kTestPhase) {
122  case kTestPhase0:
123  LOG_INFO("testphase0");
124  write_info_page(&flash, kFlashInfoPageIdOwnerSecret, kRandomData, true);
125  write_info_page(&flash, kFlashInfoPageIdIsoPart, kRandomData + 1, true);
126  read_and_check_info(true);
127 
128  // After update info partition in flash,
129  // lock secret2 partition in otp.
130  CHECK_STATUS_OK(otp_ctrl_testutils_lock_partition(
131  &otp_ctrl, kDifOtpCtrlPartitionSecret2, 0));
132  break;
133  case kTestPhase1:
134  LOG_INFO("testphase1");
135  // After RMA, all contents in flash info partition are scrapped.
136  // So expecting read data mismatch.
137  read_and_check_info(false);
138  break;
139  default:
140  LOG_ERROR("unexpected test phase : %d", kTestPhase);
141  break;
142  }
143 
144  // This print is required for host hand shake.
145  LOG_INFO("test_end");
146  return true;
147 }