blob: ada7c7af22d59bff59a001f4717133a04704a0cc [file] [log] [blame]
Wolfgang Denkad5bb452007-03-06 18:08:43 +01001/*
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
Wolfgang Denkad5bb452007-03-06 18:08:43 +010049#include <post.h>
50#include "cpu_asm.h"
51
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020052#if CONFIG_POST & CONFIG_SYS_POST_CPU
Wolfgang Denkad5bb452007-03-06 18:08:43 +010053
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};
Mike Frysingerd2397812011-05-10 07:28:35 +000062static unsigned int cpu_post_cr_size1 = ARRAY_SIZE(cpu_post_cr_table1);
Wolfgang Denkad5bb452007-03-06 18:08:43 +010063
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};
Mike Frysingerd2397812011-05-10 07:28:35 +000078static unsigned int cpu_post_cr_size2 = ARRAY_SIZE(cpu_post_cr_table2);
Wolfgang Denkad5bb452007-03-06 18:08:43 +010079
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};
Mike Frysingerd2397812011-05-10 07:28:35 +0000100static unsigned int cpu_post_cr_size3 = ARRAY_SIZE(cpu_post_cr_table3);
Wolfgang Denkad5bb452007-03-06 18:08:43 +0100101
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};
Mike Frysingerd2397812011-05-10 07:28:35 +0000240static unsigned int cpu_post_cr_size4 = ARRAY_SIZE(cpu_post_cr_table4);
Wolfgang Denkad5bb452007-03-06 18:08:43 +0100241
242int cpu_post_test_cr (void)
243{
244 int ret = 0;
245 unsigned int i;
246 unsigned long cr_sav;
Stefan Roesef2302d42008-08-06 14:05:38 +0200247 int flag = disable_interrupts();
Wolfgang Denkad5bb452007-03-06 18:08:43 +0100248
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
Stefan Roesef2302d42008-08-06 14:05:38 +0200347 if (flag)
348 enable_interrupts();
349
Wolfgang Denkad5bb452007-03-06 18:08:43 +0100350 return ret;
351}
352
353#endif