Commit | Line | Data |
---|---|---|
2ef2b01e A |
1 | #------------------------------------------------------------------------------ |
2 | # | |
3 | # Copyright (c) 2008-2009 Apple Inc. All rights reserved. | |
4 | # | |
5 | # All rights reserved. This program and the accompanying materials | |
6 | # are licensed and made available under the terms and conditions of the BSD License | |
7 | # which accompanies this distribution. The full text of the license may be found at | |
8 | # http://opensource.org/licenses/bsd-license.php | |
9 | # | |
10 | # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
11 | # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
12 | # | |
13 | #------------------------------------------------------------------------------ | |
14 | ||
15 | .text | |
16 | .align 3 | |
17 | ||
18 | .globl ASM_PFX(ExceptionHandlersStart) | |
19 | .globl ASM_PFX(ExceptionHandlersEnd) | |
20 | .globl ASM_PFX(CommonExceptionEntry) | |
21 | .globl ASM_PFX(AsmCommonExceptionEntry) | |
22 | .globl ASM_PFX(CommonCExceptionHandler) | |
23 | ||
24 | ASM_PFX(ExceptionHandlersStart): | |
25 | ||
26 | ASM_PFX(Reset): | |
27 | b ASM_PFX(ResetEntry) | |
28 | ||
29 | ASM_PFX(UndefinedInstruction): | |
30 | b ASM_PFX(UndefinedInstructionEntry) | |
31 | ||
32 | ASM_PFX(SoftwareInterrupt): | |
33 | b ASM_PFX(SoftwareInterruptEntry) | |
34 | ||
35 | ASM_PFX(PrefetchAbort): | |
36 | b ASM_PFX(PrefetchAbortEntry) | |
37 | ||
38 | ASM_PFX(DataAbort): | |
39 | b ASM_PFX(DataAbortEntry) | |
40 | ||
41 | ASM_PFX(ReservedException): | |
42 | b ASM_PFX(ReservedExceptionEntry) | |
43 | ||
44 | ASM_PFX(Irq): | |
45 | b ASM_PFX(IrqEntry) | |
46 | ||
47 | ASM_PFX(Fiq): | |
48 | b ASM_PFX(FiqEntry) | |
49 | ||
50 | ASM_PFX(ResetEntry): | |
51 | stmfd sp!,{r0-r1} | |
52 | mov r0,#0 | |
53 | ldr r1,ASM_PFX(CommonExceptionEntry) | |
54 | bx r1 | |
55 | ||
56 | ASM_PFX(UndefinedInstructionEntry): | |
57 | stmfd sp!,{r0-r1} | |
58 | mov r0,#1 | |
59 | ldr r1,ASM_PFX(CommonExceptionEntry) | |
60 | bx r1 | |
61 | ||
62 | ASM_PFX(SoftwareInterruptEntry): | |
63 | stmfd sp!,{r0-r1} | |
64 | mov r0,#2 | |
65 | ldr r1,ASM_PFX(CommonExceptionEntry) | |
66 | bx r1 | |
67 | ||
68 | ASM_PFX(PrefetchAbortEntry): | |
69 | stmfd sp!,{r0-r1} | |
70 | mov r0,#3 | |
71 | sub lr,lr,#4 | |
72 | ldr r1,ASM_PFX(CommonExceptionEntry) | |
73 | bx r1 | |
74 | ||
75 | ASM_PFX(DataAbortEntry): | |
76 | stmfd sp!,{r0-r1} | |
77 | mov r0,#4 | |
78 | sub lr,lr,#8 | |
79 | ldr r1,ASM_PFX(CommonExceptionEntry) | |
80 | bx r1 | |
81 | ||
82 | ASM_PFX(ReservedExceptionEntry): | |
83 | stmfd sp!,{r0-r1} | |
84 | mov r0,#5 | |
85 | ldr r1,ASM_PFX(CommonExceptionEntry) | |
86 | bx r1 | |
87 | ||
88 | ASM_PFX(IrqEntry): | |
89 | stmfd sp!,{r0-r1} | |
90 | mov r0,#6 | |
91 | sub lr,lr,#4 | |
92 | ldr r1,ASM_PFX(CommonExceptionEntry) | |
93 | bx r1 | |
94 | ||
95 | ASM_PFX(FiqEntry): | |
96 | stmfd sp!,{r0-r1} | |
97 | mov r0,#7 | |
98 | sub lr,lr,#4 | |
99 | ldr r1,ASM_PFX(CommonExceptionEntry) | |
100 | bx r1 | |
101 | ||
102 | ASM_PFX(CommonExceptionEntry): | |
103 | .byte 0x12 | |
104 | .byte 0x34 | |
105 | .byte 0x56 | |
106 | .byte 0x78 | |
107 | ||
108 | ASM_PFX(ExceptionHandlersEnd): | |
109 | ||
110 | ASM_PFX(AsmCommonExceptionEntry): | |
111 | mrc p15, 0, r1, c6, c0, 2 @ Read IFAR | |
112 | stmfd sp!,{r1} @ Store the IFAR | |
113 | ||
114 | mrc p15, 0, r1, c5, c0, 1 @ Read IFSR | |
115 | stmfd sp!,{r1} @ Store the IFSR | |
116 | ||
117 | mrc p15, 0, r1, c6, c0, 0 @ Read DFAR | |
118 | stmfd sp!,{r1} @ Store the DFAR | |
119 | ||
120 | mrc p15, 0, r1, c5, c0, 0 @ Read DFSR | |
121 | stmfd sp!,{r1} @ Store the DFSR | |
122 | ||
123 | mrs r1,spsr @ Read SPSR (which is the pre-exception CPSR) | |
124 | stmfd sp!,{r1} @ Store the SPSR | |
125 | ||
126 | stmfd sp!,{lr} @ Store the link register (which is the pre-exception PC) | |
127 | stmfd sp,{sp,lr}^ @ Store user/system mode stack pointer and link register | |
128 | nop @ Required by ARM architecture | |
129 | sub sp,sp,#0x08 @ Adjust stack pointer | |
130 | stmfd sp!,{r2-r12} @ Store general purpose registers | |
131 | ||
132 | ldr r3,[sp,#0x50] @ Read saved R1 from the stack (it was saved by the exception entry routine) | |
133 | ldr r2,[sp,#0x4C] @ Read saved R0 from the stack (it was saved by the exception entry routine) | |
134 | stmfd sp!,{r2-r3} @ Store general purpose registers R0 and R1 | |
135 | ||
136 | mov r1,sp @ Prepare System Context pointer as an argument for the exception handler | |
137 | ||
138 | sub sp,sp,#4 @ Adjust SP to preserve 8-byte alignment | |
139 | bl ASM_PFX(CommonCExceptionHandler) @ Call exception handler | |
140 | add sp,sp,#4 @ Adjust SP back to where we were | |
141 | ||
142 | ldr r2,[sp,#0x40] @ Load CPSR from context, in case it has changed | |
143 | msr SPSR_cxsf,r2 @ Store it back to the SPSR to be restored when exiting this handler | |
144 | ||
145 | ldmfd sp!,{r0-r12} @ Restore general purpose registers | |
146 | ldmia sp,{sp,lr}^ @ Restore user/system mode stack pointer and link register | |
147 | nop @ Required by ARM architecture | |
148 | add sp,sp,#0x08 @ Adjust stack pointer | |
149 | ldmfd sp!,{lr} @ Restore the link register (which is the pre-exception PC) | |
150 | add sp,sp,#0x1C @ Clear out the remaining stack space | |
151 | movs pc,lr @ Return from exception | |
152 |