Software APIs
sram_cp_provision.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 
5 #include <stdint.h>
6 
14 #include "sw/device/lib/testing/flash_ctrl_testutils.h"
15 #include "sw/device/lib/testing/json/provisioning_data.h"
16 #include "sw/device/lib/testing/lc_ctrl_testutils.h"
17 #include "sw/device/lib/testing/otp_ctrl_testutils.h"
18 #include "sw/device/lib/testing/pinmux_testutils.h"
19 #include "sw/device/lib/testing/test_framework/check.h"
20 #include "sw/device/lib/testing/test_framework/ottf_console.h"
21 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
22 #include "sw/device/lib/testing/test_framework/ujson_ottf.h"
23 #include "sw/device/silicon_creator/manuf/base/flash_info_permissions.h"
24 #include "sw/device/silicon_creator/manuf/data/ast/calibration_values.h"
25 #include "sw/device/silicon_creator/manuf/lib/flash_info_fields.h"
26 #include "sw/device/silicon_creator/manuf/lib/individualize.h"
27 #include "sw/device/silicon_creator/manuf/lib/otp_fields.h"
28 
30 #include "otp_ctrl_regs.h" // Generated.
31 
32 OTTF_DEFINE_TEST_CONFIG(.console.type = kOttfConsoleSpiDevice,
33  .console.base_addr = TOP_EARLGREY_SPI_DEVICE_BASE_ADDR,
34  .console.test_may_clobber = false, );
35 
36 static dif_otp_ctrl_t otp_ctrl;
37 static dif_pinmux_t pinmux;
38 static dif_flash_ctrl_state_t flash_ctrl_state;
39 static dif_lc_ctrl_t lc_ctrl;
40 
41 /**
42  * Initializes all DIF handles used in this SRAM program.
43  */
44 static status_t peripheral_handles_init(void) {
46  &flash_ctrl_state,
48  TRY(dif_lc_ctrl_init(
50  TRY(dif_otp_ctrl_init(
53  &pinmux));
54  return OK_STATUS();
55 }
56 
57 static void manually_init_ast(uint32_t *data) {
58  for (size_t i = 0; i < kFlashInfoAstCalibrationDataSizeIn32BitWords; ++i) {
59  abs_mmio_write32(TOP_EARLGREY_AST_BASE_ADDR + i * sizeof(uint32_t),
60  data[i]);
61  }
62 }
63 
64 static status_t flash_info_page_0_erase(void) {
65  uint32_t byte_address = 0;
66  // DeviceId and ManufState are located on the same flash info page.
67  TRY(flash_ctrl_testutils_info_region_setup_properties(
68  &flash_ctrl_state, kFlashInfoFieldDeviceId.page,
69  kFlashInfoFieldDeviceId.bank, kFlashInfoFieldDeviceId.partition,
70  kFlashInfoPage0Permissions, &byte_address));
71  TRY(flash_ctrl_testutils_erase_page(&flash_ctrl_state, byte_address,
72  kFlashInfoFieldDeviceId.partition,
73  kDifFlashCtrlPartitionTypeInfo));
74  return OK_STATUS();
75 }
76 
77 static status_t flash_info_page_0_write(
78  manuf_cp_provisioning_data_t *provisioning_data) {
79  uint32_t byte_address = 0;
80  TRY(flash_ctrl_testutils_info_region_setup_properties(
81  &flash_ctrl_state, kFlashInfoFieldDeviceId.page,
82  kFlashInfoFieldDeviceId.bank, kFlashInfoFieldDeviceId.partition,
83  kFlashInfoPage0Permissions, &byte_address));
84 
85  // Write DeviceId.
86  TRY(flash_ctrl_testutils_write(
87  &flash_ctrl_state, byte_address, kFlashInfoFieldDeviceId.partition,
88  provisioning_data->device_id, kDifFlashCtrlPartitionTypeInfo,
89  kHwCfgDeviceIdSizeIn32BitWords));
90 
91  // Write ManufState (on same page as DeviceId).
92  TRY(flash_ctrl_testutils_write(
93  &flash_ctrl_state, byte_address + kFlashInfoFieldManufState.byte_offset,
94  kFlashInfoFieldManufState.partition, provisioning_data->manuf_state,
95  kDifFlashCtrlPartitionTypeInfo, kHwCfgManufStateSizeIn32BitWords));
96 
97  // Write AST calibration values (on same page as DeviceId).
98  TRY(flash_ctrl_testutils_write(
99  &flash_ctrl_state,
100  byte_address + kFlashInfoFieldAstCalibrationData.byte_offset,
101  kFlashInfoFieldAstCalibrationData.partition, ast_cfg_data,
102  kDifFlashCtrlPartitionTypeInfo,
103  kFlashInfoAstCalibrationDataSizeIn32BitWords));
104 
105  return OK_STATUS();
106 }
107 
108 static status_t wafer_auth_secret_flash_info_page_erase(void) {
109  uint32_t byte_address = 0;
110  TRY(flash_ctrl_testutils_info_region_setup_properties(
111  &flash_ctrl_state, kFlashInfoFieldWaferAuthSecret.page,
112  kFlashInfoFieldWaferAuthSecret.bank,
113  kFlashInfoFieldWaferAuthSecret.partition, kFlashInfoPage3WritePermissions,
114  &byte_address));
115  TRY(flash_ctrl_testutils_erase_page(&flash_ctrl_state, byte_address,
116  kFlashInfoFieldWaferAuthSecret.partition,
117  kDifFlashCtrlPartitionTypeInfo));
118  return OK_STATUS();
119 }
120 
121 static status_t wafer_auth_secret_flash_info_page_write(
122  manuf_cp_provisioning_data_t *provisioning_data) {
123  uint32_t byte_address = 0;
124  TRY(flash_ctrl_testutils_info_region_setup_properties(
125  &flash_ctrl_state, kFlashInfoFieldWaferAuthSecret.page,
126  kFlashInfoFieldWaferAuthSecret.bank,
127  kFlashInfoFieldWaferAuthSecret.partition, kFlashInfoPage3WritePermissions,
128  &byte_address));
129  TRY(flash_ctrl_testutils_write(
130  &flash_ctrl_state, byte_address, kFlashInfoFieldWaferAuthSecret.partition,
131  provisioning_data->manuf_state, kDifFlashCtrlPartitionTypeInfo,
132  kFlashInfoWaferAuthSecretSizeIn32BitWords));
133  return OK_STATUS();
134 }
135 
136 static status_t print_inputs_to_console(
137  manuf_cp_provisioning_data_t *provisioning_data) {
138  uint32_t high;
139  uint32_t low;
140 
141  LOG_INFO("Device ID:");
142  for (size_t i = 0; i < kHwCfgDeviceIdSizeIn32BitWords; ++i) {
143  LOG_INFO("0x%08x", provisioning_data->device_id[i]);
144  }
145  LOG_INFO("Test Unlock Token Hash:");
146  for (size_t i = 0; i < ARRAYSIZE(provisioning_data->test_unlock_token_hash);
147  ++i) {
148  high = provisioning_data->test_unlock_token_hash[i] >> 32;
149  low = provisioning_data->test_unlock_token_hash[i] & 0xffffffff;
150  LOG_INFO("0x%08x%08x", high, low);
151  }
152  LOG_INFO("Test Exit Token Hash:");
153  for (size_t i = 0; i < ARRAYSIZE(provisioning_data->test_exit_token_hash);
154  ++i) {
155  high = provisioning_data->test_exit_token_hash[i] >> 32;
156  low = provisioning_data->test_exit_token_hash[i] & 0xffffffff;
157  LOG_INFO("0x%08x%08x", high, low);
158  }
159  return OK_STATUS();
160 }
161 
162 /**
163  * Provision flash info pages 0 and 3, and OTP Secret0 partition.
164  */
165 static status_t provision(ujson_t *uj) {
166  LOG_INFO("Waiting for CP provisioning data ...");
167  manuf_cp_provisioning_data_t provisioning_data;
168  TRY(ujson_deserialize_manuf_cp_provisioning_data_t(uj, &provisioning_data));
169  TRY(print_inputs_to_console(&provisioning_data));
170  TRY(flash_ctrl_testutils_wait_for_init(&flash_ctrl_state));
171  TRY(flash_info_page_0_erase());
172  TRY(wafer_auth_secret_flash_info_page_erase());
173  TRY(flash_info_page_0_write(&provisioning_data));
174  TRY(wafer_auth_secret_flash_info_page_write(&provisioning_data));
175  TRY(manuf_individualize_device_secret0(&lc_ctrl, &otp_ctrl,
176  &provisioning_data));
177  LOG_INFO("CP provisioning done.");
178  return OK_STATUS();
179 }
180 
181 bool test_main(void) {
182  // Initialize AST, DIF handles, pinmux, and UART.
183  manually_init_ast(ast_cfg_data);
184  CHECK_STATUS_OK(peripheral_handles_init());
185  pinmux_testutils_init(&pinmux);
186  ottf_console_init();
187  ujson_t uj = ujson_ottf_console();
188  LOG_INFO("AST manually configured.");
189 
190  // Perform CP provisioning operations.
191  CHECK_STATUS_OK(provision(&uj));
192 
193  return true;
194 }