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