20 #define NO_SYS_HEADERS 21 #ifndef NO_SYS_HEADERS 24 #include "x86emu/x86emui.h" 32 static void x86emu_intr_handle(
void)
36 if (M.x86.intr & INTR_SYNCH)
39 if (_X86EMU_intrTab[intno])
41 (*_X86EMU_intrTab[intno])(intno);
45 push_word((u16) M.x86.R_FLG);
48 push_word(M.x86.R_CS);
49 M.x86.R_CS = mem_access_word(intno * 4 + 2);
50 push_word(M.x86.R_IP);
51 M.x86.R_IP = mem_access_word(intno * 4);
65 void x86emu_intr_raise(u8 intrnum)
67 M.x86.intno = intrnum;
68 M.x86.intr |= INTR_SYNCH;
77 void X86EMU_exec(
void)
82 DB(x86emu_end_instr();)
86 DB(
if (CHECK_IP_FETCH()) x86emu_check_ip_access();)
88 SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP);
89 INC_DECODED_INST_LEN(1);
92 if (M.x86.intr & INTR_HALTED)
94 DB(
if (M.x86.R_SP != 0) {
99 printk(
"Service completed successfully\n");
103 if (((M.x86.intr & INTR_SYNCH) &&
104 (M.x86.intno == 0 || M.x86.intno == 2)) ||
107 x86emu_intr_handle();
111 op1 = (*sys_rdb)(((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
112 (*x86emu_optab[op1])(op1);
113 if (M.x86.debug & DEBUG_EXIT)
115 M.x86.debug &= ~DEBUG_EXIT;
125 void X86EMU_halt_sys(
void)
127 M.x86.intr |= INTR_HALTED;
142 void fetch_decode_modrm(
int *mod,
int *regh,
int *regl)
146 DB(
if (CHECK_IP_FETCH()) x86emu_check_ip_access();)
147 fetched = (*sys_rdb)(((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
148 INC_DECODED_INST_LEN(1);
149 *mod = (fetched >> 6) & 0x03;
150 *regh = (fetched >> 3) & 0x07;
151 *regl = (fetched >> 0) & 0x07;
164 u8 fetch_byte_imm(
void)
168 DB(
if (CHECK_IP_FETCH()) x86emu_check_ip_access();)
169 fetched = (*sys_rdb)(((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
170 INC_DECODED_INST_LEN(1);
184 u16 fetch_word_imm(
void)
188 DB(
if (CHECK_IP_FETCH()) x86emu_check_ip_access();)
189 fetched = (*sys_rdw)(((u32) M.x86.R_CS << 4) + (M.x86.R_IP));
191 INC_DECODED_INST_LEN(2);
205 u32 fetch_long_imm(
void)
209 DB(
if (CHECK_IP_FETCH()) x86emu_check_ip_access();)
210 fetched = (*sys_rdl)(((u32) M.x86.R_CS << 4) + (M.x86.R_IP));
212 INC_DECODED_INST_LEN(4);
245 _INLINE u32 get_data_segment(
void)
247 #define GET_SEGMENT(segment) 248 switch (M.x86.mode & SYSMODE_SEGMASK)
251 case SYSMODE_SEGOVR_DS:
252 case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS:
254 case SYSMODE_SEG_DS_SS:
256 case SYSMODE_SEGOVR_CS:
257 case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS:
259 case SYSMODE_SEGOVR_ES:
260 case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS:
262 case SYSMODE_SEGOVR_FS:
263 case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS:
265 case SYSMODE_SEGOVR_GS:
266 case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS:
268 case SYSMODE_SEGOVR_SS:
269 case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS:
273 printk(
"error: should not happen: multiple overrides.\n");
289 u8 fetch_data_byte(uint offset)
292 if (CHECK_DATA_ACCESS())
293 x86emu_check_data_access((u16) get_data_segment(), offset);
295 return (*sys_rdb)((get_data_segment() << 4) + offset);
307 u16 fetch_data_word(uint offset)
310 if (CHECK_DATA_ACCESS())
311 x86emu_check_data_access((u16) get_data_segment(), offset);
313 return (*sys_rdw)((get_data_segment() << 4) + offset);
325 u32 fetch_data_long(uint offset)
328 if (CHECK_DATA_ACCESS())
329 x86emu_check_data_access((u16) get_data_segment(), offset);
331 return (*sys_rdl)((get_data_segment() << 4) + offset);
344 u8 fetch_data_byte_abs(uint segment, uint offset)
347 if (CHECK_DATA_ACCESS())
348 x86emu_check_data_access(segment, offset);
350 return (*sys_rdb)(((u32) segment << 4) + offset);
363 u16 fetch_data_word_abs(uint segment, uint offset)
366 if (CHECK_DATA_ACCESS())
367 x86emu_check_data_access(segment, offset);
369 return (*sys_rdw)(((u32) segment << 4) + offset);
382 u32 fetch_data_long_abs(uint segment, uint offset)
385 if (CHECK_DATA_ACCESS())
386 x86emu_check_data_access(segment, offset);
388 return (*sys_rdl)(((u32) segment << 4) + offset);
402 void store_data_byte(uint offset, u8 val)
405 if (CHECK_DATA_ACCESS())
406 x86emu_check_data_access((u16) get_data_segment(), offset);
408 (*sys_wrb)((get_data_segment() << 4) + offset, val);
422 void store_data_word(uint offset, u16 val)
425 if (CHECK_DATA_ACCESS())
426 x86emu_check_data_access((u16) get_data_segment(), offset);
428 (*sys_wrw)((get_data_segment() << 4) + offset, val);
442 void store_data_long(uint offset, u32 val)
445 if (CHECK_DATA_ACCESS())
446 x86emu_check_data_access((u16) get_data_segment(), offset);
448 (*sys_wrl)((get_data_segment() << 4) + offset, val);
462 void store_data_byte_abs(uint segment, uint offset, u8 val)
465 if (CHECK_DATA_ACCESS())
466 x86emu_check_data_access(segment, offset);
468 (*sys_wrb)(((u32) segment << 4) + offset, val);
482 void store_data_word_abs(uint segment, uint offset, u16 val)
485 if (CHECK_DATA_ACCESS())
486 x86emu_check_data_access(segment, offset);
488 (*sys_wrw)(((u32) segment << 4) + offset, val);
502 void store_data_long_abs(uint segment, uint offset, u32 val)
505 if (CHECK_DATA_ACCESS())
506 x86emu_check_data_access(segment, offset);
508 (*sys_wrl)(((u32) segment << 4) + offset, val);
522 u8 *decode_rm_byte_register(
int reg)
566 u16 *decode_rm_word_register(
int reg)
610 u32 *decode_rm_long_register(
int reg)
615 DECODE_PRINTF(
"EAX");
618 DECODE_PRINTF(
"ECX");
621 DECODE_PRINTF(
"EDX");
624 DECODE_PRINTF(
"EBX");
627 DECODE_PRINTF(
"ESP");
630 DECODE_PRINTF(
"EBP");
633 DECODE_PRINTF(
"ESI");
636 DECODE_PRINTF(
"EDI");
655 u16 *decode_rm_seg_register(
int reg)
679 DECODE_PRINTF(
"ILLEGAL SEGREG");
690 u32 decode_sib_address(
int sib,
int mod)
692 u32 base = 0, i = 0, scale = 1;
697 DECODE_PRINTF(
"[EAX]");
701 DECODE_PRINTF(
"[ECX]");
705 DECODE_PRINTF(
"[EDX]");
709 DECODE_PRINTF(
"[EBX]");
713 DECODE_PRINTF(
"[ESP]");
715 M.x86.mode |= SYSMODE_SEG_DS_SS;
720 base = fetch_long_imm();
721 DECODE_PRINTF2(
"%08x", base);
725 DECODE_PRINTF(
"[EBP]");
727 M.x86.mode |= SYSMODE_SEG_DS_SS;
731 DECODE_PRINTF(
"[ESI]");
735 DECODE_PRINTF(
"[EDI]");
739 switch ((sib >> 3) & 0x07)
742 DECODE_PRINTF(
"[EAX");
746 DECODE_PRINTF(
"[ECX");
750 DECODE_PRINTF(
"[EDX");
754 DECODE_PRINTF(
"[EBX");
761 DECODE_PRINTF(
"[EBP");
765 DECODE_PRINTF(
"[ESI");
769 DECODE_PRINTF(
"[EDI");
773 scale = 1 << ((sib >> 6) & 0x03);
774 if (((sib >> 3) & 0x07) != 4)
782 DECODE_PRINTF2(
"*%d]", scale);
785 return base + (i * scale);
808 u32 decode_rm00_address(
int rm)
813 if (M.x86.mode & SYSMODE_PREFIX_ADDR)
819 DECODE_PRINTF(
"[EAX]");
822 DECODE_PRINTF(
"[ECX]");
825 DECODE_PRINTF(
"[EDX]");
828 DECODE_PRINTF(
"[EBX]");
831 sib = fetch_byte_imm();
832 return decode_sib_address(sib, 0);
834 offset = fetch_long_imm();
835 DECODE_PRINTF2(
"[%08x]", offset);
838 DECODE_PRINTF(
"[ESI]");
841 DECODE_PRINTF(
"[EDI]");
852 DECODE_PRINTF(
"[BX+SI]");
853 return (M.x86.R_BX + M.x86.R_SI) & 0xffff;
855 DECODE_PRINTF(
"[BX+DI]");
856 return (M.x86.R_BX + M.x86.R_DI) & 0xffff;
858 DECODE_PRINTF(
"[BP+SI]");
859 M.x86.mode |= SYSMODE_SEG_DS_SS;
860 return (M.x86.R_BP + M.x86.R_SI) & 0xffff;
862 DECODE_PRINTF(
"[BP+DI]");
863 M.x86.mode |= SYSMODE_SEG_DS_SS;
864 return (M.x86.R_BP + M.x86.R_DI) & 0xffff;
866 DECODE_PRINTF(
"[SI]");
869 DECODE_PRINTF(
"[DI]");
872 offset = fetch_word_imm();
873 DECODE_PRINTF2(
"[%04x]", offset);
876 DECODE_PRINTF(
"[BX]");
895 u32 decode_rm01_address(
int rm)
897 int displacement = 0;
901 if (!((M.x86.mode & SYSMODE_PREFIX_ADDR) && (rm == 4)))
902 displacement = (s8) fetch_byte_imm();
904 if (M.x86.mode & SYSMODE_PREFIX_ADDR)
910 DECODE_PRINTF2(
"%d[EAX]", displacement);
911 return M.x86.R_EAX + displacement;
913 DECODE_PRINTF2(
"%d[ECX]", displacement);
914 return M.x86.R_ECX + displacement;
916 DECODE_PRINTF2(
"%d[EDX]", displacement);
917 return M.x86.R_EDX + displacement;
919 DECODE_PRINTF2(
"%d[EBX]", displacement);
920 return M.x86.R_EBX + displacement;
922 sib = fetch_byte_imm();
923 displacement = (s8) fetch_byte_imm();
924 DECODE_PRINTF2(
"%d", displacement);
925 return decode_sib_address(sib, 1) + displacement;
927 DECODE_PRINTF2(
"%d[EBP]", displacement);
928 return M.x86.R_EBP + displacement;
930 DECODE_PRINTF2(
"%d[ESI]", displacement);
931 return M.x86.R_ESI + displacement;
933 DECODE_PRINTF2(
"%d[EDI]", displacement);
934 return M.x86.R_EDI + displacement;
944 DECODE_PRINTF2(
"%d[BX+SI]", displacement);
945 return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
947 DECODE_PRINTF2(
"%d[BX+DI]", displacement);
948 return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
950 DECODE_PRINTF2(
"%d[BP+SI]", displacement);
951 M.x86.mode |= SYSMODE_SEG_DS_SS;
952 return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
954 DECODE_PRINTF2(
"%d[BP+DI]", displacement);
955 M.x86.mode |= SYSMODE_SEG_DS_SS;
956 return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
958 DECODE_PRINTF2(
"%d[SI]", displacement);
959 return (M.x86.R_SI + displacement) & 0xffff;
961 DECODE_PRINTF2(
"%d[DI]", displacement);
962 return (M.x86.R_DI + displacement) & 0xffff;
964 DECODE_PRINTF2(
"%d[BP]", displacement);
965 M.x86.mode |= SYSMODE_SEG_DS_SS;
966 return (M.x86.R_BP + displacement) & 0xffff;
968 DECODE_PRINTF2(
"%d[BX]", displacement);
969 return (M.x86.R_BX + displacement) & 0xffff;
987 u32 decode_rm10_address(
int rm)
989 u32 displacement = 0;
993 if (!(M.x86.mode & SYSMODE_PREFIX_ADDR))
994 displacement = (u16) fetch_word_imm();
999 displacement = (u32) fetch_long_imm();
1002 if (M.x86.mode & SYSMODE_PREFIX_ADDR)
1008 DECODE_PRINTF2(
"%08x[EAX]", displacement);
1009 return M.x86.R_EAX + displacement;
1011 DECODE_PRINTF2(
"%08x[ECX]", displacement);
1012 return M.x86.R_ECX + displacement;
1014 DECODE_PRINTF2(
"%08x[EDX]", displacement);
1015 M.x86.mode |= SYSMODE_SEG_DS_SS;
1016 return M.x86.R_EDX + displacement;
1018 DECODE_PRINTF2(
"%08x[EBX]", displacement);
1019 return M.x86.R_EBX + displacement;
1021 sib = fetch_byte_imm();
1022 displacement = (u32) fetch_long_imm();
1023 DECODE_PRINTF2(
"%08x", displacement);
1024 return decode_sib_address(sib, 2) + displacement;
1027 DECODE_PRINTF2(
"%08x[EBP]", displacement);
1028 return M.x86.R_EBP + displacement;
1030 DECODE_PRINTF2(
"%08x[ESI]", displacement);
1031 return M.x86.R_ESI + displacement;
1033 DECODE_PRINTF2(
"%08x[EDI]", displacement);
1034 return M.x86.R_EDI + displacement;
1044 DECODE_PRINTF2(
"%04x[BX+SI]", displacement);
1045 return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
1047 DECODE_PRINTF2(
"%04x[BX+DI]", displacement);
1048 return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
1050 DECODE_PRINTF2(
"%04x[BP+SI]", displacement);
1051 M.x86.mode |= SYSMODE_SEG_DS_SS;
1052 return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
1054 DECODE_PRINTF2(
"%04x[BP+DI]", displacement);
1055 M.x86.mode |= SYSMODE_SEG_DS_SS;
1056 return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
1058 DECODE_PRINTF2(
"%04x[SI]", displacement);
1059 return (M.x86.R_SI + displacement) & 0xffff;
1061 DECODE_PRINTF2(
"%04x[DI]", displacement);
1062 return (M.x86.R_DI + displacement) & 0xffff;
1064 DECODE_PRINTF2(
"%04x[BP]", displacement);
1065 M.x86.mode |= SYSMODE_SEG_DS_SS;
1066 return (M.x86.R_BP + displacement) & 0xffff;
1068 DECODE_PRINTF2(
"%04x[BX]", displacement);
1069 return (M.x86.R_BX + displacement) & 0xffff;