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