1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <common.h>
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#include <post.h>
50#include "cpu_asm.h"
51
52#if CONFIG_POST & CONFIG_SYS_POST_CPU
53
54extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
55extern void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3);
56
57static ulong cpu_post_cr_table1[] =
58{
59 0xaaaaaaaa,
60 0x55555555,
61};
62static unsigned int cpu_post_cr_size1 = ARRAY_SIZE(cpu_post_cr_table1);
63
64static struct cpu_post_cr_s2 {
65 ulong xer;
66 ulong cr;
67} cpu_post_cr_table2[] =
68{
69 {
70 0xa0000000,
71 1
72 },
73 {
74 0x40000000,
75 5
76 },
77};
78static unsigned int cpu_post_cr_size2 = ARRAY_SIZE(cpu_post_cr_table2);
79
80static struct cpu_post_cr_s3 {
81 ulong cr;
82 ulong cs;
83 ulong cd;
84 ulong res;
85} cpu_post_cr_table3[] =
86{
87 {
88 0x01234567,
89 0,
90 4,
91 0x01230567
92 },
93 {
94 0x01234567,
95 7,
96 0,
97 0x71234567
98 },
99};
100static unsigned int cpu_post_cr_size3 = ARRAY_SIZE(cpu_post_cr_table3);
101
102static struct cpu_post_cr_s4 {
103 ulong cmd;
104 ulong cr;
105 ulong op1;
106 ulong op2;
107 ulong op3;
108 ulong res;
109} cpu_post_cr_table4[] =
110{
111 {
112 OP_CRAND,
113 0x0000ffff,
114 0,
115 16,
116 0,
117 0x0000ffff
118 },
119 {
120 OP_CRAND,
121 0x0000ffff,
122 16,
123 17,
124 0,
125 0x8000ffff
126 },
127 {
128 OP_CRANDC,
129 0x0000ffff,
130 0,
131 16,
132 0,
133 0x0000ffff
134 },
135 {
136 OP_CRANDC,
137 0x0000ffff,
138 16,
139 0,
140 0,
141 0x8000ffff
142 },
143 {
144 OP_CROR,
145 0x0000ffff,
146 0,
147 16,
148 0,
149 0x8000ffff
150 },
151 {
152 OP_CROR,
153 0x0000ffff,
154 0,
155 1,
156 0,
157 0x0000ffff
158 },
159 {
160 OP_CRORC,
161 0x0000ffff,
162 0,
163 16,
164 0,
165 0x0000ffff
166 },
167 {
168 OP_CRORC,
169 0x0000ffff,
170 0,
171 0,
172 0,
173 0x8000ffff
174 },
175 {
176 OP_CRXOR,
177 0x0000ffff,
178 0,
179 0,
180 0,
181 0x0000ffff
182 },
183 {
184 OP_CRXOR,
185 0x0000ffff,
186 0,
187 16,
188 0,
189 0x8000ffff
190 },
191 {
192 OP_CRNAND,
193 0x0000ffff,
194 0,
195 16,
196 0,
197 0x8000ffff
198 },
199 {
200 OP_CRNAND,
201 0x0000ffff,
202 16,
203 17,
204 0,
205 0x0000ffff
206 },
207 {
208 OP_CRNOR,
209 0x0000ffff,
210 0,
211 16,
212 0,
213 0x0000ffff
214 },
215 {
216 OP_CRNOR,
217 0x0000ffff,
218 0,
219 1,
220 0,
221 0x8000ffff
222 },
223 {
224 OP_CREQV,
225 0x0000ffff,
226 0,
227 0,
228 0,
229 0x8000ffff
230 },
231 {
232 OP_CREQV,
233 0x0000ffff,
234 0,
235 16,
236 0,
237 0x0000ffff
238 },
239};
240static unsigned int cpu_post_cr_size4 = ARRAY_SIZE(cpu_post_cr_table4);
241
242int cpu_post_test_cr (void)
243{
244 int ret = 0;
245 unsigned int i;
246 unsigned long cr_sav;
247 int flag = disable_interrupts();
248
249 asm ( "mfcr %0" : "=r" (cr_sav) : );
250
251 for (i = 0; i < cpu_post_cr_size1 && ret == 0; i++)
252 {
253 ulong cr = cpu_post_cr_table1[i];
254 ulong res;
255
256 unsigned long code[] =
257 {
258 ASM_MTCR(3),
259 ASM_MFCR(3),
260 ASM_BLR,
261 };
262
263 cpu_post_exec_11 (code, &res, cr);
264
265 ret = res == cr ? 0 : -1;
266
267 if (ret != 0)
268 {
269 post_log ("Error at cr1 test %d !\n", i);
270 }
271 }
272
273 for (i = 0; i < cpu_post_cr_size2 && ret == 0; i++)
274 {
275 struct cpu_post_cr_s2 *test = cpu_post_cr_table2 + i;
276 ulong res;
277 ulong xer;
278
279 unsigned long code[] =
280 {
281 ASM_MTXER(3),
282 ASM_MCRXR(test->cr),
283 ASM_MFCR(3),
284 ASM_MFXER(4),
285 ASM_BLR,
286 };
287
288 cpu_post_exec_21x (code, &res, &xer, test->xer);
289
290 ret = xer == 0 && ((res << (4 * test->cr)) & 0xe0000000) == test->xer ?
291 0 : -1;
292
293 if (ret != 0)
294 {
295 post_log ("Error at cr2 test %d !\n", i);
296 }
297 }
298
299 for (i = 0; i < cpu_post_cr_size3 && ret == 0; i++)
300 {
301 struct cpu_post_cr_s3 *test = cpu_post_cr_table3 + i;
302 ulong res;
303
304 unsigned long code[] =
305 {
306 ASM_MTCR(3),
307 ASM_MCRF(test->cd, test->cs),
308 ASM_MFCR(3),
309 ASM_BLR,
310 };
311
312 cpu_post_exec_11 (code, &res, test->cr);
313
314 ret = res == test->res ? 0 : -1;
315
316 if (ret != 0)
317 {
318 post_log ("Error at cr3 test %d !\n", i);
319 }
320 }
321
322 for (i = 0; i < cpu_post_cr_size4 && ret == 0; i++)
323 {
324 struct cpu_post_cr_s4 *test = cpu_post_cr_table4 + i;
325 ulong res;
326
327 unsigned long code[] =
328 {
329 ASM_MTCR(3),
330 ASM_12F(test->cmd, test->op3, test->op1, test->op2),
331 ASM_MFCR(3),
332 ASM_BLR,
333 };
334
335 cpu_post_exec_11 (code, &res, test->cr);
336
337 ret = res == test->res ? 0 : -1;
338
339 if (ret != 0)
340 {
341 post_log ("Error at cr4 test %d !\n", i);
342 }
343 }
344
345 asm ( "mtcr %0" : : "r" (cr_sav));
346
347 if (flag)
348 enable_interrupts();
349
350 return ret;
351}
352
353#endif
354