tcl: add memory testing functions for board diagnostics
[openocd.git] / tcl / tools / memtest.tcl
1 # Algorithms by Michael Barr, released into public domain
2 # Ported to OpenOCD by Shane Volpe, additional fixes by Paul Fertser
3
4 set CPU_MAX_ADDRESS 0xFFFFFFFF
5 source [find bitsbytes.tcl]
6 source [find memory.tcl]
7
8 proc runAllMemTests { baseAddress nBytes } {
9 memTestDataBus $baseAddress
10 memTestAddressBus $baseAddress $nBytes
11 memTestDevice $baseAddress $nBytes
12 }
13
14 #***********************************************************************************
15 # *
16 # * Function: memTestDataBus()
17 # *
18 # * Description: Test the data bus wiring in a memory region by
19 # * performing a walking 1's test at a fixed address
20 # * within that region. The address (and hence the
21 # * memory region) is selected by the caller.
22 # * Ported from:
23 # * http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C
24 # * Notes:
25 # *
26 # * Returns: Empty string if the test succeeds.
27 # * A non-zero result is the first pattern that failed.
28 # *
29 #***********************************************************************************
30 proc memTestDataBus { address } {
31 echo "Running memTestDataBus"
32
33 for {set i 0} {$i < 32} {incr i} {
34 # Shift bit
35 set pattern [expr {1 << $i}]
36
37 # Write pattern to memory
38 memwrite32 $address $pattern
39
40 # Read pattern from memory
41 set data [memread32 $address]
42
43 if {$data != $pattern} {
44 echo "FAILED DATABUS: Address: $address, Pattern: $pattern, Returned: $data"
45 return $pattern
46 }
47 }
48 }
49
50 #***********************************************************************************
51 # *
52 # * Function: memTestAddressBus()
53 # *
54 # * Description: Perform a walking 1's test on the relevant bits
55 # * of the address and check for aliasing. This test
56 # * will find single-bit address failures such as stuck
57 # * -high, stuck-low, and shorted pins. The base address
58 # * and size of the region are selected by the caller.
59 # * Ported from:
60 # * http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C
61 # *
62 # * Notes: For best results, the selected base address should
63 # * have enough LSB 0's to guarantee single address bit
64 # * changes. For example, to test a 64-Kbyte region,
65 # * select a base address on a 64-Kbyte boundary. Also,
66 # * select the region size as a power-of-two--if at all
67 # * possible.
68 # *
69 # * Returns: Empty string if the test succeeds.
70 # * A non-zero result is the first address at which an
71 # * aliasing problem was uncovered. By examining the
72 # * contents of memory, it may be possible to gather
73 # * additional information about the problem.
74 # *
75 #***********************************************************************************
76 proc memTestAddressBus { baseAddress nBytes } {
77 set addressMask [expr $nBytes - 1]
78 set pattern 0xAAAAAAAA
79 set antipattern 0x55555555
80
81 echo "Running memTestAddressBus"
82
83 echo "addressMask: [convertToHex $addressMask]"
84
85 echo "memTestAddressBus: Writing the default pattern at each of the power-of-two offsets..."
86 for {set offset 32} {[expr $offset & $addressMask] != 0} {set offset [expr $offset << 1] } {
87 set addr [expr $baseAddress + $offset]
88 memwrite32 $addr $pattern
89 }
90
91 echo "memTestAddressBus: Checking for address bits stuck high..."
92 memwrite32 $baseAddress $antipattern
93
94 for {set offset 32} {[expr $offset & $addressMask] != 0} {set offset [expr $offset << 1]} {
95 set addr [expr $baseAddress + $offset]
96 set data [memread32 $addr]
97
98 if {$data != $pattern} {
99 echo "FAILED DATA_ADDR_BUS_SHIGH: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]"
100 return $pattern
101 }
102 }
103
104 echo "memTestAddressBus: Checking for address bits stuck low or shorted..."
105 memwrite32 $baseAddress $pattern
106 for {set testOffset 32} {[expr $testOffset & $addressMask] != 0} {set testOffset [expr $testOffset << 1] } {
107 set addr [expr $baseAddress + $testOffset]
108 memwrite32 $addr $antipattern
109
110 set data [memread32 $baseAddress]
111 if {$data != $pattern} {
112 echo "FAILED DATA_ADDR_BUS_SLOW: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]"
113 return $pattern
114 }
115
116 for {set offset 32} {[expr $offset & $addressMask] != 0} {set offset [expr $offset << 1]} {
117 set addr [expr $baseAddress + $offset]
118 set data [memread32 $baseAddress]
119
120 if {(($data != $pattern) && ($offset != $testOffset))} {
121 echo "FAILED DATA_ADDR_BUS_SLOW2: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset], testOffset [convertToHex $testOffset]"
122 return $pattern
123 }
124 }
125 set addr [expr $baseAddress + $testOffset]
126 memwrite32 $addr $pattern
127 }
128 }
129
130 #***********************************************************************************
131 # *
132 # * Function: memTestDevice()
133 # *
134 # * Description: Test the integrity of a physical memory device by
135 # * performing an increment/decrement test over the
136 # * entire region. In the process every storage bit
137 # * in the device is tested as zero and as one. The
138 # * base address and the size of the region are
139 # * selected by the caller.
140 # * Ported from:
141 # * http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C
142 # * Notes:
143 # *
144 # * Returns: Empty string if the test succeeds.
145 # * A non-zero result is the first address at which an
146 # * incorrect value was read back. By examining the
147 # * contents of memory, it may be possible to gather
148 # * additional information about the problem.
149 # *
150 #***********************************************************************************
151 proc memTestDevice { baseAddress nBytes } {
152 echo "Running memTestDevice"
153
154 echo "memTestDevice: Filling memory with a known pattern..."
155 for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {
156 memwrite32 [expr $baseAddress + $offset] $pattern
157 }
158
159 echo "memTestDevice: Checking each location and inverting it for the second pass..."
160 for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {
161 set addr [expr $baseAddress + $offset]
162 set data [memread32 $addr]
163
164 if {$data != $pattern} {
165 echo "FAILED memTestDevice_pattern: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset]"
166 return $pattern
167 }
168
169 set antiPattern [expr ~$pattern]
170 memwrite32 [expr $baseAddress + $offset] $antiPattern
171 }
172
173 echo "memTestDevice: Checking each location for the inverted pattern and zeroing it..."
174 for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {
175 set antiPattern [expr ~$pattern & ((1<<32) - 1)]
176 set addr [expr $baseAddress + $offset]
177 set data [memread32 $addr]
178 set dataHex [convertToHex $data]
179 set antiPatternHex [convertToHex $antiPattern]
180 if {[expr $dataHex != $antiPatternHex]} {
181 echo "FAILED memTestDevice_antipattern: Address: [convertToHex $addr], antiPattern: $antiPatternHex, Returned: $dataHex, offset: $offset"
182 return $pattern
183 }
184 }
185 }
186
187 proc convertToHex { value } {
188 format 0x%08x $value
189 }

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)