bootloader_esp32.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * SPDX-FileCopyrightText: 2019-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 "bootloader_init.h"
  13. #include "bootloader_clock.h"
  14. #include "bootloader_common.h"
  15. #include "bootloader_flash_config.h"
  16. #include "bootloader_mem.h"
  17. #include "bootloader_console.h"
  18. #include "bootloader_flash_priv.h"
  19. #include "esp_private/bootloader_flash_internal.h"
  20. #include "esp_cpu.h"
  21. #include "soc/dport_reg.h"
  22. #include "soc/efuse_reg.h"
  23. #include "soc/gpio_periph.h"
  24. #include "soc/gpio_sig_map.h"
  25. #include "soc/io_mux_reg.h"
  26. #include "soc/rtc.h"
  27. #include "soc/spi_periph.h"
  28. #include "hal/gpio_hal.h"
  29. #include "xtensa/config/core.h"
  30. #include "xt_instr_macros.h"
  31. #include "esp32/rom/cache.h"
  32. #include "esp_rom_gpio.h"
  33. #include "esp_rom_efuse.h"
  34. #include "esp_rom_sys.h"
  35. #include "esp_rom_spiflash.h"
  36. #include "esp_efuse.h"
  37. static const char *TAG = "boot.esp32";
  38. #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
  39. static void bootloader_reset_mmu(void)
  40. {
  41. /* completely reset MMU in case serial bootloader was running */
  42. Cache_Read_Disable(0);
  43. #if !CONFIG_FREERTOS_UNICORE
  44. Cache_Read_Disable(1);
  45. #endif
  46. Cache_Flush(0);
  47. #if !CONFIG_FREERTOS_UNICORE
  48. Cache_Flush(1);
  49. #endif
  50. mmu_init(0);
  51. #if !CONFIG_FREERTOS_UNICORE
  52. /* The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are
  53. necessary to work around a hardware bug. */
  54. DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
  55. mmu_init(1);
  56. DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
  57. #endif
  58. /* normal ROM boot exits with DROM0 cache unmasked,
  59. but serial bootloader exits with it masked. */
  60. DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0);
  61. #if !CONFIG_FREERTOS_UNICORE
  62. DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0);
  63. #endif
  64. }
  65. #endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
  66. static esp_err_t bootloader_check_rated_cpu_clock(void)
  67. {
  68. int rated_freq = bootloader_clock_get_rated_freq_mhz();
  69. if (rated_freq < CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ) {
  70. ESP_LOGE(TAG, "Chip CPU frequency rated for %dMHz, configured for %dMHz. Modify CPU frequency in menuconfig",
  71. rated_freq, CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ);
  72. return ESP_FAIL;
  73. }
  74. return ESP_OK;
  75. }
  76. static void wdt_reset_cpu0_info_enable(void)
  77. {
  78. //We do not reset core1 info here because it didn't work before cpu1 was up. So we put it into call_start_cpu1.
  79. DPORT_REG_SET_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_PDEBUG_ENABLE | DPORT_PRO_CPU_RECORD_ENABLE);
  80. DPORT_REG_CLR_BIT(DPORT_PRO_CPU_RECORD_CTRL_REG, DPORT_PRO_CPU_RECORD_ENABLE);
  81. }
  82. static void wdt_reset_info_dump(int cpu)
  83. {
  84. uint32_t inst = 0, pid = 0, stat = 0, data = 0, pc = 0,
  85. lsstat = 0, lsaddr = 0, lsdata = 0, dstat = 0;
  86. const char *cpu_name = cpu ? "APP" : "PRO";
  87. if (cpu == 0) {
  88. stat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_STATUS_REG);
  89. pid = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PID_REG);
  90. inst = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGINST_REG);
  91. dstat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGSTATUS_REG);
  92. data = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGDATA_REG);
  93. pc = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGPC_REG);
  94. lsstat = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0STAT_REG);
  95. lsaddr = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0ADDR_REG);
  96. lsdata = DPORT_REG_READ(DPORT_PRO_CPU_RECORD_PDEBUGLS0DATA_REG);
  97. } else {
  98. #if !CONFIG_FREERTOS_UNICORE
  99. stat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_STATUS_REG);
  100. pid = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PID_REG);
  101. inst = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGINST_REG);
  102. dstat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGSTATUS_REG);
  103. data = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGDATA_REG);
  104. pc = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGPC_REG);
  105. lsstat = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0STAT_REG);
  106. lsaddr = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0ADDR_REG);
  107. lsdata = DPORT_REG_READ(DPORT_APP_CPU_RECORD_PDEBUGLS0DATA_REG);
  108. #endif
  109. }
  110. if (DPORT_RECORD_PDEBUGINST_SZ(inst) == 0 &&
  111. DPORT_RECORD_PDEBUGSTATUS_BBCAUSE(dstat) == DPORT_RECORD_PDEBUGSTATUS_BBCAUSE_WAITI) {
  112. ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x (waiti mode)", cpu_name, pc);
  113. } else {
  114. ESP_LOGW(TAG, "WDT reset info: %s CPU PC=0x%x", cpu_name, pc);
  115. }
  116. ESP_LOGD(TAG, "WDT reset info: %s CPU STATUS 0x%08x", cpu_name, stat);
  117. ESP_LOGD(TAG, "WDT reset info: %s CPU PID 0x%08x", cpu_name, pid);
  118. ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGINST 0x%08x", cpu_name, inst);
  119. ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGSTATUS 0x%08x", cpu_name, dstat);
  120. ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGDATA 0x%08x", cpu_name, data);
  121. ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGPC 0x%08x", cpu_name, pc);
  122. ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0STAT 0x%08x", cpu_name, lsstat);
  123. ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0ADDR 0x%08x", cpu_name, lsaddr);
  124. ESP_LOGD(TAG, "WDT reset info: %s CPU PDEBUGLS0DATA 0x%08x", cpu_name, lsdata);
  125. }
  126. static void bootloader_check_wdt_reset(void)
  127. {
  128. int wdt_rst = 0;
  129. soc_reset_reason_t rst_reas[2];
  130. rst_reas[0] = esp_rom_get_reset_reason(0);
  131. rst_reas[1] = esp_rom_get_reset_reason(1);
  132. if (rst_reas[0] == RESET_REASON_CORE_RTC_WDT || rst_reas[0] == RESET_REASON_CORE_MWDT0 || rst_reas[0] == RESET_REASON_CORE_MWDT1 ||
  133. rst_reas[0] == RESET_REASON_CPU0_MWDT0 || rst_reas[0] == RESET_REASON_CPU0_RTC_WDT) {
  134. ESP_LOGW(TAG, "PRO CPU has been reset by WDT.");
  135. wdt_rst = 1;
  136. }
  137. if (rst_reas[1] == RESET_REASON_CORE_RTC_WDT || rst_reas[1] == RESET_REASON_CORE_MWDT0 || rst_reas[1] == RESET_REASON_CORE_MWDT1 ||
  138. rst_reas[1] == RESET_REASON_CPU1_MWDT1 || rst_reas[1] == RESET_REASON_CPU1_RTC_WDT) {
  139. ESP_LOGW(TAG, "APP CPU has been reset by WDT.");
  140. wdt_rst = 1;
  141. }
  142. if (wdt_rst) {
  143. // if reset by WDT dump info from trace port
  144. wdt_reset_info_dump(0);
  145. #if !CONFIG_FREERTOS_UNICORE
  146. wdt_reset_info_dump(1);
  147. #endif
  148. }
  149. wdt_reset_cpu0_info_enable();
  150. }
  151. esp_err_t bootloader_init(void)
  152. {
  153. esp_err_t ret = ESP_OK;
  154. #if XCHAL_ERRATUM_572
  155. uint32_t memctl = XCHAL_CACHE_MEMCTL_DEFAULT;
  156. WSR(MEMCTL, memctl);
  157. #endif // XCHAL_ERRATUM_572
  158. // In RAM_APP, memory will be initialized in `call_start_cpu0`
  159. #if !CONFIG_APP_BUILD_TYPE_RAM
  160. bootloader_init_mem();
  161. // check that static RAM is after the stack
  162. #ifndef NDEBUG
  163. {
  164. assert(&_bss_start <= &_bss_end);
  165. assert(&_data_start <= &_data_end);
  166. int *sp = esp_cpu_get_sp();
  167. assert(sp < &_bss_start);
  168. assert(sp < &_data_start);
  169. }
  170. #endif
  171. // clear bss section
  172. bootloader_clear_bss_section();
  173. #endif // !CONFIG_APP_BUILD_TYPE_RAM
  174. // init eFuse virtual mode (read eFuses to RAM)
  175. #ifdef CONFIG_EFUSE_VIRTUAL
  176. 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!");
  177. #ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
  178. esp_efuse_init_virtual_mode_in_ram();
  179. #endif
  180. #endif
  181. // bootst up vddsdio
  182. bootloader_common_vddsdio_configure();
  183. // check rated CPU clock
  184. if ((ret = bootloader_check_rated_cpu_clock()) != ESP_OK) {
  185. return ret;
  186. }
  187. // config clock
  188. bootloader_clock_configure();
  189. // initialize uart console, from now on, we can use esp_log
  190. bootloader_console_init();
  191. /* print 2nd bootloader banner */
  192. bootloader_print_banner();
  193. #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
  194. // reset MMU
  195. bootloader_reset_mmu();
  196. // update flash ID
  197. bootloader_flash_update_id();
  198. // Check and run XMC startup flow
  199. if ((ret = bootloader_flash_xmc_startup()) != ESP_OK) {
  200. ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!");
  201. return ret;
  202. }
  203. #if !CONFIG_APP_BUILD_TYPE_RAM
  204. // read bootloader header
  205. if ((ret = bootloader_read_bootloader_header()) != ESP_OK) {
  206. return ret;
  207. }
  208. // read chip revision and check if it's compatible to bootloader
  209. if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) {
  210. return ret;
  211. }
  212. #endif // #if !CONFIG_APP_BUILD_TYPE_RAM
  213. // initialize spi flash
  214. if ((ret = bootloader_init_spi_flash()) != ESP_OK) {
  215. return ret;
  216. }
  217. #endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
  218. // check whether a WDT reset happend
  219. bootloader_check_wdt_reset();
  220. // config WDT
  221. bootloader_config_wdt();
  222. // enable RNG early entropy source
  223. bootloader_enable_random();
  224. return ret;
  225. }