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