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