xref: /openbmc/linux/arch/powerpc/lib/test_emulate_step.c (revision 4ceae137bdab2232e57b2e6fd5631a22a0160938)
1*4ceae137SRavi Bangoria /*
2*4ceae137SRavi Bangoria  * Simple sanity test for emulate_step load/store instructions.
3*4ceae137SRavi Bangoria  *
4*4ceae137SRavi Bangoria  * Copyright IBM Corp. 2016
5*4ceae137SRavi Bangoria  *
6*4ceae137SRavi Bangoria  * This program is free software;  you can redistribute it and/or modify
7*4ceae137SRavi Bangoria  * it under the terms of the GNU General Public License as published by
8*4ceae137SRavi Bangoria  * the Free Software Foundation; either version 2 of the License, or
9*4ceae137SRavi Bangoria  * (at your option) any later version.
10*4ceae137SRavi Bangoria  */
11*4ceae137SRavi Bangoria 
12*4ceae137SRavi Bangoria #define pr_fmt(fmt) "emulate_step_test: " fmt
13*4ceae137SRavi Bangoria 
14*4ceae137SRavi Bangoria #include <linux/ptrace.h>
15*4ceae137SRavi Bangoria #include <asm/sstep.h>
16*4ceae137SRavi Bangoria #include <asm/ppc-opcode.h>
17*4ceae137SRavi Bangoria 
18*4ceae137SRavi Bangoria #define IMM_L(i)		((uintptr_t)(i) & 0xffff)
19*4ceae137SRavi Bangoria 
20*4ceae137SRavi Bangoria /*
21*4ceae137SRavi Bangoria  * Defined with TEST_ prefix so it does not conflict with other
22*4ceae137SRavi Bangoria  * definitions.
23*4ceae137SRavi Bangoria  */
24*4ceae137SRavi Bangoria #define TEST_LD(r, base, i)	(PPC_INST_LD | ___PPC_RT(r) |		\
25*4ceae137SRavi Bangoria 					___PPC_RA(base) | IMM_L(i))
26*4ceae137SRavi Bangoria #define TEST_LWZ(r, base, i)	(PPC_INST_LWZ | ___PPC_RT(r) |		\
27*4ceae137SRavi Bangoria 					___PPC_RA(base) | IMM_L(i))
28*4ceae137SRavi Bangoria #define TEST_LWZX(t, a, b)	(PPC_INST_LWZX | ___PPC_RT(t) |		\
29*4ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
30*4ceae137SRavi Bangoria #define TEST_STD(r, base, i)	(PPC_INST_STD | ___PPC_RS(r) |		\
31*4ceae137SRavi Bangoria 					___PPC_RA(base) | ((i) & 0xfffc))
32*4ceae137SRavi Bangoria #define TEST_LDARX(t, a, b, eh)	(PPC_INST_LDARX | ___PPC_RT(t) |	\
33*4ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b) |	\
34*4ceae137SRavi Bangoria 					__PPC_EH(eh))
35*4ceae137SRavi Bangoria #define TEST_STDCX(s, a, b)	(PPC_INST_STDCX | ___PPC_RS(s) |	\
36*4ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
37*4ceae137SRavi Bangoria #define TEST_LFSX(t, a, b)	(PPC_INST_LFSX | ___PPC_RT(t) |		\
38*4ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
39*4ceae137SRavi Bangoria #define TEST_STFSX(s, a, b)	(PPC_INST_STFSX | ___PPC_RS(s) |	\
40*4ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
41*4ceae137SRavi Bangoria #define TEST_LFDX(t, a, b)	(PPC_INST_LFDX | ___PPC_RT(t) |		\
42*4ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
43*4ceae137SRavi Bangoria #define TEST_STFDX(s, a, b)	(PPC_INST_STFDX | ___PPC_RS(s) |	\
44*4ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
45*4ceae137SRavi Bangoria #define TEST_LVX(t, a, b)	(PPC_INST_LVX | ___PPC_RT(t) |		\
46*4ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
47*4ceae137SRavi Bangoria #define TEST_STVX(s, a, b)	(PPC_INST_STVX | ___PPC_RS(s) |		\
48*4ceae137SRavi Bangoria 					___PPC_RA(a) | ___PPC_RB(b))
49*4ceae137SRavi Bangoria #define TEST_LXVD2X(s, a, b)	(PPC_INST_LXVD2X | VSX_XX1((s), R##a, R##b))
50*4ceae137SRavi Bangoria #define TEST_STXVD2X(s, a, b)	(PPC_INST_STXVD2X | VSX_XX1((s), R##a, R##b))
51*4ceae137SRavi Bangoria 
52*4ceae137SRavi Bangoria 
53*4ceae137SRavi Bangoria static void __init init_pt_regs(struct pt_regs *regs)
54*4ceae137SRavi Bangoria {
55*4ceae137SRavi Bangoria 	static unsigned long msr;
56*4ceae137SRavi Bangoria 	static bool msr_cached;
57*4ceae137SRavi Bangoria 
58*4ceae137SRavi Bangoria 	memset(regs, 0, sizeof(struct pt_regs));
59*4ceae137SRavi Bangoria 
60*4ceae137SRavi Bangoria 	if (likely(msr_cached)) {
61*4ceae137SRavi Bangoria 		regs->msr = msr;
62*4ceae137SRavi Bangoria 		return;
63*4ceae137SRavi Bangoria 	}
64*4ceae137SRavi Bangoria 
65*4ceae137SRavi Bangoria 	asm volatile("mfmsr %0" : "=r"(regs->msr));
66*4ceae137SRavi Bangoria 
67*4ceae137SRavi Bangoria 	regs->msr |= MSR_FP;
68*4ceae137SRavi Bangoria 	regs->msr |= MSR_VEC;
69*4ceae137SRavi Bangoria 	regs->msr |= MSR_VSX;
70*4ceae137SRavi Bangoria 
71*4ceae137SRavi Bangoria 	msr = regs->msr;
72*4ceae137SRavi Bangoria 	msr_cached = true;
73*4ceae137SRavi Bangoria }
74*4ceae137SRavi Bangoria 
75*4ceae137SRavi Bangoria static void __init show_result(char *ins, char *result)
76*4ceae137SRavi Bangoria {
77*4ceae137SRavi Bangoria 	pr_info("%-14s : %s\n", ins, result);
78*4ceae137SRavi Bangoria }
79*4ceae137SRavi Bangoria 
80*4ceae137SRavi Bangoria static void __init test_ld(void)
81*4ceae137SRavi Bangoria {
82*4ceae137SRavi Bangoria 	struct pt_regs regs;
83*4ceae137SRavi Bangoria 	unsigned long a = 0x23;
84*4ceae137SRavi Bangoria 	int stepped = -1;
85*4ceae137SRavi Bangoria 
86*4ceae137SRavi Bangoria 	init_pt_regs(&regs);
87*4ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &a;
88*4ceae137SRavi Bangoria 
89*4ceae137SRavi Bangoria 	/* ld r5, 0(r3) */
90*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LD(5, 3, 0));
91*4ceae137SRavi Bangoria 
92*4ceae137SRavi Bangoria 	if (stepped == 1 && regs.gpr[5] == a)
93*4ceae137SRavi Bangoria 		show_result("ld", "PASS");
94*4ceae137SRavi Bangoria 	else
95*4ceae137SRavi Bangoria 		show_result("ld", "FAIL");
96*4ceae137SRavi Bangoria }
97*4ceae137SRavi Bangoria 
98*4ceae137SRavi Bangoria static void __init test_lwz(void)
99*4ceae137SRavi Bangoria {
100*4ceae137SRavi Bangoria 	struct pt_regs regs;
101*4ceae137SRavi Bangoria 	unsigned int a = 0x4545;
102*4ceae137SRavi Bangoria 	int stepped = -1;
103*4ceae137SRavi Bangoria 
104*4ceae137SRavi Bangoria 	init_pt_regs(&regs);
105*4ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &a;
106*4ceae137SRavi Bangoria 
107*4ceae137SRavi Bangoria 	/* lwz r5, 0(r3) */
108*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LWZ(5, 3, 0));
109*4ceae137SRavi Bangoria 
110*4ceae137SRavi Bangoria 	if (stepped == 1 && regs.gpr[5] == a)
111*4ceae137SRavi Bangoria 		show_result("lwz", "PASS");
112*4ceae137SRavi Bangoria 	else
113*4ceae137SRavi Bangoria 		show_result("lwz", "FAIL");
114*4ceae137SRavi Bangoria }
115*4ceae137SRavi Bangoria 
116*4ceae137SRavi Bangoria static void __init test_lwzx(void)
117*4ceae137SRavi Bangoria {
118*4ceae137SRavi Bangoria 	struct pt_regs regs;
119*4ceae137SRavi Bangoria 	unsigned int a[3] = {0x0, 0x0, 0x1234};
120*4ceae137SRavi Bangoria 	int stepped = -1;
121*4ceae137SRavi Bangoria 
122*4ceae137SRavi Bangoria 	init_pt_regs(&regs);
123*4ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) a;
124*4ceae137SRavi Bangoria 	regs.gpr[4] = 8;
125*4ceae137SRavi Bangoria 	regs.gpr[5] = 0x8765;
126*4ceae137SRavi Bangoria 
127*4ceae137SRavi Bangoria 	/* lwzx r5, r3, r4 */
128*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LWZX(5, 3, 4));
129*4ceae137SRavi Bangoria 	if (stepped == 1 && regs.gpr[5] == a[2])
130*4ceae137SRavi Bangoria 		show_result("lwzx", "PASS");
131*4ceae137SRavi Bangoria 	else
132*4ceae137SRavi Bangoria 		show_result("lwzx", "FAIL");
133*4ceae137SRavi Bangoria }
134*4ceae137SRavi Bangoria 
135*4ceae137SRavi Bangoria static void __init test_std(void)
136*4ceae137SRavi Bangoria {
137*4ceae137SRavi Bangoria 	struct pt_regs regs;
138*4ceae137SRavi Bangoria 	unsigned long a = 0x1234;
139*4ceae137SRavi Bangoria 	int stepped = -1;
140*4ceae137SRavi Bangoria 
141*4ceae137SRavi Bangoria 	init_pt_regs(&regs);
142*4ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &a;
143*4ceae137SRavi Bangoria 	regs.gpr[5] = 0x5678;
144*4ceae137SRavi Bangoria 
145*4ceae137SRavi Bangoria 	/* std r5, 0(r3) */
146*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_STD(5, 3, 0));
147*4ceae137SRavi Bangoria 	if (stepped == 1 || regs.gpr[5] == a)
148*4ceae137SRavi Bangoria 		show_result("std", "PASS");
149*4ceae137SRavi Bangoria 	else
150*4ceae137SRavi Bangoria 		show_result("std", "FAIL");
151*4ceae137SRavi Bangoria }
152*4ceae137SRavi Bangoria 
153*4ceae137SRavi Bangoria static void __init test_ldarx_stdcx(void)
154*4ceae137SRavi Bangoria {
155*4ceae137SRavi Bangoria 	struct pt_regs regs;
156*4ceae137SRavi Bangoria 	unsigned long a = 0x1234;
157*4ceae137SRavi Bangoria 	int stepped = -1;
158*4ceae137SRavi Bangoria 	unsigned long cr0_eq = 0x1 << 29; /* eq bit of CR0 */
159*4ceae137SRavi Bangoria 
160*4ceae137SRavi Bangoria 	init_pt_regs(&regs);
161*4ceae137SRavi Bangoria 	asm volatile("mfcr %0" : "=r"(regs.ccr));
162*4ceae137SRavi Bangoria 
163*4ceae137SRavi Bangoria 
164*4ceae137SRavi Bangoria 	/*** ldarx ***/
165*4ceae137SRavi Bangoria 
166*4ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &a;
167*4ceae137SRavi Bangoria 	regs.gpr[4] = 0;
168*4ceae137SRavi Bangoria 	regs.gpr[5] = 0x5678;
169*4ceae137SRavi Bangoria 
170*4ceae137SRavi Bangoria 	/* ldarx r5, r3, r4, 0 */
171*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LDARX(5, 3, 4, 0));
172*4ceae137SRavi Bangoria 
173*4ceae137SRavi Bangoria 	/*
174*4ceae137SRavi Bangoria 	 * Don't touch 'a' here. Touching 'a' can do Load/store
175*4ceae137SRavi Bangoria 	 * of 'a' which result in failure of subsequent stdcx.
176*4ceae137SRavi Bangoria 	 * Instead, use hardcoded value for comparison.
177*4ceae137SRavi Bangoria 	 */
178*4ceae137SRavi Bangoria 	if (stepped <= 0 || regs.gpr[5] != 0x1234) {
179*4ceae137SRavi Bangoria 		show_result("ldarx / stdcx.", "FAIL (ldarx)");
180*4ceae137SRavi Bangoria 		return;
181*4ceae137SRavi Bangoria 	}
182*4ceae137SRavi Bangoria 
183*4ceae137SRavi Bangoria 
184*4ceae137SRavi Bangoria 	/*** stdcx. ***/
185*4ceae137SRavi Bangoria 
186*4ceae137SRavi Bangoria 	regs.gpr[5] = 0x9ABC;
187*4ceae137SRavi Bangoria 
188*4ceae137SRavi Bangoria 	/* stdcx. r5, r3, r4 */
189*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_STDCX(5, 3, 4));
190*4ceae137SRavi Bangoria 
191*4ceae137SRavi Bangoria 	/*
192*4ceae137SRavi Bangoria 	 * Two possible scenarios that indicates successful emulation
193*4ceae137SRavi Bangoria 	 * of stdcx. :
194*4ceae137SRavi Bangoria 	 *  1. Reservation is active and store is performed. In this
195*4ceae137SRavi Bangoria 	 *     case cr0.eq bit will be set to 1.
196*4ceae137SRavi Bangoria 	 *  2. Reservation is not active and store is not performed.
197*4ceae137SRavi Bangoria 	 *     In this case cr0.eq bit will be set to 0.
198*4ceae137SRavi Bangoria 	 */
199*4ceae137SRavi Bangoria 	if (stepped == 1 && ((regs.gpr[5] == a && (regs.ccr & cr0_eq))
200*4ceae137SRavi Bangoria 			|| (regs.gpr[5] != a && !(regs.ccr & cr0_eq))))
201*4ceae137SRavi Bangoria 		show_result("ldarx / stdcx.", "PASS");
202*4ceae137SRavi Bangoria 	else
203*4ceae137SRavi Bangoria 		show_result("ldarx / stdcx.", "FAIL (stdcx.)");
204*4ceae137SRavi Bangoria }
205*4ceae137SRavi Bangoria 
206*4ceae137SRavi Bangoria #ifdef CONFIG_PPC_FPU
207*4ceae137SRavi Bangoria static void __init test_lfsx_stfsx(void)
208*4ceae137SRavi Bangoria {
209*4ceae137SRavi Bangoria 	struct pt_regs regs;
210*4ceae137SRavi Bangoria 	union {
211*4ceae137SRavi Bangoria 		float a;
212*4ceae137SRavi Bangoria 		int b;
213*4ceae137SRavi Bangoria 	} c;
214*4ceae137SRavi Bangoria 	int cached_b;
215*4ceae137SRavi Bangoria 	int stepped = -1;
216*4ceae137SRavi Bangoria 
217*4ceae137SRavi Bangoria 	init_pt_regs(&regs);
218*4ceae137SRavi Bangoria 
219*4ceae137SRavi Bangoria 
220*4ceae137SRavi Bangoria 	/*** lfsx ***/
221*4ceae137SRavi Bangoria 
222*4ceae137SRavi Bangoria 	c.a = 123.45;
223*4ceae137SRavi Bangoria 	cached_b = c.b;
224*4ceae137SRavi Bangoria 
225*4ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &c.a;
226*4ceae137SRavi Bangoria 	regs.gpr[4] = 0;
227*4ceae137SRavi Bangoria 
228*4ceae137SRavi Bangoria 	/* lfsx frt10, r3, r4 */
229*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LFSX(10, 3, 4));
230*4ceae137SRavi Bangoria 
231*4ceae137SRavi Bangoria 	if (stepped == 1)
232*4ceae137SRavi Bangoria 		show_result("lfsx", "PASS");
233*4ceae137SRavi Bangoria 	else
234*4ceae137SRavi Bangoria 		show_result("lfsx", "FAIL");
235*4ceae137SRavi Bangoria 
236*4ceae137SRavi Bangoria 
237*4ceae137SRavi Bangoria 	/*** stfsx ***/
238*4ceae137SRavi Bangoria 
239*4ceae137SRavi Bangoria 	c.a = 678.91;
240*4ceae137SRavi Bangoria 
241*4ceae137SRavi Bangoria 	/* stfsx frs10, r3, r4 */
242*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_STFSX(10, 3, 4));
243*4ceae137SRavi Bangoria 
244*4ceae137SRavi Bangoria 	if (stepped == 1 && c.b == cached_b)
245*4ceae137SRavi Bangoria 		show_result("stfsx", "PASS");
246*4ceae137SRavi Bangoria 	else
247*4ceae137SRavi Bangoria 		show_result("stfsx", "FAIL");
248*4ceae137SRavi Bangoria }
249*4ceae137SRavi Bangoria 
250*4ceae137SRavi Bangoria static void __init test_lfdx_stfdx(void)
251*4ceae137SRavi Bangoria {
252*4ceae137SRavi Bangoria 	struct pt_regs regs;
253*4ceae137SRavi Bangoria 	union {
254*4ceae137SRavi Bangoria 		double a;
255*4ceae137SRavi Bangoria 		long b;
256*4ceae137SRavi Bangoria 	} c;
257*4ceae137SRavi Bangoria 	long cached_b;
258*4ceae137SRavi Bangoria 	int stepped = -1;
259*4ceae137SRavi Bangoria 
260*4ceae137SRavi Bangoria 	init_pt_regs(&regs);
261*4ceae137SRavi Bangoria 
262*4ceae137SRavi Bangoria 
263*4ceae137SRavi Bangoria 	/*** lfdx ***/
264*4ceae137SRavi Bangoria 
265*4ceae137SRavi Bangoria 	c.a = 123456.78;
266*4ceae137SRavi Bangoria 	cached_b = c.b;
267*4ceae137SRavi Bangoria 
268*4ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &c.a;
269*4ceae137SRavi Bangoria 	regs.gpr[4] = 0;
270*4ceae137SRavi Bangoria 
271*4ceae137SRavi Bangoria 	/* lfdx frt10, r3, r4 */
272*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LFDX(10, 3, 4));
273*4ceae137SRavi Bangoria 
274*4ceae137SRavi Bangoria 	if (stepped == 1)
275*4ceae137SRavi Bangoria 		show_result("lfdx", "PASS");
276*4ceae137SRavi Bangoria 	else
277*4ceae137SRavi Bangoria 		show_result("lfdx", "FAIL");
278*4ceae137SRavi Bangoria 
279*4ceae137SRavi Bangoria 
280*4ceae137SRavi Bangoria 	/*** stfdx ***/
281*4ceae137SRavi Bangoria 
282*4ceae137SRavi Bangoria 	c.a = 987654.32;
283*4ceae137SRavi Bangoria 
284*4ceae137SRavi Bangoria 	/* stfdx frs10, r3, r4 */
285*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_STFDX(10, 3, 4));
286*4ceae137SRavi Bangoria 
287*4ceae137SRavi Bangoria 	if (stepped == 1 && c.b == cached_b)
288*4ceae137SRavi Bangoria 		show_result("stfdx", "PASS");
289*4ceae137SRavi Bangoria 	else
290*4ceae137SRavi Bangoria 		show_result("stfdx", "FAIL");
291*4ceae137SRavi Bangoria }
292*4ceae137SRavi Bangoria #else
293*4ceae137SRavi Bangoria static void __init test_lfsx_stfsx(void)
294*4ceae137SRavi Bangoria {
295*4ceae137SRavi Bangoria 	show_result("lfsx", "SKIP (CONFIG_PPC_FPU is not set)");
296*4ceae137SRavi Bangoria 	show_result("stfsx", "SKIP (CONFIG_PPC_FPU is not set)");
297*4ceae137SRavi Bangoria }
298*4ceae137SRavi Bangoria 
299*4ceae137SRavi Bangoria static void __init test_lfdx_stfdx(void)
300*4ceae137SRavi Bangoria {
301*4ceae137SRavi Bangoria 	show_result("lfdx", "SKIP (CONFIG_PPC_FPU is not set)");
302*4ceae137SRavi Bangoria 	show_result("stfdx", "SKIP (CONFIG_PPC_FPU is not set)");
303*4ceae137SRavi Bangoria }
304*4ceae137SRavi Bangoria #endif /* CONFIG_PPC_FPU */
305*4ceae137SRavi Bangoria 
306*4ceae137SRavi Bangoria #ifdef CONFIG_ALTIVEC
307*4ceae137SRavi Bangoria static void __init test_lvx_stvx(void)
308*4ceae137SRavi Bangoria {
309*4ceae137SRavi Bangoria 	struct pt_regs regs;
310*4ceae137SRavi Bangoria 	union {
311*4ceae137SRavi Bangoria 		vector128 a;
312*4ceae137SRavi Bangoria 		u32 b[4];
313*4ceae137SRavi Bangoria 	} c;
314*4ceae137SRavi Bangoria 	u32 cached_b[4];
315*4ceae137SRavi Bangoria 	int stepped = -1;
316*4ceae137SRavi Bangoria 
317*4ceae137SRavi Bangoria 	init_pt_regs(&regs);
318*4ceae137SRavi Bangoria 
319*4ceae137SRavi Bangoria 
320*4ceae137SRavi Bangoria 	/*** lvx ***/
321*4ceae137SRavi Bangoria 
322*4ceae137SRavi Bangoria 	cached_b[0] = c.b[0] = 923745;
323*4ceae137SRavi Bangoria 	cached_b[1] = c.b[1] = 2139478;
324*4ceae137SRavi Bangoria 	cached_b[2] = c.b[2] = 9012;
325*4ceae137SRavi Bangoria 	cached_b[3] = c.b[3] = 982134;
326*4ceae137SRavi Bangoria 
327*4ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &c.a;
328*4ceae137SRavi Bangoria 	regs.gpr[4] = 0;
329*4ceae137SRavi Bangoria 
330*4ceae137SRavi Bangoria 	/* lvx vrt10, r3, r4 */
331*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LVX(10, 3, 4));
332*4ceae137SRavi Bangoria 
333*4ceae137SRavi Bangoria 	if (stepped == 1)
334*4ceae137SRavi Bangoria 		show_result("lvx", "PASS");
335*4ceae137SRavi Bangoria 	else
336*4ceae137SRavi Bangoria 		show_result("lvx", "FAIL");
337*4ceae137SRavi Bangoria 
338*4ceae137SRavi Bangoria 
339*4ceae137SRavi Bangoria 	/*** stvx ***/
340*4ceae137SRavi Bangoria 
341*4ceae137SRavi Bangoria 	c.b[0] = 4987513;
342*4ceae137SRavi Bangoria 	c.b[1] = 84313948;
343*4ceae137SRavi Bangoria 	c.b[2] = 71;
344*4ceae137SRavi Bangoria 	c.b[3] = 498532;
345*4ceae137SRavi Bangoria 
346*4ceae137SRavi Bangoria 	/* stvx vrs10, r3, r4 */
347*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_STVX(10, 3, 4));
348*4ceae137SRavi Bangoria 
349*4ceae137SRavi Bangoria 	if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
350*4ceae137SRavi Bangoria 	    cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
351*4ceae137SRavi Bangoria 		show_result("stvx", "PASS");
352*4ceae137SRavi Bangoria 	else
353*4ceae137SRavi Bangoria 		show_result("stvx", "FAIL");
354*4ceae137SRavi Bangoria }
355*4ceae137SRavi Bangoria #else
356*4ceae137SRavi Bangoria static void __init test_lvx_stvx(void)
357*4ceae137SRavi Bangoria {
358*4ceae137SRavi Bangoria 	show_result("lvx", "SKIP (CONFIG_ALTIVEC is not set)");
359*4ceae137SRavi Bangoria 	show_result("stvx", "SKIP (CONFIG_ALTIVEC is not set)");
360*4ceae137SRavi Bangoria }
361*4ceae137SRavi Bangoria #endif /* CONFIG_ALTIVEC */
362*4ceae137SRavi Bangoria 
363*4ceae137SRavi Bangoria #ifdef CONFIG_VSX
364*4ceae137SRavi Bangoria static void __init test_lxvd2x_stxvd2x(void)
365*4ceae137SRavi Bangoria {
366*4ceae137SRavi Bangoria 	struct pt_regs regs;
367*4ceae137SRavi Bangoria 	union {
368*4ceae137SRavi Bangoria 		vector128 a;
369*4ceae137SRavi Bangoria 		u32 b[4];
370*4ceae137SRavi Bangoria 	} c;
371*4ceae137SRavi Bangoria 	u32 cached_b[4];
372*4ceae137SRavi Bangoria 	int stepped = -1;
373*4ceae137SRavi Bangoria 
374*4ceae137SRavi Bangoria 	init_pt_regs(&regs);
375*4ceae137SRavi Bangoria 
376*4ceae137SRavi Bangoria 
377*4ceae137SRavi Bangoria 	/*** lxvd2x ***/
378*4ceae137SRavi Bangoria 
379*4ceae137SRavi Bangoria 	cached_b[0] = c.b[0] = 18233;
380*4ceae137SRavi Bangoria 	cached_b[1] = c.b[1] = 34863571;
381*4ceae137SRavi Bangoria 	cached_b[2] = c.b[2] = 834;
382*4ceae137SRavi Bangoria 	cached_b[3] = c.b[3] = 6138911;
383*4ceae137SRavi Bangoria 
384*4ceae137SRavi Bangoria 	regs.gpr[3] = (unsigned long) &c.a;
385*4ceae137SRavi Bangoria 	regs.gpr[4] = 0;
386*4ceae137SRavi Bangoria 
387*4ceae137SRavi Bangoria 	/* lxvd2x vsr39, r3, r4 */
388*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_LXVD2X(39, 3, 4));
389*4ceae137SRavi Bangoria 
390*4ceae137SRavi Bangoria 	if (stepped == 1)
391*4ceae137SRavi Bangoria 		show_result("lxvd2x", "PASS");
392*4ceae137SRavi Bangoria 	else
393*4ceae137SRavi Bangoria 		show_result("lxvd2x", "FAIL");
394*4ceae137SRavi Bangoria 
395*4ceae137SRavi Bangoria 
396*4ceae137SRavi Bangoria 	/*** stxvd2x ***/
397*4ceae137SRavi Bangoria 
398*4ceae137SRavi Bangoria 	c.b[0] = 21379463;
399*4ceae137SRavi Bangoria 	c.b[1] = 87;
400*4ceae137SRavi Bangoria 	c.b[2] = 374234;
401*4ceae137SRavi Bangoria 	c.b[3] = 4;
402*4ceae137SRavi Bangoria 
403*4ceae137SRavi Bangoria 	/* stxvd2x vsr39, r3, r4 */
404*4ceae137SRavi Bangoria 	stepped = emulate_step(&regs, TEST_STXVD2X(39, 3, 4));
405*4ceae137SRavi Bangoria 
406*4ceae137SRavi Bangoria 	if (stepped == 1 && cached_b[0] == c.b[0] && cached_b[1] == c.b[1] &&
407*4ceae137SRavi Bangoria 	    cached_b[2] == c.b[2] && cached_b[3] == c.b[3])
408*4ceae137SRavi Bangoria 		show_result("stxvd2x", "PASS");
409*4ceae137SRavi Bangoria 	else
410*4ceae137SRavi Bangoria 		show_result("stxvd2x", "FAIL");
411*4ceae137SRavi Bangoria }
412*4ceae137SRavi Bangoria #else
413*4ceae137SRavi Bangoria static void __init test_lxvd2x_stxvd2x(void)
414*4ceae137SRavi Bangoria {
415*4ceae137SRavi Bangoria 	show_result("lxvd2x", "SKIP (CONFIG_VSX is not set)");
416*4ceae137SRavi Bangoria 	show_result("stxvd2x", "SKIP (CONFIG_VSX is not set)");
417*4ceae137SRavi Bangoria }
418*4ceae137SRavi Bangoria #endif /* CONFIG_VSX */
419*4ceae137SRavi Bangoria 
420*4ceae137SRavi Bangoria static int __init test_emulate_step(void)
421*4ceae137SRavi Bangoria {
422*4ceae137SRavi Bangoria 	test_ld();
423*4ceae137SRavi Bangoria 	test_lwz();
424*4ceae137SRavi Bangoria 	test_lwzx();
425*4ceae137SRavi Bangoria 	test_std();
426*4ceae137SRavi Bangoria 	test_ldarx_stdcx();
427*4ceae137SRavi Bangoria 	test_lfsx_stfsx();
428*4ceae137SRavi Bangoria 	test_lfdx_stfdx();
429*4ceae137SRavi Bangoria 	test_lvx_stvx();
430*4ceae137SRavi Bangoria 	test_lxvd2x_stxvd2x();
431*4ceae137SRavi Bangoria 
432*4ceae137SRavi Bangoria 	return 0;
433*4ceae137SRavi Bangoria }
434*4ceae137SRavi Bangoria late_initcall(test_emulate_step);
435