1;/* 2; * Copyright (c) 2006-2018, RT-Thread Development Team 3; * 4; * SPDX-License-Identifier: Apache-2.0 5; * 6; * Change Logs: 7; * Date Author Notes 8; * 2011-01-13 weety first version 9; * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP 10; * 2015-04-21 ArdaFu Remove remap code. Using mmu to map vector table 11; * 2015-06-04 aozima Align stack address to 8 byte. 12; */ 13 14#include "rt_low_level_init.h" 15 16#define S_FRAME_SIZE (18*4) ;72 17 18;#define S_SPSR (17*4) ;SPSR 19;#define S_CPSR (16*4) ;CPSR 20#define S_PC (15*4) ;R15 21;#define S_LR (14*4) ;R14 22;#define S_SP (13*4) ;R13 23 24;#define S_IP (12*4) ;R12 25;#define S_FP (11*4) ;R11 26;#define S_R10 (10*4) 27;#define S_R9 (9*4) 28;#define S_R8 (8*4) 29;#define S_R7 (7*4) 30;#define S_R6 (6*4) 31;#define S_R5 (5*4) 32;#define S_R4 (4*4) 33;#define S_R3 (3*4) 34;#define S_R2 (2*4) 35;#define S_R1 (1*4) 36;#define S_R0 (0*4) 37 38#define MODE_SYS 0x1F 39#define MODE_FIQ 0x11 40#define MODE_IRQ 0x12 41#define MODE_SVC 0x13 42#define MODE_ABT 0x17 43#define MODE_UND 0x1B 44#define MODEMASK 0x1F 45 46#define NOINT 0xC0 47 48;----------------------- Stack and Heap Definitions ---------------------------- 49 MODULE ?cstartup 50 SECTION .noinit:DATA:NOROOT(3) 51 DATA 52 53 ALIGNRAM 3 54 DS8 UND_STK_SIZE 55 PUBLIC UND_STACK_START 56UND_STACK_START: 57 58 ALIGNRAM 3 59 DS8 ABT_STK_SIZE 60 PUBLIC ABT_STACK_START 61ABT_STACK_START: 62 63 ALIGNRAM 3 64 DS8 FIQ_STK_SIZE 65 PUBLIC FIQ_STACK_START 66FIQ_STACK_START: 67 68 ALIGNRAM 3 69 DS8 IRQ_STK_SIZE 70 PUBLIC IRQ_STACK_START 71IRQ_STACK_START: 72 73 ALIGNRAM 3 74 DS8 SYS_STK_SIZE 75 PUBLIC SYS_STACK_START 76SYS_STACK_START: 77 78 ALIGNRAM 3 79 DS8 SVC_STK_SIZE 80 PUBLIC SVC_STACK_START 81SVC_STACK_START: 82 83;--------------Jump vector table------------------------------------------------ 84 SECTION .intvec:CODE:ROOT(2) 85 ARM 86 PUBLIC Entry_Point 87Entry_Point: 88__iar_init$$done: ; The interrupt vector is not needed 89 ; until after copy initialization is done 90 LDR PC, vector_reset 91 LDR PC, vector_undef 92 LDR PC, vector_swi 93 LDR PC, vector_pabt 94 LDR PC, vector_dabt 95 LDR PC, vector_resv 96 LDR PC, vector_irq 97 LDR PC, vector_fiq 98 99vector_reset: 100 DC32 Reset_Handler 101vector_undef: 102 DC32 Undef_Handler 103vector_swi: 104 DC32 SWI_Handler 105vector_pabt: 106 DC32 PAbt_Handler 107vector_dabt: 108 DC32 DAbt_Handler 109vector_resv: 110 DC32 Resv_Handler 111vector_irq: 112 DC32 IRQ_Handler 113vector_fiq: 114 DC32 FIQ_Handler 115 116;----------------- Reset Handler ----------------------------------------------- 117 EXTERN rt_low_level_init 118 EXTERN ?main 119 PUBLIC __iar_program_start 120__iar_program_start: 121Reset_Handler: 122 ; Set the cpu to SVC32 mode 123 MRS R0, CPSR 124 BIC R0, R0, #MODEMASK 125 ORR R0, R0, #MODE_SVC|NOINT 126 MSR CPSR_cxsf, R0 127 128 ; Set CO-Processor 129 ; little-end,disbale I/D Cache MMU, vector table is 0x00000000 130 MRC P15, 0, R0, C1, C0, 0 ; Read CP15 131 LDR R1, =0x00003085 ; set clear bits 132 BIC R0, R0, R1 133 MCR P15, 0, R0, C1, C0, 0 ; Write CP15 134 135 ; Call low level init function, 136 ; disable and clear all IRQs, Init MMU, Init interrupt controller, etc. 137 LDR SP, =SVC_STACK_START 138 LDR R0, =rt_low_level_init 139 BLX R0 140 141Setup_Stack: 142 ; Setup Stack for each mode 143 MRS R0, CPSR 144 BIC R0, R0, #MODEMASK 145 146 ORR R1, R0, #MODE_UND|NOINT 147 MSR CPSR_cxsf, R1 ; Undef mode 148 LDR SP, =UND_STACK_START 149 150 ORR R1,R0,#MODE_ABT|NOINT 151 MSR CPSR_cxsf,R1 ; Abort mode 152 LDR SP, =ABT_STACK_START 153 154 ORR R1,R0,#MODE_IRQ|NOINT 155 MSR CPSR_cxsf,R1 ; IRQ mode 156 LDR SP, =IRQ_STACK_START 157 158 ORR R1,R0,#MODE_FIQ|NOINT 159 MSR CPSR_cxsf,R1 ; FIQ mode 160 LDR SP, =FIQ_STACK_START 161 162 ORR R1,R0,#MODE_SYS|NOINT 163 MSR CPSR_cxsf,R1 ; SYS/User mode 164 LDR SP, =SYS_STACK_START 165 166 ORR R1,R0,#MODE_SVC|NOINT 167 MSR CPSR_cxsf,R1 ; SVC mode 168 LDR SP, =SVC_STACK_START 169 170 ; Enter the C code 171 LDR R0, =?main 172 BLX R0 173 174;----------------- Exception Handler ------------------------------------------- 175 IMPORT rt_hw_trap_udef 176 IMPORT rt_hw_trap_swi 177 IMPORT rt_hw_trap_pabt 178 IMPORT rt_hw_trap_dabt 179 IMPORT rt_hw_trap_resv 180 IMPORT rt_hw_trap_irq 181 IMPORT rt_hw_trap_fiq 182 183 IMPORT rt_interrupt_enter 184 IMPORT rt_interrupt_leave 185 IMPORT rt_thread_switch_interrupt_flag 186 IMPORT rt_interrupt_from_thread 187 IMPORT rt_interrupt_to_thread 188 189 SECTION .text:CODE:ROOT(2) 190 ARM 191Undef_Handler: 192 SUB SP, SP, #S_FRAME_SIZE 193 STMIA SP, {R0 - R12} ; Calling R0-R12 194 ADD R8, SP, #S_PC 195 STMDB R8, {SP, LR} ; Calling SP, LR 196 STR LR, [R8, #0] ; Save calling PC 197 MRS R6, SPSR 198 STR R6, [R8, #4] ; Save CPSR 199 STR R0, [R8, #8] ; Save SPSR 200 MOV R0, SP 201 BL rt_hw_trap_udef 202 203SWI_Handler: 204 BL rt_hw_trap_swi 205 206PAbt_Handler: 207 BL rt_hw_trap_pabt 208 209DAbt_Handler: 210 SUB SP, SP, #S_FRAME_SIZE 211 STMIA SP, {R0 - R12} ; Calling R0-R12 212 ADD R8, SP, #S_PC 213 STMDB R8, {SP, LR} ; Calling SP, LR 214 STR LR, [R8, #0] ; Save calling PC 215 MRS R6, SPSR 216 STR R6, [R8, #4] ; Save CPSR 217 STR R0, [R8, #8] ; Save SPSR 218 MOV R0, SP 219 BL rt_hw_trap_dabt 220 221Resv_Handler: 222 BL rt_hw_trap_resv 223 224IRQ_Handler: 225 STMFD SP!, {R0-R12,LR} 226 BL rt_interrupt_enter 227 BL rt_hw_trap_irq 228 BL rt_interrupt_leave 229 230 ; If rt_thread_switch_interrupt_flag set, 231 ; jump to rt_hw_context_switch_interrupt_do and don't return 232 LDR R0, =rt_thread_switch_interrupt_flag 233 LDR R1, [R0] 234 CMP R1, #1 235 BEQ rt_hw_context_switch_interrupt_do 236 237 LDMFD SP!, {R0-R12,LR} 238 SUBS PC, LR, #4 239 240FIQ_Handler: 241 STMFD SP!, {R0-R7,LR} 242 BL rt_hw_trap_fiq 243 LDMFD SP!, {R0-R7,LR} 244 SUBS PC, LR, #4 245 246;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) ----------------- 247rt_hw_context_switch_interrupt_do: 248 MOV R1, #0 ; Clear flag 249 STR R1, [R0] ; Save to flag variable 250 251 LDMFD SP!, {R0-R12,LR} ; Reload saved registers 252 STMFD SP, {R0-R2} ; Save R0-R2 253 SUB R1, SP, #4*3 ; Save old task's SP to R1 254 SUB R2, LR, #4 ; Save old task's PC to R2 255 256 MRS R0, SPSR ; Get CPSR of interrupt thread 257 258 MSR CPSR_c, #MODE_SVC|NOINT ; Switch to SVC mode and no interrupt 259 260 STMFD SP!, {R2} ; Push old task's PC 261 STMFD SP!, {R3-R12,LR} ; Push old task's LR,R12-R3 262 LDMFD R1, {R1-R3} 263 STMFD SP!, {R1-R3} ; Push old task's R2-R0 264 STMFD SP!, {R0} ; Push old task's CPSR 265 266 LDR R4, =rt_interrupt_from_thread 267 LDR R5, [R4] ; R5 = stack ptr in old tasks's TCB 268 STR SP, [R5] ; Store SP in preempted tasks's TCB 269 270 LDR R6, =rt_interrupt_to_thread 271 LDR R6, [R6] ; R6 = stack ptr in new tasks's TCB 272 LDR SP, [R6] ; Get new task's stack pointer 273 274 LDMFD SP!, {R4} ; Pop new task's SPSR 275 MSR SPSR_cxsf, R4 276 277 LDMFD SP!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC SPSR to CPSR 278 END 279