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