17d36db35SAvi Kivity asm(".code16gcc"); 27d36db35SAvi Kivity 37d36db35SAvi Kivity typedef unsigned char u8; 47d36db35SAvi Kivity typedef unsigned short u16; 57d36db35SAvi Kivity typedef unsigned u32; 67d36db35SAvi Kivity typedef unsigned long long u64; 77d36db35SAvi Kivity 87d36db35SAvi Kivity void test_function(void); 97d36db35SAvi Kivity 107d36db35SAvi Kivity asm( 117d36db35SAvi Kivity "test_function: \n\t" 127d36db35SAvi Kivity "mov $0x1234, %eax \n\t" 137d36db35SAvi Kivity "ret" 147d36db35SAvi Kivity ); 157d36db35SAvi Kivity 167d36db35SAvi Kivity static int strlen(const char *str) 177d36db35SAvi Kivity { 187d36db35SAvi Kivity int n; 197d36db35SAvi Kivity 207d36db35SAvi Kivity for (n = 0; *str; ++str) 217d36db35SAvi Kivity ++n; 227d36db35SAvi Kivity return n; 237d36db35SAvi Kivity } 247d36db35SAvi Kivity 257d36db35SAvi Kivity static void print_serial(const char *buf) 267d36db35SAvi Kivity { 277d36db35SAvi Kivity unsigned long len = strlen(buf); 287d36db35SAvi Kivity 297d36db35SAvi Kivity asm volatile ("cld; addr32/rep/outsb" : "+S"(buf), "+c"(len) : "d"(0xf1)); 307d36db35SAvi Kivity } 317d36db35SAvi Kivity 327d36db35SAvi Kivity static void exit(int code) 337d36db35SAvi Kivity { 347d36db35SAvi Kivity asm volatile("out %0, %1" : : "a"(code), "d"((short)0xf4)); 357d36db35SAvi Kivity } 367d36db35SAvi Kivity 377d36db35SAvi Kivity struct regs { 387d36db35SAvi Kivity u32 eax, ebx, ecx, edx; 397d36db35SAvi Kivity u32 esi, edi, esp, ebp; 407d36db35SAvi Kivity u32 eip, eflags; 417d36db35SAvi Kivity }; 427d36db35SAvi Kivity 437d36db35SAvi Kivity static u64 gdt[] = { 447d36db35SAvi Kivity 0, 457d36db35SAvi Kivity 0x00cf9b000000ffffull, // flat 32-bit code segment 467d36db35SAvi Kivity 0x00cf93000000ffffull, // flat 32-bit data segment 477d36db35SAvi Kivity }; 487d36db35SAvi Kivity 497d36db35SAvi Kivity static struct { 507d36db35SAvi Kivity u16 limit; 517d36db35SAvi Kivity void *base; 527d36db35SAvi Kivity } __attribute__((packed)) gdt_descr = { 537d36db35SAvi Kivity sizeof(gdt) - 1, 547d36db35SAvi Kivity gdt, 557d36db35SAvi Kivity }; 567d36db35SAvi Kivity 577d36db35SAvi Kivity static void exec_in_big_real_mode(const struct regs *inregs, 587d36db35SAvi Kivity struct regs *outregs, 597d36db35SAvi Kivity const u8 *insn, int insn_len) 607d36db35SAvi Kivity { 617d36db35SAvi Kivity unsigned long tmp; 627d36db35SAvi Kivity static struct regs save; 637d36db35SAvi Kivity int i; 647d36db35SAvi Kivity extern u8 test_insn[], test_insn_end[]; 657d36db35SAvi Kivity 667d36db35SAvi Kivity for (i = 0; i < insn_len; ++i) 677d36db35SAvi Kivity test_insn[i] = insn[i]; 687d36db35SAvi Kivity for (; i < test_insn_end - test_insn; ++i) 697d36db35SAvi Kivity test_insn[i] = 0x90; // nop 707d36db35SAvi Kivity 717d36db35SAvi Kivity save = *inregs; 727d36db35SAvi Kivity asm volatile( 737d36db35SAvi Kivity "lgdtl %[gdt_descr] \n\t" 747d36db35SAvi Kivity "mov %%cr0, %[tmp] \n\t" 757d36db35SAvi Kivity "or $1, %[tmp] \n\t" 767d36db35SAvi Kivity "mov %[tmp], %%cr0 \n\t" 777d36db35SAvi Kivity "mov %[bigseg], %%gs \n\t" 787d36db35SAvi Kivity "and $-2, %[tmp] \n\t" 797d36db35SAvi Kivity "mov %[tmp], %%cr0 \n\t" 807d36db35SAvi Kivity 8132001692SAvi Kivity "pushw %[save]+36; popfw \n\t" 827d36db35SAvi Kivity "xchg %%eax, %[save]+0 \n\t" 837d36db35SAvi Kivity "xchg %%ebx, %[save]+4 \n\t" 847d36db35SAvi Kivity "xchg %%ecx, %[save]+8 \n\t" 857d36db35SAvi Kivity "xchg %%edx, %[save]+12 \n\t" 867d36db35SAvi Kivity "xchg %%esi, %[save]+16 \n\t" 877d36db35SAvi Kivity "xchg %%edi, %[save]+20 \n\t" 887d36db35SAvi Kivity "xchg %%esp, %[save]+24 \n\t" 897d36db35SAvi Kivity "xchg %%ebp, %[save]+28 \n\t" 907d36db35SAvi Kivity 917d36db35SAvi Kivity "test_insn: . = . + 32\n\t" 927d36db35SAvi Kivity "test_insn_end: \n\t" 937d36db35SAvi Kivity 947d36db35SAvi Kivity "xchg %%eax, %[save]+0 \n\t" 957d36db35SAvi Kivity "xchg %%ebx, %[save]+4 \n\t" 967d36db35SAvi Kivity "xchg %%ecx, %[save]+8 \n\t" 977d36db35SAvi Kivity "xchg %%edx, %[save]+12 \n\t" 987d36db35SAvi Kivity "xchg %%esi, %[save]+16 \n\t" 997d36db35SAvi Kivity "xchg %%edi, %[save]+20 \n\t" 1007d36db35SAvi Kivity "xchg %%esp, %[save]+24 \n\t" 1017d36db35SAvi Kivity "xchg %%ebp, %[save]+28 \n\t" 1027d36db35SAvi Kivity 1037d36db35SAvi Kivity /* Save EFLAGS in outregs*/ 1047d36db35SAvi Kivity "pushfl \n\t" 1057d36db35SAvi Kivity "popl %[save]+36 \n\t" 1067d36db35SAvi Kivity 1077d36db35SAvi Kivity "xor %[tmp], %[tmp] \n\t" 1087d36db35SAvi Kivity "mov %[tmp], %%gs \n\t" 1097d36db35SAvi Kivity : [tmp]"=&r"(tmp), [save]"+m"(save) 1107d36db35SAvi Kivity : [gdt_descr]"m"(gdt_descr), [bigseg]"r"((short)16) 1117d36db35SAvi Kivity : "cc", "memory" 1127d36db35SAvi Kivity ); 1137d36db35SAvi Kivity *outregs = save; 1147d36db35SAvi Kivity } 1157d36db35SAvi Kivity 1167d36db35SAvi Kivity #define R_AX 1 1177d36db35SAvi Kivity #define R_BX 2 1187d36db35SAvi Kivity #define R_CX 4 1197d36db35SAvi Kivity #define R_DX 8 1207d36db35SAvi Kivity #define R_SI 16 1217d36db35SAvi Kivity #define R_DI 32 1227d36db35SAvi Kivity #define R_SP 64 1237d36db35SAvi Kivity #define R_BP 128 1247d36db35SAvi Kivity 1257d36db35SAvi Kivity int regs_equal(const struct regs *r1, const struct regs *r2, int ignore) 1267d36db35SAvi Kivity { 1277d36db35SAvi Kivity const u32 *p1 = &r1->eax, *p2 = &r2->eax; // yuck 1287d36db35SAvi Kivity int i; 1297d36db35SAvi Kivity 1307d36db35SAvi Kivity for (i = 0; i < 8; ++i) 1317d36db35SAvi Kivity if (!(ignore & (1 << i)) && p1[i] != p2[i]) 1327d36db35SAvi Kivity return 0; 1337d36db35SAvi Kivity return 1; 1347d36db35SAvi Kivity } 1357d36db35SAvi Kivity 1367d36db35SAvi Kivity #define MK_INSN(name, str) \ 1377d36db35SAvi Kivity asm ( \ 1387d36db35SAvi Kivity ".text 1\n\t" \ 1397d36db35SAvi Kivity "insn_" #name ": " str " \n\t" \ 1407d36db35SAvi Kivity "insn_" #name "_end: \n\t" \ 1417d36db35SAvi Kivity ".text\n\t" \ 1427d36db35SAvi Kivity ); \ 1437d36db35SAvi Kivity extern u8 insn_##name[], insn_##name##_end[] 1447d36db35SAvi Kivity 1457d36db35SAvi Kivity void test_xchg(void) 1467d36db35SAvi Kivity { 1477d36db35SAvi Kivity struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = 7}, outregs; 1487d36db35SAvi Kivity 1497d36db35SAvi Kivity MK_INSN(xchg_test1, "xchg %eax,%eax\n\t"); 1507d36db35SAvi Kivity MK_INSN(xchg_test2, "xchg %eax,%ebx\n\t"); 1517d36db35SAvi Kivity MK_INSN(xchg_test3, "xchg %eax,%ecx\n\t"); 1527d36db35SAvi Kivity MK_INSN(xchg_test4, "xchg %eax,%edx\n\t"); 1537d36db35SAvi Kivity MK_INSN(xchg_test5, "xchg %eax,%esi\n\t"); 1547d36db35SAvi Kivity MK_INSN(xchg_test6, "xchg %eax,%edi\n\t"); 1557d36db35SAvi Kivity MK_INSN(xchg_test7, "xchg %eax,%ebp\n\t"); 1567d36db35SAvi Kivity MK_INSN(xchg_test8, "xchg %eax,%esp\n\t"); 1577d36db35SAvi Kivity 1587d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 1597d36db35SAvi Kivity insn_xchg_test1, 1607d36db35SAvi Kivity insn_xchg_test1_end - insn_xchg_test1); 1617d36db35SAvi Kivity 1627d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 1637d36db35SAvi Kivity print_serial("xchg test 1: FAIL\n"); 1647d36db35SAvi Kivity else 1657d36db35SAvi Kivity print_serial("xchg test 1: PASS\n"); 1667d36db35SAvi Kivity 1677d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 1687d36db35SAvi Kivity insn_xchg_test2, 1697d36db35SAvi Kivity insn_xchg_test2_end - insn_xchg_test2); 1707d36db35SAvi Kivity 1717d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_BX) || 1727d36db35SAvi Kivity outregs.eax != inregs.ebx || 1737d36db35SAvi Kivity outregs.ebx != inregs.eax) 1747d36db35SAvi Kivity print_serial("xchg test 2: FAIL\n"); 1757d36db35SAvi Kivity else 1767d36db35SAvi Kivity print_serial("xchg test 2: PASS\n"); 1777d36db35SAvi Kivity 1787d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 1797d36db35SAvi Kivity insn_xchg_test3, 1807d36db35SAvi Kivity insn_xchg_test3_end - insn_xchg_test3); 1817d36db35SAvi Kivity 1827d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_CX) || 1837d36db35SAvi Kivity outregs.eax != inregs.ecx || 1847d36db35SAvi Kivity outregs.ecx != inregs.eax) 1857d36db35SAvi Kivity print_serial("xchg test 3: FAIL\n"); 1867d36db35SAvi Kivity else 1877d36db35SAvi Kivity print_serial("xchg test 3: PASS\n"); 1887d36db35SAvi Kivity 1897d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 1907d36db35SAvi Kivity insn_xchg_test4, 1917d36db35SAvi Kivity insn_xchg_test4_end - insn_xchg_test4); 1927d36db35SAvi Kivity 1937d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_DX) || 1947d36db35SAvi Kivity outregs.eax != inregs.edx || 1957d36db35SAvi Kivity outregs.edx != inregs.eax) 1967d36db35SAvi Kivity print_serial("xchg test 4: FAIL\n"); 1977d36db35SAvi Kivity else 1987d36db35SAvi Kivity print_serial("xchg test 4: PASS\n"); 1997d36db35SAvi Kivity 2007d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2017d36db35SAvi Kivity insn_xchg_test5, 2027d36db35SAvi Kivity insn_xchg_test5_end - insn_xchg_test5); 2037d36db35SAvi Kivity 2047d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_SI) || 2057d36db35SAvi Kivity outregs.eax != inregs.esi || 2067d36db35SAvi Kivity outregs.esi != inregs.eax) 2077d36db35SAvi Kivity print_serial("xchg test 5: FAIL\n"); 2087d36db35SAvi Kivity else 2097d36db35SAvi Kivity print_serial("xchg test 5: PASS\n"); 2107d36db35SAvi Kivity 2117d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2127d36db35SAvi Kivity insn_xchg_test6, 2137d36db35SAvi Kivity insn_xchg_test6_end - insn_xchg_test6); 2147d36db35SAvi Kivity 2157d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_DI) || 2167d36db35SAvi Kivity outregs.eax != inregs.edi || 2177d36db35SAvi Kivity outregs.edi != inregs.eax) 2187d36db35SAvi Kivity print_serial("xchg test 6: FAIL\n"); 2197d36db35SAvi Kivity else 2207d36db35SAvi Kivity print_serial("xchg test 6: PASS\n"); 2217d36db35SAvi Kivity 2227d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2237d36db35SAvi Kivity insn_xchg_test7, 2247d36db35SAvi Kivity insn_xchg_test7_end - insn_xchg_test7); 2257d36db35SAvi Kivity 2267d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_BP) || 2277d36db35SAvi Kivity outregs.eax != inregs.ebp || 2287d36db35SAvi Kivity outregs.ebp != inregs.eax) 2297d36db35SAvi Kivity print_serial("xchg test 7: FAIL\n"); 2307d36db35SAvi Kivity else 2317d36db35SAvi Kivity print_serial("xchg test 7: PASS\n"); 2327d36db35SAvi Kivity 2337d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2347d36db35SAvi Kivity insn_xchg_test8, 2357d36db35SAvi Kivity insn_xchg_test8_end - insn_xchg_test8); 2367d36db35SAvi Kivity 2377d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX | R_SP) || 2387d36db35SAvi Kivity outregs.eax != inregs.esp || 2397d36db35SAvi Kivity outregs.esp != inregs.eax) 2407d36db35SAvi Kivity print_serial("xchg test 8: FAIL\n"); 2417d36db35SAvi Kivity else 2427d36db35SAvi Kivity print_serial("xchg test 8: PASS\n"); 2437d36db35SAvi Kivity } 2447d36db35SAvi Kivity 2457d36db35SAvi Kivity void test_shld(void) 2467d36db35SAvi Kivity { 2477d36db35SAvi Kivity struct regs inregs = { .eax = 0xbe, .edx = 0xef000000 }, outregs; 2487d36db35SAvi Kivity MK_INSN(shld_test, "shld $8,%edx,%eax\n\t"); 2497d36db35SAvi Kivity 2507d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2517d36db35SAvi Kivity insn_shld_test, 2527d36db35SAvi Kivity insn_shld_test_end - insn_shld_test); 2537d36db35SAvi Kivity if (outregs.eax != 0xbeef) 2547d36db35SAvi Kivity print_serial("shld: FAIL\n"); 2557d36db35SAvi Kivity else 2567d36db35SAvi Kivity print_serial("shld: PASS\n"); 2577d36db35SAvi Kivity } 2587d36db35SAvi Kivity 2597d36db35SAvi Kivity void test_mov_imm(void) 2607d36db35SAvi Kivity { 2617d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 2627d36db35SAvi Kivity MK_INSN(mov_r32_imm_1, "mov $1234567890, %eax"); 2637d36db35SAvi Kivity MK_INSN(mov_r16_imm_1, "mov $1234, %ax"); 2647d36db35SAvi Kivity MK_INSN(mov_r8_imm_1, "mov $0x12, %ah"); 2657d36db35SAvi Kivity MK_INSN(mov_r8_imm_2, "mov $0x34, %al"); 2667d36db35SAvi Kivity MK_INSN(mov_r8_imm_3, "mov $0x12, %ah\n\t" "mov $0x34, %al\n\t"); 2677d36db35SAvi Kivity 2687d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2697d36db35SAvi Kivity insn_mov_r16_imm_1, 2707d36db35SAvi Kivity insn_mov_r16_imm_1_end - insn_mov_r16_imm_1); 2717d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234) 2727d36db35SAvi Kivity print_serial("mov test 1: FAIL\n"); 2737d36db35SAvi Kivity else 2747d36db35SAvi Kivity print_serial("mov test 1: PASS\n"); 2757d36db35SAvi Kivity 2767d36db35SAvi Kivity /* test mov $imm, %eax */ 2777d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2787d36db35SAvi Kivity insn_mov_r32_imm_1, 2797d36db35SAvi Kivity insn_mov_r32_imm_1_end - insn_mov_r32_imm_1); 2807d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234567890) 2817d36db35SAvi Kivity print_serial("mov test 2: FAIL\n"); 2827d36db35SAvi Kivity else 2837d36db35SAvi Kivity print_serial("mov test 2: PASS\n"); 2847d36db35SAvi Kivity 2857d36db35SAvi Kivity /* test mov $imm, %al/%ah */ 2867d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2877d36db35SAvi Kivity insn_mov_r8_imm_1, 2887d36db35SAvi Kivity insn_mov_r8_imm_1_end - insn_mov_r8_imm_1); 2897d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1200) 2907d36db35SAvi Kivity print_serial("mov test 3: FAIL\n"); 2917d36db35SAvi Kivity else 2927d36db35SAvi Kivity print_serial("mov test 3: PASS\n"); 2937d36db35SAvi Kivity 2947d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 2957d36db35SAvi Kivity insn_mov_r8_imm_2, 2967d36db35SAvi Kivity insn_mov_r8_imm_2_end - insn_mov_r8_imm_2); 2977d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x34) 2987d36db35SAvi Kivity print_serial("mov test 4: FAIL\n"); 2997d36db35SAvi Kivity else 3007d36db35SAvi Kivity print_serial("mov test 4: PASS\n"); 3017d36db35SAvi Kivity 3027d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3037d36db35SAvi Kivity insn_mov_r8_imm_3, 3047d36db35SAvi Kivity insn_mov_r8_imm_3_end - insn_mov_r8_imm_3); 3057d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 3067d36db35SAvi Kivity print_serial("mov test 5: FAIL\n"); 3077d36db35SAvi Kivity else 3087d36db35SAvi Kivity print_serial("mov test 5: PASS\n"); 3097d36db35SAvi Kivity } 3107d36db35SAvi Kivity 3117d36db35SAvi Kivity void test_sub_imm(void) 3127d36db35SAvi Kivity { 3137d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 3147d36db35SAvi Kivity MK_INSN(sub_r32_imm_1, "mov $1234567890, %eax\n\t" "sub $10, %eax\n\t"); 3157d36db35SAvi Kivity MK_INSN(sub_r16_imm_1, "mov $1234, %ax\n\t" "sub $10, %ax\n\t"); 3167d36db35SAvi Kivity MK_INSN(sub_r8_imm_1, "mov $0x12, %ah\n\t" "sub $0x10, %ah\n\t"); 3177d36db35SAvi Kivity MK_INSN(sub_r8_imm_2, "mov $0x34, %al\n\t" "sub $0x10, %al\n\t"); 3187d36db35SAvi Kivity 3197d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3207d36db35SAvi Kivity insn_sub_r16_imm_1, 3217d36db35SAvi Kivity insn_sub_r16_imm_1_end - insn_sub_r16_imm_1); 3227d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1224) 3237d36db35SAvi Kivity print_serial("sub test 1: FAIL\n"); 3247d36db35SAvi Kivity else 3257d36db35SAvi Kivity print_serial("sub test 1: PASS\n"); 3267d36db35SAvi Kivity 3277d36db35SAvi Kivity /* test mov $imm, %eax */ 3287d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3297d36db35SAvi Kivity insn_sub_r32_imm_1, 3307d36db35SAvi Kivity insn_sub_r32_imm_1_end - insn_sub_r32_imm_1); 3317d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 1234567880) 3327d36db35SAvi Kivity print_serial("sub test 2: FAIL\n"); 3337d36db35SAvi Kivity else 3347d36db35SAvi Kivity print_serial("sub test 2: PASS\n"); 3357d36db35SAvi Kivity 3367d36db35SAvi Kivity /* test mov $imm, %al/%ah */ 3377d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3387d36db35SAvi Kivity insn_sub_r8_imm_1, 3397d36db35SAvi Kivity insn_sub_r8_imm_1_end - insn_sub_r8_imm_1); 3407d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x0200) 3417d36db35SAvi Kivity print_serial("sub test 3: FAIL\n"); 3427d36db35SAvi Kivity else 3437d36db35SAvi Kivity print_serial("sub test 3: PASS\n"); 3447d36db35SAvi Kivity 3457d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3467d36db35SAvi Kivity insn_sub_r8_imm_2, 3477d36db35SAvi Kivity insn_sub_r8_imm_2_end - insn_sub_r8_imm_2); 3487d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x24) 3497d36db35SAvi Kivity print_serial("sub test 4: FAIL\n"); 3507d36db35SAvi Kivity else 3517d36db35SAvi Kivity print_serial("sub test 4: PASS\n"); 3527d36db35SAvi Kivity } 3537d36db35SAvi Kivity 3547d36db35SAvi Kivity 3557d36db35SAvi Kivity void test_xor_imm(void) 3567d36db35SAvi Kivity { 3577d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 3587d36db35SAvi Kivity MK_INSN(xor_r32_imm_1, "mov $1234567890, %eax\n\t" "xor $1234567890, %eax\n\t"); 3597d36db35SAvi Kivity MK_INSN(xor_r16_imm_1, "mov $1234, %ax\n\t" "xor $1234, %ax\n\t"); 3607d36db35SAvi Kivity MK_INSN(xor_r8_imm_1, "mov $0x12, %ah\n\t" "xor $0x12, %ah\n\t"); 3617d36db35SAvi Kivity MK_INSN(xor_r8_imm_2, "mov $0x34, %al\n\t" "xor $0x34, %al\n\t"); 3627d36db35SAvi Kivity 3637d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3647d36db35SAvi Kivity insn_xor_r16_imm_1, 3657d36db35SAvi Kivity insn_xor_r16_imm_1_end - insn_xor_r16_imm_1); 3667d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) 3677d36db35SAvi Kivity print_serial("xor test 1: FAIL\n"); 3687d36db35SAvi Kivity else 3697d36db35SAvi Kivity print_serial("xor test 1: PASS\n"); 3707d36db35SAvi Kivity 3717d36db35SAvi Kivity /* test mov $imm, %eax */ 3727d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3737d36db35SAvi Kivity insn_xor_r32_imm_1, 3747d36db35SAvi Kivity insn_xor_r32_imm_1_end - insn_xor_r32_imm_1); 3757d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) 3767d36db35SAvi Kivity print_serial("xor test 2: FAIL\n"); 3777d36db35SAvi Kivity else 3787d36db35SAvi Kivity print_serial("xor test 2: PASS\n"); 3797d36db35SAvi Kivity 3807d36db35SAvi Kivity /* test mov $imm, %al/%ah */ 3817d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3827d36db35SAvi Kivity insn_xor_r8_imm_1, 3837d36db35SAvi Kivity insn_xor_r8_imm_1_end - insn_xor_r8_imm_1); 3847d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) 3857d36db35SAvi Kivity print_serial("xor test 3: FAIL\n"); 3867d36db35SAvi Kivity else 3877d36db35SAvi Kivity print_serial("xor test 3: PASS\n"); 3887d36db35SAvi Kivity 3897d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 3907d36db35SAvi Kivity insn_xor_r8_imm_2, 3917d36db35SAvi Kivity insn_xor_r8_imm_2_end - insn_xor_r8_imm_2); 3927d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0) 3937d36db35SAvi Kivity print_serial("xor test 4: FAIL\n"); 3947d36db35SAvi Kivity else 3957d36db35SAvi Kivity print_serial("xor test 4: PASS\n"); 3967d36db35SAvi Kivity } 3977d36db35SAvi Kivity 3987d36db35SAvi Kivity void test_cmp_imm(void) 3997d36db35SAvi Kivity { 4007d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 4017d36db35SAvi Kivity MK_INSN(cmp_test1, "mov $0x34, %al\n\t" 4027d36db35SAvi Kivity "cmp $0x34, %al\n\t"); 4037d36db35SAvi Kivity MK_INSN(cmp_test2, "mov $0x34, %al\n\t" 4047d36db35SAvi Kivity "cmp $0x39, %al\n\t"); 4057d36db35SAvi Kivity MK_INSN(cmp_test3, "mov $0x34, %al\n\t" 4067d36db35SAvi Kivity "cmp $0x24, %al\n\t"); 4077d36db35SAvi Kivity 4087d36db35SAvi Kivity /* test cmp imm8 with AL */ 4097d36db35SAvi Kivity /* ZF: (bit 6) Zero Flag becomes 1 if an operation results 4107d36db35SAvi Kivity * in a 0 writeback, or 0 register 4117d36db35SAvi Kivity */ 4127d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4137d36db35SAvi Kivity insn_cmp_test1, 4147d36db35SAvi Kivity insn_cmp_test1_end - insn_cmp_test1); 4157d36db35SAvi Kivity if ((outregs.eflags & (1<<6)) != (1<<6)) 4167d36db35SAvi Kivity print_serial("cmp test 1: FAIL\n"); 4177d36db35SAvi Kivity else 4187d36db35SAvi Kivity print_serial("cmp test 1: PASS\n"); 4197d36db35SAvi Kivity 4207d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4217d36db35SAvi Kivity insn_cmp_test2, 4227d36db35SAvi Kivity insn_cmp_test2_end - insn_cmp_test2); 4237d36db35SAvi Kivity if ((outregs.eflags & (1<<6)) != 0) 4247d36db35SAvi Kivity print_serial("cmp test 2: FAIL\n"); 4257d36db35SAvi Kivity else 4267d36db35SAvi Kivity print_serial("cmp test 2: PASS\n"); 4277d36db35SAvi Kivity 4287d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4297d36db35SAvi Kivity insn_cmp_test3, 4307d36db35SAvi Kivity insn_cmp_test3_end - insn_cmp_test3); 4317d36db35SAvi Kivity if ((outregs.eflags & (1<<6)) != 0) 4327d36db35SAvi Kivity print_serial("cmp test 3: FAIL\n"); 4337d36db35SAvi Kivity else 4347d36db35SAvi Kivity print_serial("cmp test 3: PASS\n"); 4357d36db35SAvi Kivity } 4367d36db35SAvi Kivity 4377d36db35SAvi Kivity void test_add_imm(void) 4387d36db35SAvi Kivity { 4397d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 4407d36db35SAvi Kivity MK_INSN(add_test1, "mov $0x43211234, %eax \n\t" 4417d36db35SAvi Kivity "add $0x12344321, %eax \n\t"); 4427d36db35SAvi Kivity MK_INSN(add_test2, "mov $0x12, %eax \n\t" 4437d36db35SAvi Kivity "add $0x21, %al\n\t"); 4447d36db35SAvi Kivity 4457d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4467d36db35SAvi Kivity insn_add_test1, 4477d36db35SAvi Kivity insn_add_test1_end - insn_add_test1); 4487d36db35SAvi Kivity if (outregs.eax != 0x55555555) 4497d36db35SAvi Kivity print_serial("add test 1: FAIL\n"); 4507d36db35SAvi Kivity else 4517d36db35SAvi Kivity print_serial("add test 1: PASS\n"); 4527d36db35SAvi Kivity 4537d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4547d36db35SAvi Kivity insn_add_test2, 4557d36db35SAvi Kivity insn_add_test2_end - insn_add_test2); 4567d36db35SAvi Kivity if (outregs.eax != 0x33) 4577d36db35SAvi Kivity print_serial("add test 2: FAIL\n"); 4587d36db35SAvi Kivity else 4597d36db35SAvi Kivity print_serial("add test 2: PASS\n"); 4607d36db35SAvi Kivity } 4617d36db35SAvi Kivity 4627d36db35SAvi Kivity void test_eflags_insn(void) 4637d36db35SAvi Kivity { 4647d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 4657d36db35SAvi Kivity MK_INSN(clc, "clc"); 466b3261e48SMohammed Gamal MK_INSN(stc, "stc"); 4677d36db35SAvi Kivity MK_INSN(cli, "cli"); 4687d36db35SAvi Kivity MK_INSN(sti, "sti"); 4697d36db35SAvi Kivity MK_INSN(cld, "cld"); 4707d36db35SAvi Kivity MK_INSN(std, "std"); 4717d36db35SAvi Kivity 4727d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4737d36db35SAvi Kivity insn_clc, 4747d36db35SAvi Kivity insn_clc_end - insn_clc); 4757d36db35SAvi Kivity if (outregs.eflags & 1) 4767d36db35SAvi Kivity print_serial("clc test: FAIL\n"); 4777d36db35SAvi Kivity else 4787d36db35SAvi Kivity print_serial("clc test: PASS\n"); 4797d36db35SAvi Kivity 4807d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 481b3261e48SMohammed Gamal insn_stc, 482b3261e48SMohammed Gamal insn_stc_end - insn_stc); 483b3261e48SMohammed Gamal if (!(outregs.eflags & 1)) 484b3261e48SMohammed Gamal print_serial("stc test: FAIL\n"); 485b3261e48SMohammed Gamal else 486b3261e48SMohammed Gamal print_serial("stc test: PASS\n"); 487b3261e48SMohammed Gamal 488b3261e48SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 4897d36db35SAvi Kivity insn_cli, 4907d36db35SAvi Kivity insn_cli_end - insn_cli); 4917d36db35SAvi Kivity if (outregs.eflags & (1 << 9)) 4927d36db35SAvi Kivity print_serial("cli test: FAIL\n"); 4937d36db35SAvi Kivity else 4947d36db35SAvi Kivity print_serial("cli test: PASS\n"); 4957d36db35SAvi Kivity 4967d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 4977d36db35SAvi Kivity insn_sti, 4987d36db35SAvi Kivity insn_sti_end - insn_sti); 4997d36db35SAvi Kivity if (!(outregs.eflags & (1 << 9))) 5007d36db35SAvi Kivity print_serial("sti test: FAIL\n"); 5017d36db35SAvi Kivity else 5027d36db35SAvi Kivity print_serial("sti test: PASS\n"); 5037d36db35SAvi Kivity 5047d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5057d36db35SAvi Kivity insn_cld, 5067d36db35SAvi Kivity insn_cld_end - insn_cld); 5077d36db35SAvi Kivity if (outregs.eflags & (1 << 10)) 5087d36db35SAvi Kivity print_serial("cld test: FAIL\n"); 5097d36db35SAvi Kivity else 5107d36db35SAvi Kivity print_serial("cld test: PASS\n"); 5117d36db35SAvi Kivity 5127d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5137d36db35SAvi Kivity insn_std, 5147d36db35SAvi Kivity insn_std_end - insn_std); 5157d36db35SAvi Kivity if (!(outregs.eflags & (1 << 10))) 5167d36db35SAvi Kivity print_serial("std test: FAIL\n"); 5177d36db35SAvi Kivity else 5187d36db35SAvi Kivity print_serial("std test: PASS\n"); 5197d36db35SAvi Kivity } 5207d36db35SAvi Kivity 5217d36db35SAvi Kivity void test_io(void) 5227d36db35SAvi Kivity { 5237d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 5247d36db35SAvi Kivity MK_INSN(io_test1, "mov $0xff, %al \n\t" 5257d36db35SAvi Kivity "out %al, $0xe0 \n\t" 5267d36db35SAvi Kivity "mov $0x00, %al \n\t" 5277d36db35SAvi Kivity "in $0xe0, %al \n\t"); 5287d36db35SAvi Kivity MK_INSN(io_test2, "mov $0xffff, %ax \n\t" 5297d36db35SAvi Kivity "out %ax, $0xe0 \n\t" 5307d36db35SAvi Kivity "mov $0x0000, %ax \n\t" 5317d36db35SAvi Kivity "in $0xe0, %ax \n\t"); 5327d36db35SAvi Kivity MK_INSN(io_test3, "mov $0xffffffff, %eax \n\t" 5337d36db35SAvi Kivity "out %eax, $0xe0 \n\t" 5347d36db35SAvi Kivity "mov $0x000000, %eax \n\t" 5357d36db35SAvi Kivity "in $0xe0, %eax \n\t"); 5367d36db35SAvi Kivity MK_INSN(io_test4, "mov $0xe0, %dx \n\t" 5377d36db35SAvi Kivity "mov $0xff, %al \n\t" 5387d36db35SAvi Kivity "out %al, %dx \n\t" 5397d36db35SAvi Kivity "mov $0x00, %al \n\t" 5407d36db35SAvi Kivity "in %dx, %al \n\t"); 5417d36db35SAvi Kivity MK_INSN(io_test5, "mov $0xe0, %dx \n\t" 5427d36db35SAvi Kivity "mov $0xffff, %ax \n\t" 5437d36db35SAvi Kivity "out %ax, %dx \n\t" 5447d36db35SAvi Kivity "mov $0x0000, %ax \n\t" 5457d36db35SAvi Kivity "in %dx, %ax \n\t"); 5467d36db35SAvi Kivity MK_INSN(io_test6, "mov $0xe0, %dx \n\t" 5477d36db35SAvi Kivity "mov $0xffffffff, %eax \n\t" 5487d36db35SAvi Kivity "out %eax, %dx \n\t" 5497d36db35SAvi Kivity "mov $0x00000000, %eax \n\t" 5507d36db35SAvi Kivity "in %dx, %eax \n\t"); 5517d36db35SAvi Kivity 5527d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5537d36db35SAvi Kivity insn_io_test1, 5547d36db35SAvi Kivity insn_io_test1_end - insn_io_test1); 5557d36db35SAvi Kivity 5567d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xff) 5577d36db35SAvi Kivity print_serial("I/O test 1: FAIL\n"); 5587d36db35SAvi Kivity else 5597d36db35SAvi Kivity print_serial("I/O test 1: PASS\n"); 5607d36db35SAvi Kivity 5617d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5627d36db35SAvi Kivity insn_io_test2, 5637d36db35SAvi Kivity insn_io_test2_end - insn_io_test2); 5647d36db35SAvi Kivity 5657d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xffff) 5667d36db35SAvi Kivity print_serial("I/O test 2: FAIL\n"); 5677d36db35SAvi Kivity else 5687d36db35SAvi Kivity print_serial("I/O test 2: PASS\n"); 5697d36db35SAvi Kivity 5707d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5717d36db35SAvi Kivity insn_io_test3, 5727d36db35SAvi Kivity insn_io_test3_end - insn_io_test3); 5737d36db35SAvi Kivity 5747d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0xffffffff) 5757d36db35SAvi Kivity print_serial("I/O test 3: FAIL\n"); 5767d36db35SAvi Kivity else 5777d36db35SAvi Kivity print_serial("I/O test 3: PASS\n"); 5787d36db35SAvi Kivity 5797d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5807d36db35SAvi Kivity insn_io_test4, 5817d36db35SAvi Kivity insn_io_test4_end - insn_io_test4); 5827d36db35SAvi Kivity 5837d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xff) 5847d36db35SAvi Kivity print_serial("I/O test 4: FAIL\n"); 5857d36db35SAvi Kivity else 5867d36db35SAvi Kivity print_serial("I/O test 4: PASS\n"); 5877d36db35SAvi Kivity 5887d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5897d36db35SAvi Kivity insn_io_test5, 5907d36db35SAvi Kivity insn_io_test5_end - insn_io_test5); 5917d36db35SAvi Kivity 5927d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xffff) 5937d36db35SAvi Kivity print_serial("I/O test 5: FAIL\n"); 5947d36db35SAvi Kivity else 5957d36db35SAvi Kivity print_serial("I/O test 5: PASS\n"); 5967d36db35SAvi Kivity 5977d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 5987d36db35SAvi Kivity insn_io_test6, 5997d36db35SAvi Kivity insn_io_test6_end - insn_io_test6); 6007d36db35SAvi Kivity 6017d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_DX) || outregs.eax != 0xffffffff) 6027d36db35SAvi Kivity print_serial("I/O test 6: FAIL\n"); 6037d36db35SAvi Kivity else 6047d36db35SAvi Kivity print_serial("I/O test 6: PASS\n"); 6057d36db35SAvi Kivity } 6067d36db35SAvi Kivity 6077d36db35SAvi Kivity void test_call(void) 6087d36db35SAvi Kivity { 6097d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 6107d36db35SAvi Kivity u32 esp[16]; 6117d36db35SAvi Kivity 6127d36db35SAvi Kivity inregs.esp = (u32)esp; 6137d36db35SAvi Kivity 6147d36db35SAvi Kivity MK_INSN(call1, "mov $test_function, %eax \n\t" 6157d36db35SAvi Kivity "call *%eax\n\t"); 6167d36db35SAvi Kivity MK_INSN(call_near1, "jmp 2f\n\t" 6177d36db35SAvi Kivity "1: mov $0x1234, %eax\n\t" 6187d36db35SAvi Kivity "ret\n\t" 6197d36db35SAvi Kivity "2: call 1b\t"); 6207d36db35SAvi Kivity MK_INSN(call_near2, "call 1f\n\t" 6217d36db35SAvi Kivity "jmp 2f\n\t" 6227d36db35SAvi Kivity "1: mov $0x1234, %eax\n\t" 6237d36db35SAvi Kivity "ret\n\t" 6247d36db35SAvi Kivity "2:\t"); 6257d36db35SAvi Kivity 6267d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 6277d36db35SAvi Kivity insn_call1, 6287d36db35SAvi Kivity insn_call1_end - insn_call1); 6297d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 6307d36db35SAvi Kivity print_serial("Call Test 1: FAIL\n"); 6317d36db35SAvi Kivity else 6327d36db35SAvi Kivity print_serial("Call Test 1: PASS\n"); 6337d36db35SAvi Kivity 6347d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 6357d36db35SAvi Kivity insn_call_near1, insn_call_near1_end - insn_call_near1); 6367d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 6377d36db35SAvi Kivity print_serial("Call near Test 1: FAIL\n"); 6387d36db35SAvi Kivity else 6397d36db35SAvi Kivity print_serial("Call near Test 1: PASS\n"); 6407d36db35SAvi Kivity 6417d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 6427d36db35SAvi Kivity insn_call_near2, insn_call_near2_end - insn_call_near2); 6437d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 6447d36db35SAvi Kivity print_serial("Call near Test 2: FAIL\n"); 6457d36db35SAvi Kivity else 6467d36db35SAvi Kivity print_serial("Call near Test 2: PASS\n"); 6477d36db35SAvi Kivity } 6487d36db35SAvi Kivity 6497d36db35SAvi Kivity void test_jcc_short(void) 6507d36db35SAvi Kivity { 6517d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 6527d36db35SAvi Kivity MK_INSN(jnz_short1, "jnz 1f\n\t" 6537d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 6547d36db35SAvi Kivity "1:\n\t"); 6557d36db35SAvi Kivity MK_INSN(jnz_short2, "1:\n\t" 6567d36db35SAvi Kivity "cmp $0x1234, %eax\n\t" 6577d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 6587d36db35SAvi Kivity "jnz 1b\n\t"); 6597d36db35SAvi Kivity MK_INSN(jmp_short1, "jmp 1f\n\t" 6607d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 6617d36db35SAvi Kivity "1:\n\t"); 6627d36db35SAvi Kivity 6637d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 6647d36db35SAvi Kivity insn_jnz_short1, insn_jnz_short1_end - insn_jnz_short1); 6657d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, 0)) 6667d36db35SAvi Kivity print_serial("JNZ short Test 1: FAIL\n"); 6677d36db35SAvi Kivity else 6687d36db35SAvi Kivity print_serial("JNZ short Test 1: PASS\n"); 6697d36db35SAvi Kivity 6707d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 6717d36db35SAvi Kivity insn_jnz_short2, insn_jnz_short2_end - insn_jnz_short2); 6727d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, R_AX) || !(outregs.eflags & (1 << 6))) 6737d36db35SAvi Kivity print_serial("JNZ short Test 2: FAIL\n"); 6747d36db35SAvi Kivity else 6757d36db35SAvi Kivity print_serial("JNZ short Test 2: PASS\n"); 6767d36db35SAvi Kivity 6777d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 6787d36db35SAvi Kivity insn_jmp_short1, insn_jmp_short1_end - insn_jmp_short1); 6797d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, 0)) 6807d36db35SAvi Kivity print_serial("JMP short Test 1: FAIL\n"); 6817d36db35SAvi Kivity else 6827d36db35SAvi Kivity print_serial("JMP short Test 1: PASS\n"); 6837d36db35SAvi Kivity } 6847d36db35SAvi Kivity 6857d36db35SAvi Kivity void test_jcc_near(void) 6867d36db35SAvi Kivity { 6877d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 6887d36db35SAvi Kivity /* encode near jmp manually. gas will not do it if offsets < 127 byte */ 6897d36db35SAvi Kivity MK_INSN(jnz_near1, ".byte 0x0f, 0x85, 0x06, 0x00\n\t" 6907d36db35SAvi Kivity "mov $0x1234, %eax\n\t"); 6917d36db35SAvi Kivity MK_INSN(jnz_near2, "cmp $0x1234, %eax\n\t" 6927d36db35SAvi Kivity "mov $0x1234, %eax\n\t" 6937d36db35SAvi Kivity ".byte 0x0f, 0x85, 0xf0, 0xff\n\t"); 6947d36db35SAvi Kivity MK_INSN(jmp_near1, ".byte 0xE9, 0x06, 0x00\n\t" 6957d36db35SAvi Kivity "mov $0x1234, %eax\n\t"); 6967d36db35SAvi Kivity 6977d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 6987d36db35SAvi Kivity insn_jnz_near1, insn_jnz_near1_end - insn_jnz_near1); 6997d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, 0)) 7007d36db35SAvi Kivity print_serial("JNZ near Test 1: FAIL\n"); 7017d36db35SAvi Kivity else 7027d36db35SAvi Kivity print_serial("JNZ near Test 1: PASS\n"); 7037d36db35SAvi Kivity 7047d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 7057d36db35SAvi Kivity insn_jnz_near2, insn_jnz_near2_end - insn_jnz_near2); 7067d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, R_AX) || !(outregs.eflags & (1 << 6))) 7077d36db35SAvi Kivity print_serial("JNZ near Test 2: FAIL\n"); 7087d36db35SAvi Kivity else 7097d36db35SAvi Kivity print_serial("JNZ near Test 2: PASS\n"); 7107d36db35SAvi Kivity 7117d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 7127d36db35SAvi Kivity insn_jmp_near1, insn_jmp_near1_end - insn_jmp_near1); 7137d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, 0)) 7147d36db35SAvi Kivity print_serial("JMP near Test 1: FAIL\n"); 7157d36db35SAvi Kivity else 7167d36db35SAvi Kivity print_serial("JMP near Test 1: PASS\n"); 7177d36db35SAvi Kivity } 7187d36db35SAvi Kivity 7197d36db35SAvi Kivity void test_long_jmp() 7207d36db35SAvi Kivity { 7217d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 7227d36db35SAvi Kivity u32 esp[16]; 7237d36db35SAvi Kivity 7247d36db35SAvi Kivity inregs.esp = (u32)esp; 7257d36db35SAvi Kivity MK_INSN(long_jmp, "call 1f\n\t" 7267d36db35SAvi Kivity "jmp 2f\n\t" 7277d36db35SAvi Kivity "1: jmp $0, $test_function\n\t" 7287d36db35SAvi Kivity "2:\n\t"); 7297d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 7307d36db35SAvi Kivity insn_long_jmp, 7317d36db35SAvi Kivity insn_long_jmp_end - insn_long_jmp); 7327d36db35SAvi Kivity if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 0x1234) 7337d36db35SAvi Kivity print_serial("Long JMP Test: FAIL\n"); 7347d36db35SAvi Kivity else 7357d36db35SAvi Kivity print_serial("Long JMP Test: PASS\n"); 7367d36db35SAvi Kivity } 737fa74f8a6SMohammed Gamal 7387d36db35SAvi Kivity void test_push_pop() 7397d36db35SAvi Kivity { 7407d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 7417d36db35SAvi Kivity MK_INSN(push32, "mov $0x12345678, %eax\n\t" 7427d36db35SAvi Kivity "push %eax\n\t" 7437d36db35SAvi Kivity "pop %ebx\n\t"); 7447d36db35SAvi Kivity MK_INSN(push16, "mov $0x1234, %ax\n\t" 7457d36db35SAvi Kivity "push %ax\n\t" 7467d36db35SAvi Kivity "pop %bx\n\t"); 7477d36db35SAvi Kivity 7487d36db35SAvi Kivity MK_INSN(push_es, "mov $0x231, %bx\n\t" //Just write a dummy value to see if it gets overwritten 7497d36db35SAvi Kivity "mov $0x123, %ax\n\t" 7507d36db35SAvi Kivity "mov %ax, %es\n\t" 7517d36db35SAvi Kivity "push %es\n\t" 7527d36db35SAvi Kivity "pop %bx \n\t" 7537d36db35SAvi Kivity ); 7547d36db35SAvi Kivity MK_INSN(pop_es, "push %ax\n\t" 7557d36db35SAvi Kivity "pop %es\n\t" 7567d36db35SAvi Kivity "mov %es, %bx\n\t" 7577d36db35SAvi Kivity ); 7587d36db35SAvi Kivity MK_INSN(push_pop_ss, "push %ss\n\t" 7597d36db35SAvi Kivity "pushw %ax\n\t" 7607d36db35SAvi Kivity "popw %ss\n\t" 7617d36db35SAvi Kivity "mov %ss, %bx\n\t" 7627d36db35SAvi Kivity "pop %ss\n\t" 7637d36db35SAvi Kivity ); 7647d36db35SAvi Kivity MK_INSN(push_pop_fs, "push %fs\n\t" 7657d36db35SAvi Kivity "pushl %eax\n\t" 7667d36db35SAvi Kivity "popl %fs\n\t" 7677d36db35SAvi Kivity "mov %fs, %ebx\n\t" 7687d36db35SAvi Kivity "pop %fs\n\t" 7697d36db35SAvi Kivity ); 7707d36db35SAvi Kivity 7717d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 7727d36db35SAvi Kivity insn_push32, 7737d36db35SAvi Kivity insn_push32_end - insn_push32); 7747d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.eax != outregs.ebx || outregs.eax != 0x12345678) 7757d36db35SAvi Kivity print_serial("Push/Pop Test 1: FAIL\n"); 7767d36db35SAvi Kivity else 7777d36db35SAvi Kivity print_serial("Push/Pop Test 1: PASS\n"); 7787d36db35SAvi Kivity 7797d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 7807d36db35SAvi Kivity insn_push16, 7817d36db35SAvi Kivity insn_push16_end - insn_push16); 7827d36db35SAvi Kivity 7837d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.eax != outregs.ebx || outregs.eax != 0x1234) 7847d36db35SAvi Kivity print_serial("Push/Pop Test 2: FAIL\n"); 7857d36db35SAvi Kivity else 7867d36db35SAvi Kivity print_serial("Push/Pop Test 2: PASS\n"); 7877d36db35SAvi Kivity 7887d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 7897d36db35SAvi Kivity insn_push_es, 7907d36db35SAvi Kivity insn_push_es_end - insn_push_es); 7917d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax || outregs.eax != 0x123) 7927d36db35SAvi Kivity print_serial("Push/Pop Test 3: FAIL\n"); 7937d36db35SAvi Kivity else 7947d36db35SAvi Kivity print_serial("Push/Pop Test 3: PASS\n"); 7957d36db35SAvi Kivity 7967d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 7977d36db35SAvi Kivity insn_pop_es, 7987d36db35SAvi Kivity insn_pop_es_end - insn_pop_es); 7997d36db35SAvi Kivity 8007d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax) 8017d36db35SAvi Kivity print_serial("Push/Pop Test 4: FAIL\n"); 8027d36db35SAvi Kivity else 8037d36db35SAvi Kivity print_serial("Push/Pop Test 4: PASS\n"); 8047d36db35SAvi Kivity 8057d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 8067d36db35SAvi Kivity insn_push_pop_ss, 8077d36db35SAvi Kivity insn_push_pop_ss_end - insn_push_pop_ss); 8087d36db35SAvi Kivity 8097d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax) 8107d36db35SAvi Kivity print_serial("Push/Pop Test 5: FAIL\n"); 8117d36db35SAvi Kivity else 8127d36db35SAvi Kivity print_serial("Push/Pop Test 5: PASS\n"); 8137d36db35SAvi Kivity 8147d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 8157d36db35SAvi Kivity insn_push_pop_fs, 8167d36db35SAvi Kivity insn_push_pop_fs_end - insn_push_pop_fs); 8177d36db35SAvi Kivity 8187d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX|R_BX) || outregs.ebx != outregs.eax) 8197d36db35SAvi Kivity print_serial("Push/Pop Test 6: FAIL\n"); 8207d36db35SAvi Kivity else 8217d36db35SAvi Kivity print_serial("Push/Pop Test 6: PASS\n"); 8227d36db35SAvi Kivity } 8237d36db35SAvi Kivity 8247d36db35SAvi Kivity void test_null(void) 8257d36db35SAvi Kivity { 8267d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 8277d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 0, 0); 8287d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 8297d36db35SAvi Kivity print_serial("null test: FAIL\n"); 8307d36db35SAvi Kivity else 8317d36db35SAvi Kivity print_serial("null test: PASS\n"); 8327d36db35SAvi Kivity } 8337d36db35SAvi Kivity 8347d36db35SAvi Kivity struct { 8357d36db35SAvi Kivity char stack[500]; 8367d36db35SAvi Kivity char top[]; 8377d36db35SAvi Kivity } tmp_stack; 8387d36db35SAvi Kivity 8397d36db35SAvi Kivity void test_pusha_popa() 8407d36db35SAvi Kivity { 8417d36db35SAvi Kivity struct regs inregs = { .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6, .esp = (unsigned long)&tmp_stack.top }, outregs; 8427d36db35SAvi Kivity 8437d36db35SAvi Kivity MK_INSN(pusha, "pusha\n\t" 8447d36db35SAvi Kivity "pop %edi\n\t" 8457d36db35SAvi Kivity "pop %esi\n\t" 8467d36db35SAvi Kivity "pop %ebp\n\t" 8477d36db35SAvi Kivity "add $4, %esp\n\t" 8487d36db35SAvi Kivity "pop %ebx\n\t" 8497d36db35SAvi Kivity "pop %edx\n\t" 8507d36db35SAvi Kivity "pop %ecx\n\t" 8517d36db35SAvi Kivity "pop %eax\n\t" 8527d36db35SAvi Kivity ); 8537d36db35SAvi Kivity 8547d36db35SAvi Kivity MK_INSN(popa, "push %eax\n\t" 8557d36db35SAvi Kivity "push %ecx\n\t" 8567d36db35SAvi Kivity "push %edx\n\t" 8577d36db35SAvi Kivity "push %ebx\n\t" 8587d36db35SAvi Kivity "push %esp\n\t" 8597d36db35SAvi Kivity "push %ebp\n\t" 8607d36db35SAvi Kivity "push %esi\n\t" 8617d36db35SAvi Kivity "push %edi\n\t" 8627d36db35SAvi Kivity "popa\n\t" 8637d36db35SAvi Kivity ); 8647d36db35SAvi Kivity 8657d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 8667d36db35SAvi Kivity insn_pusha, 8677d36db35SAvi Kivity insn_pusha_end - insn_pusha); 8687d36db35SAvi Kivity 8697d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 8707d36db35SAvi Kivity print_serial("Pusha/Popa Test1: FAIL\n"); 8717d36db35SAvi Kivity else 8727d36db35SAvi Kivity print_serial("Pusha/Popa Test1: PASS\n"); 8737d36db35SAvi Kivity 8747d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 8757d36db35SAvi Kivity insn_popa, 8767d36db35SAvi Kivity insn_popa_end - insn_popa); 8777d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 8787d36db35SAvi Kivity print_serial("Pusha/Popa Test2: FAIL\n"); 8797d36db35SAvi Kivity else 8807d36db35SAvi Kivity print_serial("Pusha/Popa Test2: PASS\n"); 8817d36db35SAvi Kivity } 8827d36db35SAvi Kivity 8837d36db35SAvi Kivity void test_iret() 8847d36db35SAvi Kivity { 8857d36db35SAvi Kivity struct regs inregs = { 0 }, outregs; 8867d36db35SAvi Kivity 8877d36db35SAvi Kivity MK_INSN(iret32, "pushf\n\t" 8887d36db35SAvi Kivity "pushl %cs\n\t" 8897d36db35SAvi Kivity "call 1f\n\t" /* a near call will push eip onto the stack */ 8907d36db35SAvi Kivity "jmp 2f\n\t" 8917d36db35SAvi Kivity "1: iret\n\t" 8927d36db35SAvi Kivity "2:\n\t" 8937d36db35SAvi Kivity ); 8947d36db35SAvi Kivity 8957d36db35SAvi Kivity MK_INSN(iret16, "pushfw\n\t" 8967d36db35SAvi Kivity "pushw %cs\n\t" 8977d36db35SAvi Kivity "callw 1f\n\t" 8987d36db35SAvi Kivity "jmp 2f\n\t" 8997d36db35SAvi Kivity "1: iretw\n\t" 9007d36db35SAvi Kivity "2:\n\t"); 9017d36db35SAvi Kivity 9027d36db35SAvi Kivity MK_INSN(iret_flags32, "pushfl\n\t" 9037d36db35SAvi Kivity "popl %eax\n\t" 9047d36db35SAvi Kivity "andl $~0x2, %eax\n\t" 9057d36db35SAvi Kivity "orl $0xffc08028, %eax\n\t" 9067d36db35SAvi Kivity "pushl %eax\n\t" 9077d36db35SAvi Kivity "pushl %cs\n\t" 9087d36db35SAvi Kivity "call 1f\n\t" 9097d36db35SAvi Kivity "jmp 2f\n\t" 9107d36db35SAvi Kivity "1: iret\n\t" 9117d36db35SAvi Kivity "2:\n\t"); 9127d36db35SAvi Kivity 9137d36db35SAvi Kivity MK_INSN(iret_flags16, "pushfw\n\t" 9147d36db35SAvi Kivity "popw %ax\n\t" 9157d36db35SAvi Kivity "and $~0x2, %ax\n\t" 9167d36db35SAvi Kivity "or $0x8028, %ax\n\t" 9177d36db35SAvi Kivity "pushw %ax\n\t" 9187d36db35SAvi Kivity "pushw %cs\n\t" 9197d36db35SAvi Kivity "callw 1f\n\t" 9207d36db35SAvi Kivity "jmp 2f\n\t" 9217d36db35SAvi Kivity "1: iretw\n\t" 9227d36db35SAvi Kivity "2:\n\t"); 9237d36db35SAvi Kivity 9247d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 9257d36db35SAvi Kivity insn_iret32, 9267d36db35SAvi Kivity insn_iret32_end - insn_iret32); 9277d36db35SAvi Kivity 9287d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 9297d36db35SAvi Kivity print_serial("iret Test 1: FAIL\n"); 9307d36db35SAvi Kivity else 9317d36db35SAvi Kivity print_serial("iret Test 1: PASS\n"); 9327d36db35SAvi Kivity 9337d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 9347d36db35SAvi Kivity insn_iret16, 9357d36db35SAvi Kivity insn_iret16_end - insn_iret16); 9367d36db35SAvi Kivity 9377d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, 0)) 9387d36db35SAvi Kivity print_serial("iret Test 2: FAIL\n"); 9397d36db35SAvi Kivity else 9407d36db35SAvi Kivity print_serial("iret Test 2: PASS\n"); 9417d36db35SAvi Kivity 9427d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 9437d36db35SAvi Kivity insn_iret_flags32, 9447d36db35SAvi Kivity insn_iret_flags32_end - insn_iret_flags32); 9457d36db35SAvi Kivity 9467d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX)) 9477d36db35SAvi Kivity print_serial("iret Test 3: FAIL\n"); 9487d36db35SAvi Kivity else 9497d36db35SAvi Kivity print_serial("iret Test 3: PASS\n"); 9507d36db35SAvi Kivity 9517d36db35SAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 9527d36db35SAvi Kivity insn_iret_flags16, 9537d36db35SAvi Kivity insn_iret_flags16_end - insn_iret_flags16); 9547d36db35SAvi Kivity 9557d36db35SAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX)) 9567d36db35SAvi Kivity print_serial("iret Test 4: FAIL\n"); 9577d36db35SAvi Kivity else 9587d36db35SAvi Kivity print_serial("iret Test 4: PASS\n"); 9597d36db35SAvi Kivity } 9607d36db35SAvi Kivity 96196b9ca1eSMohammed Gamal void test_int() 96296b9ca1eSMohammed Gamal { 96396b9ca1eSMohammed Gamal struct regs inregs = { 0 }, outregs; 96496b9ca1eSMohammed Gamal 96596b9ca1eSMohammed Gamal *(u32 *)(0x11 * 4) = 0x1000; /* Store a pointer to address 0x1000 in IDT entry 0x11 */ 96696b9ca1eSMohammed Gamal *(u8 *)(0x1000) = 0xcf; /* 0x1000 contains an IRET instruction */ 96796b9ca1eSMohammed Gamal 96896b9ca1eSMohammed Gamal MK_INSN(int11, "int $0x11\n\t"); 96996b9ca1eSMohammed Gamal 97096b9ca1eSMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 97196b9ca1eSMohammed Gamal insn_int11, 97296b9ca1eSMohammed Gamal insn_int11_end - insn_int11); 97396b9ca1eSMohammed Gamal 97496b9ca1eSMohammed Gamal if (!regs_equal(&inregs, &outregs, 0)) 97596b9ca1eSMohammed Gamal print_serial("int Test 1: FAIL\n"); 97696b9ca1eSMohammed Gamal else 97796b9ca1eSMohammed Gamal print_serial("int Test 1: PASS\n"); 97896b9ca1eSMohammed Gamal } 97996b9ca1eSMohammed Gamal 980fa74f8a6SMohammed Gamal void test_imul() 981fa74f8a6SMohammed Gamal { 982fa74f8a6SMohammed Gamal struct regs inregs = { 0 }, outregs; 983fa74f8a6SMohammed Gamal 984fa74f8a6SMohammed Gamal MK_INSN(imul8_1, "mov $2, %al\n\t" 985fa74f8a6SMohammed Gamal "mov $-4, %cx\n\t" 986fa74f8a6SMohammed Gamal "imul %cl\n\t"); 987fa74f8a6SMohammed Gamal 988fa74f8a6SMohammed Gamal MK_INSN(imul16_1, "mov $2, %ax\n\t" 989fa74f8a6SMohammed Gamal "mov $-4, %cx\n\t" 990fa74f8a6SMohammed Gamal "imul %cx\n\t"); 991fa74f8a6SMohammed Gamal 992fa74f8a6SMohammed Gamal MK_INSN(imul32_1, "mov $2, %eax\n\t" 993fa74f8a6SMohammed Gamal "mov $-4, %ecx\n\t" 994fa74f8a6SMohammed Gamal "imul %ecx\n\t"); 995fa74f8a6SMohammed Gamal 996fa74f8a6SMohammed Gamal MK_INSN(imul8_2, "mov $0x12340002, %eax\n\t" 997fa74f8a6SMohammed Gamal "mov $4, %cx\n\t" 998fa74f8a6SMohammed Gamal "imul %cl\n\t"); 999fa74f8a6SMohammed Gamal 1000fa74f8a6SMohammed Gamal MK_INSN(imul16_2, "mov $2, %ax\n\t" 1001fa74f8a6SMohammed Gamal "mov $4, %cx\n\t" 1002fa74f8a6SMohammed Gamal "imul %cx\n\t"); 1003fa74f8a6SMohammed Gamal 1004fa74f8a6SMohammed Gamal MK_INSN(imul32_2, "mov $2, %eax\n\t" 1005fa74f8a6SMohammed Gamal "mov $4, %ecx\n\t" 1006fa74f8a6SMohammed Gamal "imul %ecx\n\t"); 1007fa74f8a6SMohammed Gamal 1008fa74f8a6SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 1009fa74f8a6SMohammed Gamal insn_imul8_1, 1010fa74f8a6SMohammed Gamal insn_imul8_1_end - insn_imul8_1); 1011fa74f8a6SMohammed Gamal 1012fa74f8a6SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xff) != (u8)-8) 1013fa74f8a6SMohammed Gamal print_serial("imul Test 1: FAIL\n"); 1014fa74f8a6SMohammed Gamal else 1015fa74f8a6SMohammed Gamal print_serial("imul Test 1: PASS\n"); 1016fa74f8a6SMohammed Gamal 1017fa74f8a6SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 1018fa74f8a6SMohammed Gamal insn_imul16_1, 1019fa74f8a6SMohammed Gamal insn_imul16_1_end - insn_imul16_1); 1020fa74f8a6SMohammed Gamal 1021fa74f8a6SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u16)-8) 1022fa74f8a6SMohammed Gamal print_serial("imul Test 2: FAIL\n"); 1023fa74f8a6SMohammed Gamal else 1024fa74f8a6SMohammed Gamal print_serial("imul Test 2: PASS\n"); 1025fa74f8a6SMohammed Gamal 1026fa74f8a6SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 1027fa74f8a6SMohammed Gamal insn_imul32_1, 1028fa74f8a6SMohammed Gamal insn_imul32_1_end - insn_imul32_1); 1029fa74f8a6SMohammed Gamal 1030fa74f8a6SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u32)-8) 1031fa74f8a6SMohammed Gamal print_serial("imul Test 3: FAIL\n"); 1032fa74f8a6SMohammed Gamal else 1033fa74f8a6SMohammed Gamal print_serial("imul Test 3: PASS\n"); 1034fa74f8a6SMohammed Gamal 1035fa74f8a6SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 1036fa74f8a6SMohammed Gamal insn_imul8_2, 1037fa74f8a6SMohammed Gamal insn_imul8_2_end - insn_imul8_2); 1038fa74f8a6SMohammed Gamal 1039fa74f8a6SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xffff) != 8 || 1040fa74f8a6SMohammed Gamal (outregs.eax & 0xffff0000) != 0x12340000) 1041fa74f8a6SMohammed Gamal print_serial("imul Test 4: FAIL\n"); 1042fa74f8a6SMohammed Gamal else 1043fa74f8a6SMohammed Gamal print_serial("imul Test 4: PASS\n"); 1044fa74f8a6SMohammed Gamal 1045fa74f8a6SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 1046fa74f8a6SMohammed Gamal insn_imul16_2, 1047fa74f8a6SMohammed Gamal insn_imul16_2_end - insn_imul16_2); 1048fa74f8a6SMohammed Gamal 1049fa74f8a6SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8) 1050fa74f8a6SMohammed Gamal print_serial("imul Test 5: FAIL\n"); 1051fa74f8a6SMohammed Gamal else 1052fa74f8a6SMohammed Gamal print_serial("imul Test 5: PASS\n"); 1053fa74f8a6SMohammed Gamal 1054fa74f8a6SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 1055fa74f8a6SMohammed Gamal insn_imul32_2, 1056fa74f8a6SMohammed Gamal insn_imul32_2_end - insn_imul32_2); 1057fa74f8a6SMohammed Gamal 1058fa74f8a6SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8) 1059fa74f8a6SMohammed Gamal print_serial("imul Test 6: FAIL\n"); 1060fa74f8a6SMohammed Gamal else 1061fa74f8a6SMohammed Gamal print_serial("imul Test 6: PASS\n"); 1062fa74f8a6SMohammed Gamal } 1063fa74f8a6SMohammed Gamal 106459317bd1SMohammed Gamal void test_mul() 106559317bd1SMohammed Gamal { 106659317bd1SMohammed Gamal struct regs inregs = { 0 }, outregs; 106759317bd1SMohammed Gamal 106859317bd1SMohammed Gamal MK_INSN(mul8, "mov $2, %al\n\t" 106959317bd1SMohammed Gamal "mov $4, %cx\n\t" 107059317bd1SMohammed Gamal "imul %cl\n\t"); 107159317bd1SMohammed Gamal 107259317bd1SMohammed Gamal MK_INSN(mul16, "mov $2, %ax\n\t" 107359317bd1SMohammed Gamal "mov $4, %cx\n\t" 107459317bd1SMohammed Gamal "imul %cx\n\t"); 107559317bd1SMohammed Gamal 107659317bd1SMohammed Gamal MK_INSN(mul32, "mov $2, %eax\n\t" 107759317bd1SMohammed Gamal "mov $4, %ecx\n\t" 107859317bd1SMohammed Gamal "imul %ecx\n\t"); 107959317bd1SMohammed Gamal 108059317bd1SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 108159317bd1SMohammed Gamal insn_mul8, 108259317bd1SMohammed Gamal insn_mul8_end - insn_mul8); 108359317bd1SMohammed Gamal 108459317bd1SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || (outregs.eax & 0xff) != 8) 108559317bd1SMohammed Gamal print_serial("mul Test 1: FAIL\n"); 108659317bd1SMohammed Gamal else 108759317bd1SMohammed Gamal print_serial("mul Test 1: PASS\n"); 108859317bd1SMohammed Gamal 108959317bd1SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 109059317bd1SMohammed Gamal insn_mul16, 109159317bd1SMohammed Gamal insn_mul16_end - insn_mul16); 109259317bd1SMohammed Gamal 109359317bd1SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8) 109459317bd1SMohammed Gamal print_serial("mul Test 2: FAIL\n"); 109559317bd1SMohammed Gamal else 109659317bd1SMohammed Gamal print_serial("mul Test 2: PASS\n"); 109759317bd1SMohammed Gamal 109859317bd1SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 109959317bd1SMohammed Gamal insn_mul32, 110059317bd1SMohammed Gamal insn_mul32_end - insn_mul32); 110159317bd1SMohammed Gamal 110259317bd1SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 8) 110359317bd1SMohammed Gamal print_serial("mul Test 3: FAIL\n"); 110459317bd1SMohammed Gamal else 110559317bd1SMohammed Gamal print_serial("mul Test 3: PASS\n"); 110659317bd1SMohammed Gamal } 110759317bd1SMohammed Gamal 11080d4c7614SMohammed Gamal void test_div() 11090d4c7614SMohammed Gamal { 11100d4c7614SMohammed Gamal struct regs inregs = { 0 }, outregs; 11110d4c7614SMohammed Gamal 11120d4c7614SMohammed Gamal MK_INSN(div8, "mov $257, %ax\n\t" 11130d4c7614SMohammed Gamal "mov $2, %cl\n\t" 11140d4c7614SMohammed Gamal "div %cl\n\t"); 11150d4c7614SMohammed Gamal 11160d4c7614SMohammed Gamal MK_INSN(div16, "mov $512, %ax\n\t" 11170d4c7614SMohammed Gamal "mov $5, %cx\n\t" 11180d4c7614SMohammed Gamal "div %cx\n\t"); 11190d4c7614SMohammed Gamal 11200d4c7614SMohammed Gamal MK_INSN(div32, "mov $512, %eax\n\t" 11210d4c7614SMohammed Gamal "mov $5, %ecx\n\t" 11220d4c7614SMohammed Gamal "div %ecx\n\t"); 11230d4c7614SMohammed Gamal 11240d4c7614SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 11250d4c7614SMohammed Gamal insn_div8, 11260d4c7614SMohammed Gamal insn_div8_end - insn_div8); 11270d4c7614SMohammed Gamal 11280d4c7614SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 384) 11290d4c7614SMohammed Gamal print_serial("div Test 1: FAIL\n"); 11300d4c7614SMohammed Gamal else 11310d4c7614SMohammed Gamal print_serial("div Test 1: PASS\n"); 11320d4c7614SMohammed Gamal 11330d4c7614SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 11340d4c7614SMohammed Gamal insn_div16, 11350d4c7614SMohammed Gamal insn_div16_end - insn_div16); 11360d4c7614SMohammed Gamal 11370d4c7614SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 102 || 11380d4c7614SMohammed Gamal outregs.edx != 2) 11390d4c7614SMohammed Gamal print_serial("div Test 2: FAIL\n"); 11400d4c7614SMohammed Gamal else 11410d4c7614SMohammed Gamal print_serial("div Test 2: PASS\n"); 11420d4c7614SMohammed Gamal 11430d4c7614SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 11440d4c7614SMohammed Gamal insn_div32, 11450d4c7614SMohammed Gamal insn_div32_end - insn_div32); 11460d4c7614SMohammed Gamal 11470d4c7614SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != 102 || 11480d4c7614SMohammed Gamal outregs.edx != 2) 11490d4c7614SMohammed Gamal print_serial("div Test 3: FAIL\n"); 11500d4c7614SMohammed Gamal else 11510d4c7614SMohammed Gamal print_serial("div Test 3: PASS\n"); 11520d4c7614SMohammed Gamal } 11530d4c7614SMohammed Gamal 11540d4c7614SMohammed Gamal void test_idiv() 11550d4c7614SMohammed Gamal { 11560d4c7614SMohammed Gamal struct regs inregs = { 0 }, outregs; 11570d4c7614SMohammed Gamal 11580d4c7614SMohammed Gamal MK_INSN(idiv8, "mov $256, %ax\n\t" 11590d4c7614SMohammed Gamal "mov $-2, %cl\n\t" 11600d4c7614SMohammed Gamal "idiv %cl\n\t"); 11610d4c7614SMohammed Gamal 11620d4c7614SMohammed Gamal MK_INSN(idiv16, "mov $512, %ax\n\t" 11630d4c7614SMohammed Gamal "mov $-2, %cx\n\t" 11640d4c7614SMohammed Gamal "idiv %cx\n\t"); 11650d4c7614SMohammed Gamal 11660d4c7614SMohammed Gamal MK_INSN(idiv32, "mov $512, %eax\n\t" 11670d4c7614SMohammed Gamal "mov $-2, %ecx\n\t" 11680d4c7614SMohammed Gamal "idiv %ecx\n\t"); 11690d4c7614SMohammed Gamal 11700d4c7614SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 11710d4c7614SMohammed Gamal insn_idiv8, 11720d4c7614SMohammed Gamal insn_idiv8_end - insn_idiv8); 11730d4c7614SMohammed Gamal 11740d4c7614SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u8)-128) 11750d4c7614SMohammed Gamal print_serial("idiv Test 1: FAIL\n"); 11760d4c7614SMohammed Gamal else 11770d4c7614SMohammed Gamal print_serial("idiv Test 1: PASS\n"); 11780d4c7614SMohammed Gamal 11790d4c7614SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 11800d4c7614SMohammed Gamal insn_idiv16, 11810d4c7614SMohammed Gamal insn_idiv16_end - insn_idiv16); 11820d4c7614SMohammed Gamal 11830d4c7614SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u16)-256) 11840d4c7614SMohammed Gamal print_serial("idiv Test 2: FAIL\n"); 11850d4c7614SMohammed Gamal else 11860d4c7614SMohammed Gamal print_serial("idiv Test 2: PASS\n"); 11870d4c7614SMohammed Gamal 11880d4c7614SMohammed Gamal exec_in_big_real_mode(&inregs, &outregs, 11890d4c7614SMohammed Gamal insn_idiv32, 11900d4c7614SMohammed Gamal insn_idiv32_end - insn_idiv32); 11910d4c7614SMohammed Gamal 11920d4c7614SMohammed Gamal if (!regs_equal(&inregs, &outregs, R_AX | R_CX | R_DX) || outregs.eax != (u32)-256) 11930d4c7614SMohammed Gamal print_serial("idiv Test 3: FAIL\n"); 11940d4c7614SMohammed Gamal else 11950d4c7614SMohammed Gamal print_serial("idiv Test 3: PASS\n"); 11960d4c7614SMohammed Gamal } 11970d4c7614SMohammed Gamal 11986e293cf5SWei Yongjun void test_cbw(void) 11996e293cf5SWei Yongjun { 12006e293cf5SWei Yongjun struct regs inregs = { 0 }, outregs; 12016e293cf5SWei Yongjun 12026e293cf5SWei Yongjun MK_INSN(cbw, "mov $0xFE, %eax \n\t" 12036e293cf5SWei Yongjun "cbw\n\t"); 12046e293cf5SWei Yongjun MK_INSN(cwde, "mov $0xFFFE, %eax \n\t" 12056e293cf5SWei Yongjun "cwde\n\t"); 12066e293cf5SWei Yongjun 12076e293cf5SWei Yongjun exec_in_big_real_mode(&inregs, &outregs, 12086e293cf5SWei Yongjun insn_cbw, 12096e293cf5SWei Yongjun insn_cbw_end - insn_cbw); 12106e293cf5SWei Yongjun if (outregs.eax != 0xFFFE) 12116e293cf5SWei Yongjun print_serial("cbw test1: FAIL\n"); 12126e293cf5SWei Yongjun else 12136e293cf5SWei Yongjun print_serial("cbw test 1: PASS\n"); 12146e293cf5SWei Yongjun 12156e293cf5SWei Yongjun exec_in_big_real_mode(&inregs, &outregs, 12166e293cf5SWei Yongjun insn_cwde, 12176e293cf5SWei Yongjun insn_cwde_end - insn_cwde); 12186e293cf5SWei Yongjun if (outregs.eax != 0xFFFFFFFE) 12196e293cf5SWei Yongjun print_serial("cwde test1: FAIL\n"); 12206e293cf5SWei Yongjun else 12216e293cf5SWei Yongjun print_serial("cwde test 1: PASS\n"); 12226e293cf5SWei Yongjun } 12236e293cf5SWei Yongjun 1224eacef4e2SWei Yongjun void test_loopcc(void) 1225eacef4e2SWei Yongjun { 1226eacef4e2SWei Yongjun struct regs inregs = { 0 }, outregs; 1227eacef4e2SWei Yongjun 1228eacef4e2SWei Yongjun MK_INSN(loop, "mov $10, %ecx\n\t" 1229eacef4e2SWei Yongjun "1: inc %eax\n\t" 1230eacef4e2SWei Yongjun "loop 1b\n\t"); 1231eacef4e2SWei Yongjun 1232eacef4e2SWei Yongjun MK_INSN(loope, "mov $10, %ecx\n\t" 1233eacef4e2SWei Yongjun "mov $1, %eax\n\t" 1234eacef4e2SWei Yongjun "1: dec %eax\n\t" 1235eacef4e2SWei Yongjun "loope 1b\n\t"); 1236eacef4e2SWei Yongjun 1237eacef4e2SWei Yongjun MK_INSN(loopne, "mov $10, %ecx\n\t" 1238eacef4e2SWei Yongjun "mov $5, %eax\n\t" 1239eacef4e2SWei Yongjun "1: dec %eax\n\t" 1240eacef4e2SWei Yongjun "loopne 1b\n\t"); 1241eacef4e2SWei Yongjun 1242eacef4e2SWei Yongjun exec_in_big_real_mode(&inregs, &outregs, 1243eacef4e2SWei Yongjun insn_loop, insn_loop_end - insn_loop); 1244eacef4e2SWei Yongjun if(!regs_equal(&inregs, &outregs, R_AX) || outregs.eax != 10) 1245eacef4e2SWei Yongjun print_serial("LOOPcc short Test 1: FAIL\n"); 1246eacef4e2SWei Yongjun else 1247eacef4e2SWei Yongjun print_serial("LOOPcc short Test 1: PASS\n"); 1248eacef4e2SWei Yongjun 1249eacef4e2SWei Yongjun exec_in_big_real_mode(&inregs, &outregs, 1250eacef4e2SWei Yongjun insn_loope, insn_loope_end - insn_loope); 1251eacef4e2SWei Yongjun if(!regs_equal(&inregs, &outregs, R_AX | R_CX) || 1252eacef4e2SWei Yongjun outregs.eax != -1 || outregs.ecx != 8) 1253eacef4e2SWei Yongjun print_serial("LOOPcc short Test 2: FAIL\n"); 1254eacef4e2SWei Yongjun else 1255eacef4e2SWei Yongjun print_serial("LOOPcc short Test 2: PASS\n"); 1256eacef4e2SWei Yongjun 1257eacef4e2SWei Yongjun exec_in_big_real_mode(&inregs, &outregs, 1258eacef4e2SWei Yongjun insn_loopne, insn_loopne_end - insn_loopne); 1259eacef4e2SWei Yongjun if(!regs_equal(&inregs, &outregs, R_AX | R_CX) || 1260eacef4e2SWei Yongjun outregs.eax != 0 || outregs.ecx != 5) 1261eacef4e2SWei Yongjun print_serial("LOOPcc short Test 3: FAIL\n"); 1262eacef4e2SWei Yongjun else 1263eacef4e2SWei Yongjun print_serial("LOOPcc short Test 3: PASS\n"); 1264eacef4e2SWei Yongjun } 1265eacef4e2SWei Yongjun 1266*b274feedSAvi Kivity static void test_das(void) 1267*b274feedSAvi Kivity { 1268*b274feedSAvi Kivity struct regs inregs = { 0 }, outregs = { 0 }; 1269*b274feedSAvi Kivity short i; 1270*b274feedSAvi Kivity static unsigned test_cases[1024] = { 1271*b274feedSAvi Kivity 0x46000000, 0x8701a000, 0x9710fa00, 0x97119a00, 1272*b274feedSAvi Kivity 0x02000101, 0x8301a101, 0x9310fb01, 0x93119b01, 1273*b274feedSAvi Kivity 0x02000202, 0x8301a202, 0x9710fc02, 0x97119c02, 1274*b274feedSAvi Kivity 0x06000303, 0x8701a303, 0x9310fd03, 0x93119d03, 1275*b274feedSAvi Kivity 0x02000404, 0x8301a404, 0x9310fe04, 0x93119e04, 1276*b274feedSAvi Kivity 0x06000505, 0x8701a505, 0x9710ff05, 0x97119f05, 1277*b274feedSAvi Kivity 0x06000606, 0x8701a606, 0x56100006, 0x9711a006, 1278*b274feedSAvi Kivity 0x02000707, 0x8301a707, 0x12100107, 0x9311a107, 1279*b274feedSAvi Kivity 0x02000808, 0x8301a808, 0x12100208, 0x9311a208, 1280*b274feedSAvi Kivity 0x06000909, 0x8701a909, 0x16100309, 0x9711a309, 1281*b274feedSAvi Kivity 0x1200040a, 0x9301a40a, 0x1210040a, 0x9311a40a, 1282*b274feedSAvi Kivity 0x1600050b, 0x9701a50b, 0x1610050b, 0x9711a50b, 1283*b274feedSAvi Kivity 0x1600060c, 0x9701a60c, 0x1610060c, 0x9711a60c, 1284*b274feedSAvi Kivity 0x1200070d, 0x9301a70d, 0x1210070d, 0x9311a70d, 1285*b274feedSAvi Kivity 0x1200080e, 0x9301a80e, 0x1210080e, 0x9311a80e, 1286*b274feedSAvi Kivity 0x1600090f, 0x9701a90f, 0x1610090f, 0x9711a90f, 1287*b274feedSAvi Kivity 0x02001010, 0x8301b010, 0x16100a10, 0x9711aa10, 1288*b274feedSAvi Kivity 0x06001111, 0x8701b111, 0x12100b11, 0x9311ab11, 1289*b274feedSAvi Kivity 0x06001212, 0x8701b212, 0x16100c12, 0x9711ac12, 1290*b274feedSAvi Kivity 0x02001313, 0x8301b313, 0x12100d13, 0x9311ad13, 1291*b274feedSAvi Kivity 0x06001414, 0x8701b414, 0x12100e14, 0x9311ae14, 1292*b274feedSAvi Kivity 0x02001515, 0x8301b515, 0x16100f15, 0x9711af15, 1293*b274feedSAvi Kivity 0x02001616, 0x8301b616, 0x12101016, 0x9311b016, 1294*b274feedSAvi Kivity 0x06001717, 0x8701b717, 0x16101117, 0x9711b117, 1295*b274feedSAvi Kivity 0x06001818, 0x8701b818, 0x16101218, 0x9711b218, 1296*b274feedSAvi Kivity 0x02001919, 0x8301b919, 0x12101319, 0x9311b319, 1297*b274feedSAvi Kivity 0x1600141a, 0x9701b41a, 0x1610141a, 0x9711b41a, 1298*b274feedSAvi Kivity 0x1200151b, 0x9301b51b, 0x1210151b, 0x9311b51b, 1299*b274feedSAvi Kivity 0x1200161c, 0x9301b61c, 0x1210161c, 0x9311b61c, 1300*b274feedSAvi Kivity 0x1600171d, 0x9701b71d, 0x1610171d, 0x9711b71d, 1301*b274feedSAvi Kivity 0x1600181e, 0x9701b81e, 0x1610181e, 0x9711b81e, 1302*b274feedSAvi Kivity 0x1200191f, 0x9301b91f, 0x1210191f, 0x9311b91f, 1303*b274feedSAvi Kivity 0x02002020, 0x8701c020, 0x12101a20, 0x9311ba20, 1304*b274feedSAvi Kivity 0x06002121, 0x8301c121, 0x16101b21, 0x9711bb21, 1305*b274feedSAvi Kivity 0x06002222, 0x8301c222, 0x12101c22, 0x9311bc22, 1306*b274feedSAvi Kivity 0x02002323, 0x8701c323, 0x16101d23, 0x9711bd23, 1307*b274feedSAvi Kivity 0x06002424, 0x8301c424, 0x16101e24, 0x9711be24, 1308*b274feedSAvi Kivity 0x02002525, 0x8701c525, 0x12101f25, 0x9311bf25, 1309*b274feedSAvi Kivity 0x02002626, 0x8701c626, 0x12102026, 0x9711c026, 1310*b274feedSAvi Kivity 0x06002727, 0x8301c727, 0x16102127, 0x9311c127, 1311*b274feedSAvi Kivity 0x06002828, 0x8301c828, 0x16102228, 0x9311c228, 1312*b274feedSAvi Kivity 0x02002929, 0x8701c929, 0x12102329, 0x9711c329, 1313*b274feedSAvi Kivity 0x1600242a, 0x9301c42a, 0x1610242a, 0x9311c42a, 1314*b274feedSAvi Kivity 0x1200252b, 0x9701c52b, 0x1210252b, 0x9711c52b, 1315*b274feedSAvi Kivity 0x1200262c, 0x9701c62c, 0x1210262c, 0x9711c62c, 1316*b274feedSAvi Kivity 0x1600272d, 0x9301c72d, 0x1610272d, 0x9311c72d, 1317*b274feedSAvi Kivity 0x1600282e, 0x9301c82e, 0x1610282e, 0x9311c82e, 1318*b274feedSAvi Kivity 0x1200292f, 0x9701c92f, 0x1210292f, 0x9711c92f, 1319*b274feedSAvi Kivity 0x06003030, 0x8301d030, 0x12102a30, 0x9711ca30, 1320*b274feedSAvi Kivity 0x02003131, 0x8701d131, 0x16102b31, 0x9311cb31, 1321*b274feedSAvi Kivity 0x02003232, 0x8701d232, 0x12102c32, 0x9711cc32, 1322*b274feedSAvi Kivity 0x06003333, 0x8301d333, 0x16102d33, 0x9311cd33, 1323*b274feedSAvi Kivity 0x02003434, 0x8701d434, 0x16102e34, 0x9311ce34, 1324*b274feedSAvi Kivity 0x06003535, 0x8301d535, 0x12102f35, 0x9711cf35, 1325*b274feedSAvi Kivity 0x06003636, 0x8301d636, 0x16103036, 0x9311d036, 1326*b274feedSAvi Kivity 0x02003737, 0x8701d737, 0x12103137, 0x9711d137, 1327*b274feedSAvi Kivity 0x02003838, 0x8701d838, 0x12103238, 0x9711d238, 1328*b274feedSAvi Kivity 0x06003939, 0x8301d939, 0x16103339, 0x9311d339, 1329*b274feedSAvi Kivity 0x1200343a, 0x9701d43a, 0x1210343a, 0x9711d43a, 1330*b274feedSAvi Kivity 0x1600353b, 0x9301d53b, 0x1610353b, 0x9311d53b, 1331*b274feedSAvi Kivity 0x1600363c, 0x9301d63c, 0x1610363c, 0x9311d63c, 1332*b274feedSAvi Kivity 0x1200373d, 0x9701d73d, 0x1210373d, 0x9711d73d, 1333*b274feedSAvi Kivity 0x1200383e, 0x9701d83e, 0x1210383e, 0x9711d83e, 1334*b274feedSAvi Kivity 0x1600393f, 0x9301d93f, 0x1610393f, 0x9311d93f, 1335*b274feedSAvi Kivity 0x02004040, 0x8301e040, 0x16103a40, 0x9311da40, 1336*b274feedSAvi Kivity 0x06004141, 0x8701e141, 0x12103b41, 0x9711db41, 1337*b274feedSAvi Kivity 0x06004242, 0x8701e242, 0x16103c42, 0x9311dc42, 1338*b274feedSAvi Kivity 0x02004343, 0x8301e343, 0x12103d43, 0x9711dd43, 1339*b274feedSAvi Kivity 0x06004444, 0x8701e444, 0x12103e44, 0x9711de44, 1340*b274feedSAvi Kivity 0x02004545, 0x8301e545, 0x16103f45, 0x9311df45, 1341*b274feedSAvi Kivity 0x02004646, 0x8301e646, 0x12104046, 0x9311e046, 1342*b274feedSAvi Kivity 0x06004747, 0x8701e747, 0x16104147, 0x9711e147, 1343*b274feedSAvi Kivity 0x06004848, 0x8701e848, 0x16104248, 0x9711e248, 1344*b274feedSAvi Kivity 0x02004949, 0x8301e949, 0x12104349, 0x9311e349, 1345*b274feedSAvi Kivity 0x1600444a, 0x9701e44a, 0x1610444a, 0x9711e44a, 1346*b274feedSAvi Kivity 0x1200454b, 0x9301e54b, 0x1210454b, 0x9311e54b, 1347*b274feedSAvi Kivity 0x1200464c, 0x9301e64c, 0x1210464c, 0x9311e64c, 1348*b274feedSAvi Kivity 0x1600474d, 0x9701e74d, 0x1610474d, 0x9711e74d, 1349*b274feedSAvi Kivity 0x1600484e, 0x9701e84e, 0x1610484e, 0x9711e84e, 1350*b274feedSAvi Kivity 0x1200494f, 0x9301e94f, 0x1210494f, 0x9311e94f, 1351*b274feedSAvi Kivity 0x06005050, 0x8701f050, 0x12104a50, 0x9311ea50, 1352*b274feedSAvi Kivity 0x02005151, 0x8301f151, 0x16104b51, 0x9711eb51, 1353*b274feedSAvi Kivity 0x02005252, 0x8301f252, 0x12104c52, 0x9311ec52, 1354*b274feedSAvi Kivity 0x06005353, 0x8701f353, 0x16104d53, 0x9711ed53, 1355*b274feedSAvi Kivity 0x02005454, 0x8301f454, 0x16104e54, 0x9711ee54, 1356*b274feedSAvi Kivity 0x06005555, 0x8701f555, 0x12104f55, 0x9311ef55, 1357*b274feedSAvi Kivity 0x06005656, 0x8701f656, 0x16105056, 0x9711f056, 1358*b274feedSAvi Kivity 0x02005757, 0x8301f757, 0x12105157, 0x9311f157, 1359*b274feedSAvi Kivity 0x02005858, 0x8301f858, 0x12105258, 0x9311f258, 1360*b274feedSAvi Kivity 0x06005959, 0x8701f959, 0x16105359, 0x9711f359, 1361*b274feedSAvi Kivity 0x1200545a, 0x9301f45a, 0x1210545a, 0x9311f45a, 1362*b274feedSAvi Kivity 0x1600555b, 0x9701f55b, 0x1610555b, 0x9711f55b, 1363*b274feedSAvi Kivity 0x1600565c, 0x9701f65c, 0x1610565c, 0x9711f65c, 1364*b274feedSAvi Kivity 0x1200575d, 0x9301f75d, 0x1210575d, 0x9311f75d, 1365*b274feedSAvi Kivity 0x1200585e, 0x9301f85e, 0x1210585e, 0x9311f85e, 1366*b274feedSAvi Kivity 0x1600595f, 0x9701f95f, 0x1610595f, 0x9711f95f, 1367*b274feedSAvi Kivity 0x06006060, 0x47010060, 0x16105a60, 0x9711fa60, 1368*b274feedSAvi Kivity 0x02006161, 0x03010161, 0x12105b61, 0x9311fb61, 1369*b274feedSAvi Kivity 0x02006262, 0x03010262, 0x16105c62, 0x9711fc62, 1370*b274feedSAvi Kivity 0x06006363, 0x07010363, 0x12105d63, 0x9311fd63, 1371*b274feedSAvi Kivity 0x02006464, 0x03010464, 0x12105e64, 0x9311fe64, 1372*b274feedSAvi Kivity 0x06006565, 0x07010565, 0x16105f65, 0x9711ff65, 1373*b274feedSAvi Kivity 0x06006666, 0x07010666, 0x16106066, 0x57110066, 1374*b274feedSAvi Kivity 0x02006767, 0x03010767, 0x12106167, 0x13110167, 1375*b274feedSAvi Kivity 0x02006868, 0x03010868, 0x12106268, 0x13110268, 1376*b274feedSAvi Kivity 0x06006969, 0x07010969, 0x16106369, 0x17110369, 1377*b274feedSAvi Kivity 0x1200646a, 0x1301046a, 0x1210646a, 0x1311046a, 1378*b274feedSAvi Kivity 0x1600656b, 0x1701056b, 0x1610656b, 0x1711056b, 1379*b274feedSAvi Kivity 0x1600666c, 0x1701066c, 0x1610666c, 0x1711066c, 1380*b274feedSAvi Kivity 0x1200676d, 0x1301076d, 0x1210676d, 0x1311076d, 1381*b274feedSAvi Kivity 0x1200686e, 0x1301086e, 0x1210686e, 0x1311086e, 1382*b274feedSAvi Kivity 0x1600696f, 0x1701096f, 0x1610696f, 0x1711096f, 1383*b274feedSAvi Kivity 0x02007070, 0x03011070, 0x16106a70, 0x17110a70, 1384*b274feedSAvi Kivity 0x06007171, 0x07011171, 0x12106b71, 0x13110b71, 1385*b274feedSAvi Kivity 0x06007272, 0x07011272, 0x16106c72, 0x17110c72, 1386*b274feedSAvi Kivity 0x02007373, 0x03011373, 0x12106d73, 0x13110d73, 1387*b274feedSAvi Kivity 0x06007474, 0x07011474, 0x12106e74, 0x13110e74, 1388*b274feedSAvi Kivity 0x02007575, 0x03011575, 0x16106f75, 0x17110f75, 1389*b274feedSAvi Kivity 0x02007676, 0x03011676, 0x12107076, 0x13111076, 1390*b274feedSAvi Kivity 0x06007777, 0x07011777, 0x16107177, 0x17111177, 1391*b274feedSAvi Kivity 0x06007878, 0x07011878, 0x16107278, 0x17111278, 1392*b274feedSAvi Kivity 0x02007979, 0x03011979, 0x12107379, 0x13111379, 1393*b274feedSAvi Kivity 0x1600747a, 0x1701147a, 0x1610747a, 0x1711147a, 1394*b274feedSAvi Kivity 0x1200757b, 0x1301157b, 0x1210757b, 0x1311157b, 1395*b274feedSAvi Kivity 0x1200767c, 0x1301167c, 0x1210767c, 0x1311167c, 1396*b274feedSAvi Kivity 0x1600777d, 0x1701177d, 0x1610777d, 0x1711177d, 1397*b274feedSAvi Kivity 0x1600787e, 0x1701187e, 0x1610787e, 0x1711187e, 1398*b274feedSAvi Kivity 0x1200797f, 0x1301197f, 0x1210797f, 0x1311197f, 1399*b274feedSAvi Kivity 0x82008080, 0x03012080, 0x12107a80, 0x13111a80, 1400*b274feedSAvi Kivity 0x86008181, 0x07012181, 0x16107b81, 0x17111b81, 1401*b274feedSAvi Kivity 0x86008282, 0x07012282, 0x12107c82, 0x13111c82, 1402*b274feedSAvi Kivity 0x82008383, 0x03012383, 0x16107d83, 0x17111d83, 1403*b274feedSAvi Kivity 0x86008484, 0x07012484, 0x16107e84, 0x17111e84, 1404*b274feedSAvi Kivity 0x82008585, 0x03012585, 0x12107f85, 0x13111f85, 1405*b274feedSAvi Kivity 0x82008686, 0x03012686, 0x92108086, 0x13112086, 1406*b274feedSAvi Kivity 0x86008787, 0x07012787, 0x96108187, 0x17112187, 1407*b274feedSAvi Kivity 0x86008888, 0x07012888, 0x96108288, 0x17112288, 1408*b274feedSAvi Kivity 0x82008989, 0x03012989, 0x92108389, 0x13112389, 1409*b274feedSAvi Kivity 0x9600848a, 0x1701248a, 0x9610848a, 0x1711248a, 1410*b274feedSAvi Kivity 0x9200858b, 0x1301258b, 0x9210858b, 0x1311258b, 1411*b274feedSAvi Kivity 0x9200868c, 0x1301268c, 0x9210868c, 0x1311268c, 1412*b274feedSAvi Kivity 0x9600878d, 0x1701278d, 0x9610878d, 0x1711278d, 1413*b274feedSAvi Kivity 0x9600888e, 0x1701288e, 0x9610888e, 0x1711288e, 1414*b274feedSAvi Kivity 0x9200898f, 0x1301298f, 0x9210898f, 0x1311298f, 1415*b274feedSAvi Kivity 0x86009090, 0x07013090, 0x92108a90, 0x13112a90, 1416*b274feedSAvi Kivity 0x82009191, 0x03013191, 0x96108b91, 0x17112b91, 1417*b274feedSAvi Kivity 0x82009292, 0x03013292, 0x92108c92, 0x13112c92, 1418*b274feedSAvi Kivity 0x86009393, 0x07013393, 0x96108d93, 0x17112d93, 1419*b274feedSAvi Kivity 0x82009494, 0x03013494, 0x96108e94, 0x17112e94, 1420*b274feedSAvi Kivity 0x86009595, 0x07013595, 0x92108f95, 0x13112f95, 1421*b274feedSAvi Kivity 0x86009696, 0x07013696, 0x96109096, 0x17113096, 1422*b274feedSAvi Kivity 0x82009797, 0x03013797, 0x92109197, 0x13113197, 1423*b274feedSAvi Kivity 0x82009898, 0x03013898, 0x92109298, 0x13113298, 1424*b274feedSAvi Kivity 0x86009999, 0x07013999, 0x96109399, 0x17113399, 1425*b274feedSAvi Kivity 0x1300349a, 0x1301349a, 0x1310349a, 0x1311349a, 1426*b274feedSAvi Kivity 0x1700359b, 0x1701359b, 0x1710359b, 0x1711359b, 1427*b274feedSAvi Kivity 0x1700369c, 0x1701369c, 0x1710369c, 0x1711369c, 1428*b274feedSAvi Kivity 0x1300379d, 0x1301379d, 0x1310379d, 0x1311379d, 1429*b274feedSAvi Kivity 0x1300389e, 0x1301389e, 0x1310389e, 0x1311389e, 1430*b274feedSAvi Kivity 0x1700399f, 0x1701399f, 0x1710399f, 0x1711399f, 1431*b274feedSAvi Kivity 0x030040a0, 0x030140a0, 0x17103aa0, 0x17113aa0, 1432*b274feedSAvi Kivity 0x070041a1, 0x070141a1, 0x13103ba1, 0x13113ba1, 1433*b274feedSAvi Kivity 0x070042a2, 0x070142a2, 0x17103ca2, 0x17113ca2, 1434*b274feedSAvi Kivity 0x030043a3, 0x030143a3, 0x13103da3, 0x13113da3, 1435*b274feedSAvi Kivity 0x070044a4, 0x070144a4, 0x13103ea4, 0x13113ea4, 1436*b274feedSAvi Kivity 0x030045a5, 0x030145a5, 0x17103fa5, 0x17113fa5, 1437*b274feedSAvi Kivity 0x030046a6, 0x030146a6, 0x131040a6, 0x131140a6, 1438*b274feedSAvi Kivity 0x070047a7, 0x070147a7, 0x171041a7, 0x171141a7, 1439*b274feedSAvi Kivity 0x070048a8, 0x070148a8, 0x171042a8, 0x171142a8, 1440*b274feedSAvi Kivity 0x030049a9, 0x030149a9, 0x131043a9, 0x131143a9, 1441*b274feedSAvi Kivity 0x170044aa, 0x170144aa, 0x171044aa, 0x171144aa, 1442*b274feedSAvi Kivity 0x130045ab, 0x130145ab, 0x131045ab, 0x131145ab, 1443*b274feedSAvi Kivity 0x130046ac, 0x130146ac, 0x131046ac, 0x131146ac, 1444*b274feedSAvi Kivity 0x170047ad, 0x170147ad, 0x171047ad, 0x171147ad, 1445*b274feedSAvi Kivity 0x170048ae, 0x170148ae, 0x171048ae, 0x171148ae, 1446*b274feedSAvi Kivity 0x130049af, 0x130149af, 0x131049af, 0x131149af, 1447*b274feedSAvi Kivity 0x070050b0, 0x070150b0, 0x13104ab0, 0x13114ab0, 1448*b274feedSAvi Kivity 0x030051b1, 0x030151b1, 0x17104bb1, 0x17114bb1, 1449*b274feedSAvi Kivity 0x030052b2, 0x030152b2, 0x13104cb2, 0x13114cb2, 1450*b274feedSAvi Kivity 0x070053b3, 0x070153b3, 0x17104db3, 0x17114db3, 1451*b274feedSAvi Kivity 0x030054b4, 0x030154b4, 0x17104eb4, 0x17114eb4, 1452*b274feedSAvi Kivity 0x070055b5, 0x070155b5, 0x13104fb5, 0x13114fb5, 1453*b274feedSAvi Kivity 0x070056b6, 0x070156b6, 0x171050b6, 0x171150b6, 1454*b274feedSAvi Kivity 0x030057b7, 0x030157b7, 0x131051b7, 0x131151b7, 1455*b274feedSAvi Kivity 0x030058b8, 0x030158b8, 0x131052b8, 0x131152b8, 1456*b274feedSAvi Kivity 0x070059b9, 0x070159b9, 0x171053b9, 0x171153b9, 1457*b274feedSAvi Kivity 0x130054ba, 0x130154ba, 0x131054ba, 0x131154ba, 1458*b274feedSAvi Kivity 0x170055bb, 0x170155bb, 0x171055bb, 0x171155bb, 1459*b274feedSAvi Kivity 0x170056bc, 0x170156bc, 0x171056bc, 0x171156bc, 1460*b274feedSAvi Kivity 0x130057bd, 0x130157bd, 0x131057bd, 0x131157bd, 1461*b274feedSAvi Kivity 0x130058be, 0x130158be, 0x131058be, 0x131158be, 1462*b274feedSAvi Kivity 0x170059bf, 0x170159bf, 0x171059bf, 0x171159bf, 1463*b274feedSAvi Kivity 0x070060c0, 0x070160c0, 0x17105ac0, 0x17115ac0, 1464*b274feedSAvi Kivity 0x030061c1, 0x030161c1, 0x13105bc1, 0x13115bc1, 1465*b274feedSAvi Kivity 0x030062c2, 0x030162c2, 0x17105cc2, 0x17115cc2, 1466*b274feedSAvi Kivity 0x070063c3, 0x070163c3, 0x13105dc3, 0x13115dc3, 1467*b274feedSAvi Kivity 0x030064c4, 0x030164c4, 0x13105ec4, 0x13115ec4, 1468*b274feedSAvi Kivity 0x070065c5, 0x070165c5, 0x17105fc5, 0x17115fc5, 1469*b274feedSAvi Kivity 0x070066c6, 0x070166c6, 0x171060c6, 0x171160c6, 1470*b274feedSAvi Kivity 0x030067c7, 0x030167c7, 0x131061c7, 0x131161c7, 1471*b274feedSAvi Kivity 0x030068c8, 0x030168c8, 0x131062c8, 0x131162c8, 1472*b274feedSAvi Kivity 0x070069c9, 0x070169c9, 0x171063c9, 0x171163c9, 1473*b274feedSAvi Kivity 0x130064ca, 0x130164ca, 0x131064ca, 0x131164ca, 1474*b274feedSAvi Kivity 0x170065cb, 0x170165cb, 0x171065cb, 0x171165cb, 1475*b274feedSAvi Kivity 0x170066cc, 0x170166cc, 0x171066cc, 0x171166cc, 1476*b274feedSAvi Kivity 0x130067cd, 0x130167cd, 0x131067cd, 0x131167cd, 1477*b274feedSAvi Kivity 0x130068ce, 0x130168ce, 0x131068ce, 0x131168ce, 1478*b274feedSAvi Kivity 0x170069cf, 0x170169cf, 0x171069cf, 0x171169cf, 1479*b274feedSAvi Kivity 0x030070d0, 0x030170d0, 0x17106ad0, 0x17116ad0, 1480*b274feedSAvi Kivity 0x070071d1, 0x070171d1, 0x13106bd1, 0x13116bd1, 1481*b274feedSAvi Kivity 0x070072d2, 0x070172d2, 0x17106cd2, 0x17116cd2, 1482*b274feedSAvi Kivity 0x030073d3, 0x030173d3, 0x13106dd3, 0x13116dd3, 1483*b274feedSAvi Kivity 0x070074d4, 0x070174d4, 0x13106ed4, 0x13116ed4, 1484*b274feedSAvi Kivity 0x030075d5, 0x030175d5, 0x17106fd5, 0x17116fd5, 1485*b274feedSAvi Kivity 0x030076d6, 0x030176d6, 0x131070d6, 0x131170d6, 1486*b274feedSAvi Kivity 0x070077d7, 0x070177d7, 0x171071d7, 0x171171d7, 1487*b274feedSAvi Kivity 0x070078d8, 0x070178d8, 0x171072d8, 0x171172d8, 1488*b274feedSAvi Kivity 0x030079d9, 0x030179d9, 0x131073d9, 0x131173d9, 1489*b274feedSAvi Kivity 0x170074da, 0x170174da, 0x171074da, 0x171174da, 1490*b274feedSAvi Kivity 0x130075db, 0x130175db, 0x131075db, 0x131175db, 1491*b274feedSAvi Kivity 0x130076dc, 0x130176dc, 0x131076dc, 0x131176dc, 1492*b274feedSAvi Kivity 0x170077dd, 0x170177dd, 0x171077dd, 0x171177dd, 1493*b274feedSAvi Kivity 0x170078de, 0x170178de, 0x171078de, 0x171178de, 1494*b274feedSAvi Kivity 0x130079df, 0x130179df, 0x131079df, 0x131179df, 1495*b274feedSAvi Kivity 0x830080e0, 0x830180e0, 0x13107ae0, 0x13117ae0, 1496*b274feedSAvi Kivity 0x870081e1, 0x870181e1, 0x17107be1, 0x17117be1, 1497*b274feedSAvi Kivity 0x870082e2, 0x870182e2, 0x13107ce2, 0x13117ce2, 1498*b274feedSAvi Kivity 0x830083e3, 0x830183e3, 0x17107de3, 0x17117de3, 1499*b274feedSAvi Kivity 0x870084e4, 0x870184e4, 0x17107ee4, 0x17117ee4, 1500*b274feedSAvi Kivity 0x830085e5, 0x830185e5, 0x13107fe5, 0x13117fe5, 1501*b274feedSAvi Kivity 0x830086e6, 0x830186e6, 0x931080e6, 0x931180e6, 1502*b274feedSAvi Kivity 0x870087e7, 0x870187e7, 0x971081e7, 0x971181e7, 1503*b274feedSAvi Kivity 0x870088e8, 0x870188e8, 0x971082e8, 0x971182e8, 1504*b274feedSAvi Kivity 0x830089e9, 0x830189e9, 0x931083e9, 0x931183e9, 1505*b274feedSAvi Kivity 0x970084ea, 0x970184ea, 0x971084ea, 0x971184ea, 1506*b274feedSAvi Kivity 0x930085eb, 0x930185eb, 0x931085eb, 0x931185eb, 1507*b274feedSAvi Kivity 0x930086ec, 0x930186ec, 0x931086ec, 0x931186ec, 1508*b274feedSAvi Kivity 0x970087ed, 0x970187ed, 0x971087ed, 0x971187ed, 1509*b274feedSAvi Kivity 0x970088ee, 0x970188ee, 0x971088ee, 0x971188ee, 1510*b274feedSAvi Kivity 0x930089ef, 0x930189ef, 0x931089ef, 0x931189ef, 1511*b274feedSAvi Kivity 0x870090f0, 0x870190f0, 0x93108af0, 0x93118af0, 1512*b274feedSAvi Kivity 0x830091f1, 0x830191f1, 0x97108bf1, 0x97118bf1, 1513*b274feedSAvi Kivity 0x830092f2, 0x830192f2, 0x93108cf2, 0x93118cf2, 1514*b274feedSAvi Kivity 0x870093f3, 0x870193f3, 0x97108df3, 0x97118df3, 1515*b274feedSAvi Kivity 0x830094f4, 0x830194f4, 0x97108ef4, 0x97118ef4, 1516*b274feedSAvi Kivity 0x870095f5, 0x870195f5, 0x93108ff5, 0x93118ff5, 1517*b274feedSAvi Kivity 0x870096f6, 0x870196f6, 0x971090f6, 0x971190f6, 1518*b274feedSAvi Kivity 0x830097f7, 0x830197f7, 0x931091f7, 0x931191f7, 1519*b274feedSAvi Kivity 0x830098f8, 0x830198f8, 0x931092f8, 0x931192f8, 1520*b274feedSAvi Kivity 0x870099f9, 0x870199f9, 0x971093f9, 0x971193f9, 1521*b274feedSAvi Kivity 0x930094fa, 0x930194fa, 0x931094fa, 0x931194fa, 1522*b274feedSAvi Kivity 0x970095fb, 0x970195fb, 0x971095fb, 0x971195fb, 1523*b274feedSAvi Kivity 0x970096fc, 0x970196fc, 0x971096fc, 0x971196fc, 1524*b274feedSAvi Kivity 0x930097fd, 0x930197fd, 0x931097fd, 0x931197fd, 1525*b274feedSAvi Kivity 0x930098fe, 0x930198fe, 0x931098fe, 0x931198fe, 1526*b274feedSAvi Kivity 0x970099ff, 0x970199ff, 0x971099ff, 0x971199ff, 1527*b274feedSAvi Kivity }; 1528*b274feedSAvi Kivity 1529*b274feedSAvi Kivity MK_INSN(das, "das"); 1530*b274feedSAvi Kivity 1531*b274feedSAvi Kivity for (i = 0; i < 1024; ++i) { 1532*b274feedSAvi Kivity unsigned tmp = test_cases[i]; 1533*b274feedSAvi Kivity inregs.eax = tmp & 0xff; 1534*b274feedSAvi Kivity inregs.eflags = (tmp >> 16) & 0xff; 1535*b274feedSAvi Kivity exec_in_big_real_mode(&inregs, &outregs, 1536*b274feedSAvi Kivity insn_das, 1537*b274feedSAvi Kivity insn_das_end - insn_das); 1538*b274feedSAvi Kivity 1539*b274feedSAvi Kivity if (!regs_equal(&inregs, &outregs, R_AX) 1540*b274feedSAvi Kivity || outregs.eax != ((tmp >> 8) & 0xff) 1541*b274feedSAvi Kivity || (outregs.eflags & 0xff) != (tmp >> 24)) { 1542*b274feedSAvi Kivity print_serial("DAS Test: FAIL\n"); 1543*b274feedSAvi Kivity return; 1544*b274feedSAvi Kivity } 1545*b274feedSAvi Kivity } 1546*b274feedSAvi Kivity print_serial("DAS Test: PASS\n"); 1547*b274feedSAvi Kivity } 1548*b274feedSAvi Kivity 15497d36db35SAvi Kivity void realmode_start(void) 15507d36db35SAvi Kivity { 15517d36db35SAvi Kivity test_null(); 15527d36db35SAvi Kivity 15537d36db35SAvi Kivity test_shld(); 15547d36db35SAvi Kivity test_push_pop(); 15557d36db35SAvi Kivity test_pusha_popa(); 15567d36db35SAvi Kivity test_mov_imm(); 15577d36db35SAvi Kivity test_cmp_imm(); 15587d36db35SAvi Kivity test_add_imm(); 15597d36db35SAvi Kivity test_sub_imm(); 15607d36db35SAvi Kivity test_xor_imm(); 15617d36db35SAvi Kivity test_io(); 15627d36db35SAvi Kivity test_eflags_insn(); 15637d36db35SAvi Kivity test_jcc_short(); 15647d36db35SAvi Kivity test_jcc_near(); 15657d36db35SAvi Kivity /* test_call() uses short jump so call it after testing jcc */ 15667d36db35SAvi Kivity test_call(); 15677d36db35SAvi Kivity /* long jmp test uses call near so test it after testing call */ 15687d36db35SAvi Kivity test_long_jmp(); 15697d36db35SAvi Kivity test_xchg(); 15707d36db35SAvi Kivity test_iret(); 157196b9ca1eSMohammed Gamal test_int(); 1572fa74f8a6SMohammed Gamal test_imul(); 157359317bd1SMohammed Gamal test_mul(); 15740d4c7614SMohammed Gamal test_div(); 15750d4c7614SMohammed Gamal test_idiv(); 1576eacef4e2SWei Yongjun test_loopcc(); 15776e293cf5SWei Yongjun test_cbw(); 1578*b274feedSAvi Kivity test_das(); 15797d36db35SAvi Kivity 15807d36db35SAvi Kivity exit(0); 15817d36db35SAvi Kivity } 15827d36db35SAvi Kivity 15837d36db35SAvi Kivity unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff }; 15847d36db35SAvi Kivity 15857d36db35SAvi Kivity struct __attribute__((packed)) { 15867d36db35SAvi Kivity unsigned short limit; 15877d36db35SAvi Kivity void *base; 15887d36db35SAvi Kivity } r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt }; 15897d36db35SAvi Kivity 15907d36db35SAvi Kivity asm( 15917d36db35SAvi Kivity ".section .init \n\t" 15927d36db35SAvi Kivity 15937d36db35SAvi Kivity ".code32 \n\t" 15947d36db35SAvi Kivity 15957d36db35SAvi Kivity "mb_magic = 0x1BADB002 \n\t" 15967d36db35SAvi Kivity "mb_flags = 0x0 \n\t" 15977d36db35SAvi Kivity 15987d36db35SAvi Kivity "# multiboot header \n\t" 15997d36db35SAvi Kivity ".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t" 16007d36db35SAvi Kivity 16017d36db35SAvi Kivity ".globl start \n\t" 16027d36db35SAvi Kivity ".data \n\t" 16037d36db35SAvi Kivity ". = . + 4096 \n\t" 16047d36db35SAvi Kivity "stacktop: \n\t" 16057d36db35SAvi Kivity 16067d36db35SAvi Kivity ".text \n\t" 16077d36db35SAvi Kivity "start: \n\t" 16087d36db35SAvi Kivity "lgdt r_gdt_descr \n\t" 16097d36db35SAvi Kivity "ljmp $8, $1f; 1: \n\t" 16107d36db35SAvi Kivity ".code16gcc \n\t" 16117d36db35SAvi Kivity "mov $16, %eax \n\t" 16127d36db35SAvi Kivity "mov %ax, %ds \n\t" 16137d36db35SAvi Kivity "mov %ax, %es \n\t" 16147d36db35SAvi Kivity "mov %ax, %fs \n\t" 16157d36db35SAvi Kivity "mov %ax, %gs \n\t" 16167d36db35SAvi Kivity "mov %ax, %ss \n\t" 16177d36db35SAvi Kivity "mov %cr0, %eax \n\t" 16187d36db35SAvi Kivity "btc $0, %eax \n\t" 16197d36db35SAvi Kivity "mov %eax, %cr0 \n\t" 16207d36db35SAvi Kivity "ljmp $0, $realmode_entry \n\t" 16217d36db35SAvi Kivity 16227d36db35SAvi Kivity "realmode_entry: \n\t" 16237d36db35SAvi Kivity 16247d36db35SAvi Kivity "xor %ax, %ax \n\t" 16257d36db35SAvi Kivity "mov %ax, %ds \n\t" 16267d36db35SAvi Kivity "mov %ax, %es \n\t" 16277d36db35SAvi Kivity "mov %ax, %ss \n\t" 16287d36db35SAvi Kivity "mov %ax, %fs \n\t" 16297d36db35SAvi Kivity "mov %ax, %gs \n\t" 16307d36db35SAvi Kivity "mov $stacktop, %esp\n\t" 16317d36db35SAvi Kivity "ljmp $0, $realmode_start \n\t" 16327d36db35SAvi Kivity 16337d36db35SAvi Kivity ".code16gcc \n\t" 16347d36db35SAvi Kivity ); 1635