5 #include "sw/device/silicon_creator/lib/bootstrap.h" 
   13 #include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h" 
   14 #include "sw/device/silicon_creator/lib/drivers/rstmgr.h" 
   15 #include "sw/device/silicon_creator/lib/drivers/spi_device.h" 
   16 #include "sw/device/silicon_creator/lib/error.h" 
   17 #include "sw/device/silicon_creator/lib/stack_utilization.h" 
   19 #include "flash_ctrl_regs.h" 
   26       FLASH_CTRL_PARAM_BYTES_PER_BANK * FLASH_CTRL_PARAM_REG_NUM_BANKS,
 
   29 static_assert(FLASH_CTRL_PARAM_REG_NUM_BANKS == 2, 
"Flash must have 2 banks");
 
   46 typedef enum bootstrap_state {
 
   51   kBootstrapStateErase = 0xd4576543,
 
   56   kBootstrapStateEraseVerify = 0xf3c71bac,
 
   61   kBootstrapStateProgram = 0xbdd8ca60,
 
   75 static rom_error_t bootstrap_sector_erase(uint32_t addr) {
 
   76   static_assert(FLASH_CTRL_PARAM_BYTES_PER_PAGE == 2048,
 
   77                 "Page size must be 2 KiB");
 
   82     kPageAddrMask = ~UINT32_C(4096) + 1,
 
   85   if (addr >= kMaxAddress) {
 
   86     return kErrorBootstrapEraseAddress;
 
   88   addr &= kPageAddrMask;
 
   91       .read = kMultiBitBool4False,
 
   92       .write = kMultiBitBool4False,
 
   93       .erase = kMultiBitBool4True,
 
   95   rom_error_t err_0 = flash_ctrl_data_erase(addr, kFlashCtrlEraseTypePage);
 
   96   rom_error_t err_1 = flash_ctrl_data_erase(
 
   97       addr + FLASH_CTRL_PARAM_BYTES_PER_PAGE, kFlashCtrlEraseTypePage);
 
   99       .read = kMultiBitBool4False,
 
  100       .write = kMultiBitBool4False,
 
  101       .erase = kMultiBitBool4False,
 
  104   HARDENED_RETURN_IF_ERROR(err_0);
 
  124 static rom_error_t bootstrap_page_program(uint32_t addr, 
size_t byte_count,
 
  126   static_assert(__builtin_popcount(FLASH_CTRL_PARAM_BYTES_PER_WORD) == 1,
 
  127                 "Bytes per flash word must be a power of two.");
 
  132     kFlashWordMask = FLASH_CTRL_PARAM_BYTES_PER_WORD - 1,
 
  136     kFlashProgPageSize = 256,
 
  143     kFlashProgPageMask = kFlashProgPageSize - 1,
 
  146   if (addr & kFlashWordMask || addr >= kMaxAddress) {
 
  147     return kErrorBootstrapProgramAddress;
 
  151   size_t flash_word_misalignment = byte_count & kFlashWordMask;
 
  152   if (flash_word_misalignment > 0) {
 
  153     size_t padding_byte_count =
 
  154         FLASH_CTRL_PARAM_BYTES_PER_WORD - flash_word_misalignment;
 
  155     for (
size_t i = 0; i < padding_byte_count; ++i) {
 
  156       data[byte_count++] = 0xff;
 
  159   size_t rem_word_count = byte_count / 
sizeof(uint32_t);
 
  162       .read = kMultiBitBool4False,
 
  163       .write = kMultiBitBool4True,
 
  164       .erase = kMultiBitBool4False,
 
  168   rom_error_t err_0 = kErrorOk;
 
  169   size_t prog_page_misalignment = addr & kFlashProgPageMask;
 
  170   if (prog_page_misalignment > 0) {
 
  172         (kFlashProgPageSize - prog_page_misalignment) / 
sizeof(uint32_t);
 
  173     if (word_count > rem_word_count) {
 
  174       word_count = rem_word_count;
 
  176     err_0 = flash_ctrl_data_write(addr, word_count, data);
 
  177     rem_word_count -= word_count;
 
  178     data += word_count * 
sizeof(uint32_t);
 
  181     addr &= ~(uint32_t)kFlashProgPageMask;
 
  183   rom_error_t err_1 = kErrorOk;
 
  184   if (rem_word_count > 0) {
 
  185     err_1 = flash_ctrl_data_write(addr, rem_word_count, data);
 
  188       .read = kMultiBitBool4False,
 
  189       .write = kMultiBitBool4False,
 
  190       .erase = kMultiBitBool4False,
 
  193   HARDENED_RETURN_IF_ERROR(err_0);
 
  208 static rom_error_t bootstrap_handle_erase(bootstrap_state_t *state) {
 
  212   RETURN_IF_ERROR(spi_device_cmd_get(&cmd));
 
  218   rom_error_t error = kErrorUnknown;
 
  220     case kSpiDeviceOpcodeChipErase:
 
  221     case kSpiDeviceOpcodeSectorErase:
 
  222       error = bootstrap_chip_erase();
 
  223       HARDENED_RETURN_IF_ERROR(error);
 
  224       *state = kBootstrapStateEraseVerify;
 
  231       spi_device_flash_status_clear();
 
  247 static rom_error_t bootstrap_handle_erase_verify(bootstrap_state_t *state) {
 
  250   const rom_error_t err = bootstrap_erase_verify();
 
  251   HARDENED_RETURN_IF_ERROR(err);
 
  253   spi_device_flash_status_clear();
 
  255   *state = kBootstrapStateProgram;
 
  266 static rom_error_t bootstrap_handle_program(bootstrap_state_t *state) {
 
  269                 "Payload must be word aligned.");
 
  273       "Payload size must be a multiple of flash word size.");
 
  278   RETURN_IF_ERROR(spi_device_cmd_get(&cmd));
 
  280   if (cmd.
opcode != kSpiDeviceOpcodeReset &&
 
  285   rom_error_t error = kErrorUnknown;
 
  287     case kSpiDeviceOpcodeChipErase:
 
  288       error = bootstrap_chip_erase();
 
  290     case kSpiDeviceOpcodeSectorErase:
 
  291       error = bootstrap_sector_erase(cmd.
address);
 
  293     case kSpiDeviceOpcodePageProgram:
 
  297     case kSpiDeviceOpcodeReset:
 
  299       stack_utilization_print();
 
  301 #ifdef OT_PLATFORM_RV32 
  306       error = kErrorUnknown;
 
  315   HARDENED_RETURN_IF_ERROR(error);
 
  317   spi_device_flash_status_clear();
 
  321 rom_error_t enter_bootstrap(
void) {
 
  325   bootstrap_state_t state = kBootstrapStateErase;
 
  326   rom_error_t error = kErrorUnknown;
 
  328     switch (launder32(state)) {
 
  329       case kBootstrapStateErase:
 
  331         error = bootstrap_handle_erase(&state);
 
  333       case kBootstrapStateEraseVerify:
 
  335         error = bootstrap_handle_erase_verify(&state);
 
  337       case kBootstrapStateProgram:
 
  339         error = bootstrap_handle_program(&state);
 
  342         error = kErrorBootstrapInvalidState;
 
  344     HARDENED_RETURN_IF_ERROR(error);