Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | /* * Copyright (c) 2013-2014 Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Full C support initialization * * * Initialization of full C support: zero the .bss, copy the .data if XIP, * call z_cstart(). * * Stack is available in this module, but not the global data/bss until their * initialization is performed. */ #include <kernel.h> #include <zephyr/types.h> #include <toolchain.h> #include <linker/linker-defs.h> #include <kernel_internal.h> #include <arch/arm/cortex_m/cmsis.h> #if defined(__GNUC__) /* * GCC can detect if memcpy is passed a NULL argument, however one of * the cases of relocate_vector_table() it is valid to pass NULL, so we * supress the warning for this case. We need to do this before * string.h is included to get the declaration of memcpy. */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnonnull" #endif #include <string.h> #ifdef CONFIG_CPU_CORTEX_M_HAS_VTOR #ifdef CONFIG_XIP #define VECTOR_ADDRESS ((uintptr_t)_vector_start) #else #define VECTOR_ADDRESS CONFIG_SRAM_BASE_ADDRESS #endif static inline void relocate_vector_table(void) { SCB->VTOR = VECTOR_ADDRESS & SCB_VTOR_TBLOFF_Msk; __DSB(); __ISB(); } #else #if defined(CONFIG_SW_VECTOR_RELAY) Z_GENERIC_SECTION(.vt_pointer_section) void *_vector_table_pointer; #endif #define VECTOR_ADDRESS 0 void __weak relocate_vector_table(void) { #if defined(CONFIG_XIP) && (CONFIG_FLASH_BASE_ADDRESS != 0) || \ !defined(CONFIG_XIP) && (CONFIG_SRAM_BASE_ADDRESS != 0) size_t vector_size = (size_t)_vector_end - (size_t)_vector_start; (void)memcpy(VECTOR_ADDRESS, _vector_start, vector_size); #elif defined(CONFIG_SW_VECTOR_RELAY) _vector_table_pointer = _vector_start; #endif } #if defined(__GNUC__) #pragma GCC diagnostic pop #endif #endif /* CONFIG_CPU_CORTEX_M_HAS_VTOR */ #ifdef CONFIG_FLOAT static inline void enable_floating_point(void) { /* * Upon reset, the Co-Processor Access Control Register is 0x00000000. * Enable CP10 and CP11 co-processors to enable floating point. */ SCB->CPACR |= CPACR_CP10_FULL_ACCESS | CPACR_CP11_FULL_ACCESS; /* * Upon reset, the FPU Context Control Register is 0xC0000000 * (both Automatic and Lazy state preservation is enabled). * Disable lazy state preservation so the volatile FP registers are * always saved on exception. */ FPU->FPCCR = FPU_FPCCR_ASPEN_Msk; /* FPU_FPCCR_LSPEN = 0 */ /* * Although automatic state preservation is enabled, the processor * does not automatically save the volatile FP registers until they * have first been touched. Perform a dummy move operation so that * the stack frames are created as expected before any thread * context switching can occur. It has to be surrounded by instruction * synchronization barriers to ensure that the whole sequence is * serialized. */ __asm__ volatile( "isb;\n\t" "vmov s0, s0;\n\t" "isb;\n\t" ); } #else static inline void enable_floating_point(void) { } #endif extern FUNC_NORETURN void z_cstart(void); /** * * @brief Prepare to and run C code * * This routine prepares for the execution of and runs C code. * * @return N/A */ extern void z_IntLibInit(void); #ifdef CONFIG_BOOT_TIME_MEASUREMENT extern u64_t __start_time_stamp; #endif void _PrepC(void) { relocate_vector_table(); enable_floating_point(); z_bss_zero(); z_data_copy(); #ifdef CONFIG_BOOT_TIME_MEASUREMENT __start_time_stamp = 0U; #endif z_IntLibInit(); z_cstart(); CODE_UNREACHABLE; } |