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