;/* ; * Copyright (c) 2006-2018, RT-Thread Development Team ; * ; * SPDX-License-Identifier: Apache-2.0 ; * ; * Change Logs: ; * Date Author Notes ; * 2011-08-14 weety first version ; * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP ; * 2015-04-21 ArdaFu Remove remap code. Using mmu to map vector table ; * 2015-06-04 aozima Align stack address to 8 byte. ; */ UND_STK_SIZE EQU 512 SVC_STK_SIZE EQU 4096 ABT_STK_SIZE EQU 512 IRQ_STK_SIZE EQU 1024 FIQ_STK_SIZE EQU 1024 SYS_STK_SIZE EQU 512 Heap_Size EQU 512 S_FRAME_SIZE EQU (18*4) ;72 S_PC EQU (15*4) ;R15 MODE_USR EQU 0X10 MODE_FIQ EQU 0X11 MODE_IRQ EQU 0X12 MODE_SVC EQU 0X13 MODE_ABT EQU 0X17 MODE_UND EQU 0X1B MODE_SYS EQU 0X1F MODEMASK EQU 0X1F NOINT EQU 0xC0 ;----------------------- Stack and Heap Definitions ---------------------------- AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE UND_STK_SIZE EXPORT UND_STACK_START UND_STACK_START ALIGN 8 SPACE ABT_STK_SIZE EXPORT ABT_STACK_START ABT_STACK_START ALIGN 8 SPACE FIQ_STK_SIZE EXPORT FIQ_STACK_START FIQ_STACK_START ALIGN 8 SPACE IRQ_STK_SIZE EXPORT IRQ_STACK_START IRQ_STACK_START ALIGN 8 SPACE SYS_STK_SIZE EXPORT SYS_STACK_START SYS_STACK_START ALIGN 8 SPACE SVC_STK_SIZE EXPORT SVC_STACK_START SVC_STACK_START Stack_Top __initial_sp __heap_base Heap_Mem SPACE Heap_Size __heap_limit PRESERVE8 ;--------------Jump vector table------------------------------------------------ EXPORT Entry_Point AREA RESET, CODE, READONLY ARM Entry_Point LDR PC, vector_reset LDR PC, vector_undef LDR PC, vector_swi LDR PC, vector_pabt LDR PC, vector_dabt LDR PC, vector_resv LDR PC, vector_irq LDR PC, vector_fiq vector_reset DCD Reset_Handler vector_undef DCD Undef_Handler vector_swi DCD SWI_Handler vector_pabt DCD PAbt_Handler vector_dabt DCD DAbt_Handler vector_resv DCD Resv_Handler vector_irq DCD IRQ_Handler vector_fiq DCD FIQ_Handler ;----------------- Reset Handler ----------------------------------------------- IMPORT rt_low_level_init IMPORT __main EXPORT Reset_Handler Reset_Handler ; set the cpu to SVC32 mode MRS R0,CPSR BIC R0,R0,#MODEMASK ORR R0,R0,#MODE_SVC:OR:NOINT MSR CPSR_cxsf,R0 ; Set CO-Processor ; little-end,disbale I/D Cache MMU, vector table is 0x00000000 MRC p15, 0, R0, c1, c0, 0 ; Read CP15 LDR R1, =0x00003085 ; set clear bits BIC R0, R0, R1 MCR p15, 0, R0, c1, c0, 0 ; Write CP15 ; Call low level init function, ; disable and clear all IRQs, Init MMU, Init interrupt controller, etc. LDR SP, =SVC_STACK_START LDR R0, =rt_low_level_init BLX R0 Setup_Stack ; Setup Stack for each mode MRS R0, CPSR BIC R0, R0, #MODEMASK ORR R1, R0, #MODE_UND:OR:NOINT MSR CPSR_cxsf, R1 ; Undef mode LDR SP, =UND_STACK_START ORR R1,R0,#MODE_ABT:OR:NOINT MSR CPSR_cxsf,R1 ; Abort mode LDR SP, =ABT_STACK_START ORR R1,R0,#MODE_IRQ:OR:NOINT MSR CPSR_cxsf,R1 ; IRQ mode LDR SP, =IRQ_STACK_START ORR R1,R0,#MODE_FIQ:OR:NOINT MSR CPSR_cxsf,R1 ; FIQ mode LDR SP, =FIQ_STACK_START ORR R1,R0,#MODE_SYS:OR:NOINT MSR CPSR_cxsf,R1 ; SYS/User mode LDR SP, =SYS_STACK_START ORR R1,R0,#MODE_SVC:OR:NOINT MSR CPSR_cxsf,R1 ; SVC mode LDR SP, =SVC_STACK_START ; Enter the C code LDR R0, =__main BLX R0 ;----------------- Exception Handler ------------------------------------------- IMPORT rt_hw_trap_udef IMPORT rt_hw_trap_swi IMPORT rt_hw_trap_pabt IMPORT rt_hw_trap_dabt IMPORT rt_hw_trap_resv IMPORT rt_hw_trap_irq IMPORT rt_hw_trap_fiq IMPORT rt_interrupt_enter IMPORT rt_interrupt_leave IMPORT rt_thread_switch_interrupt_flag IMPORT rt_interrupt_from_thread IMPORT rt_interrupt_to_thread Undef_Handler PROC SUB SP, SP, #S_FRAME_SIZE STMIA SP, {R0 - R12} ; Calling R0-R12 ADD R8, SP, #S_PC STMDB R8, {SP, LR} ; Calling SP, LR STR LR, [R8, #0] ; Save calling PC MRS R6, SPSR STR R6, [R8, #4] ; Save CPSR STR R0, [R8, #8] ; Save SPSR MOV R0, SP BL rt_hw_trap_udef ENDP SWI_Handler PROC BL rt_hw_trap_swi ENDP PAbt_Handler PROC BL rt_hw_trap_pabt ENDP DAbt_Handler PROC SUB SP, SP, #S_FRAME_SIZE STMIA SP, {R0 - R12} ; Calling R0-R12 ADD R8, SP, #S_PC STMDB R8, {SP, LR} ; Calling SP, LR STR LR, [R8, #0] ; Save calling PC MRS R6, SPSR STR R6, [R8, #4] ; Save CPSR STR R0, [R8, #8] ; Save SPSR MOV R0, SP BL rt_hw_trap_dabt ENDP Resv_Handler PROC BL rt_hw_trap_resv ENDP FIQ_Handler PROC STMFD SP!, {R0-R7,LR} BL rt_hw_trap_fiq LDMFD SP!, {R0-R7,LR} SUBS PC, LR, #4 ENDP IRQ_Handler PROC STMFD SP!, {R0-R12,LR} BL rt_interrupt_enter BL rt_hw_trap_irq BL rt_interrupt_leave ; If rt_thread_switch_interrupt_flag set, ; jump to rt_hw_context_switch_interrupt_do and don't return LDR R0, =rt_thread_switch_interrupt_flag LDR R1, [R0] CMP R1, #1 BEQ rt_hw_context_switch_interrupt_do LDMFD SP!, {R0-R12,LR} SUBS PC, LR, #4 ENDP ;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) ----------------- rt_hw_context_switch_interrupt_do PROC MOV R1, #0 ; Clear flag STR R1, [R0] ; Save to flag variable LDMFD SP!, {R0-R12,LR} ; Reload saved registers STMFD SP, {R0-R2} ; Save R0-R2 SUB R1, SP, #4*3 ; Save old task's SP to R1 SUB R2, LR, #4 ; Save old task's PC to R2 MRS R0, SPSR ; Get CPSR of interrupt thread MSR CPSR_c, #MODE_SVC:OR:NOINT ; Switch to SVC mode and no interrupt STMFD SP!, {R2} ; Push old task's PC STMFD SP!, {R3-R12,LR} ; Push old task's LR,R12-R3 LDMFD R1, {R1-R3} STMFD SP!, {R1-R3} ; Push old task's R2-R0 STMFD SP!, {R0} ; Push old task's CPSR LDR R4, =rt_interrupt_from_thread LDR R5, [R4] ; R5 = stack ptr in old tasks's TCB STR SP, [R5] ; Store SP in preempted tasks's TCB LDR R6, =rt_interrupt_to_thread LDR R6, [R6] ; R6 = stack ptr in new tasks's TCB LDR SP, [R6] ; Get new task's stack pointer LDMFD SP!, {R4} ; Pop new task's SPSR MSR SPSR_cxsf, R4 LDMFD SP!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC SPSR to CPSR ENDP ;******************************************************************************* ; User Stack and Heap initialization ;******************************************************************************* IF :DEF:__MICROLIB EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit ELSE IMPORT __use_two_region_memory EXPORT __user_initial_stackheap __user_initial_stackheap LDR R0, = Heap_Mem ; heap base LDR R1, = SVC_STACK_START ; stack base (top-address) LDR R2, = (Heap_Mem + Heap_Size) ; heap limit LDR R3, = (SVC_STACK_START - SVC_STK_SIZE) ; stack limit (low-address) BX LR ALIGN ENDIF END