xref: /nrf52832-nimble/rt-thread/libcpu/arm/arm926/start_rvds.S (revision 104654410c56c573564690304ae786df310c91fc)
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-enddisbale 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