blob: da6ef3745d0cb0c74282071b1fee1be5fec77cdc [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
2 * (C) Copyright 2002
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24#include <common.h>
25
26/*
27 * CPU test
28 * Condition register istructions: mtcr, mfcr, mcrxr,
29 * crand, crandc, cror, crorc, crxor,
30 * crnand, crnor, creqv, mcrf
31 *
32 * The mtcrf/mfcr instructions is tested by loading different
33 * values into the condition register (mtcrf), moving its value
34 * to a general-purpose register (mfcr) and comparing this value
35 * with the expected one.
36 * The mcrxr instruction is tested by loading a fixed value
37 * into the XER register (mtspr), moving XER value to the
38 * condition register (mcrxr), moving it to a general-purpose
39 * register (mfcr) and comparing the value of this register with
40 * the expected one.
41 * The rest of instructions is tested by loading a fixed
42 * value into the condition register (mtcrf), executing each
43 * instruction several times to modify all 4-bit condition
44 * fields, moving the value of the conditional register to a
45 * general-purpose register (mfcr) and comparing it with the
46 * expected one.
47 */
48
49#ifdef CONFIG_POST
50
51#include <post.h>
52#include "cpu_asm.h"
53
54#if CONFIG_POST & CFG_POST_CPU
55
56extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
57extern void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3);
58
59static ulong cpu_post_cr_table1[] =
60{
61 0xaaaaaaaa,
62 0x55555555,
63};
64static unsigned int cpu_post_cr_size1 =
65 sizeof (cpu_post_cr_table1) / sizeof (ulong);
66
67static struct cpu_post_cr_s2 {
68 ulong xer;
69 ulong cr;
70} cpu_post_cr_table2[] =
71{
72 {
wdenk8bde7f72003-06-27 21:31:46 +000073 0xa0000000,
wdenkc6097192002-11-03 00:24:07 +000074 1
75 },
76 {
wdenk8bde7f72003-06-27 21:31:46 +000077 0x40000000,
wdenkc6097192002-11-03 00:24:07 +000078 5
79 },
80};
81static unsigned int cpu_post_cr_size2 =
82 sizeof (cpu_post_cr_table2) / sizeof (struct cpu_post_cr_s2);
83
84static struct cpu_post_cr_s3 {
85 ulong cr;
86 ulong cs;
87 ulong cd;
88 ulong res;
89} cpu_post_cr_table3[] =
90{
91 {
wdenk8bde7f72003-06-27 21:31:46 +000092 0x01234567,
wdenkc6097192002-11-03 00:24:07 +000093 0,
94 4,
95 0x01230567
96 },
97 {
wdenk8bde7f72003-06-27 21:31:46 +000098 0x01234567,
wdenkc6097192002-11-03 00:24:07 +000099 7,
100 0,
101 0x71234567
102 },
103};
104static unsigned int cpu_post_cr_size3 =
105 sizeof (cpu_post_cr_table3) / sizeof (struct cpu_post_cr_s3);
106
107static struct cpu_post_cr_s4 {
108 ulong cmd;
109 ulong cr;
110 ulong op1;
111 ulong op2;
112 ulong op3;
113 ulong res;
114} cpu_post_cr_table4[] =
115{
116 {
117 OP_CRAND,
wdenk8bde7f72003-06-27 21:31:46 +0000118 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000119 0,
120 16,
121 0,
wdenk8bde7f72003-06-27 21:31:46 +0000122 0x0000ffff
wdenkc6097192002-11-03 00:24:07 +0000123 },
124 {
125 OP_CRAND,
wdenk8bde7f72003-06-27 21:31:46 +0000126 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000127 16,
128 17,
129 0,
wdenk8bde7f72003-06-27 21:31:46 +0000130 0x8000ffff
wdenkc6097192002-11-03 00:24:07 +0000131 },
132 {
133 OP_CRANDC,
wdenk8bde7f72003-06-27 21:31:46 +0000134 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000135 0,
136 16,
137 0,
wdenk8bde7f72003-06-27 21:31:46 +0000138 0x0000ffff
wdenkc6097192002-11-03 00:24:07 +0000139 },
140 {
141 OP_CRANDC,
wdenk8bde7f72003-06-27 21:31:46 +0000142 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000143 16,
144 0,
145 0,
wdenk8bde7f72003-06-27 21:31:46 +0000146 0x8000ffff
wdenkc6097192002-11-03 00:24:07 +0000147 },
148 {
149 OP_CROR,
wdenk8bde7f72003-06-27 21:31:46 +0000150 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000151 0,
152 16,
153 0,
wdenk8bde7f72003-06-27 21:31:46 +0000154 0x8000ffff
wdenkc6097192002-11-03 00:24:07 +0000155 },
156 {
157 OP_CROR,
wdenk8bde7f72003-06-27 21:31:46 +0000158 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000159 0,
160 1,
161 0,
wdenk8bde7f72003-06-27 21:31:46 +0000162 0x0000ffff
wdenkc6097192002-11-03 00:24:07 +0000163 },
164 {
165 OP_CRORC,
wdenk8bde7f72003-06-27 21:31:46 +0000166 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000167 0,
168 16,
169 0,
wdenk8bde7f72003-06-27 21:31:46 +0000170 0x0000ffff
wdenkc6097192002-11-03 00:24:07 +0000171 },
172 {
173 OP_CRORC,
wdenk8bde7f72003-06-27 21:31:46 +0000174 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000175 0,
176 0,
177 0,
wdenk8bde7f72003-06-27 21:31:46 +0000178 0x8000ffff
wdenkc6097192002-11-03 00:24:07 +0000179 },
180 {
181 OP_CRXOR,
wdenk8bde7f72003-06-27 21:31:46 +0000182 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000183 0,
184 0,
185 0,
wdenk8bde7f72003-06-27 21:31:46 +0000186 0x0000ffff
wdenkc6097192002-11-03 00:24:07 +0000187 },
188 {
189 OP_CRXOR,
wdenk8bde7f72003-06-27 21:31:46 +0000190 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000191 0,
192 16,
193 0,
wdenk8bde7f72003-06-27 21:31:46 +0000194 0x8000ffff
wdenkc6097192002-11-03 00:24:07 +0000195 },
196 {
197 OP_CRNAND,
wdenk8bde7f72003-06-27 21:31:46 +0000198 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000199 0,
200 16,
201 0,
wdenk8bde7f72003-06-27 21:31:46 +0000202 0x8000ffff
wdenkc6097192002-11-03 00:24:07 +0000203 },
204 {
205 OP_CRNAND,
wdenk8bde7f72003-06-27 21:31:46 +0000206 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000207 16,
208 17,
209 0,
wdenk8bde7f72003-06-27 21:31:46 +0000210 0x0000ffff
wdenkc6097192002-11-03 00:24:07 +0000211 },
212 {
213 OP_CRNOR,
wdenk8bde7f72003-06-27 21:31:46 +0000214 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000215 0,
216 16,
217 0,
wdenk8bde7f72003-06-27 21:31:46 +0000218 0x0000ffff
wdenkc6097192002-11-03 00:24:07 +0000219 },
220 {
221 OP_CRNOR,
wdenk8bde7f72003-06-27 21:31:46 +0000222 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000223 0,
224 1,
225 0,
wdenk8bde7f72003-06-27 21:31:46 +0000226 0x8000ffff
wdenkc6097192002-11-03 00:24:07 +0000227 },
228 {
229 OP_CREQV,
wdenk8bde7f72003-06-27 21:31:46 +0000230 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000231 0,
232 0,
233 0,
wdenk8bde7f72003-06-27 21:31:46 +0000234 0x8000ffff
wdenkc6097192002-11-03 00:24:07 +0000235 },
236 {
237 OP_CREQV,
wdenk8bde7f72003-06-27 21:31:46 +0000238 0x0000ffff,
wdenkc6097192002-11-03 00:24:07 +0000239 0,
240 16,
241 0,
wdenk8bde7f72003-06-27 21:31:46 +0000242 0x0000ffff
wdenkc6097192002-11-03 00:24:07 +0000243 },
244};
245static unsigned int cpu_post_cr_size4 =
246 sizeof (cpu_post_cr_table4) / sizeof (struct cpu_post_cr_s4);
247
248int cpu_post_test_cr (void)
249{
250 int ret = 0;
251 unsigned int i;
252 unsigned long cr_sav;
253
254 asm ( "mfcr %0" : "=r" (cr_sav) : );
255
256 for (i = 0; i < cpu_post_cr_size1 && ret == 0; i++)
257 {
258 ulong cr = cpu_post_cr_table1[i];
259 ulong res;
260
wdenk8bde7f72003-06-27 21:31:46 +0000261 unsigned long code[] =
wdenkc6097192002-11-03 00:24:07 +0000262 {
263 ASM_MTCR(3),
264 ASM_MFCR(3),
265 ASM_BLR,
266 };
267
268 cpu_post_exec_11 (code, &res, cr);
269
270 ret = res == cr ? 0 : -1;
271
wdenk8bde7f72003-06-27 21:31:46 +0000272 if (ret != 0)
273 {
274 post_log ("Error at cr1 test %d !\n", i);
275 }
wdenkc6097192002-11-03 00:24:07 +0000276 }
277
278 for (i = 0; i < cpu_post_cr_size2 && ret == 0; i++)
279 {
280 struct cpu_post_cr_s2 *test = cpu_post_cr_table2 + i;
281 ulong res;
282 ulong xer;
283
wdenk8bde7f72003-06-27 21:31:46 +0000284 unsigned long code[] =
wdenkc6097192002-11-03 00:24:07 +0000285 {
286 ASM_MTXER(3),
287 ASM_MCRXR(test->cr),
288 ASM_MFCR(3),
289 ASM_MFXER(4),
290 ASM_BLR,
291 };
292
293 cpu_post_exec_21x (code, &res, &xer, test->xer);
294
295 ret = xer == 0 && ((res << (4 * test->cr)) & 0xe0000000) == test->xer ?
296 0 : -1;
297
wdenk8bde7f72003-06-27 21:31:46 +0000298 if (ret != 0)
299 {
300 post_log ("Error at cr2 test %d !\n", i);
301 }
wdenkc6097192002-11-03 00:24:07 +0000302 }
303
304 for (i = 0; i < cpu_post_cr_size3 && ret == 0; i++)
305 {
306 struct cpu_post_cr_s3 *test = cpu_post_cr_table3 + i;
307 ulong res;
308
wdenk8bde7f72003-06-27 21:31:46 +0000309 unsigned long code[] =
wdenkc6097192002-11-03 00:24:07 +0000310 {
311 ASM_MTCR(3),
312 ASM_MCRF(test->cd, test->cs),
313 ASM_MFCR(3),
314 ASM_BLR,
315 };
316
317 cpu_post_exec_11 (code, &res, test->cr);
318
319 ret = res == test->res ? 0 : -1;
320
wdenk8bde7f72003-06-27 21:31:46 +0000321 if (ret != 0)
322 {
323 post_log ("Error at cr3 test %d !\n", i);
324 }
wdenkc6097192002-11-03 00:24:07 +0000325 }
326
327 for (i = 0; i < cpu_post_cr_size4 && ret == 0; i++)
328 {
329 struct cpu_post_cr_s4 *test = cpu_post_cr_table4 + i;
330 ulong res;
331
wdenk8bde7f72003-06-27 21:31:46 +0000332 unsigned long code[] =
wdenkc6097192002-11-03 00:24:07 +0000333 {
334 ASM_MTCR(3),
335 ASM_12F(test->cmd, test->op3, test->op1, test->op2),
336 ASM_MFCR(3),
337 ASM_BLR,
338 };
339
340 cpu_post_exec_11 (code, &res, test->cr);
341
342 ret = res == test->res ? 0 : -1;
343
wdenk8bde7f72003-06-27 21:31:46 +0000344 if (ret != 0)
345 {
346 post_log ("Error at cr4 test %d !\n", i);
347 }
wdenkc6097192002-11-03 00:24:07 +0000348 }
349
350 asm ( "mtcr %0" : : "r" (cr_sav));
351
352 return ret;
353}
354
355#endif
356#endif