]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - post/lib_powerpc/cr.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / post / lib_powerpc / cr.c
1 /*
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 #include <post.h>
50 #include "cpu_asm.h"
51
52 #if CONFIG_POST & CONFIG_SYS_POST_CPU
53
54 extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
55 extern void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3);
56
57 static ulong cpu_post_cr_table1[] =
58 {
59     0xaaaaaaaa,
60     0x55555555,
61 };
62 static unsigned int cpu_post_cr_size1 =
63     sizeof (cpu_post_cr_table1) / sizeof (ulong);
64
65 static 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 };
79 static unsigned int cpu_post_cr_size2 =
80     sizeof (cpu_post_cr_table2) / sizeof (struct cpu_post_cr_s2);
81
82 static 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 };
102 static unsigned int cpu_post_cr_size3 =
103     sizeof (cpu_post_cr_table3) / sizeof (struct cpu_post_cr_s3);
104
105 static 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 };
243 static unsigned int cpu_post_cr_size4 =
244     sizeof (cpu_post_cr_table4) / sizeof (struct cpu_post_cr_s4);
245
246 int cpu_post_test_cr (void)
247 {
248     int ret = 0;
249     unsigned int i;
250     unsigned long cr_sav;
251     int flag = disable_interrupts();
252
253     asm ( "mfcr %0" : "=r" (cr_sav) : );
254
255     for (i = 0; i < cpu_post_cr_size1 && ret == 0; i++)
256     {
257         ulong cr = cpu_post_cr_table1[i];
258         ulong res;
259
260         unsigned long code[] =
261         {
262             ASM_MTCR(3),
263             ASM_MFCR(3),
264             ASM_BLR,
265         };
266
267         cpu_post_exec_11 (code, &res, cr);
268
269         ret = res == cr ? 0 : -1;
270
271         if (ret != 0)
272         {
273             post_log ("Error at cr1 test %d !\n", i);
274         }
275     }
276
277     for (i = 0; i < cpu_post_cr_size2 && ret == 0; i++)
278     {
279         struct cpu_post_cr_s2 *test = cpu_post_cr_table2 + i;
280         ulong res;
281         ulong xer;
282
283         unsigned long code[] =
284         {
285             ASM_MTXER(3),
286             ASM_MCRXR(test->cr),
287             ASM_MFCR(3),
288             ASM_MFXER(4),
289             ASM_BLR,
290         };
291
292         cpu_post_exec_21x (code, &res, &xer, test->xer);
293
294         ret = xer == 0 && ((res << (4 * test->cr)) & 0xe0000000) == test->xer ?
295               0 : -1;
296
297         if (ret != 0)
298         {
299             post_log ("Error at cr2 test %d !\n", i);
300         }
301     }
302
303     for (i = 0; i < cpu_post_cr_size3 && ret == 0; i++)
304     {
305         struct cpu_post_cr_s3 *test = cpu_post_cr_table3 + i;
306         ulong res;
307
308         unsigned long code[] =
309         {
310             ASM_MTCR(3),
311             ASM_MCRF(test->cd, test->cs),
312             ASM_MFCR(3),
313             ASM_BLR,
314         };
315
316         cpu_post_exec_11 (code, &res, test->cr);
317
318         ret = res == test->res ? 0 : -1;
319
320         if (ret != 0)
321         {
322             post_log ("Error at cr3 test %d !\n", i);
323         }
324     }
325
326     for (i = 0; i < cpu_post_cr_size4 && ret == 0; i++)
327     {
328         struct cpu_post_cr_s4 *test = cpu_post_cr_table4 + i;
329         ulong res;
330
331         unsigned long code[] =
332         {
333             ASM_MTCR(3),
334             ASM_12F(test->cmd, test->op3, test->op1, test->op2),
335             ASM_MFCR(3),
336             ASM_BLR,
337         };
338
339         cpu_post_exec_11 (code, &res, test->cr);
340
341         ret = res == test->res ? 0 : -1;
342
343         if (ret != 0)
344         {
345             post_log ("Error at cr4 test %d !\n", i);
346         }
347     }
348
349     asm ( "mtcr %0" : : "r" (cr_sav));
350
351     if (flag)
352         enable_interrupts();
353
354     return ret;
355 }
356
357 #endif