Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/exception_handlers.S
1471 views
1
/*
2
* Copyright (c) 2019 CTCaer
3
*
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms and conditions of the GNU General Public License,
6
* version 2, as published by the Free Software Foundation.
7
*
8
* This program is distributed in the hope it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11
* more details.
12
*
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15
*/
16
17
/*
18
* Armv7tdmi Status register.
19
*
20
* bit0: Mode 0.
21
* bit1: Mode 1.
22
* bit2: Mode 2.
23
* bit3: Mode 3.
24
* bit4: Mode 4.
25
* bit5: Thumb state.
26
* bit6: FIQ disable.
27
* bit7: IRQ disable.
28
* bit8-27: Reserved.
29
* bit28: Overflow condition.
30
* bit29: Carry/Borrow/Extend condition.
31
* bit30: Zero condition.
32
* bit31: Negative/Less than condition.
33
*
34
* M[4:0] | Mode | Visible Thumb-state registers | Visible ARM-state registers
35
* 10000 | USER | r0–r7, SP, LR, PC, CPSR | r0–r14, PC, CPSR
36
* 10001 | FIQ | r0–r7, SP_fiq, LR_fiq, PC, CPSR, SPSR_fiq | r0–r7, r8_fiq–r14_fiq, PC, CPSR, SPSR_fiq
37
* 10010 | IRQ | r0–r7, SP_irq, LR_irq, PC, CPSR, SPSR_irq | r0–r12, r13_irq, r14_irq, PC, CPSR, SPSR_irq
38
* 10011 | SVC | r0–r7, SP_svc, LR_svc, PC, CPSR, SPSR_svc | r0–r12, r13_svc, r14_svc, PC, CPSR, SPSR_svc
39
* 10111 | ABRT | r0–r7, SP_abt, LR_abt, PC, CPSR, SPSR_abt | r0–r12, r13_abt, r14_abt, PC, CPSR, SPSR_abt
40
* 11011 | UNDF | r0–r7, SP_und, LR_und, PC, CPSR, SPSR_und | r0–r12, r13_und, r14_und, PC, CPSR, SPSR_und
41
* 11111 | SYS | r0–r7, SP, LR, PC, CPSR | r0–r14, PC, CPSR
42
*/
43
44
#define EXCP_EN_ADDR 0x4003FFFC
45
#define EXCP_TYPE_ADDR 0x4003FFF8
46
#define EXCP_LR_ADDR 0x4003FFF4
47
48
#define EXCP_VEC_BASE 0x6000F000
49
#define EVP_COP_RESET_VECTOR 0x200
50
#define EVP_COP_UNDEF_VECTOR 0x204
51
#define EVP_COP_SWI_VECTOR 0x208
52
#define EVP_COP_PREFETCH_ABORT_VECTOR 0x20C
53
#define EVP_COP_DATA_ABORT_VECTOR 0x210
54
#define EVP_COP_RSVD_VECTOR 0x214
55
#define EVP_COP_IRQ_VECTOR 0x218
56
#define EVP_COP_FIQ_VECTOR 0x21C
57
58
#define MODE_USR 0x10
59
#define MODE_FIQ 0x11
60
#define MODE_IRQ 0x12
61
#define MODE_SVC 0x13
62
#define MODE_ABT 0x17
63
#define MODE_UDF 0x1B
64
#define MODE_SYS 0x1F
65
#define MODE_MASK 0x1F
66
67
#define FIQ 0x40
68
#define IRQ 0x80
69
70
.section .text._irq_setup
71
.arm
72
73
.extern ipl_main
74
.type ipl_main, %function
75
76
.extern svc_handler
77
.type svc_handler, %function
78
79
.extern irq_handler
80
.type irq_handler, %function
81
82
.extern fiq_setup
83
.type fiq_setup, %function
84
85
.extern fiq_handler
86
.type fiq_handler, %function
87
88
.globl _irq_setup
89
.type _irq_setup, %function
90
_irq_setup:
91
MRS R0, CPSR
92
BIC R0, R0, #MODE_MASK /* Clear mode bits */
93
ORR R0, R0, #(MODE_SVC | IRQ | FIQ) /* SUPERVISOR mode, IRQ/FIQ disabled */
94
MSR CPSR, R0
95
96
/* Setup IRQ stack pointer */
97
MSR CPSR, #(MODE_IRQ | IRQ | FIQ) /* IRQ mode, IRQ/FIQ disabled */
98
LDR SP, =0x40040000
99
100
/* Setup FIQ stack pointer */
101
MSR CPSR, #(MODE_FIQ | IRQ | FIQ) /* FIQ mode, IRQ/FIQ disabled */
102
LDR SP, =0x40040000
103
104
/* Setup SYS stack pointer */
105
MSR CPSR, #(MODE_SYS | IRQ | FIQ) /* SYSTEM mode, IRQ/FIQ disabled */
106
LDR SP, =0x4003FF00 /* Will be changed later to DRAM */
107
108
MOV LR, PC
109
BL setup_vectors
110
/*BL fiq_setup*/
111
112
/* Enable interrupts */
113
BL irq_enable_cpu_irq_exceptions
114
115
B ipl_main
116
B .
117
118
.globl excp_reset
119
.type excp_reset, %function
120
excp_reset:
121
LDR R0, =EXCP_EN_ADDR
122
LDR R1, =0x30505645 /* EVP0 */
123
STR R1, [R0] /* EVP0 in EXCP_EN_ADDR */
124
LDR R0, =EXCP_LR_ADDR
125
MOV R1, LR
126
STR R1, [R0] /* Save LR in EXCP_LR_ADDR */
127
LDR R0, =__bss_start
128
EOR R1, R1, R1
129
LDR R2, =__bss_end
130
SUB R2, R2, R0
131
BL memset
132
B _irq_setup
133
134
_reset_handler:
135
LDR R0, =EXCP_TYPE_ADDR
136
LDR R1, =0x545352 /* RST */
137
STR R1, [R0] /* RST in EXCP_TYPE_ADDR */
138
B excp_reset
139
140
_undefined_handler:
141
LDR R0, =EXCP_TYPE_ADDR
142
LDR R1, =0x464455 /* UDF */
143
STR R1, [R0] /* UDF in EXCP_TYPE_ADDR */
144
B excp_reset
145
146
_prefetch_abort_handler:
147
LDR R0, =EXCP_TYPE_ADDR
148
LDR R1, =0x54424150 /* PABT */
149
STR R1, [R0] /* PABT in EXCP_TYPE_ADDR */
150
B excp_reset
151
152
_data_abort_handler:
153
LDR R0, =EXCP_TYPE_ADDR
154
LDR R1, =0x54424144 /* DABT */
155
STR R1, [R0] /* DABT in EXCP_TYPE_ADDR */
156
B excp_reset
157
158
.globl irq_enable_cpu_irq_exceptions
159
.type irq_enable_cpu_irq_exceptions, %function
160
irq_enable_cpu_irq_exceptions:
161
MRS R12, CPSR
162
BIC R12, R12, #(IRQ | FIQ) /* IRQ/FIQ enabled */
163
MSR CPSR, R12
164
BX LR
165
166
.globl irq_disable_cpu_irq_exceptions
167
.type irq_disable_cpu_irq_exceptions, %function
168
irq_disable_cpu_irq_exceptions:
169
MRS R12, CPSR
170
ORR R12, R12, #(IRQ | FIQ) /* IRQ/FIQ disabled */
171
MSR CPSR, R12
172
BX LR
173
174
_irq_handler:
175
MOV R13, R0 /* Save R0 in R13_IRQ */
176
SUB R0, LR, #4 /* Put return address in R0_SYS */
177
MOV LR, R1 /* Save R1 in R14_IRQ (LR) */
178
MRS R1, SPSR /* Put the SPSR in R1_SYS */
179
180
MSR CPSR_c, #(MODE_SYS | IRQ) /* SYSTEM mode, IRQ disabled */
181
STMFD SP!, {R0, R1} /* SPSR and PC */
182
STMFD SP!, {R2-R3, R12, LR} /* AAPCS-clobbered registers */
183
MOV R0, SP /* Make SP_SYS visible to IRQ mode */
184
SUB SP, SP, #8 /* Make room for stacking R0 and R1 */
185
186
MSR CPSR_c, #(MODE_IRQ | IRQ) /* IRQ mode, IRQ disabled */
187
STMFD R0!, {R13, R14} /* Finish saving the context (R0, R1) */
188
189
MSR CPSR_c, #(MODE_SYS | IRQ) /* SYSTEM mode, IRQ disabled */
190
LDR R12, =irq_handler
191
MOV LR, PC /* Copy the return address to link register */
192
BX R12 /* Call the C IRQ handler (ARM/THUMB) */
193
194
MSR CPSR_c, #(MODE_SYS | IRQ | FIQ) /* SYSTEM mode, IRQ/FIQ disabled */
195
MOV R0, SP /* Make SP_SYS visible to IRQ mode */
196
ADD SP, SP, #32 /* Fake unstacking 8 registers from SP_SYS */
197
198
MSR CPSR_c, #(MODE_IRQ | IRQ | FIQ) /* IRQ mode, IRQ/FIQ disabled */
199
MOV SP, R0 /* Copy SP_SYS to SP_IRQ */
200
LDR R0, [SP, #28] /* Load the saved SPSR from the stack */
201
MSR SPSR_cxsf, R0 /* Copy it into SPSR_IRQ */
202
203
LDMFD SP, {R0-R3, R12, LR}^ /* Unstack all saved USER/SYSTEM registers */
204
NOP /* Cant access barked registers immediately */
205
LDR LR, [SP, #24] /* Load return address from the SYS stack */
206
MOVS PC, LR /* Return restoring CPSR from SPSR */
207
208
_fiq_handler:
209
BL fiq_handler
210
211
setup_vectors:
212
/* Setup vectors */
213
LDR R0, =EXCP_VEC_BASE
214
215
LDR R1, =_reset_handler
216
STR R1, [R0, #EVP_COP_RESET_VECTOR]
217
218
LDR R1, =_undefined_handler
219
STR R1, [R0, #EVP_COP_UNDEF_VECTOR]
220
221
LDR R1, =_reset_handler
222
STR R1, [R0, #EVP_COP_SWI_VECTOR]
223
224
LDR R1, =_prefetch_abort_handler
225
STR R1, [R0, #EVP_COP_PREFETCH_ABORT_VECTOR]
226
227
LDR R1, =_data_abort_handler
228
STR R1, [R0, #EVP_COP_DATA_ABORT_VECTOR]
229
230
LDR R1, =_reset_handler
231
STR R1, [R0, #EVP_COP_RSVD_VECTOR]
232
233
LDR R1, =_irq_handler
234
STR R1, [R0, #EVP_COP_IRQ_VECTOR]
235
236
LDR R1, =_fiq_handler
237
STR R1, [R0, #EVP_COP_FIQ_VECTOR]
238
239
BX LR
240
241