1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <common.h>
25
26
27
28
29
30
31
32
33
34
35
36
37
38#include <post.h>
39#include "cpu_asm.h"
40
41#if CONFIG_POST & CONFIG_SYS_POST_CPU
42
43extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
44 ulong op2);
45extern ulong cpu_post_makecr (long v);
46
47static struct cpu_post_three_s
48{
49 ulong cmd;
50 ulong op1;
51 ulong op2;
52 ulong res;
53} cpu_post_three_table[] =
54{
55 {
56 OP_ADD,
57 100,
58 200,
59 300
60 },
61 {
62 OP_ADD,
63 100,
64 -200,
65 -100
66 },
67 {
68 OP_ADDC,
69 100,
70 200,
71 300
72 },
73 {
74 OP_ADDC,
75 100,
76 -200,
77 -100
78 },
79 {
80 OP_ADDE,
81 100,
82 200,
83 300
84 },
85 {
86 OP_ADDE,
87 100,
88 -200,
89 -100
90 },
91 {
92 OP_SUBF,
93 100,
94 200,
95 100
96 },
97 {
98 OP_SUBF,
99 300,
100 200,
101 -100
102 },
103 {
104 OP_SUBFC,
105 100,
106 200,
107 100
108 },
109 {
110 OP_SUBFC,
111 300,
112 200,
113 -100
114 },
115 {
116 OP_SUBFE,
117 100,
118 200,
119 200 + ~100
120 },
121 {
122 OP_SUBFE,
123 300,
124 200,
125 200 + ~300
126 },
127 {
128 OP_MULLW,
129 200,
130 300,
131 200 * 300
132 },
133 {
134 OP_MULHW,
135 0x10000000,
136 0x10000000,
137 0x1000000
138 },
139 {
140 OP_MULHWU,
141 0x80000000,
142 0x80000000,
143 0x40000000
144 },
145 {
146 OP_DIVW,
147 -20,
148 5,
149 -4
150 },
151 {
152 OP_DIVWU,
153 0x8000,
154 0x200,
155 0x40
156 },
157};
158static unsigned int cpu_post_three_size = ARRAY_SIZE(cpu_post_three_table);
159
160int cpu_post_test_three (void)
161{
162 int ret = 0;
163 unsigned int i, reg;
164 int flag = disable_interrupts();
165
166 for (i = 0; i < cpu_post_three_size && ret == 0; i++)
167 {
168 struct cpu_post_three_s *test = cpu_post_three_table + i;
169
170 for (reg = 0; reg < 32 && ret == 0; reg++)
171 {
172 unsigned int reg0 = (reg + 0) % 32;
173 unsigned int reg1 = (reg + 1) % 32;
174 unsigned int reg2 = (reg + 2) % 32;
175 unsigned int stk = reg < 16 ? 31 : 15;
176 unsigned long code[] =
177 {
178 ASM_STW(stk, 1, -4),
179 ASM_ADDI(stk, 1, -24),
180 ASM_STW(3, stk, 12),
181 ASM_STW(4, stk, 16),
182 ASM_STW(reg0, stk, 8),
183 ASM_STW(reg1, stk, 4),
184 ASM_STW(reg2, stk, 0),
185 ASM_LWZ(reg1, stk, 12),
186 ASM_LWZ(reg0, stk, 16),
187 ASM_12(test->cmd, reg2, reg1, reg0),
188 ASM_STW(reg2, stk, 12),
189 ASM_LWZ(reg2, stk, 0),
190 ASM_LWZ(reg1, stk, 4),
191 ASM_LWZ(reg0, stk, 8),
192 ASM_LWZ(3, stk, 12),
193 ASM_ADDI(1, stk, 24),
194 ASM_LWZ(stk, 1, -4),
195 ASM_BLR,
196 };
197 unsigned long codecr[] =
198 {
199 ASM_STW(stk, 1, -4),
200 ASM_ADDI(stk, 1, -24),
201 ASM_STW(3, stk, 12),
202 ASM_STW(4, stk, 16),
203 ASM_STW(reg0, stk, 8),
204 ASM_STW(reg1, stk, 4),
205 ASM_STW(reg2, stk, 0),
206 ASM_LWZ(reg1, stk, 12),
207 ASM_LWZ(reg0, stk, 16),
208 ASM_12(test->cmd, reg2, reg1, reg0) | BIT_C,
209 ASM_STW(reg2, stk, 12),
210 ASM_LWZ(reg2, stk, 0),
211 ASM_LWZ(reg1, stk, 4),
212 ASM_LWZ(reg0, stk, 8),
213 ASM_LWZ(3, stk, 12),
214 ASM_ADDI(1, stk, 24),
215 ASM_LWZ(stk, 1, -4),
216 ASM_BLR,
217 };
218 ulong res;
219 ulong cr;
220
221 if (ret == 0)
222 {
223 cr = 0;
224 cpu_post_exec_22 (code, & cr, & res, test->op1, test->op2);
225
226 ret = res == test->res && cr == 0 ? 0 : -1;
227
228 if (ret != 0)
229 {
230 post_log ("Error at three test %d !\n", i);
231 }
232 }
233
234 if (ret == 0)
235 {
236 cpu_post_exec_22 (codecr, & cr, & res, test->op1, test->op2);
237
238 ret = res == test->res &&
239 (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
240
241 if (ret != 0)
242 {
243 post_log ("Error at three test %d !\n", i);
244 }
245 }
246 }
247 }
248
249 if (flag)
250 enable_interrupts();
251
252 return ret;
253}
254
255#endif
256