aboutsummaryrefslogtreecommitdiff
path: root/Debug/ARMv7M
blob: 3d96da682db2d0a0b98ae56e4b8864b84fcf0914 (plain) (blame)
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
144
145
146
147
148
149
150
151
152
#
# Assorted ARMv7M macros
#

echo Loading ARMv7M GDB macros.  Use 'help armv7m' for more information.\n

define armv7m
	echo Use 'help armv7m' for more information.\n
end

document armv7m
. Various macros for working with the ARMv7M family of processors.
.
.    vecstate
.        Print information about the current exception handling state.
.
. Use 'help <macro>' for more specific help.
end


define vecstate
	set $icsr  = *(uint32_t *)0xe000ed04
	set $vect  = $icsr & 0x1ff
	set $pend  = ($icsr & 0x1ff000) >> 12
	set $shcsr = *(uint32_t *)0xe000ed24
	set $cfsr  = *(uint32_t *)0xe000ed28
	set $mmfsr = $cfsr & 0xff
	set $bfsr  = ($cfsr >> 8) & 0xff
	set $ufsr  = ($cfsr >> 16) & 0xffff
	set $hfsr  = *(uint32_t *)0xe000ed2c
	set $bfar  = *(uint32_t *)0xe000ed38
	set $mmfar = *(uint32_t *)0xe000ed34

	# XXX Currently, rather than look at $vect, we just decode the
	# fault status registers directly.

	if $hfsr != 0
		printf "HardFault:"
		if $hfsr & (1<<1)
			printf " due to vector table read fault\n"
		end
		if $hfsr & (1<<30)
			printf " forced ue to escalated or disabled configurable fault (see below)\n"
		end
		if $hfsr & (1<<31)
			printf " due to an unexpected debug event\n"
		end
	end
	if $mmfsr != 0
		printf "MemManage:"
		if $mmfsr & (1<<5)
			printf " during lazy FP state save"
		end
		if $mmfsr & (1<<4)
			printf " during exception entry"
		end
		if $mmfsr & (1<<3)
			printf " during exception return"
		end
		if $mmfsr & (1<<0)
			printf " during data access"
		end
		if $mmfsr & (1<<0)
			printf " during instruction prefetch"
		end
		if $mmfsr & (1<<7)
			printf " accessing 0x%08x", $mmfar
		end
		printf "\n"
	end
	if $bfsr != 0
		printf "BusFault:"
		if $bfsr & (1<<2)
			printf " (imprecise)"
		end
		if $bfsr & (1<<1)
			printf " (precise)"
		end
		if $bfsr & (1<<5)
			printf " during lazy FP state save"
		end
		if $bfsr & (1<<4)
			printf " during exception entry"
		end
		if $bfsr & (1<<3)
			printf " during exception return"
		end
		if $bfsr & (1<<0)
			printf " during instruction prefetch"
		end
		if $bfsr & (1<<7)
			printf " accessing 0x%08x", $bfar
		end
		printf "\n"
	end
	if $ufsr != 0
		printf "UsageFault"
		if $ufsr & (1<<9)
			printf " due to divide-by-zero"
		end
		if $ufsr & (1<<8)
			printf " due to unaligned memory access"
		end
		if $ufsr & (1<<3)
			printf " due to access to disabled/absent coprocessor"
		end
		if $ufsr & (1<<2)
			printf " due to a bad EXC_RETURN value"
		end
		if $ufsr & (1<<1)
			printf " due to bad T or IT bits in EPSR"
		end
		if $ufsr & (1<<0)
			printf " due to executing an undefined instruction"
		end
		printf "\n"
	end
	if ((uint32_t)$lr & 0xf0000000) == 0xf0000000
		if ($lr & 1)
			set $frame_ptr = (uint32_t *)$msp
		else
			set $frame_ptr = (uint32_t *)$psp
		end
		printf "  r0: %08x  r1: %08x  r2: %08x  r3: %08x\n, $frame_ptr[0], $frame_ptr[1], $frame_ptr[2], $frame_ptr[3]
		printf "  r4: %08x  r5: %08x  r6: %08x  r7: %08x\n", $r4, $r5, $r6, $r7
		printf "  r8: %08x  r9: %08x r10: %08x r11: %08x\n", $r8, $r9, $r10, $r11
		printf " r12: $08x  lr: %08x  pc: %08xx PSR: %08x\n", $frame_ptr[4], $frame_ptr[5], $frame_ptr[6], $frame_ptr[7]

		# Swap to the context of the faulting code and try to print a backtrace
		set $saved_sp = $sp
		if $lr & 0x10
			set $sp = $frame_ptr + (8 * 4)
		else
			set $sp = $frame_ptr + (26 * 4)
		end
		set $saved_lr = $lr
		set $lr = $frame_ptr[5]
		set $saved_pc = $pc
		set $pc = $frame_ptr[6]
		bt
		set $sp = $saved_sp
		set $lr = $saved_lr
		set $pc = $saved_pc
	else
		printf "(not currently in exception state)\n"
	end
end

document vecstate
.    vecstate
.        Print information about the current exception handling state.
end