xref: /openbmc/u-boot/post/lib_powerpc/cmp.c (revision 5794619e)
1 /*
2  * (C) Copyright 2002
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23 
24 #include <common.h>
25 
26 /*
27  * CPU test
28  * Integer compare instructions:	cmpw, cmplw
29  *
30  * To verify these instructions the test runs them with
31  * different combinations of operands, reads the condition
32  * register value and compares it with the expected one.
33  * The test contains a pre-built table
34  * containing the description of each test case: the instruction,
35  * the values of the operands, the condition field to save
36  * the result in and the expected result.
37  */
38 
39 #include <post.h>
40 #include "cpu_asm.h"
41 
42 #if CONFIG_POST & CONFIG_SYS_POST_CPU
43 
44 extern void cpu_post_exec_12 (ulong *code, ulong *res, ulong op1, ulong op2);
45 
46 static struct cpu_post_cmp_s
47 {
48     ulong cmd;
49     ulong op1;
50     ulong op2;
51     ulong cr;
52     ulong res;
53 } cpu_post_cmp_table[] =
54 {
55     {
56 	OP_CMPW,
57 	123,
58 	123,
59 	2,
60 	0x02
61     },
62     {
63 	OP_CMPW,
64 	123,
65 	133,
66 	3,
67 	0x08
68     },
69     {
70 	OP_CMPW,
71 	123,
72 	-133,
73 	4,
74 	0x04
75     },
76     {
77 	OP_CMPLW,
78 	123,
79 	123,
80 	2,
81 	0x02
82     },
83     {
84 	OP_CMPLW,
85 	123,
86 	-133,
87 	3,
88 	0x08
89     },
90     {
91 	OP_CMPLW,
92 	123,
93 	113,
94 	4,
95 	0x04
96     },
97 };
98 static unsigned int cpu_post_cmp_size =
99     sizeof (cpu_post_cmp_table) / sizeof (struct cpu_post_cmp_s);
100 
101 int cpu_post_test_cmp (void)
102 {
103     int ret = 0;
104     unsigned int i;
105     int flag = disable_interrupts();
106 
107     for (i = 0; i < cpu_post_cmp_size && ret == 0; i++)
108     {
109 	struct cpu_post_cmp_s *test = cpu_post_cmp_table + i;
110 	unsigned long code[] =
111 	{
112 	    ASM_2C(test->cmd, test->cr, 3, 4),
113 	    ASM_MFCR(3),
114 	    ASM_BLR
115 	};
116 	ulong res;
117 
118 	cpu_post_exec_12 (code, & res, test->op1, test->op2);
119 
120 	ret = ((res >> (28 - 4 * test->cr)) & 0xe) == test->res ? 0 : -1;
121 
122 	if (ret != 0)
123 	{
124 	    post_log ("Error at cmp test %d !\n", i);
125 	}
126     }
127 
128     if (flag)
129 	enable_interrupts();
130 
131     return ret;
132 }
133 
134 #endif
135