1/* 2 * Copyright (c) 2014 Wind River Systems, Inc. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7/** 8 * @file 9 * @brief Reset handler 10 * 11 * Reset handler that prepares the system for running C code. 12 */ 13 14#include <zephyr/toolchain.h> 15#include <zephyr/linker/sections.h> 16#include <zephyr/arch/cpu.h> 17#include <swap_macros.h> 18#include <zephyr/arch/arc/asm-compat/assembler.h> 19#ifdef CONFIG_ARC_EARLY_SOC_INIT 20 #include <soc_ctrl.h> 21#endif 22 23GDATA(z_interrupt_stacks) 24GDATA(z_main_stack) 25GDATA(_VectorTable) 26 27/* use one of the available interrupt stacks during init */ 28 29 30#define INIT_STACK z_interrupt_stacks 31#define INIT_STACK_SIZE CONFIG_ISR_STACK_SIZE 32 33GTEXT(__reset) 34GTEXT(__start) 35 36/** 37 * @brief Reset vector 38 * 39 * Ran when the system comes out of reset. The processor is at supervisor level. 40 * 41 * Locking interrupts prevents anything from interrupting the CPU. 42 * 43 * When these steps are completed, jump to _PrepC(), which will finish setting 44 * up the system for running C code. 45 */ 46 47SECTION_SUBSEC_FUNC(TEXT,_reset_and__start,__reset) 48SECTION_SUBSEC_FUNC(TEXT,_reset_and__start,__start) 49 /* lock interrupts: will get unlocked when switch to main task 50 * also make sure the processor in the correct status 51 */ 52 mov_s r0, 0 53 kflag r0 54 55#ifdef CONFIG_ARC_SECURE_FIRMWARE 56 sflag r0 57#endif 58 /* interrupt related init */ 59#ifndef CONFIG_ARC_NORMAL_FIRMWARE 60 /* IRQ_ACT and IRQ_CTRL should be initialized and set in secure mode */ 61 sr r0, [_ARC_V2_AUX_IRQ_ACT] 62 sr r0, [_ARC_V2_AUX_IRQ_CTRL] 63#endif 64 sr r0, [_ARC_V2_AUX_IRQ_HINT] 65 66 /* set the vector table base early, 67 * so that exception vectors can be handled. 68 */ 69 MOVR r0, _VectorTable 70#ifdef CONFIG_ARC_SECURE_FIRMWARE 71 sr r0, [_ARC_V2_IRQ_VECT_BASE_S] 72#else 73 SRR r0, [_ARC_V2_IRQ_VECT_BASE] 74#endif 75 76 lr r0, [_ARC_V2_STATUS32] 77 bset r0, r0, _ARC_V2_STATUS32_DZ_BIT 78 kflag r0 79 80#if defined(CONFIG_USERSPACE) 81 lr r0, [_ARC_V2_STATUS32] 82 bset r0, r0, _ARC_V2_STATUS32_US_BIT 83 kflag r0 84#endif 85 86#ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS 87 lr r0, [_ARC_V2_STATUS32] 88 bset r0, r0, _ARC_V2_STATUS32_AD_BIT 89 kflag r0 90#endif 91 92/* Invalidate icache */ 93 lr r0, [_ARC_V2_I_CACHE_BUILD] 94 and.f r0, r0, 0xff 95 bz.nd done_icache_invalidate 96 97 mov_s r2, 0 98 sr r2, [_ARC_V2_IC_IVIC] 99 /* writing to IC_IVIC needs 3 NOPs */ 100 nop_s 101 nop_s 102 nop_s 103done_icache_invalidate: 104 105/* Invalidate dcache */ 106 lr r3, [_ARC_V2_D_CACHE_BUILD] 107 and.f r3, r3, 0xff 108 bz.nd done_dcache_invalidate 109 110 mov_s r1, 1 111 sr r1, [_ARC_V2_DC_IVDC] 112 113done_dcache_invalidate: 114 115#ifdef CONFIG_ARC_EARLY_SOC_INIT 116 soc_early_asm_init_percpu 117#endif 118 119 _dsp_extension_probe 120 121/* 122 * Init ARC internal architecture state 123 * Force to initialize internal architecture state to reset values 124 * For scenarios where board hardware is not re-initialized between tests, 125 * some settings need to be restored to its default initial states as a 126 * substitution of normal hardware reset sequence. 127 */ 128#ifdef CONFIG_INIT_ARCH_HW_AT_BOOT 129 /* Set MPU (v4 or v8) registers to default */ 130#if CONFIG_ARC_MPU_VER == 4 || CONFIG_ARC_MPU_VER == 8 131 /* Set default reset value to _ARC_V2_MPU_EN register */ 132#define ARC_MPU_EN_RESET_VALUE 0x400181C0 133 mov_s r1, ARC_MPU_EN_RESET_VALUE 134 sr r1, [_ARC_V2_MPU_EN] 135 /* Get MPU region numbers */ 136 lr r3, [_ARC_V2_MPU_BUILD] 137 lsr_s r3, r3, 8 138 and r3, r3, 0xff 139 mov_s r1, 0 140 mov_s r2, 0 141 /* Set all MPU regions by iterating index */ 142mpu_regions_reset: 143 brge r2, r3, done_mpu_regions_reset 144 sr r2, [_ARC_V2_MPU_INDEX] 145 sr r1, [_ARC_V2_MPU_RSTART] 146 sr r1, [_ARC_V2_MPU_REND] 147 sr r1, [_ARC_V2_MPU_RPER] 148 add_s r2, r2, 1 149 b_s mpu_regions_reset 150done_mpu_regions_reset: 151#endif 152#endif 153 154#if defined(CONFIG_SMP) || CONFIG_MP_MAX_NUM_CPUS > 1 155 _get_cpu_id r0 156 breq r0, 0, _master_core_startup 157 158/* 159 * Non-masters wait for master core (core 0) to boot enough 160 */ 161_slave_core_wait: 162#if CONFIG_MP_MAX_NUM_CPUS == 1 163 kflag 1 164#endif 165 ld r1, [arc_cpu_wake_flag] 166 brne r0, r1, _slave_core_wait 167 168 LDR sp, arc_cpu_sp 169 /* signal master core that slave core runs */ 170 st 0, [arc_cpu_wake_flag] 171 172#if defined(CONFIG_ARC_FIRQ_STACK) 173 push r0 174 jl z_arc_firq_stack_set 175 pop r0 176#endif 177 j z_arc_slave_start 178 179_master_core_startup: 180#endif 181 182#ifdef CONFIG_INIT_STACKS 183 /* 184 * use the main stack to call memset on the interrupt stack and the 185 * FIRQ stack when CONFIG_INIT_STACKS is enabled before switching to 186 * one of them for the rest of the early boot 187 */ 188 mov_s sp, z_main_stack 189 add sp, sp, CONFIG_MAIN_STACK_SIZE 190 191 mov_s r0, z_interrupt_stacks 192 mov_s r1, 0xaa 193 mov_s r2, CONFIG_ISR_STACK_SIZE 194 jl memset 195 196#endif /* CONFIG_INIT_STACKS */ 197 198 mov_s sp, INIT_STACK 199 add sp, sp, INIT_STACK_SIZE 200 201#if defined(CONFIG_ARC_FIRQ_STACK) 202 jl z_arc_firq_stack_set 203#endif 204 205 j _PrepC 206