xref: /kvm-unit-tests/powerpc/emulator.c (revision 8260a1561239fe48391227a86db5928d33dbf518)
1 /*
2  * Test some powerpc instructions
3  */
4 
5 #include <libcflat.h>
6 #include <asm/processor.h>
7 
8 static int verbose;
9 static int volatile is_invalid;
10 
11 static void program_check_handler(struct pt_regs *regs, void *opaque)
12 {
13 	int *data = opaque;
14 
15 	if (verbose) {
16 		printf("Detected invalid instruction 0x%016lx: %08x\n",
17 		       regs->nip, *(uint32_t*)regs->nip);
18 	}
19 
20 	/* the result is bit 16 to 19 of SRR1
21 	 * bit 0: SRR0 contains the address of the next instruction
22 	 * bit 1: Trap
23 	 * bit 2: Privileged instruction
24 	 * bit 3: Illegal instruction
25 	 * bit 4: FP enabled exception type
26 	 */
27 
28 	*data = regs->msr >> 16;
29 
30 	regs->nip += 4;
31 }
32 
33 static void test_illegal(void)
34 {
35 	report_prefix_push("invalid");
36 
37 	is_invalid = 0;
38 
39 	asm volatile (".long 0");
40 
41 	report("exception", is_invalid == 8); /* illegal instruction */
42 
43 	report_prefix_pop();
44 }
45 
46 static void test_64bit(void)
47 {
48 	uint64_t msr;
49 
50 	report_prefix_push("64bit");
51 
52 	asm("mfmsr %[msr]": [msr] "=r" (msr));
53 
54 	report("detected", msr & 0x8000000000000000UL);
55 
56 	report_prefix_pop();
57 }
58 
59 int main(int argc, char **argv)
60 {
61 	int i;
62 
63 	handle_exception(0x700, program_check_handler, (void *)&is_invalid);
64 
65 	for (i = 0; i < argc; i++) {
66 		if (strcmp(argv[i], "-v") == 0) {
67 			verbose = 1;
68 		}
69 	}
70 
71 	report_prefix_push("emulator");
72 
73 	test_64bit();
74 	test_illegal();
75 
76 	report_prefix_pop();
77 
78 	return report_summary();
79 }
80