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 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | /* * 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(z_interrupt_stacks) GDATA(z_main_stack) GDATA(_VectorTable) /* use one of the available interrupt stacks during init */ #define INIT_STACK z_interrupt_stacks #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_s 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_s r0, 0xffffffff sr r0, [_ARC_V2_TMR0_LIMIT] mov_s 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_s 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_s 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_s nop_s nop_s 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: /* * Init ARC internal architecture state * Force to initialize internal architecture state to reset values * For scenarios where board hardware is not re-initialized between tests, * some settings need to be restored to its default initial states as a * substitution of normal hardware reset sequence. */ #ifdef CONFIG_INIT_ARCH_HW_AT_BOOT /* Set MPU (v3) registers to default */ #if CONFIG_ARC_MPU_VER == 3 /* Set default reset value to _ARC_V2_MPU_EN register */ #define ARC_MPU_EN_RESET_VALUE 0x400181C0 mov_s r1, ARC_MPU_EN_RESET_VALUE sr r1, [_ARC_V2_MPU_EN] /* Get MPU region numbers */ lr r3, [_ARC_V2_MPU_BUILD] lsr_s r3, r3, 8 and r3, r3, 0xff mov_s r1, 0 mov_s r2, 0 /* Set all MPU regions by iterating index */ mpu_regions_reset: brge r2, r3, done_mpu_regions_reset sr r2, [_ARC_V2_MPU_INDEX] sr r1, [_ARC_V2_MPU_RSTART] sr r1, [_ARC_V2_MPU_REND] sr r1, [_ARC_V2_MPU_RPER] add_s r2, r2, 1 b_s mpu_regions_reset done_mpu_regions_reset: #endif #endif #if defined(CONFIG_SMP) || CONFIG_MP_NUM_CPUS > 1 _get_cpu_id r0 breq r0, 0, _master_core_startup /* * Non-masters wait for master core (core 0) to boot enough */ _slave_core_wait: #if CONFIG_MP_NUM_CPUS == 1 kflag 1 #endif ld r1, [arc_cpu_wake_flag] brne r0, r1, _slave_core_wait ld sp, [arc_cpu_sp] /* signal master core that slave core runs */ st 0, [arc_cpu_wake_flag] #if defined(CONFIG_ARC_FIRQ_STACK) push r0 jl z_arc_firq_stack_set pop r0 #endif j z_arc_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_s sp, z_main_stack add sp, sp, CONFIG_MAIN_STACK_SIZE mov_s r0, z_interrupt_stacks mov_s r1, 0xaa mov_s r2, CONFIG_ISR_STACK_SIZE jl memset #endif /* CONFIG_INIT_STACKS */ mov_s sp, INIT_STACK add sp, sp, INIT_STACK_SIZE #if defined(CONFIG_ARC_FIRQ_STACK) jl z_arc_firq_stack_set #endif j _PrepC |