summaryrefslogtreecommitdiff
path: root/testing/examples/cortex/cm3-ftest.cfg
diff options
context:
space:
mode:
Diffstat (limited to 'testing/examples/cortex/cm3-ftest.cfg')
-rw-r--r--testing/examples/cortex/cm3-ftest.cfg143
1 files changed, 143 insertions, 0 deletions
diff --git a/testing/examples/cortex/cm3-ftest.cfg b/testing/examples/cortex/cm3-ftest.cfg
new file mode 100644
index 00000000..2dae2493
--- /dev/null
+++ b/testing/examples/cortex/cm3-ftest.cfg
@@ -0,0 +1,143 @@
+#
+# For each named Cortex-M3 vector_catch flag VECTOR ...
+# bus_err state_err
+# chk_err nocp_err
+# mm_err reset
+#
+# BUT NYET hard_err, int_err (their test cases don't yet work) ...
+#
+# Do the following:
+#
+# - Test #1: verify that OpenOCD ignores exceptions by default
+# + l_VECTOR (loads testcase to RAM)
+# + fault triggers loop-to-self exception "handler"
+# + "halt"
+# + observe fault "handling" -- loop-to-self from load_and_run (below)
+#
+# - Test #2: verify that "vector_catch" makes OpenOCD stops ignoring them
+# + cortex_m3 vector_catch none
+# + cortex_m3 vector_catch VECTOR
+# + l_VECTOR (loads testcase to RAM)
+# + fault triggers vector catch hardware
+# + observe OpenOCD entering debug state with no assistance
+#
+# NOTE "reset" includes the NVIC, so that test case gets its reset vector
+# from the flash, not from the vector table set up here. Which means that
+# for that vector_catch option, the Test #1 (above) "observe" step won't
+# use the SRAM address.
+#
+
+# we can fully automate test #2
+proc vector_test {tag} {
+ halt
+ # REVISIT -- annoying, we'd like to scrap vector_catch output
+ cortex_m3 vector_catch none
+ cortex_m3 vector_catch $tag
+ eval "l_$tag"
+}
+
+#
+# Load and start one vector_catch test case.
+#
+# name -- tag for the vector_catch flag being tested
+# halfwords -- array of instructions (some wide, some narrow)
+# n_instr -- how many instructions are in $halfwords
+#
+proc load_and_run { name halfwords n_instr } {
+ reset halt
+
+ # Load code at beginning of SRAM.
+ echo "# code to trigger $name vector"
+ set addr 0x20000000
+
+ # ocd_array2mem should be faster, though we'd need to
+ # compute the resulting $addr ourselves
+ foreach opcode $halfwords {
+ mwh $addr $opcode
+ incr addr 2
+ }
+
+ # create default loop-to-self at $addr ... it serves as
+ # (a) "main loop" on error
+ # (b) handler for all exceptions that get triggered
+ mwh $addr 0xe7fe
+
+ # disassemble, as sanity check and what's-happening trace
+ cortex_m3 disassemble 0x20000000 [expr 1 + $n_instr ]
+
+ # Assume that block of code is at most 16 halfwords long.
+ # Create a basic table of loop-to-self exception handlers.
+ mww 0x20000020 $addr 16
+ # Store its address in VTOR
+ mww 0xe000ed08 0x20000020
+ # Use SHCSR to ensure nothing escalates to a HardFault
+ mww 0xe000ed24 0x00070000
+
+ # now start, trigering the $name vector catch logic
+ resume 0x20000000
+}
+
+#proc l_hard_err {} {
+# IMPLEMENT ME
+# FORCED -- escalate something to HardFault
+#}
+
+#proc l_int_err {} {
+# IMPLEMENT ME
+# STKERR -- exception stack BusFault
+#}
+
+# BusFault, escalates to HardFault
+proc l_bus_err {} {
+ # PRECISERR -- assume less than 512 MBytes of SRAM
+ load_and_run bus_err {
+ 0xf06f 0x4040
+ 0x7800
+ } 2
+}
+
+# UsageFault, escalates to HardFault
+proc l_state_err {} {
+ # UNDEFINSTR -- issue architecturally undefined instruction
+ load_and_run state_err {
+ 0xde00
+ } 1
+}
+
+# UsageFault, escalates to HardFault
+proc l_chk_err {} {
+ # UNALIGNED -- LDM through unaligned pointer
+ load_and_run chk_err {
+ 0xf04f 0x0001
+ 0xe890 0x0006
+ } 2
+}
+
+# UsageFault, escalates to HardFault
+proc l_nocp_err {} {
+ # NOCP -- issue cp14 DCC instruction
+ load_and_run nocp_err {
+ 0xee10 0x0e15
+ } 1
+}
+
+# MemManage, escalates to HardFault
+proc l_mm_err {} {
+ # IACCVIOL -- instruction fetch from an XN region
+ load_and_run mm_err {
+ 0xf04f 0x4060
+ 0x4687
+ } 2
+}
+
+proc l_reset {} {
+ # issue SYSRESETREQ via AIRCR
+ load_and_run reset {
+ 0xf04f 0x0104
+ 0xf2c0 0x51fa
+ 0xf44f 0x406d
+ 0xf100 0x000c
+ 0xf2ce 0x0000
+ 0x6001
+ } 6
+}