summaryrefslogtreecommitdiff
path: root/bsp/rdk/s100/startup/vector_gcc.S
blob: b622ace660be70eb3f7d06d89ee4355ee7fce08c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2013-07-05     Bernard      the first version
 */
 
.macro push_svc_reg pc_adjust
    sub     sp, sp, #17 * 4         @/* Sizeof(struct rt_hw_exp_stack)  */
    stmia   sp, {r0 - r12}          @/* Calling r0-r12                  */
    mov     r0, sp
    mrs     r6, spsr                @/* Save CPSR                       */
    sub     r5, lr, #\pc_adjust
    str     r5, [r0, #15*4]         @/* Push fault PC                   */
    str     r6, [r0, #16*4]         @/* Push CPSR                       */
    cps     #0x13                   @/* Switch to SVC mode               */
    str     sp, [r0, #13*4]         @/* Save calling SP                 */
    str     lr, [r0, #14*4]         @/* Save calling PC                 */
.endm

/*
    * EL2 exceptions are unexpected in the normal RT-Thread runtime because
    * the core has already descended into EL1. Keep the SDK policy simple:
    * capture a minimal register frame for diagnostics, then stop.
    */
.macro push_hyp_reg pc_adjust
    mov     r7, sp
    sub     sp, sp, #17 * 4
    stmia   sp, {r0 - r12}
    mov     r0, sp
    str     r7, [r0, #13*4]
    str     lr, [r0, #14*4]
    sub     r6, lr, #\pc_adjust
    str     r6, [r0, #15*4]
    mrs     r6, spsr
    str     r6, [r0, #16*4]
.endm

.globl SWI_Handler
SWI_Handler:
    push_svc_reg 4
    bl      rt_hw_trap_swi
    b       .

.globl Undefined_Handler
Undefined_Handler:
    push_svc_reg 4
	bl	rt_hw_trap_undef
    b   .

.globl SVC_Handler
SVC_Handler:
	push_svc_reg 4
	b	rt_hw_trap_svc
    b   .

.globl Prefetch_Handler
Prefetch_Handler:
    push_svc_reg 4
	b	rt_hw_trap_pabt
    b   .

.globl Abort_Handler
Abort_Handler:
    push_svc_reg 8
	b	rt_hw_trap_dabt
    b   .

.globl Reserved_Handler
Reserved_Handler:
    push_svc_reg 4
	b	rt_hw_trap_resv
    b   .

.globl FIQ_Handler
FIQ_Handler:
    stmdb   sp!, {r0-r12, lr}

#ifdef RT_USING_FPU
    vmrs    r0, fpexc
    tst     r0, #0x40000000
    beq     __no_vfp_frame_str_fiq
    vstmdb  sp!, {d0-d15}
    vmrs    r1, fpscr
    stmdb   sp!, {r1}
__no_vfp_frame_str_fiq:
    stmdb   sp!, {r0}
#endif

    bl      rt_interrupt_enter
    bl      rt_hw_trap_fiq
    bl      rt_interrupt_leave

#ifdef RT_USING_FPU
    ldmia   sp!, {r0}
    vmsr    fpexc, r0
    tst     r0, #0x40000000
    beq     __no_vfp_frame_ldr_fiq
    ldmia   sp!, {r1}
    vmsr    fpscr, r1
    vldmia  sp!, {d0-d15}
__no_vfp_frame_ldr_fiq:
#endif

    ldmia   sp!, {r0-r12, lr}
    subs    pc, lr, #4

.globl EL2_Undefined_Handler
EL2_Undefined_Handler:
    push_hyp_reg 4
    mov r1, #0
    b   .

.globl EL2_Prefetch_Handler
EL2_Prefetch_Handler:
    push_hyp_reg 4
    mov r1, #1
    b   .

.globl EL2_Abort_Handler
EL2_Abort_Handler:
    push_hyp_reg 8
    mov r1, #2
    b   .

.globl EL2_IRQ_Handler
EL2_IRQ_Handler:
    push_hyp_reg 4
    mov r1, #3
    b   .

.globl EL2_FIQ_Handler
EL2_FIQ_Handler:
    push_hyp_reg 4
    mov r1, #4
    b   .

.globl  EL2_HVC_Handler
EL2_HVC_Handler:
    push_hyp_reg 4
    mov r1, #5
    b   .

.globl  EL2_Trap_Handler
EL2_Trap_Handler:
    push_hyp_reg 4
    mov r1, #6
    b   .