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