aboutsummaryrefslogtreecommitdiff
path: root/testing/examples/cortex/cm3-ftest.cfg
blob: 2dae2493f83f54be8eb6fa26222531dd5bcb9e6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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
}