xref: /aosp_15_r20/external/coreboot/src/soc/mediatek/common/memory_test.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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 
complex_mem_test(u8 * start,unsigned int len)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 }
298