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 | /* * 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 _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> #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) _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; memcpy(VECTOR_ADDRESS, _vector_start, vector_size); #elif defined(CONFIG_SW_VECTOR_RELAY) _vector_table_pointer = _vector_start; #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 coprocessors 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 * synchronisation 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 _Cstart(void); /** * * @brief Prepare to and run C code * * This routine prepares for the execution of and runs C code. * * @return N/A */ #ifdef CONFIG_BOOT_TIME_MEASUREMENT extern u64_t __start_time_stamp; #endif void _PrepC(void) { relocate_vector_table(); enable_floating_point(); _bss_zero(); _data_copy(); #ifdef CONFIG_BOOT_TIME_MEASUREMENT __start_time_stamp = 0; #endif _Cstart(); CODE_UNREACHABLE; } |