1 // Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma once 16 17 #include "esp_attr.h" 18 19 #include "soc/soc_caps.h" 20 #include "hal/cpu_hal.h" 21 22 #include "sdkconfig.h" 23 24 #ifdef __cplusplus 25 extern "C" { 26 #endif 27 28 extern bool g_spiram_ok; // [refactor-todo] better way to communicate this from port layer to common startup code 29 30 // Port layer defines the entry point. It then transfer control to a `sys_startup_fn_t`, stored in this 31 // array, one per core. 32 typedef void (*sys_startup_fn_t)(void); 33 34 /* This array of per-CPU system layer startup functions is initialized in the non-port part of esp_system */ 35 #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE 36 extern sys_startup_fn_t const g_startup_fn[SOC_CPU_CORES_NUM]; 37 #else 38 extern sys_startup_fn_t const g_startup_fn[1]; 39 #endif 40 41 // Utility to execute `sys_startup_fn_t` for the current core. 42 #define SYS_STARTUP_FN() ((*g_startup_fn[(cpu_hal_get_core_id())])()) 43 44 #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE 45 void startup_resume_other_cores(void); 46 #endif 47 48 typedef struct { 49 void (*fn)(void); 50 uint32_t cores; 51 } esp_system_init_fn_t; 52 53 /* 54 * Declare an component initialization function that will execute on the specified cores (ex. if BIT0 == 1, will execute 55 * on CORE0, CORE1 if BIT1 and so on). 56 * 57 * @note Initialization functions should be placed in a compilation unit where at least one other 58 * symbol is referenced 'meaningfully' in another compilation unit, otherwise this gets discarded during linking. (By 59 * 'meaningfully' we mean the reference should not itself get optimized out by the compiler/discarded by the linker). 60 */ 61 #define ESP_SYSTEM_INIT_FN(f, c, ...) \ 62 static void __attribute__((used)) __VA_ARGS__ __esp_system_init_fn_##f(void); \ 63 static __attribute__((used)) esp_system_init_fn_t _SECTION_ATTR_IMPL(".esp_system_init_fn", f) \ 64 esp_system_init_fn_##f = { .fn = ( __esp_system_init_fn_##f), .cores = (c) }; \ 65 static __attribute__((used)) __VA_ARGS__ void __esp_system_init_fn_##f(void) // [refactor-todo] this can be made public API if we allow components to declare init functions, 66 // instead of calling them explicitly 67 68 extern uint64_t g_startup_time; // Startup time that serves as the point of origin for system time. Should be set by the entry 69 // function in the port layer. May be 0 as well if this is not backed by a persistent counter, in which case 70 // startup time = system time = 0 at the point the entry function sets this variable. 71 72 #ifdef __cplusplus 73 } 74 #endif 75