Add missing CHANGELOG entry.
[oweals/u-boot.git] / post / cpu / 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 #ifdef CONFIG_POST
50
51 #include <post.h>
52 #include "cpu_asm.h"
53
54 #if CONFIG_POST & CFG_POST_CPU
55
56 extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
57 extern void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3);
58
59 static ulong cpu_post_cr_table1[] =
60 {
61     0xaaaaaaaa,
62     0x55555555,
63 };
64 static unsigned int cpu_post_cr_size1 =
65     sizeof (cpu_post_cr_table1) / sizeof (ulong);
66
67 static struct cpu_post_cr_s2 {
68     ulong xer;
69     ulong cr;
70 } cpu_post_cr_table2[] =
71 {
72     {
73         0xa0000000,
74         1
75     },
76     {
77         0x40000000,
78         5
79     },
80 };
81 static unsigned int cpu_post_cr_size2 =
82     sizeof (cpu_post_cr_table2) / sizeof (struct cpu_post_cr_s2);
83
84 static struct cpu_post_cr_s3 {
85     ulong cr;
86     ulong cs;
87     ulong cd;
88     ulong res;
89 } cpu_post_cr_table3[] =
90 {
91     {
92         0x01234567,
93         0,
94         4,
95         0x01230567
96     },
97     {
98         0x01234567,
99         7,
100         0,
101         0x71234567
102     },
103 };
104 static unsigned int cpu_post_cr_size3 =
105     sizeof (cpu_post_cr_table3) / sizeof (struct cpu_post_cr_s3);
106
107 static 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,
118         0x0000ffff,
119         0,
120         16,
121         0,
122         0x0000ffff
123     },
124     {
125         OP_CRAND,
126         0x0000ffff,
127         16,
128         17,
129         0,
130         0x8000ffff
131     },
132     {
133         OP_CRANDC,
134         0x0000ffff,
135         0,
136         16,
137         0,
138         0x0000ffff
139     },
140     {
141         OP_CRANDC,
142         0x0000ffff,
143         16,
144         0,
145         0,
146         0x8000ffff
147     },
148     {
149         OP_CROR,
150         0x0000ffff,
151         0,
152         16,
153         0,
154         0x8000ffff
155     },
156     {
157         OP_CROR,
158         0x0000ffff,
159         0,
160         1,
161         0,
162         0x0000ffff
163     },
164     {
165         OP_CRORC,
166         0x0000ffff,
167         0,
168         16,
169         0,
170         0x0000ffff
171     },
172     {
173         OP_CRORC,
174         0x0000ffff,
175         0,
176         0,
177         0,
178         0x8000ffff
179     },
180     {
181         OP_CRXOR,
182         0x0000ffff,
183         0,
184         0,
185         0,
186         0x0000ffff
187     },
188     {
189         OP_CRXOR,
190         0x0000ffff,
191         0,
192         16,
193         0,
194         0x8000ffff
195     },
196     {
197         OP_CRNAND,
198         0x0000ffff,
199         0,
200         16,
201         0,
202         0x8000ffff
203     },
204     {
205         OP_CRNAND,
206         0x0000ffff,
207         16,
208         17,
209         0,
210         0x0000ffff
211     },
212     {
213         OP_CRNOR,
214         0x0000ffff,
215         0,
216         16,
217         0,
218         0x0000ffff
219     },
220     {
221         OP_CRNOR,
222         0x0000ffff,
223         0,
224         1,
225         0,
226         0x8000ffff
227     },
228     {
229         OP_CREQV,
230         0x0000ffff,
231         0,
232         0,
233         0,
234         0x8000ffff
235     },
236     {
237         OP_CREQV,
238         0x0000ffff,
239         0,
240         16,
241         0,
242         0x0000ffff
243     },
244 };
245 static unsigned int cpu_post_cr_size4 =
246     sizeof (cpu_post_cr_table4) / sizeof (struct cpu_post_cr_s4);
247
248 int 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
261         unsigned long code[] =
262         {
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
272         if (ret != 0)
273         {
274             post_log ("Error at cr1 test %d !\n", i);
275         }
276     }
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
284         unsigned long code[] =
285         {
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
298         if (ret != 0)
299         {
300             post_log ("Error at cr2 test %d !\n", i);
301         }
302     }
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
309         unsigned long code[] =
310         {
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
321         if (ret != 0)
322         {
323             post_log ("Error at cr3 test %d !\n", i);
324         }
325     }
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
332         unsigned long code[] =
333         {
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
344         if (ret != 0)
345         {
346             post_log ("Error at cr4 test %d !\n", i);
347         }
348     }
349
350     asm ( "mtcr %0" : : "r" (cr_sav));
351
352     return ret;
353 }
354
355 #endif
356 #endif