1 | /* $NetBSD: x86emu.h,v 1.1 2007/12/01 20:14:10 joerg Exp $ */ |
2 | |
3 | /**************************************************************************** |
4 | * |
5 | * Realmode X86 Emulator Library |
6 | * |
7 | * Copyright (C) 1996-1999 SciTech Software, Inc. |
8 | * Copyright (C) David Mosberger-Tang |
9 | * Copyright (C) 1999 Egbert Eich |
10 | * Copyright (C) 2007 Joerg Sonnenberger |
11 | * |
12 | * ======================================================================== |
13 | * |
14 | * Permission to use, copy, modify, distribute, and sell this software and |
15 | * its documentation for any purpose is hereby granted without fee, |
16 | * provided that the above copyright notice appear in all copies and that |
17 | * both that copyright notice and this permission notice appear in |
18 | * supporting documentation, and that the name of the authors not be used |
19 | * in advertising or publicity pertaining to distribution of the software |
20 | * without specific, written prior permission. The authors makes no |
21 | * representations about the suitability of this software for any purpose. |
22 | * It is provided "as is" without express or implied warranty. |
23 | * |
24 | * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
25 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO |
26 | * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
27 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF |
28 | * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR |
29 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
30 | * PERFORMANCE OF THIS SOFTWARE. |
31 | * |
32 | ****************************************************************************/ |
33 | |
34 | #ifndef __X86EMU_X86EMU_H |
35 | #define __X86EMU_X86EMU_H |
36 | |
37 | #include <sys/types.h> |
38 | #include <sys/endian.h> |
39 | |
40 | #ifdef _KERNEL |
41 | #include <sys/systm.h> |
42 | #else |
43 | #include <setjmp.h> |
44 | #endif |
45 | |
46 | /* |
47 | * General EAX, EBX, ECX, EDX type registers. Note that for |
48 | * portability, and speed, the issue of byte swapping is not addressed |
49 | * in the registers. All registers are stored in the default format |
50 | * available on the host machine. The only critical issue is that the |
51 | * registers should line up EXACTLY in the same manner as they do in |
52 | * the 386. That is: |
53 | * |
54 | * EAX & 0xff === AL |
55 | * EAX & 0xffff == AX |
56 | * |
57 | * etc. The result is that alot of the calculations can then be |
58 | * done using the native instruction set fully. |
59 | */ |
60 | |
61 | #ifdef __BIG_ENDIAN__ |
62 | |
63 | struct X86EMU_register32 { |
64 | uint32_t e_reg; |
65 | }; |
66 | |
67 | struct X86EMU_register16 { |
68 | uint16_t filler0; |
69 | uint16_t x_reg; |
70 | }; |
71 | |
72 | struct X86EMU_register8 { |
73 | uint8_t filler0, filler1; |
74 | uint8_t h_reg, l_reg; |
75 | }; |
76 | |
77 | #else /* !__BIG_ENDIAN__ */ |
78 | |
79 | struct X86EMU_register32 { |
80 | uint32_t e_reg; |
81 | }; |
82 | |
83 | struct X86EMU_register16 { |
84 | uint16_t x_reg; |
85 | }; |
86 | |
87 | struct X86EMU_register8 { |
88 | uint8_t l_reg, h_reg; |
89 | }; |
90 | |
91 | #endif /* BIG_ENDIAN */ |
92 | |
93 | union X86EMU_register { |
94 | struct X86EMU_register32 I32_reg; |
95 | struct X86EMU_register16 I16_reg; |
96 | struct X86EMU_register8 I8_reg; |
97 | }; |
98 | |
99 | struct X86EMU_regs { |
100 | uint16_t register_cs; |
101 | uint16_t register_ds; |
102 | uint16_t register_es; |
103 | uint16_t register_fs; |
104 | uint16_t register_gs; |
105 | uint16_t register_ss; |
106 | uint32_t register_flags; |
107 | union X86EMU_register register_a; |
108 | union X86EMU_register register_b; |
109 | union X86EMU_register register_c; |
110 | union X86EMU_register register_d; |
111 | |
112 | union X86EMU_register register_sp; |
113 | union X86EMU_register register_bp; |
114 | union X86EMU_register register_si; |
115 | union X86EMU_register register_di; |
116 | union X86EMU_register register_ip; |
117 | |
118 | /* |
119 | * MODE contains information on: |
120 | * REPE prefix 2 bits repe,repne |
121 | * SEGMENT overrides 5 bits normal,DS,SS,CS,ES |
122 | * Delayed flag set 3 bits (zero, signed, parity) |
123 | * reserved 6 bits |
124 | * interrupt # 8 bits instruction raised interrupt |
125 | * BIOS video segregs 4 bits |
126 | * Interrupt Pending 1 bits |
127 | * Extern interrupt 1 bits |
128 | * Halted 1 bits |
129 | */ |
130 | uint32_t mode; |
131 | volatile int intr; /* mask of pending interrupts */ |
132 | uint8_t intno; |
133 | uint8_t __pad[3]; |
134 | }; |
135 | |
136 | struct X86EMU { |
137 | char *mem_base; |
138 | size_t mem_size; |
139 | void *sys_private; |
140 | struct X86EMU_regs x86; |
141 | |
142 | #ifdef _KERNEL |
143 | label_t exec_state; |
144 | #else |
145 | jmp_buf exec_state; |
146 | #endif |
147 | |
148 | uint64_t cur_cycles; |
149 | |
150 | unsigned int cur_mod:2; |
151 | unsigned int cur_rl:3; |
152 | unsigned int cur_rh:3; |
153 | uint32_t cur_offset; |
154 | |
155 | uint8_t (*emu_rdb)(struct X86EMU *, uint32_t addr); |
156 | uint16_t (*emu_rdw)(struct X86EMU *, uint32_t addr); |
157 | uint32_t (*emu_rdl)(struct X86EMU *, uint32_t addr); |
158 | void (*emu_wrb)(struct X86EMU *, uint32_t addr,uint8_t val); |
159 | void (*emu_wrw)(struct X86EMU *, uint32_t addr, uint16_t val); |
160 | void (*emu_wrl)(struct X86EMU *, uint32_t addr, uint32_t val); |
161 | |
162 | uint8_t (*emu_inb)(struct X86EMU *, uint16_t addr); |
163 | uint16_t (*emu_inw)(struct X86EMU *, uint16_t addr); |
164 | uint32_t (*emu_inl)(struct X86EMU *, uint16_t addr); |
165 | void (*emu_outb)(struct X86EMU *, uint16_t addr, uint8_t val); |
166 | void (*emu_outw)(struct X86EMU *, uint16_t addr, uint16_t val); |
167 | void (*emu_outl)(struct X86EMU *, uint16_t addr, uint32_t val); |
168 | |
169 | void (*_X86EMU_intrTab[256])(struct X86EMU *, int); |
170 | }; |
171 | |
172 | __BEGIN_DECLS |
173 | |
174 | void X86EMU_init_default(struct X86EMU *); |
175 | |
176 | /* decode.c */ |
177 | |
178 | void X86EMU_exec(struct X86EMU *); |
179 | void X86EMU_exec_call(struct X86EMU *, uint16_t, uint16_t); |
180 | void X86EMU_exec_intr(struct X86EMU *, uint8_t); |
181 | void X86EMU_halt_sys(struct X86EMU *) __dead; |
182 | |
183 | __END_DECLS |
184 | |
185 | #endif /* __X86EMU_X86EMU_H */ |
186 | |