93de47a1cff3e8edfc54759dd108a14792dbb1ea
[oweals/u-boot.git] / post / lib_powerpc / cr.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2002
4  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5  */
6
7 #include <common.h>
8
9 /*
10  * CPU test
11  * Condition register istructions:      mtcr, mfcr, mcrxr,
12  *                                      crand, crandc, cror, crorc, crxor,
13  *                                      crnand, crnor, creqv, mcrf
14  *
15  * The mtcrf/mfcr instructions is tested by loading different
16  * values into the condition register (mtcrf), moving its value
17  * to a general-purpose register (mfcr) and comparing this value
18  * with the expected one.
19  * The mcrxr instruction is tested by loading a fixed value
20  * into the XER register (mtspr), moving XER value to the
21  * condition register (mcrxr), moving it to a general-purpose
22  * register (mfcr) and comparing the value of this register with
23  * the expected one.
24  * The rest of instructions is tested by loading a fixed
25  * value into the condition register (mtcrf), executing each
26  * instruction several times to modify all 4-bit condition
27  * fields, moving the value of the conditional register to a
28  * general-purpose register (mfcr) and comparing it with the
29  * expected one.
30  */
31
32 #include <post.h>
33 #include "cpu_asm.h"
34
35 #if CONFIG_POST & CONFIG_SYS_POST_CPU
36
37 extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
38 extern void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3);
39
40 static ulong cpu_post_cr_table1[] =
41 {
42     0xaaaaaaaa,
43     0x55555555,
44 };
45 static unsigned int cpu_post_cr_size1 = ARRAY_SIZE(cpu_post_cr_table1);
46
47 static struct cpu_post_cr_s2 {
48     ulong xer;
49     ulong cr;
50 } cpu_post_cr_table2[] =
51 {
52     {
53         0xa0000000,
54         1
55     },
56     {
57         0x40000000,
58         5
59     },
60 };
61 static unsigned int cpu_post_cr_size2 = ARRAY_SIZE(cpu_post_cr_table2);
62
63 static struct cpu_post_cr_s3 {
64     ulong cr;
65     ulong cs;
66     ulong cd;
67     ulong res;
68 } cpu_post_cr_table3[] =
69 {
70     {
71         0x01234567,
72         0,
73         4,
74         0x01230567
75     },
76     {
77         0x01234567,
78         7,
79         0,
80         0x71234567
81     },
82 };
83 static unsigned int cpu_post_cr_size3 = ARRAY_SIZE(cpu_post_cr_table3);
84
85 static struct cpu_post_cr_s4 {
86     ulong cmd;
87     ulong cr;
88     ulong op1;
89     ulong op2;
90     ulong op3;
91     ulong res;
92 } cpu_post_cr_table4[] =
93 {
94     {
95         OP_CRAND,
96         0x0000ffff,
97         0,
98         16,
99         0,
100         0x0000ffff
101     },
102     {
103         OP_CRAND,
104         0x0000ffff,
105         16,
106         17,
107         0,
108         0x8000ffff
109     },
110     {
111         OP_CRANDC,
112         0x0000ffff,
113         0,
114         16,
115         0,
116         0x0000ffff
117     },
118     {
119         OP_CRANDC,
120         0x0000ffff,
121         16,
122         0,
123         0,
124         0x8000ffff
125     },
126     {
127         OP_CROR,
128         0x0000ffff,
129         0,
130         16,
131         0,
132         0x8000ffff
133     },
134     {
135         OP_CROR,
136         0x0000ffff,
137         0,
138         1,
139         0,
140         0x0000ffff
141     },
142     {
143         OP_CRORC,
144         0x0000ffff,
145         0,
146         16,
147         0,
148         0x0000ffff
149     },
150     {
151         OP_CRORC,
152         0x0000ffff,
153         0,
154         0,
155         0,
156         0x8000ffff
157     },
158     {
159         OP_CRXOR,
160         0x0000ffff,
161         0,
162         0,
163         0,
164         0x0000ffff
165     },
166     {
167         OP_CRXOR,
168         0x0000ffff,
169         0,
170         16,
171         0,
172         0x8000ffff
173     },
174     {
175         OP_CRNAND,
176         0x0000ffff,
177         0,
178         16,
179         0,
180         0x8000ffff
181     },
182     {
183         OP_CRNAND,
184         0x0000ffff,
185         16,
186         17,
187         0,
188         0x0000ffff
189     },
190     {
191         OP_CRNOR,
192         0x0000ffff,
193         0,
194         16,
195         0,
196         0x0000ffff
197     },
198     {
199         OP_CRNOR,
200         0x0000ffff,
201         0,
202         1,
203         0,
204         0x8000ffff
205     },
206     {
207         OP_CREQV,
208         0x0000ffff,
209         0,
210         0,
211         0,
212         0x8000ffff
213     },
214     {
215         OP_CREQV,
216         0x0000ffff,
217         0,
218         16,
219         0,
220         0x0000ffff
221     },
222 };
223 static unsigned int cpu_post_cr_size4 = ARRAY_SIZE(cpu_post_cr_table4);
224
225 int cpu_post_test_cr (void)
226 {
227     int ret = 0;
228     unsigned int i;
229     unsigned long cr_sav;
230     int flag = disable_interrupts();
231
232     asm ( "mfcr %0" : "=r" (cr_sav) : );
233
234     for (i = 0; i < cpu_post_cr_size1 && ret == 0; i++)
235     {
236         ulong cr = cpu_post_cr_table1[i];
237         ulong res;
238
239         unsigned long code[] =
240         {
241             ASM_MTCR(3),
242             ASM_MFCR(3),
243             ASM_BLR,
244         };
245
246         cpu_post_exec_11 (code, &res, cr);
247
248         ret = res == cr ? 0 : -1;
249
250         if (ret != 0)
251         {
252             post_log ("Error at cr1 test %d !\n", i);
253         }
254     }
255
256     for (i = 0; i < cpu_post_cr_size2 && ret == 0; i++)
257     {
258         struct cpu_post_cr_s2 *test = cpu_post_cr_table2 + i;
259         ulong res;
260         ulong xer;
261
262         unsigned long code[] =
263         {
264             ASM_MTXER(3),
265             ASM_MCRXR(test->cr),
266             ASM_MFCR(3),
267             ASM_MFXER(4),
268             ASM_BLR,
269         };
270
271         cpu_post_exec_21x (code, &res, &xer, test->xer);
272
273         ret = xer == 0 && ((res << (4 * test->cr)) & 0xe0000000) == test->xer ?
274               0 : -1;
275
276         if (ret != 0)
277         {
278             post_log ("Error at cr2 test %d !\n", i);
279         }
280     }
281
282     for (i = 0; i < cpu_post_cr_size3 && ret == 0; i++)
283     {
284         struct cpu_post_cr_s3 *test = cpu_post_cr_table3 + i;
285         ulong res;
286
287         unsigned long code[] =
288         {
289             ASM_MTCR(3),
290             ASM_MCRF(test->cd, test->cs),
291             ASM_MFCR(3),
292             ASM_BLR,
293         };
294
295         cpu_post_exec_11 (code, &res, test->cr);
296
297         ret = res == test->res ? 0 : -1;
298
299         if (ret != 0)
300         {
301             post_log ("Error at cr3 test %d !\n", i);
302         }
303     }
304
305     for (i = 0; i < cpu_post_cr_size4 && ret == 0; i++)
306     {
307         struct cpu_post_cr_s4 *test = cpu_post_cr_table4 + i;
308         ulong res;
309
310         unsigned long code[] =
311         {
312             ASM_MTCR(3),
313             ASM_12F(test->cmd, test->op3, test->op1, test->op2),
314             ASM_MFCR(3),
315             ASM_BLR,
316         };
317
318         cpu_post_exec_11 (code, &res, test->cr);
319
320         ret = res == test->res ? 0 : -1;
321
322         if (ret != 0)
323         {
324             post_log ("Error at cr4 test %d !\n", i);
325         }
326     }
327
328     asm ( "mtcr %0" : : "r" (cr_sav));
329
330     if (flag)
331         enable_interrupts();
332
333     return ret;
334 }
335
336 #endif