|
- #
- # 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
- arm 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
- }
|