blob: d58d2bdeb4e875424dd516003c3df52ff7c5510b [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
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 <kernel/thread.h>
28#include <arch/arm/cm.h>
29#include <platform.h>
30
31static void dump_frame(const struct arm_cm_exception_frame *frame)
32{
33
34 printf("exception frame at %p\n", frame);
35 printf("\tr0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x r4 0x%08x\n",
36 frame->r0, frame->r1, frame->r2, frame->r3, frame->r4);
37 printf("\tr5 0x%08x r6 0x%08x r7 0x%08x r8 0x%08x r9 0x%08x\n",
38 frame->r5, frame->r6, frame->r7, frame->r8, frame->r9);
39 printf("\tr10 0x%08x r11 0x%08x r12 0x%08x\n",
40 frame->r10, frame->r11, frame->r12);
41 printf("\tlr 0x%08x pc 0x%08x psr 0x%08x\n",
42 frame->lr, frame->pc, frame->psr);
43}
44
45static void hardfault(struct arm_cm_exception_frame *frame)
46{
47 printf("hardfault: ");
48 dump_frame(frame);
49
50#if (__CORTEX_M >= 0X03) || (__CORTEX_SC >= 300)
51 printf("HFSR 0x%x\n", SCB->HFSR);
52#endif
53
54 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
55}
56
57static void memmanage(struct arm_cm_exception_frame *frame)
58{
59 printf("memmanage: ");
60 dump_frame(frame);
61
62#if (__CORTEX_M >= 0X03) || (__CORTEX_SC >= 300)
63 uint32_t mmfsr = SCB->CFSR & 0xff;
64
65 if (mmfsr & (1<<0)) { // IACCVIOL
66 printf("instruction fault\n");
67 }
68 if (mmfsr & (1<<1)) { // DACCVIOL
69 printf("data fault\n");
70 }
71 if (mmfsr & (1<<3)) { // MUNSTKERR
72 printf("fault on exception return\n");
73 }
74 if (mmfsr & (1<<4)) { // MSTKERR
75 printf("fault on exception entry\n");
76 }
77 if (mmfsr & (1<<5)) { // MLSPERR
78 printf("fault on lazy fpu preserve\n");
79 }
80 if (mmfsr & (1<<7)) { // MMARVALID
81 printf("fault address 0x%x\n", SCB->MMFAR);
82 }
83#endif
84 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
85}
86
87
88static void usagefault(struct arm_cm_exception_frame *frame)
89{
90 printf("usagefault: ");
91 dump_frame(frame);
92
93 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
94}
95
96static void busfault(struct arm_cm_exception_frame *frame)
97{
98 printf("busfault: ");
99 dump_frame(frame);
100
101 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
102}
103
104/* raw exception vectors */
105
106void _nmi(void)
107{
108 printf("nmi\n");
109 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
110}
111#if (__CORTEX_M >= 0X03) || (__CORTEX_SC >= 300)
112
113__NAKED void _hardfault(void)
114{
115 __asm__ volatile(
116 "push {r4-r11};"
117 "mov r0, sp;"
118 "b %0;"
119 :: "i" (hardfault)
120 );
121 __UNREACHABLE;
122}
123
124void _memmanage(void)
125{
126 __asm__ volatile(
127 "push {r4-r11};"
128 "mov r0, sp;"
129 "b %0;"
130 :: "i" (memmanage)
131 );
132 __UNREACHABLE;
133}
134
135void _busfault(void)
136{
137 __asm__ volatile(
138 "push {r4-r11};"
139 "mov r0, sp;"
140 "b %0;"
141 :: "i" (busfault)
142 );
143 __UNREACHABLE;
144}
145
146void _usagefault(void)
147{
148 __asm__ volatile(
149 "push {r4-r11};"
150 "mov r0, sp;"
151 "b %0;"
152 :: "i" (usagefault)
153 );
154 __UNREACHABLE;
155}
156#else
157
158__NAKED void _hardfault(void)
159{
160 struct arm_cm_exception_frame * frame;
161 __asm__ volatile(
162 "push {r4-r7};"
163 "mov r4, r8;"
164 "mov r5, r9;"
165 "mov r6, r10;"
166 "mov r7, r11;"
167 "push {r4-r7};"
168 "mov %0, sp;"
169 : "=r" (frame):
170 );
171
172 printf("hardfault: ");
173 dump_frame(frame);
174
175 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
176 __UNREACHABLE;
177}
178
179void _memmanage(void)
180{
181 struct arm_cm_exception_frame * frame;
182 __asm__ volatile(
183 "push {r4-r7};"
184 "mov r4, r8;"
185 "mov r5, r9;"
186 "mov r6, r10;"
187 "mov r7, r11;"
188 "push {r4-r7};"
189 "mov %0, sp;"
190 : "=r" (frame):
191 );
192 printf("memmanage: ");
193 dump_frame(frame);
194
195 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
196 __UNREACHABLE;
197}
198
199void _busfault(void)
200{
201 struct arm_cm_exception_frame * frame;
202 __asm__ volatile(
203 "push {r4-r7};"
204 "mov r4, r8;"
205 "mov r5, r9;"
206 "mov r6, r10;"
207 "mov r7, r11;"
208 "push {r4-r7};"
209 "mov %0, sp;"
210 : "=r" (frame):
211 );
212 printf("busfault: ");
213 dump_frame(frame);
214
215 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
216 __UNREACHABLE;
217}
218
219void _usagefault(void)
220{
221 struct arm_cm_exception_frame * frame;
222 __asm__ volatile(
223 "push {r4-r7};"
224 "mov r4, r8;"
225 "mov r5, r9;"
226 "mov r6, r10;"
227 "mov r7, r11;"
228 "push {r4-r7};"
229 "mov %0, sp;"
230 : "=r" (frame):
231 );
232 printf("usagefault: ");
233 dump_frame(frame);
234 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
235 __UNREACHABLE;
236}
237#endif
238/* systick handler */
239void __WEAK _systick(void)
240{
241 printf("systick\n");
242 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
243}
244
245void __WEAK _debugmonitor(void)
246{
247 printf("debugmonitor\n");
248 platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
249}