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 .
|