startup.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdint.h>
  7. #include <string.h>
  8. #include "esp_attr.h"
  9. #include "esp_err.h"
  10. #include "esp_system.h"
  11. #include "esp_log.h"
  12. #include "esp_ota_ops.h"
  13. #include "sdkconfig.h"
  14. #include "soc/soc_caps.h"
  15. #include "hal/wdt_hal.h"
  16. #include "hal/uart_types.h"
  17. #include "hal/uart_ll.h"
  18. #include "esp_system.h"
  19. #include "esp_log.h"
  20. #include "esp_heap_caps_init.h"
  21. #include "esp_spi_flash.h"
  22. #include "esp_flash_internal.h"
  23. #include "esp_newlib.h"
  24. #include "esp_vfs_dev.h"
  25. #include "esp_timer.h"
  26. #include "esp_efuse.h"
  27. #include "esp_flash_encrypt.h"
  28. #include "esp_secure_boot.h"
  29. #include "esp_sleep.h"
  30. #include "esp_xt_wdt.h"
  31. /***********************************************/
  32. // Headers for other components init functions
  33. #include "nvs_flash.h"
  34. #include "esp_phy_init.h"
  35. #include "esp_coexist_internal.h"
  36. #if CONFIG_ESP_COREDUMP_ENABLE
  37. #include "esp_core_dump.h"
  38. #endif
  39. #include "esp_app_trace.h"
  40. #include "esp_private/dbg_stubs.h"
  41. #include "esp_pm.h"
  42. #include "esp_private/pm_impl.h"
  43. #include "esp_pthread.h"
  44. #include "esp_private/usb_console.h"
  45. #include "esp_vfs_cdcacm.h"
  46. #include "esp_vfs_usb_serial_jtag.h"
  47. #include "brownout.h"
  48. #include "esp_rom_sys.h"
  49. // [refactor-todo] make this file completely target-independent
  50. #if CONFIG_IDF_TARGET_ESP32
  51. #include "esp32/clk.h"
  52. #include "esp32/spiram.h"
  53. #elif CONFIG_IDF_TARGET_ESP32S2
  54. #include "esp32s2/clk.h"
  55. #include "esp32s2/spiram.h"
  56. #elif CONFIG_IDF_TARGET_ESP32S3
  57. #include "esp32s3/clk.h"
  58. #include "esp32s3/spiram.h"
  59. #elif CONFIG_IDF_TARGET_ESP32C3
  60. #include "esp32c3/clk.h"
  61. #elif CONFIG_IDF_TARGET_ESP32H2
  62. #include "esp32h2/clk.h"
  63. #endif
  64. /***********************************************/
  65. #include "esp_private/startup_internal.h"
  66. // Ensure that system configuration matches the underlying number of cores.
  67. // This should enable us to avoid checking for both everytime.
  68. #if !(SOC_CPU_CORES_NUM > 1) && !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
  69. #error "System has been configured to run on multiple cores, but target SoC only has a single core."
  70. #endif
  71. #define STRINGIFY(s) STRINGIFY2(s)
  72. #define STRINGIFY2(s) #s
  73. uint64_t g_startup_time = 0;
  74. #if SOC_APB_BACKUP_DMA
  75. // APB DMA lock initialising API
  76. extern void esp_apb_backup_dma_lock_init(void);
  77. #endif
  78. // App entry point for core 0
  79. extern void esp_startup_start_app(void);
  80. // Entry point for core 0 from hardware init (port layer)
  81. void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default"))) __attribute__((noreturn));
  82. #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
  83. // Entry point for core [1..X] from hardware init (port layer)
  84. void start_cpu_other_cores(void) __attribute__((weak, alias("start_cpu_other_cores_default"))) __attribute__((noreturn));
  85. // App entry point for core [1..X]
  86. void esp_startup_start_app_other_cores(void) __attribute__((weak, alias("esp_startup_start_app_other_cores_default"))) __attribute__((noreturn));
  87. static volatile bool s_system_inited[SOC_CPU_CORES_NUM] = { false };
  88. const sys_startup_fn_t g_startup_fn[SOC_CPU_CORES_NUM] = { [0] = start_cpu0,
  89. #if SOC_CPU_CORES_NUM > 1
  90. [1 ... SOC_CPU_CORES_NUM - 1] = start_cpu_other_cores
  91. #endif
  92. };
  93. static volatile bool s_system_full_inited = false;
  94. #else
  95. const sys_startup_fn_t g_startup_fn[1] = { start_cpu0 };
  96. #endif
  97. #ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
  98. // workaround for C++ exception crashes
  99. void _Unwind_SetNoFunctionContextInstall(unsigned char enable) __attribute__((weak, alias("_Unwind_SetNoFunctionContextInstall_Default")));
  100. // workaround for C++ exception large memory allocation
  101. void _Unwind_SetEnableExceptionFdeSorting(unsigned char enable);
  102. static IRAM_ATTR void _Unwind_SetNoFunctionContextInstall_Default(unsigned char enable __attribute__((unused)))
  103. {
  104. (void)0;
  105. }
  106. #endif // CONFIG_COMPILER_CXX_EXCEPTIONS
  107. static const char* TAG = "cpu_start";
  108. /**
  109. * This function overwrites a the same function of libsupc++ (part of libstdc++).
  110. * Consequently, libsupc++ will then follow our configured exception emergency pool size.
  111. *
  112. * It will be called even with -fno-exception for user code since the stdlib still uses exceptions.
  113. */
  114. size_t __cxx_eh_arena_size_get(void)
  115. {
  116. #ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
  117. return CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE;
  118. #else
  119. return 0;
  120. #endif
  121. }
  122. /**
  123. * Xtensa gcc is configured to emit a .ctors section, RISC-V gcc is configured with --enable-initfini-array
  124. * so it emits an .init_array section instead.
  125. * But the init_priority sections will be sorted for iteration in ascending order during startup.
  126. * The rest of the init_array sections is sorted for iteration in descending order during startup, however.
  127. * Hence a different section is generated for the init_priority functions which is looped
  128. * over in ascending direction instead of descending direction.
  129. * The RISC-V-specific behavior is dependent on the linker script ld/esp32c3/sections.ld.in.
  130. */
  131. static void do_global_ctors(void)
  132. {
  133. #if __riscv
  134. extern void (*__init_priority_array_start)(void);
  135. extern void (*__init_priority_array_end)(void);
  136. #endif
  137. extern void (*__init_array_start)(void);
  138. extern void (*__init_array_end)(void);
  139. #ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
  140. struct object { long placeholder[ 10 ]; };
  141. void __register_frame_info (const void *begin, struct object *ob);
  142. extern char __eh_frame[];
  143. static struct object ob;
  144. __register_frame_info( __eh_frame, &ob );
  145. #endif // CONFIG_COMPILER_CXX_EXCEPTIONS
  146. void (**p)(void);
  147. #if __riscv
  148. for (p = &__init_priority_array_start; p < &__init_priority_array_end; ++p) {
  149. ESP_EARLY_LOGD(TAG, "calling init function: %p", *p);
  150. (*p)();
  151. }
  152. #endif
  153. for (p = &__init_array_end - 1; p >= &__init_array_start; --p) {
  154. ESP_EARLY_LOGD(TAG, "calling init function: %p", *p);
  155. (*p)();
  156. }
  157. }
  158. static void do_system_init_fn(void)
  159. {
  160. extern esp_system_init_fn_t _esp_system_init_fn_array_start;
  161. extern esp_system_init_fn_t _esp_system_init_fn_array_end;
  162. esp_system_init_fn_t *p;
  163. for (p = &_esp_system_init_fn_array_end - 1; p >= &_esp_system_init_fn_array_start; --p) {
  164. if (p->cores & BIT(cpu_hal_get_core_id())) {
  165. (*(p->fn))();
  166. }
  167. }
  168. #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
  169. s_system_inited[cpu_hal_get_core_id()] = true;
  170. #endif
  171. }
  172. #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
  173. static void esp_startup_start_app_other_cores_default(void)
  174. {
  175. while (1) {
  176. esp_rom_delay_us(UINT32_MAX);
  177. }
  178. }
  179. static void IRAM_ATTR start_cpu_other_cores_default(void)
  180. {
  181. do_system_init_fn();
  182. while (!s_system_full_inited) {
  183. esp_rom_delay_us(100);
  184. }
  185. esp_startup_start_app_other_cores();
  186. }
  187. #endif
  188. static void do_core_init(void)
  189. {
  190. /* Initialize heap allocator. WARNING: This *needs* to happen *after* the app cpu has booted.
  191. If the heap allocator is initialized first, it will put free memory linked list items into
  192. memory also used by the ROM. Starting the app cpu will let its ROM initialize that memory,
  193. corrupting those linked lists. Initializing the allocator *after* the app cpu has booted
  194. works around this problem.
  195. With SPI RAM enabled, there's a second reason: half of the SPI RAM will be managed by the
  196. app CPU, and when that is not up yet, the memory will be inaccessible and heap_caps_init may
  197. fail initializing it properly. */
  198. heap_caps_init();
  199. esp_newlib_init();
  200. esp_newlib_time_init();
  201. if (g_spiram_ok) {
  202. #if CONFIG_SPIRAM_BOOT_INIT && (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
  203. esp_err_t r=esp_spiram_add_to_heapalloc();
  204. if (r != ESP_OK) {
  205. ESP_EARLY_LOGE(TAG, "External RAM could not be added to heap!");
  206. abort();
  207. }
  208. #if CONFIG_SPIRAM_USE_MALLOC
  209. heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
  210. #endif
  211. #endif
  212. }
  213. #if CONFIG_ESP32_BROWNOUT_DET || \
  214. CONFIG_ESP32S2_BROWNOUT_DET || \
  215. CONFIG_ESP32S3_BROWNOUT_DET || \
  216. CONFIG_ESP32C3_BROWNOUT_DET || \
  217. CONFIG_ESP32H2_BROWNOUT_DET
  218. // [refactor-todo] leads to call chain rtc_is_register (driver) -> esp_intr_alloc (esp32/esp32s2) ->
  219. // malloc (newlib) -> heap_caps_malloc (heap), so heap must be at least initialized
  220. esp_brownout_init();
  221. #endif
  222. #ifdef CONFIG_VFS_SUPPORT_IO
  223. #ifdef CONFIG_ESP_CONSOLE_UART
  224. esp_vfs_dev_uart_register();
  225. const char *default_stdio_dev = "/dev/uart/" STRINGIFY(CONFIG_ESP_CONSOLE_UART_NUM);
  226. #endif // CONFIG_ESP_CONSOLE_UART
  227. #ifdef CONFIG_ESP_CONSOLE_USB_CDC
  228. ESP_ERROR_CHECK(esp_usb_console_init());
  229. ESP_ERROR_CHECK(esp_vfs_dev_cdcacm_register());
  230. const char *default_stdio_dev = "/dev/cdcacm";
  231. #endif // CONFIG_ESP_CONSOLE_USB_CDC
  232. #ifdef CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
  233. ESP_ERROR_CHECK(esp_vfs_dev_usb_serial_jtag_register());
  234. const char *default_stdio_dev = "/dev/usbserjtag";
  235. #endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
  236. #endif // CONFIG_VFS_SUPPORT_IO
  237. #if defined(CONFIG_VFS_SUPPORT_IO) && !defined(CONFIG_ESP_CONSOLE_NONE)
  238. esp_reent_init(_GLOBAL_REENT);
  239. _GLOBAL_REENT->_stdin = fopen(default_stdio_dev, "r");
  240. _GLOBAL_REENT->_stdout = fopen(default_stdio_dev, "w");
  241. _GLOBAL_REENT->_stderr = fopen(default_stdio_dev, "w");
  242. #else // defined(CONFIG_VFS_SUPPORT_IO) && !defined(CONFIG_ESP_CONSOLE_NONE)
  243. _REENT_SMALL_CHECK_INIT(_GLOBAL_REENT);
  244. #endif // defined(CONFIG_VFS_SUPPORT_IO) && !defined(CONFIG_ESP_CONSOLE_NONE)
  245. esp_err_t err __attribute__((unused));
  246. err = esp_pthread_init();
  247. assert(err == ESP_OK && "Failed to init pthread module!");
  248. spi_flash_init();
  249. /* init default OS-aware flash access critical section */
  250. spi_flash_guard_set(&g_flash_guard_default_ops);
  251. esp_flash_app_init();
  252. esp_err_t flash_ret = esp_flash_init_default_chip();
  253. assert(flash_ret == ESP_OK);
  254. (void)flash_ret;
  255. #ifdef CONFIG_EFUSE_VIRTUAL
  256. 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!");
  257. #ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
  258. const esp_partition_t *efuse_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_EFUSE_EM, NULL);
  259. if (efuse_partition) {
  260. esp_efuse_init_virtual_mode_in_flash(efuse_partition->address, efuse_partition->size);
  261. }
  262. #endif
  263. #endif
  264. #if CONFIG_SECURE_DISABLE_ROM_DL_MODE
  265. err = esp_efuse_disable_rom_download_mode();
  266. assert(err == ESP_OK && "Failed to disable ROM download mode");
  267. #endif
  268. #if CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE
  269. err = esp_efuse_enable_rom_secure_download_mode();
  270. assert(err == ESP_OK && "Failed to enable Secure Download mode");
  271. #endif
  272. #if CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE
  273. esp_efuse_disable_basic_rom_console();
  274. #endif
  275. #ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
  276. esp_flash_encryption_init_checks();
  277. #endif
  278. #if defined(CONFIG_SECURE_BOOT) || defined(CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT)
  279. // Note: in some configs this may read flash, so placed after flash init
  280. esp_secure_boot_init_checks();
  281. #endif
  282. #if CONFIG_ESP_XT_WDT
  283. esp_xt_wdt_config_t cfg = {
  284. .timeout = CONFIG_ESP_XT_WDT_TIMEOUT,
  285. .auto_backup_clk_enable = CONFIG_ESP_XT_WDT_BACKUP_CLK_ENABLE,
  286. };
  287. err = esp_xt_wdt_init(&cfg);
  288. assert(err == ESP_OK && "Failed to init xtwdt");
  289. #endif
  290. }
  291. static void do_secondary_init(void)
  292. {
  293. #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
  294. // The port layer transferred control to this function with other cores 'paused',
  295. // resume execution so that cores might execute component initialization functions.
  296. startup_resume_other_cores();
  297. #endif
  298. // Execute initialization functions esp_system_init_fn_t assigned to the main core. While
  299. // this is happening, all other cores are executing the initialization functions
  300. // assigned to them since they have been resumed already.
  301. do_system_init_fn();
  302. #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
  303. // Wait for all cores to finish secondary init.
  304. volatile bool system_inited = false;
  305. while (!system_inited) {
  306. system_inited = true;
  307. for (int i = 0; i < SOC_CPU_CORES_NUM; i++) {
  308. system_inited &= s_system_inited[i];
  309. }
  310. esp_rom_delay_us(100);
  311. }
  312. #endif
  313. }
  314. static void start_cpu0_default(void)
  315. {
  316. ESP_EARLY_LOGI(TAG, "Pro cpu start user code");
  317. int cpu_freq = esp_clk_cpu_freq();
  318. ESP_EARLY_LOGI(TAG, "cpu freq: %d", cpu_freq);
  319. // Display information about the current running image.
  320. if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) {
  321. const esp_app_desc_t *app_desc = esp_ota_get_app_description();
  322. ESP_EARLY_LOGI(TAG, "Application information:");
  323. #ifndef CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR
  324. ESP_EARLY_LOGI(TAG, "Project name: %s", app_desc->project_name);
  325. #endif
  326. #ifndef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR
  327. ESP_EARLY_LOGI(TAG, "App version: %s", app_desc->version);
  328. #endif
  329. #ifdef CONFIG_BOOTLOADER_APP_SECURE_VERSION
  330. ESP_EARLY_LOGI(TAG, "Secure version: %d", app_desc->secure_version);
  331. #endif
  332. #ifdef CONFIG_APP_COMPILE_TIME_DATE
  333. ESP_EARLY_LOGI(TAG, "Compile time: %s %s", app_desc->date, app_desc->time);
  334. #endif
  335. char buf[17];
  336. esp_ota_get_app_elf_sha256(buf, sizeof(buf));
  337. ESP_EARLY_LOGI(TAG, "ELF file SHA256: %s...", buf);
  338. ESP_EARLY_LOGI(TAG, "ESP-IDF: %s", app_desc->idf_ver);
  339. }
  340. // Initialize core components and services.
  341. do_core_init();
  342. // Execute constructors.
  343. do_global_ctors();
  344. // Execute init functions of other components; blocks
  345. // until all cores finish (when !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE).
  346. do_secondary_init();
  347. // Now that the application is about to start, disable boot watchdog
  348. #ifndef CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE
  349. wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL};
  350. wdt_hal_write_protect_disable(&rtc_wdt_ctx);
  351. wdt_hal_disable(&rtc_wdt_ctx);
  352. wdt_hal_write_protect_enable(&rtc_wdt_ctx);
  353. #endif
  354. #if SOC_CPU_CORES_NUM > 1 && !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
  355. s_system_full_inited = true;
  356. #endif
  357. esp_startup_start_app();
  358. while (1);
  359. }
  360. IRAM_ATTR ESP_SYSTEM_INIT_FN(init_components0, BIT(0))
  361. {
  362. esp_timer_init();
  363. #if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND && !CONFIG_PM_SLP_DISABLE_GPIO
  364. // Configure to isolate (disable the Input/Output/Pullup/Pulldown
  365. // function of the pin) all GPIO pins in sleep state
  366. esp_sleep_config_gpio_isolate();
  367. // Enable automatic switching of GPIO configuration
  368. esp_sleep_enable_gpio_switch(true);
  369. #endif
  370. #if CONFIG_APPTRACE_ENABLE
  371. esp_err_t err = esp_apptrace_init();
  372. assert(err == ESP_OK && "Failed to init apptrace module on PRO CPU!");
  373. #endif
  374. #if CONFIG_APPTRACE_SV_ENABLE
  375. SEGGER_SYSVIEW_Conf();
  376. #endif
  377. #if CONFIG_ESP_DEBUG_STUBS_ENABLE
  378. esp_dbg_stubs_init();
  379. #endif
  380. #if defined(CONFIG_PM_ENABLE)
  381. esp_pm_impl_init();
  382. #endif
  383. #if CONFIG_ESP_COREDUMP_ENABLE
  384. esp_core_dump_init();
  385. #endif
  386. #if SOC_APB_BACKUP_DMA
  387. esp_apb_backup_dma_lock_init();
  388. #endif
  389. #if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE
  390. esp_coex_adapter_register(&g_coex_adapter_funcs);
  391. coex_pre_init();
  392. #endif
  393. #ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
  394. ESP_EARLY_LOGD(TAG, "Setting C++ exception workarounds.");
  395. _Unwind_SetNoFunctionContextInstall(1);
  396. _Unwind_SetEnableExceptionFdeSorting(0);
  397. #endif // CONFIG_COMPILER_CXX_EXCEPTIONS
  398. }