xref: /nrf52832-nimble/rt-thread/libcpu/arm/am335x/start_iar.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 * 2015-04-06     zchong      the first version
9 */
10
11        MODULE  ?cstartup
12
13        ; --------------------
14; Mode, correspords to bits 0-5 in CPSR
15
16MODE_MSK DEFINE 0x1F            ; Bit mask for mode bits in CPSR
17I_Bit    DEFINE 0x80            ; when I bit is set, IRQ is disabled
18F_Bit    DEFINE 0x40            ; when F bit is set, FIQ is disabled
19
20USR_MODE DEFINE 0x10            ; User mode
21FIQ_MODE DEFINE 0x11            ; Fast Interrupt Request mode
22IRQ_MODE DEFINE 0x12            ; Interrupt Request mode
23SVC_MODE DEFINE 0x13            ; Supervisor mode
24ABT_MODE DEFINE 0x17            ; Abort mode
25UND_MODE DEFINE 0x1B            ; Undefined Instruction mode
26SYS_MODE DEFINE 0x1F            ; System mode
27
28
29        ;; Forward declaration of sections.
30        SECTION IRQ_STACK:DATA:NOROOT(3)
31        SECTION FIQ_STACK:DATA:NOROOT(3)
32        SECTION SVC_STACK:DATA:NOROOT(3)
33        SECTION ABT_STACK:DATA:NOROOT(3)
34        SECTION UND_STACK:DATA:NOROOT(3)
35        SECTION CSTACK:DATA:NOROOT(3)
36        SECTION .text:CODE
37
38
39        SECTION .intvec:CODE:NOROOT(5)
40
41        PUBLIC  __vector
42        PUBLIC  __iar_program_start
43
44
45__iar_init$$done:               ; The vector table is not needed
46                                ; until after copy initialization is done
47
48__vector:                       ; Make this a DATA label, so that stack usage
49                                ; analysis doesn't consider it an uncalled fun
50        ARM
51
52        ; All default exception handlers (except reset) are
53        ; defined as weak symbol definitions.
54        ; If a handler is defined by the application it will take precedence.
55        LDR     PC,Reset_Addr           ; Reset
56        LDR     PC,Undefined_Addr       ; Undefined instructions
57        LDR     PC,SWI_Addr             ; Software interrupt (SWI/SVC)
58        LDR     PC,Prefetch_Addr        ; Prefetch abort
59        LDR     PC,Abort_Addr           ; Data abort
60        DCD     0                       ; RESERVED
61        LDR     PC,IRQ_Addr             ; IRQ
62        LDR     PC,FIQ_Addr             ; FIQ
63
64        DATA
65
66Reset_Addr:     DCD   __iar_program_start
67Undefined_Addr: DCD   Undefined_Handler
68SWI_Addr:       DCD   SWI_Handler
69Prefetch_Addr:  DCD   Prefetch_Handler
70Abort_Addr:     DCD   Abort_Handler
71IRQ_Addr:       DCD   IRQ_Handler
72FIQ_Addr:       DCD   FIQ_Handler
73
74
75; --------------------------------------------------
76; ?cstartup -- low-level system initialization code.
77;
78; After a reset execution starts here, the mode is ARM, supervisor
79; with interrupts disabled.
80;
81
82        SECTION .text:CODE:NOROOT(2)
83
84        EXTERN  rt_hw_trap_udef
85        EXTERN  rt_hw_trap_swi
86        EXTERN  rt_hw_trap_pabt
87        EXTERN  rt_hw_trap_dabt
88        EXTERN  rt_hw_trap_fiq
89        EXTERN  rt_hw_trap_irq
90        EXTERN  rt_interrupt_enter
91        EXTERN  rt_interrupt_leave
92        EXTERN  rt_thread_switch_interrupt_flag
93        EXTERN  rt_interrupt_from_thread
94        EXTERN  rt_interrupt_to_thread
95        EXTERN  rt_current_thread
96        EXTERN  vmm_thread
97        EXTERN  vmm_virq_check
98
99        EXTERN  __cmain
100        REQUIRE __vector
101        EXTWEAK __iar_init_core
102        EXTWEAK __iar_init_vfp
103
104
105        ARM
106
107__iar_program_start:
108?cstartup:
109
110;
111; Add initialization needed before setup of stackpointers here.
112;
113
114;
115; Initialize the stack pointers.
116; The pattern below can be used for any of the exception stacks:
117; FIQ, IRQ, SVC, ABT, UND, SYS.
118; The USR mode uses the same stack as SYS.
119; The stack segments must be defined in the linker command file,
120; and be declared above.
121;
122
123        MRS     r0, cpsr                ; Original PSR value
124
125        ;; Set up the interrupt stack pointer.
126        BIC     r0, r0, #MODE_MSK       ; Clear the mode bits
127        ORR     r0, r0, #IRQ_MODE       ; Set IRQ mode bits
128        MSR     cpsr_c, r0              ; Change the mode
129        LDR     sp, =SFE(IRQ_STACK)     ; End of IRQ_STACK
130        BIC     sp,sp,#0x7              ; Make sure SP is 8 aligned
131
132        ;; Set up the fast interrupt stack pointer.
133        BIC     r0, r0, #MODE_MSK       ; Clear the mode bits
134        ORR     r0, r0, #FIQ_MODE       ; Set FIR mode bits
135        MSR     cpsr_c, r0              ; Change the mode
136        LDR     sp, =SFE(FIQ_STACK)     ; End of FIQ_STACK
137        BIC     sp,sp,#0x7              ; Make sure SP is 8 aligned
138
139        BIC     r0,r0,#MODE_MSK         ; Clear the mode bits
140        ORR     r0,r0,#ABT_MODE         ; Set Abort mode bits
141        MSR     cpsr_c,r0               ; Change the mode
142        LDR     sp,=SFE(ABT_STACK)      ; End of ABT_STACK
143        BIC     sp,sp,#0x7              ; Make sure SP is 8 aligned
144
145        BIC     r0,r0,#MODE_MSK         ; Clear the mode bits
146        ORR     r0,r0,#UND_MODE         ; Set Undefined mode bits
147        MSR     cpsr_c,r0               ; Change the mode
148        LDR     sp,=SFE(UND_STACK)      ; End of UND_STACK
149        BIC     sp,sp,#0x7              ; Make sure SP is 8 aligned
150
151        ;; Set up the normal stack pointer.
152        BIC     r0 ,r0, #MODE_MSK       ; Clear the mode bits
153        ORR     r0 ,r0, #SVC_MODE       ; Set System mode bits
154        MSR     cpsr_c, r0              ; Change the mode
155        LDR     sp, =SFE(SVC_STACK)     ; End of SVC_STACK
156        BIC     sp,sp,#0x7              ; Make sure SP is 8 aligned
157
158        ;; Turn on core features assumed to be enabled.
159        BL      __iar_init_core
160
161        ;; Initialize VFP (if needed).
162        BL      __iar_init_vfp
163
164
165        ;; Continue to __cmain for C-level initialization.
166        B       __cmain
167
168
169Undefined_Handler:
170        SUB     sp, sp, #72
171        STMIA   sp, {r0 - r12}          ;/* Calling r0-r12                  */
172        ADD     r8, sp, #60
173
174        MRS     r1, cpsr
175        MRS     r2, spsr
176        ORR     r2,r2, #I_Bit | F_Bit
177        MSR     cpsr_c, r2
178        MOV     r0, r0
179        STMDB   r8, {sp, lr}            ;/* Calling SP, LR                  */
180        MSR     cpsr_c, r1              ;/* return to Undefined Instruction mode  */
181
182        STR     lr, [r8, #0]            ;/* Save calling PC                 */
183        MRS     r6, spsr
184        STR     r6, [r8, #4]            ;/* Save CPSR                       */
185        STR     r0, [r8, #8]            ;/* Save OLD_R0                     */
186        MOV     r0, sp
187
188        BL      rt_hw_trap_udef
189
190        LDMIA    sp, {r0 - r12}         ;/* Calling r0 - r2  */
191        MOV      r0, r0
192        LDR      lr, [sp, #60]          ;/* Get PC   */
193        ADD      sp, sp, #72
194        MOVS     pc, lr                 ;/* return & move spsr_svc into cpsr */
195
196SWI_Handler:
197        BL      rt_hw_trap_swi
198
199Prefetch_Handler:
200        BL      rt_hw_trap_pabt
201
202Abort_Handler:
203        SUB     sp, sp, #72
204        STMIA   sp, {r0 - r12}          ;/* Calling r0-r12                  */
205        ADD     r8, sp, #60
206        STMDB   r8, {sp, lr}            ;/* Calling SP, LR                  */
207        STR     lr, [r8, #0]            ;/* Save calling PC                 */
208        MRS     r6, spsr
209        STR     r6, [r8, #4]            ;/* Save CPSR                       */
210        STR     r0, [r8, #8]            ;/* Save OLD_R0                     */
211        MOV     r0, sp
212
213        BL      rt_hw_trap_dabt
214
215        LDMIA    sp, {r0 - r12}         ;/* Calling r0 - r2  */
216        MOV      r0, r0
217        LDR      lr, [sp, #60]          ;/* Get PC   */
218        ADD      sp, sp, #72
219        MOVS     pc, lr                 ;/* return & move spsr_svc into cpsr */
220
221FIQ_Handler:
222        STMFD   sp!,{r0-r7,lr}
223        BL      rt_hw_trap_fiq
224        LDMFD   sp!,{r0-r7,lr}
225        SUBS    pc,lr,#4
226
227IRQ_Handler:
228        STMFD   sp!, {r0-r12,lr}
229
230        BL      rt_interrupt_enter
231        BL      rt_hw_trap_irq
232        BL      rt_interrupt_leave
233
234        ; if rt_thread_switch_interrupt_flag set, jump to
235        ; rt_hw_context_switch_interrupt_do and don't return
236        LDR     r0, =rt_thread_switch_interrupt_flag
237        LDR     r1, [r0]
238        CMP     r1, #1
239        BEQ     rt_hw_context_switch_interrupt_do
240
241        LDMFD   sp!, {r0-r12,lr}
242        SUBS    pc, lr, #4
243
244rt_hw_context_switch_interrupt_do:
245        MOV     r1,  #0         ; clear flag
246        STR     r1,  [r0]
247
248        LDMFD   sp!, {r0-r12,lr}; reload saved registers
249        STMFD   sp,  {r0-r2}    ; save r0-r2
250
251        MRS     r0,  spsr       ; get cpsr of interrupt thread
252
253        SUB     r1,  sp, #4*3
254        SUB     r2,  lr, #4     ; save old task's pc to r2
255
256        ; switch to SVC mode with no interrupt
257        MSR     cpsr_c, #I_Bit | F_Bit | SVC_MODE
258
259        STMFD   sp!, {r2}       ; push old task's pc
260        STMFD   sp!, {r3-r12,lr}; push old task's lr,r12-r4
261        LDMFD   r1,  {r1-r3}    ; restore r0-r2 of the interrupt thread
262        STMFD   sp!, {r1-r3}    ; push old task's r0-r2
263        STMFD   sp!, {r0}       ; push old task's cpsr
264
265        LDR     r4,  =rt_interrupt_from_thread
266        LDR     r5,  [r4]
267        STR     sp,  [r5]       ; store sp in preempted tasks's TCB
268
269        LDR     r6,  =rt_interrupt_to_thread
270        LDR     r6,  [r6]
271        LDR     sp,  [r6]       ; get new task's stack pointer
272
273        LDMFD   sp!, {r4}       ; pop new task's cpsr to spsr
274        MSR     spsr_cxsf, r4
275
276        LDMFD   sp!, {r0-r12,lr,pc}^ ; pop new task's r0-r12,lr & pc, copy spsr to cpsr
277
278     END
279