bootloader_esp32c3.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdint.h>
  7. #include "sdkconfig.h"
  8. #include "esp_attr.h"
  9. #include "esp_log.h"
  10. #include "esp_image_format.h"
  11. #include "flash_qio_mode.h"
  12. #include "esp_rom_gpio.h"
  13. #include "esp_rom_efuse.h"
  14. #include "esp_rom_uart.h"
  15. #include "esp_rom_sys.h"
  16. #include "esp_rom_spiflash.h"
  17. #include "soc/efuse_reg.h"
  18. #include "soc/gpio_sig_map.h"
  19. #include "soc/io_mux_reg.h"
  20. #include "soc/assist_debug_reg.h"
  21. #include "esp_cpu.h"
  22. #include "soc/rtc.h"
  23. #include "soc/rtc_cntl_reg.h"
  24. #include "soc/spi_periph.h"
  25. #include "soc/extmem_reg.h"
  26. #include "soc/io_mux_reg.h"
  27. #include "soc/system_reg.h"
  28. #include "soc/chip_revision.h"
  29. #include "esp32c3/rom/efuse.h"
  30. #include "esp32c3/rom/ets_sys.h"
  31. #include "bootloader_common.h"
  32. #include "bootloader_init.h"
  33. #include "bootloader_clock.h"
  34. #include "bootloader_flash_config.h"
  35. #include "bootloader_mem.h"
  36. #include "esp_private/regi2c_ctrl.h"
  37. #include "soc/regi2c_lp_bias.h"
  38. #include "soc/regi2c_bias.h"
  39. #include "bootloader_console.h"
  40. #include "bootloader_flash_priv.h"
  41. #include "esp_private/bootloader_flash_internal.h"
  42. #include "bootloader_soc.h"
  43. #include "esp_efuse.h"
  44. #include "hal/mmu_hal.h"
  45. #include "hal/cache_hal.h"
  46. #include "hal/efuse_hal.h"
  47. static const char *TAG = "boot.esp32c3";
  48. static void wdt_reset_cpu0_info_enable(void)
  49. {
  50. REG_SET_BIT(SYSTEM_CPU_PERI_CLK_EN_REG, SYSTEM_CLK_EN_ASSIST_DEBUG);
  51. REG_CLR_BIT(SYSTEM_CPU_PERI_RST_EN_REG, SYSTEM_RST_EN_ASSIST_DEBUG);
  52. REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_EN_REG, ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN);
  53. }
  54. static void wdt_reset_info_dump(int cpu)
  55. {
  56. (void) cpu;
  57. // saved PC was already printed by the ROM bootloader.
  58. // nothing to do here.
  59. }
  60. static void bootloader_check_wdt_reset(void)
  61. {
  62. int wdt_rst = 0;
  63. soc_reset_reason_t rst_reason = esp_rom_get_reset_reason(0);
  64. if (rst_reason == RESET_REASON_CORE_RTC_WDT || rst_reason == RESET_REASON_CORE_MWDT0 || rst_reason == RESET_REASON_CORE_MWDT1 ||
  65. rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_MWDT1 || rst_reason == RESET_REASON_CPU0_RTC_WDT) {
  66. ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
  67. wdt_rst = 1;
  68. }
  69. if (wdt_rst) {
  70. // if reset by WDT dump info from trace port
  71. wdt_reset_info_dump(0);
  72. }
  73. wdt_reset_cpu0_info_enable();
  74. }
  75. static void bootloader_super_wdt_auto_feed(void)
  76. {
  77. REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, RTC_CNTL_SWD_WKEY_VALUE);
  78. REG_SET_BIT(RTC_CNTL_SWD_CONF_REG, RTC_CNTL_SWD_AUTO_FEED_EN);
  79. REG_WRITE(RTC_CNTL_SWD_WPROTECT_REG, 0);
  80. }
  81. static inline void bootloader_hardware_init(void)
  82. {
  83. // This check is always included in the bootloader so it can
  84. // print the minimum revision error message later in the boot
  85. if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 3)) {
  86. REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_IPH, 1);
  87. REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 12);
  88. }
  89. }
  90. static inline void bootloader_ana_reset_config(void)
  91. {
  92. /*
  93. For origin chip & ECO1: only support swt reset;
  94. For ECO2: fix brownout reset bug, support swt & brownout reset;
  95. For ECO3: fix clock glitch reset bug, support all reset, include: swt & brownout & clock glitch reset.
  96. */
  97. switch (efuse_hal_chip_revision()) {
  98. case 0:
  99. case 1:
  100. //Enable WDT reset. Disable BOR and GLITCH reset
  101. bootloader_ana_super_wdt_reset_config(true);
  102. bootloader_ana_bod_reset_config(false);
  103. bootloader_ana_clock_glitch_reset_config(false);
  104. break;
  105. case 2:
  106. //Enable WDT and BOR reset. Disable GLITCH reset
  107. bootloader_ana_super_wdt_reset_config(true);
  108. bootloader_ana_bod_reset_config(true);
  109. bootloader_ana_clock_glitch_reset_config(false);
  110. break;
  111. case 3:
  112. default:
  113. //Enable WDT, BOR, and GLITCH reset
  114. bootloader_ana_super_wdt_reset_config(true);
  115. bootloader_ana_bod_reset_config(true);
  116. bootloader_ana_clock_glitch_reset_config(true);
  117. break;
  118. }
  119. }
  120. esp_err_t bootloader_init(void)
  121. {
  122. esp_err_t ret = ESP_OK;
  123. bootloader_hardware_init();
  124. bootloader_ana_reset_config();
  125. bootloader_super_wdt_auto_feed();
  126. // In RAM_APP, memory will be initialized in `call_start_cpu0`
  127. #if !CONFIG_APP_BUILD_TYPE_RAM
  128. // protect memory region
  129. bootloader_init_mem();
  130. /* check that static RAM is after the stack */
  131. assert(&_bss_start <= &_bss_end);
  132. assert(&_data_start <= &_data_end);
  133. // clear bss section
  134. bootloader_clear_bss_section();
  135. #endif // !CONFIG_APP_BUILD_TYPE_RAM
  136. // init eFuse virtual mode (read eFuses to RAM)
  137. #ifdef CONFIG_EFUSE_VIRTUAL
  138. ESP_LOGW(TAG, "eFuse virtual mode is enabled. If Secure boot or Flash encryption is enabled then it does not provide any security. FOR TESTING ONLY!");
  139. #ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
  140. esp_efuse_init_virtual_mode_in_ram();
  141. #endif
  142. #endif
  143. // config clock
  144. bootloader_clock_configure();
  145. // initialize console, from now on, we can use esp_log
  146. bootloader_console_init();
  147. /* print 2nd bootloader banner */
  148. bootloader_print_banner();
  149. #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
  150. //init cache hal
  151. cache_hal_init();
  152. //init mmu
  153. mmu_hal_init();
  154. // update flash ID
  155. bootloader_flash_update_id();
  156. // Check and run XMC startup flow
  157. if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) {
  158. ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!");
  159. return ret;
  160. }
  161. #if !CONFIG_APP_BUILD_TYPE_RAM
  162. // read bootloader header
  163. if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
  164. return ret;
  165. }
  166. // read chip revision and check if it's compatible to bootloader
  167. if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) {
  168. return ret;
  169. }
  170. #endif //#if !CONFIG_APP_BUILD_TYPE_RAM
  171. // initialize spi flash
  172. if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
  173. return ret;
  174. }
  175. #endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
  176. // check whether a WDT reset happend
  177. bootloader_check_wdt_reset();
  178. // config WDT
  179. bootloader_config_wdt();
  180. // enable RNG early entropy source
  181. bootloader_enable_random();
  182. return ret;
  183. }