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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | /* * Copyright (c) 2014 Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Reset handler * * Reset handler that prepares the system for running C code. */ #include <toolchain.h> #include <linker/sections.h> #include <arch/cpu.h> #include <swap_macros.h> GDATA(_interrupt_stack) GDATA(_main_stack) GDATA(_VectorTable) /* use one of the available interrupt stacks during init */ #define INIT_STACK _interrupt_stack #define INIT_STACK_SIZE CONFIG_ISR_STACK_SIZE GTEXT(__reset) GTEXT(__start) /** * * @brief Reset vector * * Ran when the system comes out of reset. The processor is at supervisor level. * * Locking interrupts prevents anything from interrupting the CPU. * * When these steps are completed, jump to _PrepC(), which will finish setting * up the system for running C code. * * @return N/A */ SECTION_FUNC(TEXT,__reset) SECTION_FUNC(TEXT,__start) /* lock interrupts: will get unlocked when switch to main task * also make sure the processor in the correct status */ mov r0, 0 kflag r0 #ifdef CONFIG_ARC_SECURE_FIRMWARE sflag r0 #endif #if defined(CONFIG_BOOT_TIME_MEASUREMENT) && defined(CONFIG_ARCV2_TIMER) /* * ARCV2 timer (timer0) is a free run timer, let it start to count * here. */ mov r0, 0xffffffff sr r0, [_ARC_V2_TMR0_LIMIT] mov r0, 0 sr r0, [_ARC_V2_TMR0_COUNT] #endif /* interrupt related init */ #ifndef CONFIG_ARC_NORMAL_FIRMWARE /* IRQ_ACT and IRQ_CTRL should be initialized and set in secure mode */ sr r0, [_ARC_V2_AUX_IRQ_ACT] sr r0, [_ARC_V2_AUX_IRQ_CTRL] #endif sr r0, [_ARC_V2_AUX_IRQ_HINT] /* set the vector table base early, * so that exception vectors can be handled. */ mov r0, _VectorTable #ifdef CONFIG_ARC_SECURE_FIRMWARE sr r0, [_ARC_V2_IRQ_VECT_BASE_S] #else sr r0, [_ARC_V2_IRQ_VECT_BASE] #endif #if defined(CONFIG_USERSPACE) lr r0, [_ARC_V2_STATUS32] bset r0, r0, _ARC_V2_STATUS32_US_BIT kflag r0 #endif #ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS lr r0, [_ARC_V2_STATUS32] bset r0, r0, _ARC_V2_STATUS32_AD_BIT kflag r0 #endif mov r1, 1 invalidate_and_disable_icache: lr r0, [_ARC_V2_I_CACHE_BUILD] and.f r0, r0, 0xff bz.nd invalidate_dcache mov_s r2, 0 sr r2, [_ARC_V2_IC_IVIC] /* writing to IC_IVIC needs 3 NOPs */ nop nop nop sr r1, [_ARC_V2_IC_CTRL] invalidate_dcache: lr r3, [_ARC_V2_D_CACHE_BUILD] and.f r3, r3, 0xff bz.nd done_cache_invalidate sr r1, [_ARC_V2_DC_IVDC] done_cache_invalidate: #if defined(CONFIG_SYS_POWER_DEEP_SLEEP_STATES) && \ !defined(CONFIG_BOOTLOADER_CONTEXT_RESTORE) jl @_sys_resume_from_deep_sleep #endif #ifdef CONFIG_SMP _get_cpu_id r0 breq r0, 0, _master_core_startup /* * Non-masters wait for master core (core 0) to boot enough */ _slave_core_wait: ld r1, [arc_cpu_wake_flag] brne r0, r1, _slave_core_wait /* signal master core that slave core runs */ st 0, [arc_cpu_wake_flag] /* get sp set by master core */ _get_curr_cpu_irq_stack sp j z_arch_slave_start _master_core_startup: #endif #ifdef CONFIG_INIT_STACKS /* * use the main stack to call memset on the interrupt stack and the * FIRQ stack when CONFIG_INIT_STACKS is enabled before switching to * one of them for the rest of the early boot */ mov sp, _main_stack add sp, sp, CONFIG_MAIN_STACK_SIZE mov_s r0, _interrupt_stack mov_s r1, 0xaa mov_s r2, CONFIG_ISR_STACK_SIZE jl memset #endif /* CONFIG_INIT_STACKS */ mov sp, INIT_STACK add sp, sp, INIT_STACK_SIZE j @_PrepC |