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-08-14 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 14UND_STK_SIZE EQU 512 15SVC_STK_SIZE EQU 4096 16ABT_STK_SIZE EQU 512 17IRQ_STK_SIZE EQU 1024 18FIQ_STK_SIZE EQU 1024 19SYS_STK_SIZE EQU 512 20Heap_Size EQU 512 21 22S_FRAME_SIZE EQU (18*4) ;72 23S_PC EQU (15*4) ;R15 24 25MODE_USR EQU 0X10 26MODE_FIQ EQU 0X11 27MODE_IRQ EQU 0X12 28MODE_SVC EQU 0X13 29MODE_ABT EQU 0X17 30MODE_UND EQU 0X1B 31MODE_SYS EQU 0X1F 32MODEMASK EQU 0X1F 33 34NOINT EQU 0xC0 35 36;----------------------- Stack and Heap Definitions ---------------------------- 37 AREA STACK, NOINIT, READWRITE, ALIGN=3 38Stack_Mem 39 40 SPACE UND_STK_SIZE 41 EXPORT UND_STACK_START 42UND_STACK_START 43 44 ALIGN 8 45 SPACE ABT_STK_SIZE 46 EXPORT ABT_STACK_START 47ABT_STACK_START 48 49 ALIGN 8 50 SPACE FIQ_STK_SIZE 51 EXPORT FIQ_STACK_START 52FIQ_STACK_START 53 54 ALIGN 8 55 SPACE IRQ_STK_SIZE 56 EXPORT IRQ_STACK_START 57IRQ_STACK_START 58 59 ALIGN 8 60 SPACE SYS_STK_SIZE 61 EXPORT SYS_STACK_START 62SYS_STACK_START 63 64 ALIGN 8 65 SPACE SVC_STK_SIZE 66 EXPORT SVC_STACK_START 67SVC_STACK_START 68Stack_Top 69__initial_sp 70 71__heap_base 72Heap_Mem SPACE Heap_Size 73__heap_limit 74 75 PRESERVE8 76;--------------Jump vector table------------------------------------------------ 77 EXPORT Entry_Point 78 AREA RESET, CODE, READONLY 79 ARM 80Entry_Point 81 LDR PC, vector_reset 82 LDR PC, vector_undef 83 LDR PC, vector_swi 84 LDR PC, vector_pabt 85 LDR PC, vector_dabt 86 LDR PC, vector_resv 87 LDR PC, vector_irq 88 LDR PC, vector_fiq 89 90vector_reset 91 DCD Reset_Handler 92vector_undef 93 DCD Undef_Handler 94vector_swi 95 DCD SWI_Handler 96vector_pabt 97 DCD PAbt_Handler 98vector_dabt 99 DCD DAbt_Handler 100vector_resv 101 DCD Resv_Handler 102vector_irq 103 DCD IRQ_Handler 104vector_fiq 105 DCD FIQ_Handler 106 107;----------------- Reset Handler ----------------------------------------------- 108 IMPORT rt_low_level_init 109 IMPORT __main 110 EXPORT Reset_Handler 111Reset_Handler 112 ; set the cpu to SVC32 mode 113 MRS R0,CPSR 114 BIC R0,R0,#MODEMASK 115 ORR R0,R0,#MODE_SVC:OR:NOINT 116 MSR CPSR_cxsf,R0 117 118 ; Set CO-Processor 119 ; little-end,disbale I/D Cache MMU, vector table is 0x00000000 120 MRC p15, 0, R0, c1, c0, 0 ; Read CP15 121 LDR R1, =0x00003085 ; set clear bits 122 BIC R0, R0, R1 123 MCR p15, 0, R0, c1, c0, 0 ; Write CP15 124 125 ; Call low level init function, 126 ; disable and clear all IRQs, Init MMU, Init interrupt controller, etc. 127 LDR SP, =SVC_STACK_START 128 LDR R0, =rt_low_level_init 129 BLX R0 130 131Setup_Stack 132 ; Setup Stack for each mode 133 MRS R0, CPSR 134 BIC R0, R0, #MODEMASK 135 136 ORR R1, R0, #MODE_UND:OR:NOINT 137 MSR CPSR_cxsf, R1 ; Undef mode 138 LDR SP, =UND_STACK_START 139 140 ORR R1,R0,#MODE_ABT:OR:NOINT 141 MSR CPSR_cxsf,R1 ; Abort mode 142 LDR SP, =ABT_STACK_START 143 144 ORR R1,R0,#MODE_IRQ:OR:NOINT 145 MSR CPSR_cxsf,R1 ; IRQ mode 146 LDR SP, =IRQ_STACK_START 147 148 ORR R1,R0,#MODE_FIQ:OR:NOINT 149 MSR CPSR_cxsf,R1 ; FIQ mode 150 LDR SP, =FIQ_STACK_START 151 152 ORR R1,R0,#MODE_SYS:OR:NOINT 153 MSR CPSR_cxsf,R1 ; SYS/User mode 154 LDR SP, =SYS_STACK_START 155 156 ORR R1,R0,#MODE_SVC:OR:NOINT 157 MSR CPSR_cxsf,R1 ; SVC mode 158 LDR SP, =SVC_STACK_START 159 160 ; Enter the C code 161 LDR R0, =__main 162 BLX R0 163 164;----------------- Exception Handler ------------------------------------------- 165 IMPORT rt_hw_trap_udef 166 IMPORT rt_hw_trap_swi 167 IMPORT rt_hw_trap_pabt 168 IMPORT rt_hw_trap_dabt 169 IMPORT rt_hw_trap_resv 170 IMPORT rt_hw_trap_irq 171 IMPORT rt_hw_trap_fiq 172 173 IMPORT rt_interrupt_enter 174 IMPORT rt_interrupt_leave 175 IMPORT rt_thread_switch_interrupt_flag 176 IMPORT rt_interrupt_from_thread 177 IMPORT rt_interrupt_to_thread 178 179Undef_Handler PROC 180 SUB SP, SP, #S_FRAME_SIZE 181 STMIA SP, {R0 - R12} ; Calling R0-R12 182 ADD R8, SP, #S_PC 183 STMDB R8, {SP, LR} ; Calling SP, LR 184 STR LR, [R8, #0] ; Save calling PC 185 MRS R6, SPSR 186 STR R6, [R8, #4] ; Save CPSR 187 STR R0, [R8, #8] ; Save SPSR 188 MOV R0, SP 189 BL rt_hw_trap_udef 190 ENDP 191 192SWI_Handler PROC 193 BL rt_hw_trap_swi 194 ENDP 195 196PAbt_Handler PROC 197 BL rt_hw_trap_pabt 198 ENDP 199 200DAbt_Handler PROC 201 SUB SP, SP, #S_FRAME_SIZE 202 STMIA SP, {R0 - R12} ; Calling R0-R12 203 ADD R8, SP, #S_PC 204 STMDB R8, {SP, LR} ; Calling SP, LR 205 STR LR, [R8, #0] ; Save calling PC 206 MRS R6, SPSR 207 STR R6, [R8, #4] ; Save CPSR 208 STR R0, [R8, #8] ; Save SPSR 209 MOV R0, SP 210 BL rt_hw_trap_dabt 211 ENDP 212 213Resv_Handler PROC 214 BL rt_hw_trap_resv 215 ENDP 216 217FIQ_Handler PROC 218 STMFD SP!, {R0-R7,LR} 219 BL rt_hw_trap_fiq 220 LDMFD SP!, {R0-R7,LR} 221 SUBS PC, LR, #4 222 ENDP 223 224IRQ_Handler PROC 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 ENDP 240 241;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) ----------------- 242rt_hw_context_switch_interrupt_do PROC 243 MOV R1, #0 ; Clear flag 244 STR R1, [R0] ; Save to flag variable 245 246 LDMFD SP!, {R0-R12,LR} ; Reload saved registers 247 STMFD SP, {R0-R2} ; Save R0-R2 248 SUB R1, SP, #4*3 ; Save old task's SP to R1 249 SUB R2, LR, #4 ; Save old task's PC to R2 250 251 MRS R0, SPSR ; Get CPSR of interrupt thread 252 253 MSR CPSR_c, #MODE_SVC:OR:NOINT ; Switch to SVC mode and no interrupt 254 255 STMFD SP!, {R2} ; Push old task's PC 256 STMFD SP!, {R3-R12,LR} ; Push old task's LR,R12-R3 257 LDMFD R1, {R1-R3} 258 STMFD SP!, {R1-R3} ; Push old task's R2-R0 259 STMFD SP!, {R0} ; Push old task's CPSR 260 261 LDR R4, =rt_interrupt_from_thread 262 LDR R5, [R4] ; R5 = stack ptr in old tasks's TCB 263 STR SP, [R5] ; Store SP in preempted tasks's TCB 264 265 LDR R6, =rt_interrupt_to_thread 266 LDR R6, [R6] ; R6 = stack ptr in new tasks's TCB 267 LDR SP, [R6] ; Get new task's stack pointer 268 269 LDMFD SP!, {R4} ; Pop new task's SPSR 270 MSR SPSR_cxsf, R4 271 272 LDMFD SP!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC SPSR to CPSR 273 ENDP 274 275;******************************************************************************* 276; User Stack and Heap initialization 277;******************************************************************************* 278 IF :DEF:__MICROLIB 279 280 EXPORT __initial_sp 281 EXPORT __heap_base 282 EXPORT __heap_limit 283 284 ELSE 285 286 IMPORT __use_two_region_memory 287 EXPORT __user_initial_stackheap 288 289__user_initial_stackheap 290 291 LDR R0, = Heap_Mem ; heap base 292 LDR R1, = SVC_STACK_START ; stack base (top-address) 293 LDR R2, = (Heap_Mem + Heap_Size) ; heap limit 294 LDR R3, = (SVC_STACK_START - SVC_STK_SIZE) ; stack limit (low-address) 295 BX LR 296 297 ALIGN 298 299 ENDIF 300 301 END 302