1 /*
2 * Copyright (c) 2012-2013 Travis Geiselbrecht
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23 #include <debug.h>
24 #include <stdio.h>
25 #include <compiler.h>
26 #include <stdint.h>
27 #include <bits.h>
28 #include <kernel/thread.h>
29 #include <arch/arm/cm.h>
30 #include <platform.h>
31
dump_frame(const struct arm_cm_exception_frame * frame)32 static void dump_frame(const struct arm_cm_exception_frame *frame)
33 {
34
35 printf("exception frame at %p\n", frame);
36 printf("\tr0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x r4 0x%08x\n",
37 frame->r0, frame->r1, frame->r2, frame->r3, frame->r4);
38 printf("\tr5 0x%08x r6 0x%08x r7 0x%08x r8 0x%08x r9 0x%08x\n",
39 frame->r5, frame->r6, frame->r7, frame->r8, frame->r9);
40 printf("\tr10 0x%08x r11 0x%08x r12 0x%08x\n",
41 frame->r10, frame->r11, frame->r12);
42 printf("\tlr 0x%08x pc 0x%08x psr 0x%08x\n",
43 frame->lr, frame->pc, frame->psr);
44 }
45
hardfault(struct arm_cm_exception_frame * frame)46 static void hardfault(struct arm_cm_exception_frame *frame)
47 {
48 printf("hardfault: ");
49 dump_frame(frame);
50
51 #if (__CORTEX_M >= 0X03) || (__CORTEX_SC >= 300)
52 printf("HFSR 0x%x\n", SCB->HFSR);
53 #endif
54
55 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
56 }
57
memmanage(struct arm_cm_exception_frame * frame)58 static void memmanage(struct arm_cm_exception_frame *frame)
59 {
60 printf("memmanage: ");
61 dump_frame(frame);
62
63 #if (__CORTEX_M >= 0X03) || (__CORTEX_SC >= 300)
64 uint32_t mmfsr = SCB->CFSR & 0xff;
65
66 if (mmfsr & (1<<0)) { // IACCVIOL
67 printf("instruction fault\n");
68 }
69 if (mmfsr & (1<<1)) { // DACCVIOL
70 printf("data fault\n");
71 }
72 if (mmfsr & (1<<3)) { // MUNSTKERR
73 printf("fault on exception return\n");
74 }
75 if (mmfsr & (1<<4)) { // MSTKERR
76 printf("fault on exception entry\n");
77 }
78 if (mmfsr & (1<<5)) { // MLSPERR
79 printf("fault on lazy fpu preserve\n");
80 }
81 if (mmfsr & (1<<7)) { // MMARVALID
82 printf("fault address 0x%x\n", SCB->MMFAR);
83 }
84 #endif
85 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
86 }
87
88
usagefault(struct arm_cm_exception_frame * frame)89 static void usagefault(struct arm_cm_exception_frame *frame)
90 {
91 printf("usagefault: ");
92 dump_frame(frame);
93
94 #if (__CORTEX_M >= 0x03)
95 uint32_t ufsr = BITS_SHIFT(SCB->CFSR, 31, 16);
96 printf("UFSR 0x%x: ", ufsr);
97
98 if (ufsr & (1<<0))
99 printf("undefined instruction\n");
100 if (ufsr & (1<<1))
101 printf("ESPR invalid\n");
102 if (ufsr & (1<<2))
103 printf("integrity check failed on EXC_RETURN\n");
104 if (ufsr & (1<<3))
105 printf("coprocessor access error\n");
106 if (ufsr & (1<<8))
107 printf("unaligned error\n");
108 if (ufsr & (1<<9))
109 printf("division by zero\n");
110 #endif
111
112 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
113 }
114
busfault(struct arm_cm_exception_frame * frame)115 static void busfault(struct arm_cm_exception_frame *frame)
116 {
117 printf("busfault: ");
118 dump_frame(frame);
119
120 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
121 }
122
123 /* raw exception vectors */
124
_nmi(void)125 void _nmi(void)
126 {
127 printf("nmi\n");
128 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
129 }
130 #if (__CORTEX_M >= 0X03) || (__CORTEX_SC >= 300)
131
_hardfault(void)132 __NAKED void _hardfault(void)
133 {
134 __asm__ volatile(
135 "push {r4-r11};"
136 "mov r0, sp;"
137 "b %0;"
138 :: "i" (hardfault)
139 );
140 __UNREACHABLE;
141 }
142
_memmanage(void)143 void _memmanage(void)
144 {
145 __asm__ volatile(
146 "push {r4-r11};"
147 "mov r0, sp;"
148 "b %0;"
149 :: "i" (memmanage)
150 );
151 __UNREACHABLE;
152 }
153
_busfault(void)154 void _busfault(void)
155 {
156 __asm__ volatile(
157 "push {r4-r11};"
158 "mov r0, sp;"
159 "b %0;"
160 :: "i" (busfault)
161 );
162 __UNREACHABLE;
163 }
164
_usagefault(void)165 void _usagefault(void)
166 {
167 __asm__ volatile(
168 "push {r4-r11};"
169 "mov r0, sp;"
170 "b %0;"
171 :: "i" (usagefault)
172 );
173 __UNREACHABLE;
174 }
175 #else
176
_hardfault(void)177 __NAKED void _hardfault(void)
178 {
179 struct arm_cm_exception_frame *frame;
180 __asm__ volatile(
181 "push {r4-r7};"
182 "mov r4, r8;"
183 "mov r5, r9;"
184 "mov r6, r10;"
185 "mov r7, r11;"
186 "push {r4-r7};"
187 "mov %0, sp;"
188 : "=r" (frame):
189 );
190
191 printf("hardfault: ");
192 dump_frame(frame);
193
194 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
195 __UNREACHABLE;
196 }
197
_memmanage(void)198 void _memmanage(void)
199 {
200 struct arm_cm_exception_frame *frame;
201 __asm__ volatile(
202 "push {r4-r7};"
203 "mov r4, r8;"
204 "mov r5, r9;"
205 "mov r6, r10;"
206 "mov r7, r11;"
207 "push {r4-r7};"
208 "mov %0, sp;"
209 : "=r" (frame):
210 );
211 printf("memmanage: ");
212 dump_frame(frame);
213
214 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
215 __UNREACHABLE;
216 }
217
_busfault(void)218 void _busfault(void)
219 {
220 struct arm_cm_exception_frame *frame;
221 __asm__ volatile(
222 "push {r4-r7};"
223 "mov r4, r8;"
224 "mov r5, r9;"
225 "mov r6, r10;"
226 "mov r7, r11;"
227 "push {r4-r7};"
228 "mov %0, sp;"
229 : "=r" (frame):
230 );
231 printf("busfault: ");
232 dump_frame(frame);
233
234 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
235 __UNREACHABLE;
236 }
237
_usagefault(void)238 void _usagefault(void)
239 {
240 struct arm_cm_exception_frame *frame;
241 __asm__ volatile(
242 "push {r4-r7};"
243 "mov r4, r8;"
244 "mov r5, r9;"
245 "mov r6, r10;"
246 "mov r7, r11;"
247 "push {r4-r7};"
248 "mov %0, sp;"
249 : "=r" (frame):
250 );
251 printf("usagefault: ");
252 dump_frame(frame);
253 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
254 __UNREACHABLE;
255 }
256 #endif
257 /* systick handler */
_systick(void)258 void __WEAK _systick(void)
259 {
260 printf("systick\n");
261 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
262 }
263
_debugmonitor(void)264 void __WEAK _debugmonitor(void)
265 {
266 printf("debugmonitor\n");
267 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
268 }
269