]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - post/lib_powerpc/cr.c
Merge branch 'master' of git://git.denx.de/u-boot-blackfin
[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 = ARRAY_SIZE(cpu_post_cr_table1);
63
64 static 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 };
78 static unsigned int cpu_post_cr_size2 = ARRAY_SIZE(cpu_post_cr_table2);
79
80 static 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 };
100 static unsigned int cpu_post_cr_size3 = ARRAY_SIZE(cpu_post_cr_table3);
101
102 static 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 };
240 static unsigned int cpu_post_cr_size4 = ARRAY_SIZE(cpu_post_cr_table4);
241
242 int 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