coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
memory_test.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <soc/emi.h>
4 
5 enum {
6  /* test patterns */
7  PATTERN0 = 0x00000000,
8  PATTERN1 = 0x5A5A5A5A,
9  PATTERN2 = 0xA5A5A5A5,
10  PATTERN3 = 0xA5A5A500,
11  PATTERN4 = 0xA500A500,
12  PATTERN5 = 0xA5000000,
13  PATTERN6 = 0xFFFF0000,
14  PATTERN7 = 0x0000FFFF,
15  PATTERN8 = 0x00000012,
16  PATTERN9 = 0x00000034,
17  PATTERNA = 0x00000056,
18  PATTERNB = 0x00000078,
19  PATTERNC = 0x00001234,
20  PATTERND = 0x00005678,
21  PATTERNE = 0x12345678,
22  PATTERNF = 0xFFFFFFFF
23 };
24 
25 int complex_mem_test(u8 *start, unsigned int len)
26 {
27  unsigned char *mem8_base = (unsigned char *)start;
28  unsigned short *mem16_base = (unsigned short *)start;
29  unsigned int *mem32_base = (unsigned int *)start;
30  unsigned int *mem_base = (unsigned int *)start;
31  unsigned char pattern8;
32  unsigned short pattern16;
33  unsigned int i, j, size, pattern32;
34  unsigned int value;
35  uintptr_t p;
36 
37  size = len >> 2;
38 
39  /* verify the tied bits (tied high) */
40  for (i = 0; i < size; i++)
41  mem32_base[i] = PATTERN0;
42 
43  for (i = 0; i < size; i++) {
44  if (mem32_base[i] != PATTERN0)
45  return -1;
46 
47  mem32_base[i] = PATTERNF;
48  }
49 
50  /* verify the tied bits (tied low) */
51  for (i = 0; i < size; i++) {
52  if (mem32_base[i] != PATTERNF)
53  return -2;
54  mem32_base[i] = PATTERN0;
55  }
56 
57  /* verify pattern 1 (0x00~0xff) */
58  pattern8 = PATTERN0;
59  for (i = 0; i < len; i++)
60  mem8_base[i] = pattern8++;
61  pattern8 = PATTERN0;
62  for (i = 0; i < len; i++) {
63  if (mem8_base[i] != pattern8++)
64  return -3;
65  }
66 
67  /* verify pattern 2 (0x00~0xff) */
68  pattern8 = PATTERN0;
69  for (i = j = 0; i < len; i += 2, j++) {
70  if (mem8_base[i] == pattern8)
71  mem16_base[j] = pattern8;
72  if (mem16_base[j] != pattern8)
73  return -4;
74 
75  pattern8 += 2;
76  }
77 
78  /* verify pattern 3 (0x00~0xffff) */
79  pattern16 = PATTERN0;
80  for (i = 0; i < (len >> 1); i++)
81  mem16_base[i] = pattern16++;
82  pattern16 = PATTERN0;
83  for (i = 0; i < (len >> 1); i++) {
84  if (mem16_base[i] != pattern16++)
85  return -5;
86  }
87 
88  /* verify pattern 4 (0x00~0xffffffff) */
89  pattern32 = PATTERN0;
90  for (i = 0; i < (len >> 2); i++)
91  mem32_base[i] = pattern32++;
92  pattern32 = PATTERN0;
93  for (i = 0; i < (len >> 2); i++) {
94  if (mem32_base[i] != pattern32++)
95  return -6;
96  }
97 
98  /* pattern 5: filling memory range with 0x12345678 */
99  for (i = 0; i < size; i++)
100  mem32_base[i] = PATTERNE;
101 
102  /* read check then fill memory with a5a5a5a5 pattern */
103  for (i = 0; i < size; i++) {
104  if (mem32_base[i] != PATTERNE)
105  return -7;
106 
107  mem32_base[i] = PATTERN2;
108  }
109 
110  /* read check then fill memory with 00 byte pattern at offset 0h */
111  for (i = 0; i < size; i++) {
112  if (mem32_base[i] != PATTERN2)
113  return -8;
114 
115  mem8_base[i * 4] = PATTERN0;
116  }
117 
118  /* read check then fill memory with 00 byte pattern at offset 2h */
119  for (i = 0; i < size; i++) {
120  if (mem32_base[i] != PATTERN3)
121  return -9;
122 
123  mem8_base[i * 4 + 2] = PATTERN0;
124  }
125 
126  /* read check then fill memory with 00 byte pattern at offset 1h */
127  for (i = 0; i < size; i++) {
128  if (mem32_base[i] != PATTERN4)
129  return -10;
130 
131  mem8_base[i * 4 + 1] = PATTERN0;
132  }
133 
134  /* read check then fill memory with 00 byte pattern at offset 3h */
135  for (i = 0; i < size; i++) {
136  if (mem32_base[i] != PATTERN5)
137  return -11;
138 
139  mem8_base[i * 4 + 3] = PATTERN0;
140  }
141 
142  /* read check then fill memory with ffff word pattern at offset 1h */
143  for (i = 0; i < size; i++) {
144  if (mem32_base[i] != PATTERN0)
145  return -12;
146 
147  mem16_base[i * 2 + 1] = PATTERN7;
148  }
149 
150  /* read check then fill memory with ffff word pattern at offset 0h */
151  for (i = 0; i < size; i++) {
152  if (mem32_base[i] != PATTERN6)
153  return -13;
154 
155  mem16_base[i * 2] = PATTERN7;
156  }
157 
158  /* read check */
159  for (i = 0; i < size; i++) {
160  if (mem32_base[i] != PATTERNF)
161  return -14;
162  }
163 
164  /* stage 1 => write 0 */
165  for (i = 0; i < size; i++)
166  mem_base[i] = PATTERN1;
167 
168  /* stage 2 => read 0, write 0xf */
169  for (i = 0; i < size; i++) {
170  value = mem_base[i];
171 
172  if (value != PATTERN1)
173  return -15;
174 
175  mem_base[i] = PATTERN2;
176  }
177 
178  /* stage 3 => read 0xf, write 0 */
179  for (i = 0; i < size; i++) {
180  value = mem_base[i];
181  if (value != PATTERN2)
182  return -16;
183 
184  mem_base[i] = PATTERN1;
185  }
186 
187  /* stage 4 => read 0, write 0xf */
188  for (i = 0; i < size; i++) {
189  value = mem_base[i];
190  if (value != PATTERN1)
191  return -17;
192 
193  mem_base[i] = PATTERN2;
194  }
195 
196  /* stage 5 => read 0xf, write 0 */
197  for (i = 0; i < size; i++) {
198  value = mem_base[i];
199  if (value != PATTERN2)
200  return -18;
201 
202  mem_base[i] = PATTERN1;
203  }
204 
205  /* stage 6 => read 0 */
206  for (i = 0; i < size; i++) {
207  value = mem_base[i];
208  if (value != PATTERN1)
209  return -19;
210  }
211 
212  /* 1/2/4-byte combination test */
213  p = (uintptr_t)mem_base;
214 
215  while (p < (uintptr_t)mem_base + (size << 2)) {
216  *((unsigned char *)p) = PATTERNB;
217  p += 1;
218  *((unsigned char *)p) = PATTERNA;
219  p += 1;
220  *((unsigned short *)p) = PATTERNC;
221  p += 2;
222  *((unsigned int *)p) = PATTERNE;
223  p += 4;
224  *((unsigned short *)p) = PATTERND;
225  p += 2;
226  *((unsigned char *)p) = PATTERN9;
227  p += 1;
228  *((unsigned char *)p) = PATTERN8;
229  p += 1;
230  *((unsigned int *)p) = PATTERNE;
231  p += 4;
232  *((unsigned char *)p) = PATTERNB;
233  p += 1;
234  *((unsigned char *)p) = PATTERNA;
235  p += 1;
236  *((unsigned short *)p) = PATTERNC;
237  p += 2;
238  *((unsigned int *)p) = PATTERNE;
239  p += 4;
240  *((unsigned short *)p) = PATTERND;
241  p += 2;
242  *((unsigned char *)p) = PATTERN9;
243  p += 1;
244  *((unsigned char *)p) = PATTERN8;
245  p += 1;
246  *((unsigned int *)p) = PATTERNE;
247  p += 4;
248  }
249 
250  for (i = 0; i < size; i++) {
251  value = mem_base[i];
252  if (value != PATTERNE)
253  return -20;
254  }
255 
256  /* verify pattern 1 (0x00~0xff) */
257  pattern8 = PATTERN0;
258  mem8_base[0] = pattern8;
259  for (i = 0; i < size * 4; i++) {
260  unsigned char waddr8, raddr8;
261 
262  waddr8 = i + 1;
263  raddr8 = i;
264  if (i < size * 4 - 1)
265  mem8_base[waddr8] = pattern8 + 1;
266  if (mem8_base[raddr8] != pattern8)
267  return -21;
268 
269  pattern8++;
270  }
271 
272  /* verify pattern 2 (0x00~0xffff) */
273  pattern16 = PATTERN0;
274  mem16_base[0] = pattern16;
275  for (i = 0; i < size * 2; i++) {
276  if (i < size * 2 - 1)
277  mem16_base[i + 1] = pattern16 + 1;
278  if (mem16_base[i] != pattern16)
279  return -22;
280 
281  pattern16++;
282  }
283 
284  /* verify pattern 3 (0x00~0xffffffff) */
285  pattern32 = PATTERN0;
286  mem32_base[0] = pattern32;
287  for (i = 0; i < size; i++) {
288  if (i < size - 1)
289  mem32_base[i + 1] = pattern32 + 1;
290  if (mem32_base[i] != pattern32)
291  return -23;
292 
293  pattern32++;
294  }
295 
296  return 0;
297 }
pte_t value
Definition: mmu.c:91
@ PATTERN6
Definition: memory_test.c:13
@ PATTERNF
Definition: memory_test.c:22
@ PATTERNC
Definition: memory_test.c:19
@ PATTERN5
Definition: memory_test.c:12
@ PATTERN2
Definition: memory_test.c:9
@ PATTERNE
Definition: memory_test.c:21
@ PATTERND
Definition: memory_test.c:20
@ PATTERN3
Definition: memory_test.c:10
@ PATTERN7
Definition: memory_test.c:14
@ PATTERN0
Definition: memory_test.c:7
@ PATTERNB
Definition: memory_test.c:18
@ PATTERN1
Definition: memory_test.c:8
@ PATTERN4
Definition: memory_test.c:11
@ PATTERN9
Definition: memory_test.c:16
@ PATTERN8
Definition: memory_test.c:15
@ PATTERNA
Definition: memory_test.c:17
int complex_mem_test(u8 *start, unsigned int len)
Definition: memory_test.c:25
unsigned long uintptr_t
Definition: stdint.h:21
uint8_t u8
Definition: stdint.h:45