Cortex-M3 vector_catch testing support
[openocd.git] / testing / examples / cortex / fault.c
1 /*
2 * COMPILE: arm-none-eabi-gcc -mthumb -march=armv7-m ...
3 * ... plus, provide at least a default exception vector table.
4 *
5 * RUN: this is best run from SRAM. It starts at main() then triggers
6 * a fault before more than a handful of instructions have executed.
7 * Run each test case in two modes:
8 *
9 * (1) Faults caught on the Cortex-M3. Default handlers are usually
10 * loop-to-self NOPs, so a debugger won't notice faults until they
11 * halt the core and examine xSPR and other registers.
12 *
13 * To verify the fault triggered, issue "halt" from OpenOCD; you
14 * should be told about the fault and (some of) its details.
15 * Then it's time to run the next test.
16 *
17 * NOTE however that "reset" will restart everything; verify that
18 * case by observing your reset handler doing its normal work.
19 *
20 * (2) Faults intercepted by OpenOCD "vector_catch ..." commands.
21 *
22 * OpenOCD should tell you about the fault, and show the same
23 * details, without your "halt" command.
24 *
25 * Someday, a fancy version of this code could provide a vector table and
26 * fault handlers which use semihosting (when that works on Cortex-M3) to
27 * report what happened, again without needing a "halt" command.
28 */
29
30
31 /* These symbols match the OpenOCD "cortex_m3 vector_catch" bit names. */
32 enum vc_case {
33 hard_err,
34 int_err,
35 bus_err,
36 state_err,
37 chk_err,
38 nocp_err,
39 mm_err,
40 reset,
41 };
42
43 /* REVISIT come up with a way to avoid recompiling, maybe:
44 * - write it in RAM before starting
45 * - compiled-in BKPT, manual patch of r0, then resume
46 * - ...
47 */
48
49 #ifndef VC_ID
50 #warning "no VC_ID ... using reset"
51 #define VC_ID reset
52 #endif
53
54 int main(void) __attribute__ ((externally_visible, noreturn));
55
56 /*
57 * Trigger various Cortex-M3 faults to verify that OpenOCD behaves OK
58 * in terms of its vector_catch handling.
59 *
60 * Fault handling should be left entirely up to the application code
61 * UNLESS a "vector_catch" command tells OpenOCD to intercept a fault.
62 *
63 * See ARMv7-M architecure spec table B1-9 for the list of faults and
64 * their mappings to the vector catch bits.
65 */
66 int main(void)
67 {
68 /* One test case for each vector catch bit. We're not doing
69 * hardware testing; so it doesn't matter when some DEMCR bits
70 * could apply in multiple ways.
71 */
72 switch (VC_ID) {
73
74 /* "cortex_m3 vector_catch hard_err" */
75 case hard_err:
76 /* FORCED - Fault escalation */
77
78 /* FIXME code this */
79 break;
80
81 /* "cortex_m3 vector_catch int_err" */
82 case int_err:
83 /* STKERR -- Exception stack BusFault */
84
85 /* FIXME code this */
86 break;
87
88 /* "cortex_m3 vector_catch bus_err" */
89 case bus_err:
90 /* PRECISERR -- precise data bus read
91 * Here we assume a Cortex-M3 with 512 MBytes SRAM is very
92 * unlikely, so the last SRAM byte isn't a valid address.
93 */
94 __asm__ volatile(
95 "mov r0, #0x3fffffff\n"
96 "ldrb r0, [r0]\n"
97 );
98 break;
99
100 /* "cortex_m3 vector_catch state_err" */
101 case state_err:
102 /* UNDEFINSTR -- architectural undefined instruction */
103 __asm__ volatile(".hword 0xde00");
104 break;
105
106 /* "cortex_m3 vector_catch chk_err" */
107 case chk_err:
108 /* UNALIGNED ldm */
109 __asm__ volatile(
110 "mov r0, #1\n"
111 "ldm r0, {r1, r2}\n"
112 );
113 break;
114
115 /* "cortex_m3 vector_catch nocp_err" */
116 case nocp_err:
117 /* NOCP ... Cortex-M3 has no coprocessors (like CP14 DCC),
118 * but these instructions are allowed by ARMv7-M.
119 */
120 __asm__ volatile("mrc p14, 0, r0, c0, c5, 0");
121 break;
122
123 /* "cortex_m3 vector_catch mm_err" */
124 case mm_err:
125 /* IACCVIOL -- instruction fetch from an XN region */
126 __asm__ volatile(
127 "mov r0, #0xe0000000\n"
128 "mov pc, r0\n"
129 );
130 break;
131
132 /* "cortex_m3 vector_catch reset" */
133 case reset:
134 __asm__ volatile(
135 /* r1 = SYSRESETREQ */
136 "mov r1, #0x0004\n"
137 /* r1 |= VECTKEY */
138 "movt r1, #0x05fa\n"
139 /* r0 = &AIRCR */
140 "mov r0, #0xed00\n"
141 "add r0, #0xc\n"
142 "movt r0, #0xe000\n"
143 /* AIRCR = ... */
144 "str r1, [r0, #0]\n"
145 );
146 break;
147 }
148
149 /* don't return */
150 while (1)
151 continue;
152 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)