5 #include "sw/device/silicon_creator/rom_ext/rescue.h"
9 #include "sw/device/silicon_creator/lib/boot_data.h"
10 #include "sw/device/silicon_creator/lib/dbg_print.h"
11 #include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
12 #include "sw/device/silicon_creator/lib/drivers/lifecycle.h"
13 #include "sw/device/silicon_creator/lib/drivers/retention_sram.h"
14 #include "sw/device/silicon_creator/lib/drivers/rstmgr.h"
15 #include "sw/device/silicon_creator/lib/drivers/uart.h"
16 #include "sw/device/silicon_creator/lib/ownership/datatypes.h"
17 #include "sw/device/silicon_creator/lib/ownership/owner_block.h"
18 #include "sw/device/silicon_creator/lib/xmodem.h"
20 #include "flash_ctrl_regs.h"
27 const uint32_t kFlashPageSize = FLASH_CTRL_PARAM_BYTES_PER_PAGE;
28 const uint32_t kFlashBankSize =
29 kFlashPageSize * FLASH_CTRL_PARAM_REG_PAGES_PER_BANK;
33 uint32_t bank_offset =
34 state->mode == kRescueModeFirmwareSlotB ? kFlashBankSize : 0;
35 if (state->flash_offset == 0) {
39 .read = kMultiBitBool4True,
40 .write = kMultiBitBool4True,
41 .erase = kMultiBitBool4True,
43 for (uint32_t addr = state->flash_start; addr < state->flash_limit;
44 addr += kFlashPageSize) {
45 HARDENED_RETURN_IF_ERROR(
46 flash_ctrl_data_erase(bank_offset + addr, kFlashCtrlEraseTypePage));
48 state->flash_offset = state->flash_start;
50 if (state->flash_offset < state->flash_limit) {
51 HARDENED_RETURN_IF_ERROR(flash_ctrl_data_write(
52 bank_offset + state->flash_offset,
53 sizeof(state->data) /
sizeof(uint32_t), state->data));
54 state->flash_offset +=
sizeof(state->data);
56 xmodem_cancel(iohandle);
57 return kErrorRescueImageTooBig;
68 HARDENED_RETURN_IF_ERROR(flash_ctrl_info_erase(
69 &kFlashCtrlInfoPageOwnerSlot1, kFlashCtrlEraseTypePage));
70 HARDENED_RETURN_IF_ERROR(flash_ctrl_info_write(
71 &kFlashCtrlInfoPageOwnerSlot1, 0,
72 sizeof(state->data) /
sizeof(uint32_t), state->data));
74 dbg_printf(
"error: cannot accept owner_block in current state\r\n");
79 static void change_speed(
void) {
80 dbg_printf(
"ok: waiting for baudrate\r\n");
82 OT_DISCARD(uart_read((uint8_t *)&speed,
sizeof(speed), 10000));
100 case kRescueBaud1M50:
107 dbg_printf(
"ok: new baudrate %C\r\n", speed);
109 uart_enable_receiver();
111 dbg_printf(
"error: unsupported baudrate %C\r\n", speed);
115 #ifdef ROM_EXT_KLOBBER_ALLOWED
122 static void ownership_erase(
void) {
123 lifecycle_state_t lc_state = lifecycle_state_get();
124 if (lc_state == kLcStateDev) {
125 OT_DISCARD(flash_ctrl_info_erase(&kFlashCtrlInfoPageOwnerSlot0,
126 kFlashCtrlEraseTypePage));
127 OT_DISCARD(flash_ctrl_info_erase(&kFlashCtrlInfoPageOwnerSlot1,
128 kFlashCtrlEraseTypePage));
129 dbg_printf(
"ok: erased owner blocks\r\n");
131 dbg_printf(
"error: erase not allowed in state %x\r\n", lc_state);
143 case kRescueModeBaud:
146 case kRescueModeReboot:
147 dbg_printf(
"ok: reboot\r\n");
148 state->mode = (rescue_mode_t)mode;
150 case kRescueModeWait:
151 dbg_printf(
"ok: wait after upload\r\n");
152 state->reboot =
false;
154 #ifdef ROM_EXT_KLOBBER_ALLOWED
155 case kRescueModeKlobber:
163 hardened_bool_t allow = owner_rescue_command_allowed(state->config, mode);
166 case kRescueModeBootLog:
167 dbg_printf(
"ok: receive boot_log via xmodem-crc\r\n");
169 case kRescueModeBootSvcRsp:
170 dbg_printf(
"ok: receive boot_svc response via xmodem-crc\r\n");
172 case kRescueModeBootSvcReq:
173 dbg_printf(
"ok: send boot_svc request via xmodem-crc\r\n");
175 case kRescueModeOwnerBlock:
181 dbg_printf(
"ok: send owner_block via xmodem-crc\r\n");
183 dbg_printf(
"error: cannot accept owner_block in current state\r\n");
187 case kRescueModeFirmware:
188 case kRescueModeFirmwareSlotB:
189 dbg_printf(
"ok: send firmware via xmodem-crc\r\n");
191 case kRescueModeOwnerPage0:
192 case kRescueModeOwnerPage1:
193 dbg_printf(
"ok: receive owner page via xmodem-crc\r\n");
195 case kRescueModeOpenTitanID:
196 dbg_printf(
"ok: receive device ID via xmodem-crc\r\n");
200 dbg_printf(
"error: unrecognized mode\r\n");
203 state->mode = (rescue_mode_t)mode;
205 dbg_printf(
"error: mode not allowed\r\n");
210 state->flash_offset = 0;
216 owner_rescue_command_allowed(state->config, state->mode);
218 return kErrorRescueBadMode;
222 switch (state->mode) {
223 case kRescueModeBootLog:
227 case kRescueModeBootSvcRsp:
231 case kRescueModeOpenTitanID: {
233 lifecycle_device_id_get(&
id);
234 HARDENED_RETURN_IF_ERROR(xmodem_send(iohandle, &
id,
sizeof(
id)));
237 case kRescueModeOwnerPage0:
238 case kRescueModeOwnerPage1:
239 HARDENED_RETURN_IF_ERROR(flash_ctrl_info_read(
240 state->mode == kRescueModeOwnerPage0 ? &kFlashCtrlInfoPageOwnerSlot0
241 : &kFlashCtrlInfoPageOwnerSlot1,
242 0,
sizeof(state->data) /
sizeof(uint32_t), state->data));
243 HARDENED_RETURN_IF_ERROR(
244 xmodem_send(iohandle, state->data,
sizeof(state->data)));
247 case kRescueModeBootSvcReq:
248 case kRescueModeOwnerBlock:
249 case kRescueModeFirmware:
250 case kRescueModeFirmwareSlotB:
253 case kRescueModeReboot:
256 return kErrorRescueReboot;
259 return kErrorRescueBadMode;
261 validate_mode(kRescueModeFirmware, state, bootdata);
268 owner_rescue_command_allowed(state->config, state->mode);
270 xmodem_cancel(iohandle);
271 return kErrorRescueBadMode;
275 switch (state->mode) {
276 case kRescueModeBootLog:
277 case kRescueModeBootSvcRsp:
278 case kRescueModeOpenTitanID:
279 case kRescueModeOwnerPage0:
280 case kRescueModeOwnerPage1:
283 case kRescueModeBootSvcReq:
286 allow = owner_rescue_command_allowed(state->config, msg->
header.
type);
288 xmodem_cancel(iohandle);
289 return kErrorRescueBadMode;
296 case kRescueModeOwnerBlock:
297 if (state->offset ==
sizeof(state->data)) {
298 HARDENED_RETURN_IF_ERROR(flash_owner_block(state, bootdata));
302 case kRescueModeFirmware:
303 case kRescueModeFirmwareSlotB:
304 if (state->offset ==
sizeof(state->data)) {
305 HARDENED_RETURN_IF_ERROR(flash_firmware_block(state));
309 case kRescueModeReboot:
312 return kErrorRescueBadMode;
321 uint32_t next_mode = 0;
323 state->reboot =
true;
324 validate_mode(kRescueModeFirmware, &rescue_state, bootdata);
326 xmodem_recv_start(iohandle);
328 HARDENED_RETURN_IF_ERROR(handle_send_modes(&rescue_state, bootdata));
329 result = xmodem_recv_frame(iohandle, state->frame,
330 state->data + state->offset, &rxlen, &command);
331 if (state->frame == 1 && result == kErrorXModemTimeoutStart) {
332 xmodem_recv_start(iohandle);
338 state->offset += rxlen;
339 HARDENED_RETURN_IF_ERROR(handle_recv_modes(&rescue_state, bootdata));
340 xmodem_ack(iohandle,
true);
342 case kErrorXModemEndOfFile:
343 if (state->offset % 2048 != 0) {
346 while (state->offset % 2048 != 0) {
347 state->data[state->offset++] = 0xFF;
349 HARDENED_RETURN_IF_ERROR(handle_recv_modes(&rescue_state, bootdata));
351 xmodem_ack(iohandle,
true);
352 if (!state->reboot) {
355 state->flash_offset = 0;
358 return kErrorRescueReboot;
359 case kErrorXModemCrc:
360 xmodem_ack(iohandle,
false);
362 case kErrorXModemCancel:
364 case kErrorXModemUnknown:
365 if (state->frame == 1) {
366 if (command ==
'\r') {
367 validate_mode(next_mode, &rescue_state, bootdata);
370 next_mode = (next_mode << 8) | command;
384 rescue_state.config = config;
389 rescue_state.flash_start = CHIP_ROM_EXT_SIZE_MAX;
390 rescue_state.flash_limit = kFlashBankSize;
392 rescue_state.flash_start = (uint32_t)config->
start * kFlashPageSize;
393 rescue_state.flash_limit =
394 (uint32_t)(config->
start + config->
size) * kFlashPageSize;
396 rom_error_t result = protocol(&rescue_state, bootdata);
397 if (result == kErrorRescueReboot) {