diff options
author | Tiago Vignatti <tiago.vignatti@nokia.com> | 2008-03-11 02:42:13 -0300 |
---|---|---|
committer | Tiago Vignatti <tiago.vignatti@nokia.com> | 2009-11-10 20:21:16 +0200 |
commit | a40e38a271fdf8909ff12f8fed41df606009ef88 (patch) | |
tree | f55c24a798f6aa90d7eb6e8e8da2daacc46ec752 /src | |
parent | c2d64f84c2babb287552965efe39a759075d22c2 (diff) |
drop the first blob of xorg's x86emu
yeah, I know is not the best way to do it...
Signed-off-by: Tiago Vignatti <tiago.vignatti@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/thunk.c | 10 | ||||
-rw-r--r-- | src/x86emu/Makefile.am | 23 | ||||
-rw-r--r-- | src/x86emu/debug.c | 155 | ||||
-rw-r--r-- | src/x86emu/decode.c | 85 | ||||
-rw-r--r-- | src/x86emu/ops.c | 29 | ||||
-rw-r--r-- | src/x86emu/ops2.c | 88 | ||||
-rw-r--r-- | src/x86emu/prim_ops.c | 326 | ||||
-rw-r--r-- | src/x86emu/sys.c | 83 | ||||
-rw-r--r-- | src/x86emu/x86emu.h (renamed from src/x86emu/x86emu/x86emu.h) | 17 | ||||
-rw-r--r-- | src/x86emu/x86emu/debug.h | 10 | ||||
-rw-r--r-- | src/x86emu/x86emu/fpu_regs.h | 8 | ||||
-rw-r--r-- | src/x86emu/x86emu/prim_ops.h | 1 | ||||
-rw-r--r-- | src/x86emu/x86emu/prim_x86_gcc.h | 79 | ||||
-rw-r--r-- | src/x86emu/x86emu/regs.h | 8 | ||||
-rw-r--r-- | src/x86emu/x86emu/types.h | 2 | ||||
-rw-r--r-- | src/x86emu/x86emu/x86emui.h | 18 |
17 files changed, 506 insertions, 443 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index ea1d8b9..3f7adbc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,9 +1,10 @@ +SUBDIRS = x86emu + lib_LTLIBRARIES = libx86.la if X86EMU -libx86_la_SOURCES = x86-common.c thunk.c x86emu/decode.c x86emu/debug.c \ - x86emu/fpu.c x86emu/ops.c x86emu/ops2.c \ - x86emu/prim_ops.c x86emu/sys.c +libx86_la_SOURCES = x86-common.c thunk.c +libx86_la_LIBADD = x86emu/libx86emu.la else libx86_la_SOURCES = x86-common.c lrmi.c endif diff --git a/src/thunk.c b/src/thunk.c index b2b365f..4f392d0 100644 --- a/src/thunk.c +++ b/src/thunk.c @@ -1,7 +1,7 @@ #include <stdarg.h> #include <stdio.h> #include <string.h> -#include "x86emu/x86emu/x86emu.h" +#include "x86emu/x86emu.h" #include "libx86.h" #include "x86-common.h" @@ -63,6 +63,14 @@ #define X86_VIP_MASK 0x00100000 /* virtual interrupt pending */ #define X86_ID_MASK 0x00200000 +#define MEM_RB(name, addr) (*name->mem->rb)(name, addr) +#define MEM_RW(name, addr) (*name->mem->rw)(name, addr) +#define MEM_RL(name, addr) (*name->mem->rl)(name, addr) +#define MEM_WB(name, addr, val) (*name->mem->wb)(name, addr, val) +#define MEM_WW(addr, val) wrw(addr, val) +#define MEM_WL(name, addr, val) (*name->mem->wl)(name, addr, val) + + #define SHMERRORPTR (pointer)(-1) #define __BUILDIO(bwl,bw,type) \ diff --git a/src/x86emu/Makefile.am b/src/x86emu/Makefile.am new file mode 100644 index 0000000..2fc9337 --- /dev/null +++ b/src/x86emu/Makefile.am @@ -0,0 +1,23 @@ +noinst_LTLIBRARIES = libx86emu.la + +libx86emu_la_SOURCES = debug.c \ + decode.c \ + fpu.c \ + ops2.c \ + ops.c \ + prim_ops.c \ + sys.c \ + x86emu.h + +EXTRA_DIST = validate.c \ + x86emu/debug.h \ + x86emu/decode.h \ + x86emu/fpu.h \ + x86emu/fpu_regs.h \ + x86emu/ops.h \ + x86emu/prim_asm.h \ + x86emu/prim_ops.h \ + x86emu/prim_x86_gcc.h \ + x86emu/regs.h \ + x86emu/types.h \ + x86emu/x86emui.h diff --git a/src/x86emu/debug.c b/src/x86emu/debug.c index 837dc18..5eda908 100644 --- a/src/x86emu/debug.c +++ b/src/x86emu/debug.c @@ -38,9 +38,9 @@ ****************************************************************************/ #include "x86emu/x86emui.h" -#ifdef IN_MODULE -#include "xf86_ansic.h" -#else +#include <stdio.h> +#include <string.h> +#ifndef NO_SYS_HEADERS #include <stdarg.h> #include <stdlib.h> #endif @@ -56,18 +56,14 @@ static int parse_line (char *s, int *ps, int *n); /* should look something like debug's output. */ void X86EMU_trace_regs (void) { -return; if (DEBUG_TRACE()) { x86emu_dump_regs(); } if (DEBUG_DECODE() && ! DEBUG_DECODE_NOPRINT()) { - printf("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip); + printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip); print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip); print_decoded_instruction(); } - printf("%04x:%04x \n",M.x86.saved_cs, M.x86.saved_ip); - print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip); - print_decoded_instruction(); } void X86EMU_trace_xregs (void) @@ -83,7 +79,7 @@ void x86emu_just_disassemble (void) * This routine called if the flag DEBUG_DISASSEMBLE is set kind * of a hack! */ - printf("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip); + printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip); print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip); print_decoded_instruction(); } @@ -194,12 +190,12 @@ static void print_encoded_bytes (u16 s, u16 o) for (i=0; i< M.x86.enc_pos; i++) { sprintf(buf1+2*i,"%02x", fetch_data_byte_abs(s,o+i)); } - printf("%-20s",buf1); + printk("%-20s",buf1); } static void print_decoded_instruction (void) { - printf("%s", M.x86.decoded_buf); + printk("%s", M.x86.decoded_buf); } void x86emu_print_int_vect (u16 iv) @@ -209,7 +205,7 @@ void x86emu_print_int_vect (u16 iv) if (iv > 256) return; seg = fetch_data_word_abs(0,iv*4); off = fetch_data_word_abs(0,iv*4+2); - printf("%04x:%04x ", seg, off); + printk("%04x:%04x ", seg, off); } void X86EMU_dump_memory (u16 seg, u16 off, u32 amt) @@ -221,12 +217,12 @@ void X86EMU_dump_memory (u16 seg, u16 off, u32 amt) current = start; while (end <= off + amt) { - printf("%04x:%04x ", seg, start); + printk("%04x:%04x ", seg, start); for (i=start; i< off; i++) - printf(" "); + printk(" "); for ( ; i< end; i++) - printf("%02x ", fetch_data_byte_abs(seg,i)); - printf("\n"); + printk("%02x ", fetch_data_byte_abs(seg,i)); + printk("\n"); start = end; end = start + 16; } @@ -260,7 +256,7 @@ void x86emu_single_step (void) done=0; offset = M.x86.saved_ip; while (!done) { - printf("-"); + printk("-"); p = fgets(s, 1023, stdin); cmd = parse_line(s, ps, &ntok); switch(cmd) { @@ -310,10 +306,11 @@ void x86emu_single_step (void) } break; case 'q': - exit(1); + M.x86.debug |= DEBUG_EXIT; + return; case 'P': noDecode = (noDecode)?0:1; - printf("Toggled decoding to %s\n",(noDecode)?"FALSE":"TRUE"); + printk("Toggled decoding to %s\n",(noDecode)?"FALSE":"TRUE"); break; case 't': case 0: @@ -366,68 +363,68 @@ static int parse_line (char *s, int *ps, int *n) void x86emu_dump_regs (void) { - fprintf(stderr, "\tAX=%04x ", M.x86.R_AX ); - fprintf(stderr, "BX=%04x ", M.x86.R_BX ); - fprintf(stderr, "CX=%04x ", M.x86.R_CX ); - fprintf(stderr, "DX=%04x ", M.x86.R_DX ); - fprintf(stderr, "SP=%04x ", M.x86.R_SP ); - fprintf(stderr, "BP=%04x ", M.x86.R_BP ); - fprintf(stderr, "SI=%04x ", M.x86.R_SI ); - fprintf(stderr, "DI=%04x\n", M.x86.R_DI ); - fprintf(stderr, "\tDS=%04x ", M.x86.R_DS ); - fprintf(stderr, "ES=%04x ", M.x86.R_ES ); - fprintf(stderr, "SS=%04x ", M.x86.R_SS ); - fprintf(stderr, "CS=%04x ", M.x86.R_CS ); - fprintf(stderr, "IP=%04x ", M.x86.R_IP ); - if (ACCESS_FLAG(F_OF)) fprintf(stderr, "OV "); /* CHECKED... */ - else fprintf(stderr, "NV "); - if (ACCESS_FLAG(F_DF)) fprintf(stderr, "DN "); - else fprintf(stderr, "UP "); - if (ACCESS_FLAG(F_IF)) fprintf(stderr, "EI "); - else fprintf(stderr, "DI "); - if (ACCESS_FLAG(F_SF)) fprintf(stderr, "NG "); - else fprintf(stderr, "PL "); - if (ACCESS_FLAG(F_ZF)) fprintf(stderr, "ZR "); - else fprintf(stderr, "NZ "); - if (ACCESS_FLAG(F_AF)) fprintf(stderr, "AC "); - else fprintf(stderr, "NA "); - if (ACCESS_FLAG(F_PF)) fprintf(stderr, "PE "); - else fprintf(stderr, "PO "); - if (ACCESS_FLAG(F_CF)) fprintf(stderr, "CY "); - else fprintf(stderr, "NC "); - fprintf(stderr, "\n"); + printk("\tAX=%04x ", M.x86.R_AX ); + printk("BX=%04x ", M.x86.R_BX ); + printk("CX=%04x ", M.x86.R_CX ); + printk("DX=%04x ", M.x86.R_DX ); + printk("SP=%04x ", M.x86.R_SP ); + printk("BP=%04x ", M.x86.R_BP ); + printk("SI=%04x ", M.x86.R_SI ); + printk("DI=%04x\n", M.x86.R_DI ); + printk("\tDS=%04x ", M.x86.R_DS ); + printk("ES=%04x ", M.x86.R_ES ); + printk("SS=%04x ", M.x86.R_SS ); + printk("CS=%04x ", M.x86.R_CS ); + printk("IP=%04x ", M.x86.R_IP ); + if (ACCESS_FLAG(F_OF)) printk("OV "); /* CHECKED... */ + else printk("NV "); + if (ACCESS_FLAG(F_DF)) printk("DN "); + else printk("UP "); + if (ACCESS_FLAG(F_IF)) printk("EI "); + else printk("DI "); + if (ACCESS_FLAG(F_SF)) printk("NG "); + else printk("PL "); + if (ACCESS_FLAG(F_ZF)) printk("ZR "); + else printk("NZ "); + if (ACCESS_FLAG(F_AF)) printk("AC "); + else printk("NA "); + if (ACCESS_FLAG(F_PF)) printk("PE "); + else printk("PO "); + if (ACCESS_FLAG(F_CF)) printk("CY "); + else printk("NC "); + printk("\n"); } void x86emu_dump_xregs (void) { - printf("\tEAX=%08x ", M.x86.R_EAX ); - printf("EBX=%08x ", M.x86.R_EBX ); - printf("ECX=%08x ", M.x86.R_ECX ); - printf("EDX=%08x \n", M.x86.R_EDX ); - printf("\tESP=%08x ", M.x86.R_ESP ); - printf("EBP=%08x ", M.x86.R_EBP ); - printf("ESI=%08x ", M.x86.R_ESI ); - printf("EDI=%08x\n", M.x86.R_EDI ); - printf("\tDS=%04x ", M.x86.R_DS ); - printf("ES=%04x ", M.x86.R_ES ); - printf("SS=%04x ", M.x86.R_SS ); - printf("CS=%04x ", M.x86.R_CS ); - printf("EIP=%08x\n\t", M.x86.R_EIP ); - if (ACCESS_FLAG(F_OF)) printf("OV "); /* CHECKED... */ - else printf("NV "); - if (ACCESS_FLAG(F_DF)) printf("DN "); - else printf("UP "); - if (ACCESS_FLAG(F_IF)) printf("EI "); - else printf("DI "); - if (ACCESS_FLAG(F_SF)) printf("NG "); - else printf("PL "); - if (ACCESS_FLAG(F_ZF)) printf("ZR "); - else printf("NZ "); - if (ACCESS_FLAG(F_AF)) printf("AC "); - else printf("NA "); - if (ACCESS_FLAG(F_PF)) printf("PE "); - else printf("PO "); - if (ACCESS_FLAG(F_CF)) printf("CY "); - else printf("NC "); - printf("\n"); + printk("\tEAX=%08x ", M.x86.R_EAX ); + printk("EBX=%08x ", M.x86.R_EBX ); + printk("ECX=%08x ", M.x86.R_ECX ); + printk("EDX=%08x \n", M.x86.R_EDX ); + printk("\tESP=%08x ", M.x86.R_ESP ); + printk("EBP=%08x ", M.x86.R_EBP ); + printk("ESI=%08x ", M.x86.R_ESI ); + printk("EDI=%08x\n", M.x86.R_EDI ); + printk("\tDS=%04x ", M.x86.R_DS ); + printk("ES=%04x ", M.x86.R_ES ); + printk("SS=%04x ", M.x86.R_SS ); + printk("CS=%04x ", M.x86.R_CS ); + printk("EIP=%08x\n\t", M.x86.R_EIP ); + if (ACCESS_FLAG(F_OF)) printk("OV "); /* CHECKED... */ + else printk("NV "); + if (ACCESS_FLAG(F_DF)) printk("DN "); + else printk("UP "); + if (ACCESS_FLAG(F_IF)) printk("EI "); + else printk("DI "); + if (ACCESS_FLAG(F_SF)) printk("NG "); + else printk("PL "); + if (ACCESS_FLAG(F_ZF)) printk("ZR "); + else printk("NZ "); + if (ACCESS_FLAG(F_AF)) printk("AC "); + else printk("NA "); + if (ACCESS_FLAG(F_PF)) printk("PE "); + else printk("PO "); + if (ACCESS_FLAG(F_CF)) printk("CY "); + else printk("NC "); + printk("\n"); } diff --git a/src/x86emu/decode.c b/src/x86emu/decode.c index 9071649..9339f4c 100644 --- a/src/x86emu/decode.c +++ b/src/x86emu/decode.c @@ -37,7 +37,7 @@ * ****************************************************************************/ - +#include <stdlib.h> #include "x86emu/x86emui.h" /*----------------------------- Implementation ----------------------------*/ @@ -103,8 +103,14 @@ DB( if (CHECK_IP_FETCH()) INC_DECODED_INST_LEN(1); if (M.x86.intr) { if (M.x86.intr & INTR_HALTED) { -DB( - X86EMU_trace_regs();) +DB( if (M.x86.R_SP != 0) { + printk("halted\n"); + X86EMU_trace_regs(); + } + else { + if (M.x86.debug) + printk("Service completed successfully\n"); + }) return; } if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || M.x86.intno == 2)) || @@ -112,16 +118,12 @@ DB( x86emu_intr_handle(); } } - if ((M.x86.R_CS == 0) && (M.x86.R_IP == 0)) { -DB( - X86EMU_trace_regs();) - return; - } - op1 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++)); - // fprintf (stderr, "%s", M.x86.decoded_buf); - // x86emu_dump_regs(); (*x86emu_optab[op1])(op1); + if (M.x86.debug & DEBUG_EXIT) { + M.x86.debug &= ~DEBUG_EXIT; + return; + } } } @@ -716,10 +718,7 @@ u16* decode_rm_seg_register( DECODE_PRINTF("ILLEGAL SEGREG"); break; } - printf("reg %d\n", reg); - //DECODE_PRINTF("CS"); - //return &M.x86.R_CS; - /*HALT_SYS();*/ + HALT_SYS(); return NULL; /* NOT REACHED OR REACHED ON ERROR */ } @@ -843,6 +842,7 @@ u32 decode_rm00_address( int sib; if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + /* 32-bit addressing */ switch (rm) { case 0: DECODE_PRINTF("[EAX]"); @@ -872,21 +872,22 @@ u32 decode_rm00_address( } HALT_SYS(); } else { + /* 16-bit addressing */ switch (rm) { case 0: DECODE_PRINTF("[BX+SI]"); - return M.x86.R_BX + M.x86.R_SI; + return (M.x86.R_BX + M.x86.R_SI) & 0xffff; case 1: DECODE_PRINTF("[BX+DI]"); - return M.x86.R_BX + M.x86.R_DI; + return (M.x86.R_BX + M.x86.R_DI) & 0xffff; case 2: DECODE_PRINTF("[BP+SI]"); M.x86.mode |= SYSMODE_SEG_DS_SS; - return M.x86.R_BP + M.x86.R_SI; + return (M.x86.R_BP + M.x86.R_SI) & 0xffff; case 3: DECODE_PRINTF("[BP+DI]"); M.x86.mode |= SYSMODE_SEG_DS_SS; - return M.x86.R_BP + M.x86.R_DI; + return (M.x86.R_BP + M.x86.R_DI) & 0xffff; case 4: DECODE_PRINTF("[SI]"); return M.x86.R_SI; @@ -928,6 +929,7 @@ u32 decode_rm01_address( displacement = (s8)fetch_byte_imm(); if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + /* 32-bit addressing */ switch (rm) { case 0: DECODE_PRINTF2("%d[EAX]", displacement); @@ -958,34 +960,35 @@ u32 decode_rm01_address( } HALT_SYS(); } else { + /* 16-bit addressing */ switch (rm) { case 0: DECODE_PRINTF2("%d[BX+SI]", displacement); - return M.x86.R_BX + M.x86.R_SI + displacement; + return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff; case 1: DECODE_PRINTF2("%d[BX+DI]", displacement); - return M.x86.R_BX + M.x86.R_DI + displacement; + return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff; case 2: DECODE_PRINTF2("%d[BP+SI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; - return M.x86.R_BP + M.x86.R_SI + displacement; + return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff; case 3: DECODE_PRINTF2("%d[BP+DI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; - return M.x86.R_BP + M.x86.R_DI + displacement; + return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff; case 4: DECODE_PRINTF2("%d[SI]", displacement); - return M.x86.R_SI + displacement; + return (M.x86.R_SI + displacement) & 0xffff; case 5: DECODE_PRINTF2("%d[DI]", displacement); - return M.x86.R_DI + displacement; + return (M.x86.R_DI + displacement) & 0xffff; case 6: DECODE_PRINTF2("%d[BP]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; - return M.x86.R_BP + displacement; + return (M.x86.R_BP + displacement) & 0xffff; case 7: DECODE_PRINTF2("%d[BX]", displacement); - return M.x86.R_BX + displacement; + return (M.x86.R_BX + displacement) & 0xffff; } HALT_SYS(); } @@ -1019,6 +1022,7 @@ u32 decode_rm10_address( } if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + /* 32-bit addressing */ switch (rm) { case 0: DECODE_PRINTF2("%08x[EAX]", displacement); @@ -1051,34 +1055,35 @@ u32 decode_rm10_address( } HALT_SYS(); } else { + /* 16-bit addressing */ switch (rm) { case 0: - DECODE_PRINTF2("%04x[BX+SI]", displacement); - return M.x86.R_BX + M.x86.R_SI + displacement; + DECODE_PRINTF2("%04x[BX+SI]", displacement); + return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff; case 1: - DECODE_PRINTF2("%04x[BX+DI]", displacement); - return M.x86.R_BX + M.x86.R_DI + displacement; + DECODE_PRINTF2("%04x[BX+DI]", displacement); + return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff; case 2: DECODE_PRINTF2("%04x[BP+SI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; - return M.x86.R_BP + M.x86.R_SI + displacement; + return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff; case 3: DECODE_PRINTF2("%04x[BP+DI]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; - return M.x86.R_BP + M.x86.R_DI + displacement; + return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff; case 4: - DECODE_PRINTF2("%04x[SI]", displacement); - return M.x86.R_SI + displacement; + DECODE_PRINTF2("%04x[SI]", displacement); + return (M.x86.R_SI + displacement) & 0xffff; case 5: - DECODE_PRINTF2("%04x[DI]", displacement); - return M.x86.R_DI + displacement; + DECODE_PRINTF2("%04x[DI]", displacement); + return (M.x86.R_DI + displacement) & 0xffff; case 6: DECODE_PRINTF2("%04x[BP]", displacement); M.x86.mode |= SYSMODE_SEG_DS_SS; - return M.x86.R_BP + displacement; + return (M.x86.R_BP + displacement) & 0xffff; case 7: - DECODE_PRINTF2("%04x[BX]", displacement); - return M.x86.R_BX + displacement; + DECODE_PRINTF2("%04x[BX]", displacement); + return (M.x86.R_BX + displacement) & 0xffff; } HALT_SYS(); } diff --git a/src/x86emu/ops.c b/src/x86emu/ops.c index 7431863..37ae2c9 100644 --- a/src/x86emu/ops.c +++ b/src/x86emu/ops.c @@ -70,7 +70,6 @@ * ****************************************************************************/ - #include "x86emu/x86emui.h" /*----------------------------- Implementation ----------------------------*/ @@ -86,11 +85,22 @@ static void x86emuOp_illegal_op( u8 op1) { START_OF_INSTR(); + if (M.x86.R_SP != 0) { DECODE_PRINTF("ILLEGAL X86 OPCODE\n"); TRACE_REGS(); - printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n", - M.x86.R_CS, M.x86.R_IP-1,op1); + DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n", + M.x86.R_CS, M.x86.R_IP-1,op1)); HALT_SYS(); + } + else { + /* If we get here, it means the stack pointer is back to zero + * so we are just returning from an emulator service call + * so therte is no need to display an error message. We trap + * the emulator with an 0xF1 opcode to finish the service + * call. + */ + X86EMU_halt_sys(); + } END_OF_INSTR(); } @@ -9403,6 +9413,8 @@ static void x86emuOp_aam(u8 X86EMU_UNUSED(op1)) DECODE_PRINTF("AAM\n"); a = fetch_byte_imm(); /* this is a stupid encoding. */ if (a != 10) { + /* fix: add base decoding + aam_word(u8 val, int base a) */ DECODE_PRINTF("ERROR DECODING AAM\n"); TRACE_REGS(); HALT_SYS(); @@ -9420,9 +9432,18 @@ Handles opcode 0xd5 ****************************************************************************/ static void x86emuOp_aad(u8 X86EMU_UNUSED(op1)) { + u8 a; + START_OF_INSTR(); DECODE_PRINTF("AAD\n"); - (void) fetch_byte_imm(); + a = fetch_byte_imm(); + if (a != 10) { + /* fix: add base decoding + aad_word(u16 val, int base a) */ + DECODE_PRINTF("ERROR DECODING AAM\n"); + TRACE_REGS(); + HALT_SYS(); + } TRACE_AND_STEP(); M.x86.R_AX = aad_word(M.x86.R_AX); DECODE_CLEAR_SEGOVR(); diff --git a/src/x86emu/ops2.c b/src/x86emu/ops2.c index 4bf95c1..324de8a 100644 --- a/src/x86emu/ops2.c +++ b/src/x86emu/ops2.c @@ -65,6 +65,40 @@ static void x86emuOp2_illegal_op( /**************************************************************************** REMARKS: +Handles opcode 0x0f,0x31 +****************************************************************************/ +static void x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2)) +{ +#ifdef __HAS_LONG_LONG__ + static u64 counter = 0; +#else + static u32 counter = 0; +#endif + + counter += 0x10000; + + /* read timestamp counter */ + /* + * Note that instead of actually trying to accurately measure this, we just + * increase the counter by a fixed amount every time we hit one of these + * instructions. Feel free to come up with a better method. + */ + START_OF_INSTR(); + DECODE_PRINTF("RDTSC\n"); + TRACE_AND_STEP(); +#ifdef __HAS_LONG_LONG__ + M.x86.R_EAX = counter & 0xffffffff; + M.x86.R_EDX = counter >> 32; +#else + M.x86.R_EAX = counter; + M.x86.R_EDX = 0; +#endif + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** +REMARKS: Handles opcode 0x0f,0x80-0x8F ****************************************************************************/ static void x86emuOp2_long_jump(u8 op2) @@ -294,6 +328,20 @@ static void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2)) } /**************************************************************************** +REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output +Handles opcode 0x0f,0xa2 +****************************************************************************/ +static void x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2)) +{ + START_OF_INSTR(); + DECODE_PRINTF("CPUID\n"); + TRACE_AND_STEP(); + cpuid(); + DECODE_CLEAR_SEGOVR(); + END_OF_INSTR(); +} + +/**************************************************************************** REMARKS: Handles opcode 0x0f,0xa3 ****************************************************************************/ @@ -2129,7 +2177,7 @@ static void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2)) uint srcoffset; START_OF_INSTR(); - DECODE_PRINTF("BSF\n"); + DECODE_PRINTF("BSF\t"); FETCH_DECODE_MODRM(mod, rh, rl); switch(mod) { case 0: @@ -2209,25 +2257,25 @@ static void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2)) break; case 3: /* register to register */ if (M.x86.mode & SYSMODE_PREFIX_DATA) { - u32 *srcreg, *dstreg; + u32 srcval, *dstreg; - srcreg = DECODE_RM_LONG_REGISTER(rl); + srcval = *DECODE_RM_LONG_REGISTER(rl); DECODE_PRINTF(","); dstreg = DECODE_RM_LONG_REGISTER(rh); TRACE_AND_STEP(); - CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); for(*dstreg = 0; *dstreg < 32; (*dstreg)++) - if ((*srcreg >> *dstreg) & 1) break; + if ((srcval >> *dstreg) & 1) break; } else { - u16 *srcreg, *dstreg; + u16 srcval, *dstreg; - srcreg = DECODE_RM_WORD_REGISTER(rl); + srcval = *DECODE_RM_WORD_REGISTER(rl); DECODE_PRINTF(","); dstreg = DECODE_RM_WORD_REGISTER(rh); TRACE_AND_STEP(); - CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); for(*dstreg = 0; *dstreg < 16; (*dstreg)++) - if ((*srcreg >> *dstreg) & 1) break; + if ((srcval >> *dstreg) & 1) break; } break; } @@ -2245,7 +2293,7 @@ static void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2)) uint srcoffset; START_OF_INSTR(); - DECODE_PRINTF("BSF\n"); + DECODE_PRINTF("BSR\t"); FETCH_DECODE_MODRM(mod, rh, rl); switch(mod) { case 0: @@ -2325,25 +2373,25 @@ static void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2)) break; case 3: /* register to register */ if (M.x86.mode & SYSMODE_PREFIX_DATA) { - u32 *srcreg, *dstreg; + u32 srcval, *dstreg; - srcreg = DECODE_RM_LONG_REGISTER(rl); + srcval = *DECODE_RM_LONG_REGISTER(rl); DECODE_PRINTF(","); dstreg = DECODE_RM_LONG_REGISTER(rh); TRACE_AND_STEP(); - CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); for(*dstreg = 31; *dstreg > 0; (*dstreg)--) - if ((*srcreg >> *dstreg) & 1) break; + if ((srcval >> *dstreg) & 1) break; } else { - u16 *srcreg, *dstreg; + u16 srcval, *dstreg; - srcreg = DECODE_RM_WORD_REGISTER(rl); + srcval = *DECODE_RM_WORD_REGISTER(rl); DECODE_PRINTF(","); dstreg = DECODE_RM_WORD_REGISTER(rh); TRACE_AND_STEP(); - CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF); + CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); for(*dstreg = 15; *dstreg > 0; (*dstreg)--) - if ((*srcreg >> *dstreg) & 1) break; + if ((srcval >> *dstreg) & 1) break; } break; } @@ -2580,7 +2628,7 @@ void (*x86emu_optab2[256])(u8) = /* 0x2f */ x86emuOp2_illegal_op, /* 0x30 */ x86emuOp2_illegal_op, -/* 0x31 */ x86emuOp2_illegal_op, +/* 0x31 */ x86emuOp2_rdtsc, /* 0x32 */ x86emuOp2_illegal_op, /* 0x33 */ x86emuOp2_illegal_op, /* 0x34 */ x86emuOp2_illegal_op, @@ -2700,7 +2748,7 @@ void (*x86emu_optab2[256])(u8) = /* 0xa0 */ x86emuOp2_push_FS, /* 0xa1 */ x86emuOp2_pop_FS, -/* 0xa2 */ x86emuOp2_illegal_op, +/* 0xa2 */ x86emuOp2_cpuid, /* 0xa3 */ x86emuOp2_bt_R, /* 0xa4 */ x86emuOp2_shld_IMM, /* 0xa5 */ x86emuOp2_shld_CL, diff --git a/src/x86emu/prim_ops.c b/src/x86emu/prim_ops.c index ba4ffde..b42cdc0 100644 --- a/src/x86emu/prim_ops.c +++ b/src/x86emu/prim_ops.c @@ -97,12 +97,18 @@ * ****************************************************************************/ +#include <stdlib.h> + #define PRIM_OPS_NO_REDEFINE_ASM #include "x86emu/x86emui.h" -/*------------------------- Global Variables ------------------------------*/ +#if defined(__GNUC__) +# if defined (__i386__) || defined(__i386) || defined(__AMD64__) || defined(__x86_64__) || defined(__amd64__) +# include "x86emu/prim_x86_gcc.h" +# endif +#endif -#ifndef __HAVE_INLINE_ASSEMBLER__ +/*------------------------- Global Variables ------------------------------*/ static u32 x86emu_parity_tab[8] = { @@ -116,15 +122,11 @@ static u32 x86emu_parity_tab[8] = 0x69969669, }; -#endif - #define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0) #define XOR2(x) (((x) ^ ((x)>>1)) & 0x1) /*----------------------------- Implementation ----------------------------*/ -#ifndef __HAVE_INLINE_ASSEMBLER__ - /**************************************************************************** REMARKS: Implements the AAA instruction and side effects. @@ -2086,7 +2088,7 @@ Implements the IMUL instruction and side effects. void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s) { #ifdef __HAS_LONG_LONG__ - s64 res = (s32)d * (s32)s; + s64 res = (s64)(s32)d * (s32)s; *res_lo = (u32)res; *res_hi = (u32)(res >> 32); @@ -2178,7 +2180,7 @@ Implements the MUL instruction and side effects. void mul_long(u32 s) { #ifdef __HAS_LONG_LONG__ - u64 res = (u32)M.x86.R_EAX * (u32)s; + u64 res = (u64)M.x86.R_EAX * s; M.x86.R_EAX = (u32)res; M.x86.R_EDX = (u32)(res >> 32); @@ -2454,8 +2456,6 @@ void div_long(u32 s) M.x86.R_EDX = (u32)mod; } -#endif /* __HAVE_INLINE_ASSEMBLER__ */ - /**************************************************************************** REMARKS: Implements the IN string instruction and side effects. @@ -2660,255 +2660,63 @@ DB( if (CHECK_SP_ACCESS()) return res; } -#ifdef __HAVE_INLINE_ASSEMBLER__ - -u16 aaa_word (u16 d) -{ return aaa_word_asm(&M.x86.R_EFLG,d); } - -u16 aas_word (u16 d) -{ return aas_word_asm(&M.x86.R_EFLG,d); } - -u16 aad_word (u16 d) -{ return aad_word_asm(&M.x86.R_EFLG,d); } - -u16 aam_word (u8 d) -{ return aam_word_asm(&M.x86.R_EFLG,d); } - -u8 adc_byte (u8 d, u8 s) -{ return adc_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 adc_word (u16 d, u16 s) -{ return adc_word_asm(&M.x86.R_EFLG,d,s); } - -u32 adc_long (u32 d, u32 s) -{ return adc_long_asm(&M.x86.R_EFLG,d,s); } - -u8 add_byte (u8 d, u8 s) -{ return add_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 add_word (u16 d, u16 s) -{ return add_word_asm(&M.x86.R_EFLG,d,s); } - -u32 add_long (u32 d, u32 s) -{ return add_long_asm(&M.x86.R_EFLG,d,s); } - -u8 and_byte (u8 d, u8 s) -{ return and_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 and_word (u16 d, u16 s) -{ return and_word_asm(&M.x86.R_EFLG,d,s); } - -u32 and_long (u32 d, u32 s) -{ return and_long_asm(&M.x86.R_EFLG,d,s); } - -u8 cmp_byte (u8 d, u8 s) -{ return cmp_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 cmp_word (u16 d, u16 s) -{ return cmp_word_asm(&M.x86.R_EFLG,d,s); } - -u32 cmp_long (u32 d, u32 s) -{ return cmp_long_asm(&M.x86.R_EFLG,d,s); } - -u8 daa_byte (u8 d) -{ return daa_byte_asm(&M.x86.R_EFLG,d); } - -u8 das_byte (u8 d) -{ return das_byte_asm(&M.x86.R_EFLG,d); } - -u8 dec_byte (u8 d) -{ return dec_byte_asm(&M.x86.R_EFLG,d); } - -u16 dec_word (u16 d) -{ return dec_word_asm(&M.x86.R_EFLG,d); } - -u32 dec_long (u32 d) -{ return dec_long_asm(&M.x86.R_EFLG,d); } - -u8 inc_byte (u8 d) -{ return inc_byte_asm(&M.x86.R_EFLG,d); } - -u16 inc_word (u16 d) -{ return inc_word_asm(&M.x86.R_EFLG,d); } - -u32 inc_long (u32 d) -{ return inc_long_asm(&M.x86.R_EFLG,d); } - -u8 or_byte (u8 d, u8 s) -{ return or_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 or_word (u16 d, u16 s) -{ return or_word_asm(&M.x86.R_EFLG,d,s); } - -u32 or_long (u32 d, u32 s) -{ return or_long_asm(&M.x86.R_EFLG,d,s); } - -u8 neg_byte (u8 s) -{ return neg_byte_asm(&M.x86.R_EFLG,s); } - -u16 neg_word (u16 s) -{ return neg_word_asm(&M.x86.R_EFLG,s); } - -u32 neg_long (u32 s) -{ return neg_long_asm(&M.x86.R_EFLG,s); } - -u8 not_byte (u8 s) -{ return not_byte_asm(&M.x86.R_EFLG,s); } - -u16 not_word (u16 s) -{ return not_word_asm(&M.x86.R_EFLG,s); } - -u32 not_long (u32 s) -{ return not_long_asm(&M.x86.R_EFLG,s); } - -u8 rcl_byte (u8 d, u8 s) -{ return rcl_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 rcl_word (u16 d, u8 s) -{ return rcl_word_asm(&M.x86.R_EFLG,d,s); } - -u32 rcl_long (u32 d, u8 s) -{ return rcl_long_asm(&M.x86.R_EFLG,d,s); } - -u8 rcr_byte (u8 d, u8 s) -{ return rcr_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 rcr_word (u16 d, u8 s) -{ return rcr_word_asm(&M.x86.R_EFLG,d,s); } - -u32 rcr_long (u32 d, u8 s) -{ return rcr_long_asm(&M.x86.R_EFLG,d,s); } - -u8 rol_byte (u8 d, u8 s) -{ return rol_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 rol_word (u16 d, u8 s) -{ return rol_word_asm(&M.x86.R_EFLG,d,s); } - -u32 rol_long (u32 d, u8 s) -{ return rol_long_asm(&M.x86.R_EFLG,d,s); } - -u8 ror_byte (u8 d, u8 s) -{ return ror_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 ror_word (u16 d, u8 s) -{ return ror_word_asm(&M.x86.R_EFLG,d,s); } - -u32 ror_long (u32 d, u8 s) -{ return ror_long_asm(&M.x86.R_EFLG,d,s); } - -u8 shl_byte (u8 d, u8 s) -{ return shl_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 shl_word (u16 d, u8 s) -{ return shl_word_asm(&M.x86.R_EFLG,d,s); } - -u32 shl_long (u32 d, u8 s) -{ return shl_long_asm(&M.x86.R_EFLG,d,s); } - -u8 shr_byte (u8 d, u8 s) -{ return shr_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 shr_word (u16 d, u8 s) -{ return shr_word_asm(&M.x86.R_EFLG,d,s); } - -u32 shr_long (u32 d, u8 s) -{ return shr_long_asm(&M.x86.R_EFLG,d,s); } - -u8 sar_byte (u8 d, u8 s) -{ return sar_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 sar_word (u16 d, u8 s) -{ return sar_word_asm(&M.x86.R_EFLG,d,s); } - -u32 sar_long (u32 d, u8 s) -{ return sar_long_asm(&M.x86.R_EFLG,d,s); } - -u16 shld_word (u16 d, u16 fill, u8 s) -{ return shld_word_asm(&M.x86.R_EFLG,d,fill,s); } - -u32 shld_long (u32 d, u32 fill, u8 s) -{ return shld_long_asm(&M.x86.R_EFLG,d,fill,s); } - -u16 shrd_word (u16 d, u16 fill, u8 s) -{ return shrd_word_asm(&M.x86.R_EFLG,d,fill,s); } - -u32 shrd_long (u32 d, u32 fill, u8 s) -{ return shrd_long_asm(&M.x86.R_EFLG,d,fill,s); } - -u8 sbb_byte (u8 d, u8 s) -{ return sbb_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 sbb_word (u16 d, u16 s) -{ return sbb_word_asm(&M.x86.R_EFLG,d,s); } - -u32 sbb_long (u32 d, u32 s) -{ return sbb_long_asm(&M.x86.R_EFLG,d,s); } - -u8 sub_byte (u8 d, u8 s) -{ return sub_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 sub_word (u16 d, u16 s) -{ return sub_word_asm(&M.x86.R_EFLG,d,s); } - -u32 sub_long (u32 d, u32 s) -{ return sub_long_asm(&M.x86.R_EFLG,d,s); } - -void test_byte (u8 d, u8 s) -{ test_byte_asm(&M.x86.R_EFLG,d,s); } - -void test_word (u16 d, u16 s) -{ test_word_asm(&M.x86.R_EFLG,d,s); } - -void test_long (u32 d, u32 s) -{ test_long_asm(&M.x86.R_EFLG,d,s); } - -u8 xor_byte (u8 d, u8 s) -{ return xor_byte_asm(&M.x86.R_EFLG,d,s); } - -u16 xor_word (u16 d, u16 s) -{ return xor_word_asm(&M.x86.R_EFLG,d,s); } - -u32 xor_long (u32 d, u32 s) -{ return xor_long_asm(&M.x86.R_EFLG,d,s); } - -void imul_byte (u8 s) -{ imul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s); } - -void imul_word (u16 s) -{ imul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s); } - -void imul_long (u32 s) -{ imul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s); } - -void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s) -{ imul_long_asm(&M.x86.R_EFLG,res_lo,res_hi,d,s); } - -void mul_byte (u8 s) -{ mul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s); } - -void mul_word (u16 s) -{ mul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s); } - -void mul_long (u32 s) -{ mul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s); } - -void idiv_byte (u8 s) -{ idiv_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s); } - -void idiv_word (u16 s) -{ idiv_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s); } - -void idiv_long (u32 s) -{ idiv_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s); } - -void div_byte (u8 s) -{ div_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s); } - -void div_word (u16 s) -{ div_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s); } +/**************************************************************************** +REMARKS: +CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output +****************************************************************************/ +void cpuid (void) +{ + u32 feature = M.x86.R_EAX; -void div_long (u32 s) -{ div_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s); } +#ifdef X86EMU_HAS_HW_CPUID + /* If the platform allows it, we will base our values on the real + * results from the CPUID instruction. We limit support to the + * first two features, and the results of those are sanitized. + */ + if (feature <= 1) + hw_cpuid(&M.x86.R_EAX, &M.x86.R_EBX, &M.x86.R_ECX, &M.x86.R_EDX); +#endif + switch (feature) { + case 0: + /* Regardless if we have real data from the hardware, the emulator + * will only support upto feature 1, which we set in register EAX. + * Registers EBX:EDX:ECX contain a string identifying the CPU. + */ + M.x86.R_EAX = 1; +#ifndef X86EMU_HAS_HW_CPUID + /* EBX:EDX:ECX = "GenuineIntel" */ + M.x86.R_EBX = 0x756e6547; + M.x86.R_EDX = 0x49656e69; + M.x86.R_ECX = 0x6c65746e; #endif + break; + case 1: +#ifndef X86EMU_HAS_HW_CPUID + /* If we don't have x86 compatible hardware, we return values from an + * Intel 486dx4; which was one of the first processors to have CPUID. + */ + M.x86.R_EAX = 0x00000480; + M.x86.R_EBX = 0x00000000; + M.x86.R_ECX = 0x00000000; + M.x86.R_EDX = 0x00000002; /* VME */ +#else + /* In the case that we have hardware CPUID instruction, we make sure + * that the features reported are limited to TSC and VME. + */ + M.x86.R_EDX &= 0x00000012; +#endif + break; + default: + /* Finally, we don't support any additional features. Most CPUs + * return all zeros when queried for invalid or unsupported feature + * numbers. + */ + M.x86.R_EAX = 0; + M.x86.R_EBX = 0; + M.x86.R_ECX = 0; + M.x86.R_EDX = 0; + break; + } +} + diff --git a/src/x86emu/sys.c b/src/x86emu/sys.c index 73fc66e..4d90ea3 100644 --- a/src/x86emu/sys.c +++ b/src/x86emu/sys.c @@ -40,14 +40,12 @@ * ****************************************************************************/ -#include "x86emu/x86emu.h" +#include "x86emu.h" #include "x86emu/x86emui.h" #include "x86emu/regs.h" #include "x86emu/debug.h" #include "x86emu/prim_ops.h" -#ifdef IN_MODULE -#include "xf86_ansic.h" -#else +#ifndef NO_SYS_HEADERS #include <string.h> #endif /*------------------------- Global Variables ------------------------------*/ @@ -59,6 +57,7 @@ X86EMU_intrFuncs _X86EMU_intrTab[256]; #if defined(__alpha__) || defined(__alpha) /* to cope with broken egcs-1.1.2 :-(((( */ +#define ALPHA_UALOADS /* * inline functions to do unaligned accesses * from linux/include/asm-alpha/unaligned.h @@ -210,6 +209,60 @@ static __inline__ void stw_u(unsigned long r5, unsigned short * r11) :"r" (r5), "r" (r11)); #endif } + +#elif defined(__GNUC__) && ((__GNUC__ < 3)) && \ + (defined (__ia64__) || defined (ia64__)) +#define IA64_UALOADS +/* + * EGCS 1.1 knows about arbitrary unaligned loads. Define some + * packed structures to talk about such things with. + */ +struct __una_u64 { unsigned long x __attribute__((packed)); }; +struct __una_u32 { unsigned int x __attribute__((packed)); }; +struct __una_u16 { unsigned short x __attribute__((packed)); }; + +static __inline__ unsigned long +__uldq (const unsigned long * r11) +{ + const struct __una_u64 *ptr = (const struct __una_u64 *) r11; + return ptr->x; +} + +static __inline__ unsigned long +uldl (const unsigned int * r11) +{ + const struct __una_u32 *ptr = (const struct __una_u32 *) r11; + return ptr->x; +} + +static __inline__ unsigned long +uldw (const unsigned short * r11) +{ + const struct __una_u16 *ptr = (const struct __una_u16 *) r11; + return ptr->x; +} + +static __inline__ void +ustq (unsigned long r5, unsigned long * r11) +{ + struct __una_u64 *ptr = (struct __una_u64 *) r11; + ptr->x = r5; +} + +static __inline__ void +ustl (unsigned long r5, unsigned int * r11) +{ + struct __una_u32 *ptr = (struct __una_u32 *) r11; + ptr->x = r5; +} + +static __inline__ void +ustw (unsigned long r5, unsigned short * r11) +{ + struct __una_u16 *ptr = (struct __una_u16 *) r11; + ptr->x = r5; +} + #endif /**************************************************************************** @@ -263,8 +316,10 @@ u16 X86API rdw( } else #endif -#if defined(__alpha__) || defined(__alpha) +#if defined(ALPHA_UALOADS) val = ldw_u((u16*)(M.mem_base + addr)); +#elif defined(IA64_UALOADS) + val = uldw((u16*)(M.mem_base + addr)); #else val = *(u16*)(M.mem_base + addr); #endif @@ -300,8 +355,10 @@ u32 X86API rdl( } else #endif -#if defined(__alpha__) || defined(__alpha) +#if defined(ALPHA_UALOADS) val = ldl_u((u32*)(M.mem_base + addr)); +#elif defined(IA64_UALOADS) + val = uldl((u32*)(M.mem_base + addr)); #else val = *(u32*)(M.mem_base + addr); #endif @@ -356,8 +413,10 @@ DB( if (DEBUG_MEM_TRACE()) } else #endif -#if defined(__alpha__) || defined(__alpha) +#if defined(ALPHA_UALOADS) stw_u(val,(u16*)(M.mem_base + addr)); +#elif defined(IA64_UALOADS) + ustw(val,(u16*)(M.mem_base + addr)); #else *(u16*)(M.mem_base + addr) = val; #endif @@ -390,8 +449,10 @@ DB( if (DEBUG_MEM_TRACE()) } else #endif -#if defined(__alpha__) || defined(__alpha) +#if defined(ALPHA_UALOADS) stl_u(val,(u32*)(M.mem_base + addr)); +#elif defined(IA64_UALOADS) + ustl(val,(u32*)(M.mem_base + addr)); #else *(u32*)(M.mem_base + addr) = val; #endif @@ -408,7 +469,6 @@ Default PIO byte read function. Doesn't perform real inb. static u8 X86API p_inb( X86EMU_pioAddr addr) { - printf("No real inb\n"); DB( if (DEBUG_IO_TRACE()) printk("inb %#04x \n", addr);) return 0; @@ -425,7 +485,6 @@ Default PIO word read function. Doesn't perform real inw. static u16 X86API p_inw( X86EMU_pioAddr addr) { - printf("No real inw\n"); DB( if (DEBUG_IO_TRACE()) printk("inw %#04x \n", addr);) return 0; @@ -442,7 +501,6 @@ Default PIO long read function. Doesn't perform real inl. static u32 X86API p_inl( X86EMU_pioAddr addr) { - printf("No real inl\n"); DB( if (DEBUG_IO_TRACE()) printk("inl %#04x \n", addr);) return 0; @@ -459,7 +517,6 @@ static void X86API p_outb( X86EMU_pioAddr addr, u8 val) { - printf("No real outb\n"); DB( if (DEBUG_IO_TRACE()) printk("outb %#02x -> %#04x \n", val, addr);) return; @@ -476,7 +533,6 @@ static void X86API p_outw( X86EMU_pioAddr addr, u16 val) { - printf("No real outw\n"); DB( if (DEBUG_IO_TRACE()) printk("outw %#04x -> %#04x \n", val, addr);) return; @@ -493,7 +549,6 @@ static void X86API p_outl( X86EMU_pioAddr addr, u32 val) { - printf("No real outl\n"); DB( if (DEBUG_IO_TRACE()) printk("outl %#08x -> %#04x \n", val, addr);) return; diff --git a/src/x86emu/x86emu/x86emu.h b/src/x86emu/x86emu.h index 8a83eed..795e2d6 100644 --- a/src/x86emu/x86emu/x86emu.h +++ b/src/x86emu/x86emu.h @@ -47,15 +47,17 @@ #define X86APIP _ASMAPIP typedef int X86EMU_pioAddr; #else -#include "types.h" +#include "x86emu/types.h" #define X86API #define X86APIP * #endif -#include "regs.h" +#include "x86emu/regs.h" /*---------------------- Macros and type definitions ----------------------*/ -/* #pragma pack(1) */ /* Don't pack structs with function pointers! */ +#ifdef PACK +# pragma PACK /* Don't pack structs with function pointers! */ +#endif /**************************************************************************** REMARKS: @@ -128,8 +130,10 @@ extern u32 X86API rdl(u32 addr); extern void X86API wrb(u32 addr, u8 val); extern void X86API wrw(u32 addr, u16 val); extern void X86API wrl(u32 addr, u32 val); - -/* #pragma pack() */ + +#ifdef END_PACK +# pragma END_PACK +#endif /*--------------------- type definitions -----------------------------------*/ @@ -168,6 +172,7 @@ void X86EMU_halt_sys(void); #define DEBUG_DISASSEMBLE_F 0x000008 #define DEBUG_BREAK_F 0x000010 #define DEBUG_SVC_F 0x000020 +#define DEBUG_SAVE_IP_CS_F 0x000040 #define DEBUG_FS_F 0x000080 #define DEBUG_PROC_F 0x000100 #define DEBUG_SYSINT_F 0x000200 /* bios system interrupts. */ @@ -177,7 +182,7 @@ void X86EMU_halt_sys(void); #define DEBUG_IO_TRACE_F 0x002000 #define DEBUG_TRACECALL_REGS_F 0x004000 #define DEBUG_DECODE_NOPRINT_F 0x008000 -#define DEBUG_SAVE_IP_CS_F 0x010000 +#define DEBUG_EXIT 0x010000 #define DEBUG_SYS_F (DEBUG_SVC_F|DEBUG_FS_F|DEBUG_PROC_F) void X86EMU_trace_regs(void); diff --git a/src/x86emu/x86emu/debug.h b/src/x86emu/x86emu/debug.h index 0886a76..57f3546 100644 --- a/src/x86emu/x86emu/debug.h +++ b/src/x86emu/x86emu/debug.h @@ -101,12 +101,10 @@ #ifdef DEBUG -# define DECODE_PRINTF(x) \ - if (DEBUG_DECODE()) \ +# define DECODE_PRINTF(x) if (DEBUG_DECODE()) \ x86emu_decode_printf(x) -# define DECODE_PRINTF2(x,y) \ - if (DEBUG_DECODE()) \ +# define DECODE_PRINTF2(x,y) if (DEBUG_DECODE()) \ x86emu_decode_printf2(x,y) /* @@ -137,8 +135,8 @@ if (DEBUG_DISASSEMBLE()) { \ x86emu_just_disassemble(); \ goto EndOfTheInstructionProcedure; \ - } /*\ - if (DEBUG_TRACE() || DEBUG_DECODE()) X86EMU_trace_regs()*/ + } \ + if (DEBUG_TRACE() || DEBUG_DECODE()) X86EMU_trace_regs() #else # define TRACE_REGS() #endif diff --git a/src/x86emu/x86emu/fpu_regs.h b/src/x86emu/x86emu/fpu_regs.h index f349f18..e59b807 100644 --- a/src/x86emu/x86emu/fpu_regs.h +++ b/src/x86emu/x86emu/fpu_regs.h @@ -41,6 +41,10 @@ #ifdef X86_FPU_SUPPORT +#ifdef PACK +# pragma PACK +#endif + /* Basic 8087 register can hold any of the following values: */ union x86_fpu_reg_u { @@ -85,6 +89,10 @@ struct x86_fpu_registers { short x86_fpu_tos, x86_fpu_bos; }; +#ifdef END_PACK +# pragma END_PACK +#endif + /* * There are two versions of the following macro. * diff --git a/src/x86emu/x86emu/prim_ops.h b/src/x86emu/x86emu/prim_ops.h index f9f87eb..d4441c7 100644 --- a/src/x86emu/x86emu/prim_ops.h +++ b/src/x86emu/x86emu/prim_ops.h @@ -135,6 +135,7 @@ void push_word (u16 w); void push_long (u32 w); u16 pop_word (void); u32 pop_long (void); +void cpuid (void); #if defined(__HAVE_INLINE_ASSEMBLER__) && !defined(PRIM_OPS_NO_REDEFINE_ASM) diff --git a/src/x86emu/x86emu/prim_x86_gcc.h b/src/x86emu/x86emu/prim_x86_gcc.h new file mode 100644 index 0000000..af61e20 --- /dev/null +++ b/src/x86emu/x86emu/prim_x86_gcc.h @@ -0,0 +1,79 @@ +/**************************************************************************** +* +* Inline helpers for x86emu +* +* Copyright (C) 2008 Bart Trojanowski, Symbio Technologies, LLC +* +* ======================================================================== +* +* Permission to use, copy, modify, distribute, and sell this software and +* its documentation for any purpose is hereby granted without fee, +* provided that the above copyright notice appear in all copies and that +* both that copyright notice and this permission notice appear in +* supporting documentation, and that the name of the authors not be used +* in advertising or publicity pertaining to distribution of the software +* without specific, written prior permission. The authors makes no +* representations about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +* +* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +* +* ======================================================================== +* +* Language: GNU C +* Environment: GCC on i386 or x86-64 +* Developer: Bart Trojanowski +* +* Description: This file defines a few x86 macros that can be used by the +* emulator to execute native instructions. +* +* For PIC vs non-PIC code refer to: +* http://sam.zoy.org/blog/2007-04-13-shlib-with-non-pic-code-have-inline-assembly-and-pic-mix-well +* +****************************************************************************/ +#ifndef __X86EMU_PRIM_X86_GCC_H +#define __X86EMU_PRIM_X86_GCC_H + +#include "x86emu/types.h" + +#if !defined(__GNUC__) || !(defined (__i386__) || defined(__i386) || defined(__AMD64__) || defined(__x86_64__) || defined(__amd64__)) +#error This file is intended to be used by gcc on i386 or x86-64 system +#endif + +#if defined(__PIC__) && defined(__i386__) + +#define X86EMU_HAS_HW_CPUID 1 +static inline void hw_cpuid (u32 *a, u32 *b, u32 *c, u32 *d) +{ + __asm__ __volatile__ ("pushl %%ebx \n\t" + "cpuid \n\t" + "movl %%ebx, %1 \n\t" + "popl %%ebx \n\t" + : "=a" (*a), "=r" (*b), + "=c" (*c), "=d" (*d) + : "a" (*a), "c" (*c) + : "cc"); +} + +#else // ! (__PIC__ && __i386__) + +#define x86EMU_HAS_HW_CPUID 1 +static inline void hw_cpuid (u32 *a, u32 *b, u32 *c, u32 *d) +{ + __asm__ __volatile__ ("cpuid" + : "=a" (*a), "=b" (*b), + "=c" (*c), "=d" (*d) + : "a" (*a), "c" (*c) + : "cc"); +} + +#endif // __PIC__ && __i386__ + + +#endif // __X86EMU_PRIM_X86_GCC_H diff --git a/src/x86emu/x86emu/regs.h b/src/x86emu/x86emu/regs.h index 46d9f12..52cf8e4 100644 --- a/src/x86emu/x86emu/regs.h +++ b/src/x86emu/x86emu/regs.h @@ -41,6 +41,10 @@ /*---------------------- Macros and type definitions ----------------------*/ +#ifdef PACK +# pragma PACK +#endif + /* * General EAX, EBX, ECX, EDX type registers. Note that for * portability, and speed, the issue of byte swapping is not addressed @@ -302,6 +306,10 @@ typedef struct { X86EMU_regs x86; } X86EMU_sysEnv; +#ifdef END_PACK +# pragma END_PACK +#endif + /*----------------------------- Global Variables --------------------------*/ #ifdef __cplusplus diff --git a/src/x86emu/x86emu/types.h b/src/x86emu/x86emu/types.h index c2b5dab..c0c09c1 100644 --- a/src/x86emu/x86emu/types.h +++ b/src/x86emu/x86emu/types.h @@ -40,7 +40,7 @@ #ifndef __X86EMU_TYPES_H #define __X86EMU_TYPES_H -#ifndef IN_MODULE +#ifndef NO_SYS_HEADERS #include <sys/types.h> #endif diff --git a/src/x86emu/x86emu/x86emui.h b/src/x86emu/x86emu/x86emui.h index ed82604..112ee36 100644 --- a/src/x86emu/x86emu/x86emui.h +++ b/src/x86emu/x86emu/x86emui.h @@ -62,17 +62,15 @@ #endif #include "x86emu.h" -#include "regs.h" -#include "debug.h" -#include "decode.h" -#include "ops.h" -#include "prim_ops.h" -#include "fpu.h" -#include "fpu_regs.h" +#include "x86emu/regs.h" +#include "x86emu/debug.h" +#include "x86emu/decode.h" +#include "x86emu/ops.h" +#include "x86emu/prim_ops.h" +#include "x86emu/fpu.h" +#include "x86emu/fpu_regs.h" -#ifdef IN_MODULE -#include <xf86_ansic.h> -#else +#ifndef NO_SYS_HEADERS #include <stdio.h> #include <stdlib.h> #include <string.h> |