Statistics
| Branch: | Revision:

root / cpu-i386.h @ 2c1794c4

History | View | Annotate | Download (8.6 kB)

1 3ef693a0 bellard
/*
2 3ef693a0 bellard
 * i386 virtual CPU header
3 3ef693a0 bellard
 * 
4 3ef693a0 bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 3ef693a0 bellard
 *
6 3ef693a0 bellard
 * This library is free software; you can redistribute it and/or
7 3ef693a0 bellard
 * modify it under the terms of the GNU Lesser General Public
8 3ef693a0 bellard
 * License as published by the Free Software Foundation; either
9 3ef693a0 bellard
 * version 2 of the License, or (at your option) any later version.
10 3ef693a0 bellard
 *
11 3ef693a0 bellard
 * This library is distributed in the hope that it will be useful,
12 3ef693a0 bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 3ef693a0 bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 3ef693a0 bellard
 * Lesser General Public License for more details.
15 3ef693a0 bellard
 *
16 3ef693a0 bellard
 * You should have received a copy of the GNU Lesser General Public
17 3ef693a0 bellard
 * License along with this library; if not, write to the Free Software
18 3ef693a0 bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 0ecfa993 bellard
 */
20 367e86e8 bellard
#ifndef CPU_I386_H
21 367e86e8 bellard
#define CPU_I386_H
22 367e86e8 bellard
23 04369ff2 bellard
#include "config.h"
24 0ecfa993 bellard
#include <setjmp.h>
25 0ecfa993 bellard
26 367e86e8 bellard
#define R_EAX 0
27 367e86e8 bellard
#define R_ECX 1
28 367e86e8 bellard
#define R_EDX 2
29 367e86e8 bellard
#define R_EBX 3
30 367e86e8 bellard
#define R_ESP 4
31 367e86e8 bellard
#define R_EBP 5
32 367e86e8 bellard
#define R_ESI 6
33 367e86e8 bellard
#define R_EDI 7
34 367e86e8 bellard
35 367e86e8 bellard
#define R_AL 0
36 367e86e8 bellard
#define R_CL 1
37 367e86e8 bellard
#define R_DL 2
38 367e86e8 bellard
#define R_BL 3
39 367e86e8 bellard
#define R_AH 4
40 367e86e8 bellard
#define R_CH 5
41 367e86e8 bellard
#define R_DH 6
42 367e86e8 bellard
#define R_BH 7
43 367e86e8 bellard
44 367e86e8 bellard
#define R_ES 0
45 367e86e8 bellard
#define R_CS 1
46 367e86e8 bellard
#define R_SS 2
47 367e86e8 bellard
#define R_DS 3
48 367e86e8 bellard
#define R_FS 4
49 367e86e8 bellard
#define R_GS 5
50 367e86e8 bellard
51 aad13cd1 bellard
/* segment descriptor fields */
52 aad13cd1 bellard
#define DESC_G_MASK     (1 << 23)
53 66e85a21 bellard
#define DESC_B_SHIFT    22
54 66e85a21 bellard
#define DESC_B_MASK     (1 << DESC_B_SHIFT)
55 aad13cd1 bellard
#define DESC_AVL_MASK   (1 << 20)
56 aad13cd1 bellard
#define DESC_P_MASK     (1 << 15)
57 aad13cd1 bellard
#define DESC_DPL_SHIFT  13
58 aad13cd1 bellard
#define DESC_S_MASK     (1 << 12)
59 aad13cd1 bellard
#define DESC_TYPE_SHIFT 8
60 aad13cd1 bellard
#define DESC_A_MASK     (1 << 8)
61 aad13cd1 bellard
62 aad13cd1 bellard
#define DESC_CS_MASK    (1 << 11)
63 aad13cd1 bellard
#define DESC_C_MASK     (1 << 10)
64 aad13cd1 bellard
#define DESC_R_MASK     (1 << 9)
65 aad13cd1 bellard
66 aad13cd1 bellard
#define DESC_E_MASK     (1 << 10)
67 aad13cd1 bellard
#define DESC_W_MASK     (1 << 9)
68 aad13cd1 bellard
69 fc2b4c48 bellard
/* eflags masks */
70 367e86e8 bellard
#define CC_C           0x0001
71 367e86e8 bellard
#define CC_P         0x0004
72 367e86e8 bellard
#define CC_A        0x0010
73 367e86e8 bellard
#define CC_Z        0x0040
74 367e86e8 bellard
#define CC_S    0x0080
75 367e86e8 bellard
#define CC_O    0x0800
76 367e86e8 bellard
77 fc2b4c48 bellard
#define TF_MASK                 0x00000100
78 fc2b4c48 bellard
#define IF_MASK                 0x00000200
79 fc2b4c48 bellard
#define DF_MASK                 0x00000400
80 fc2b4c48 bellard
#define IOPL_MASK                0x00003000
81 fc2b4c48 bellard
#define NT_MASK                         0x00004000
82 fc2b4c48 bellard
#define RF_MASK                        0x00010000
83 fc2b4c48 bellard
#define VM_MASK                        0x00020000
84 fc2b4c48 bellard
#define AC_MASK                        0x00040000 
85 fc2b4c48 bellard
#define VIF_MASK                0x00080000
86 fc2b4c48 bellard
#define VIP_MASK                0x00100000
87 fc2b4c48 bellard
#define ID_MASK                 0x00200000
88 367e86e8 bellard
89 13b55754 bellard
#define CR0_PE_MASK  (1 << 0)
90 13b55754 bellard
#define CR0_TS_MASK  (1 << 3)
91 13b55754 bellard
#define CR0_WP_MASK  (1 << 16)
92 13b55754 bellard
#define CR0_AM_MASK  (1 << 18)
93 13b55754 bellard
#define CR0_PG_MASK  (1 << 31)
94 13b55754 bellard
95 13b55754 bellard
#define CR4_VME_MASK  (1 << 0)
96 13b55754 bellard
#define CR4_PVI_MASK  (1 << 1)
97 13b55754 bellard
#define CR4_TSD_MASK  (1 << 2)
98 13b55754 bellard
#define CR4_DE_MASK   (1 << 3)
99 66e85a21 bellard
#define CR4_PSE_MASK  (1 << 4)
100 66e85a21 bellard
101 66e85a21 bellard
#define PG_PRESENT_BIT        0
102 66e85a21 bellard
#define PG_RW_BIT        1
103 66e85a21 bellard
#define PG_USER_BIT        2
104 66e85a21 bellard
#define PG_PWT_BIT        3
105 66e85a21 bellard
#define PG_PCD_BIT        4
106 66e85a21 bellard
#define PG_ACCESSED_BIT        5
107 66e85a21 bellard
#define PG_DIRTY_BIT        6
108 66e85a21 bellard
#define PG_PSE_BIT        7
109 66e85a21 bellard
#define PG_GLOBAL_BIT        8
110 66e85a21 bellard
111 66e85a21 bellard
#define PG_PRESENT_MASK  (1 << PG_PRESENT_BIT)
112 66e85a21 bellard
#define PG_RW_MASK         (1 << PG_RW_BIT)
113 66e85a21 bellard
#define PG_USER_MASK         (1 << PG_USER_BIT)
114 66e85a21 bellard
#define PG_PWT_MASK         (1 << PG_PWT_BIT)
115 66e85a21 bellard
#define PG_PCD_MASK         (1 << PG_PCD_BIT)
116 66e85a21 bellard
#define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)
117 66e85a21 bellard
#define PG_DIRTY_MASK         (1 << PG_DIRTY_BIT)
118 66e85a21 bellard
#define PG_PSE_MASK         (1 << PG_PSE_BIT)
119 66e85a21 bellard
#define PG_GLOBAL_MASK         (1 << PG_GLOBAL_BIT)
120 66e85a21 bellard
121 66e85a21 bellard
#define PG_ERROR_W_BIT     1
122 66e85a21 bellard
123 66e85a21 bellard
#define PG_ERROR_P_MASK    0x01
124 66e85a21 bellard
#define PG_ERROR_W_MASK    (1 << PG_ERROR_W_BIT)
125 66e85a21 bellard
#define PG_ERROR_U_MASK    0x04
126 66e85a21 bellard
#define PG_ERROR_RSVD_MASK 0x08
127 13b55754 bellard
128 3c1cf9fa bellard
#define MSR_IA32_APICBASE               0x1b
129 3c1cf9fa bellard
#define MSR_IA32_APICBASE_BSP           (1<<8)
130 3c1cf9fa bellard
#define MSR_IA32_APICBASE_ENABLE        (1<<11)
131 3c1cf9fa bellard
#define MSR_IA32_APICBASE_BASE          (0xfffff<<12)
132 3c1cf9fa bellard
133 3c1cf9fa bellard
#define MSR_IA32_SYSENTER_CS            0x174
134 3c1cf9fa bellard
#define MSR_IA32_SYSENTER_ESP           0x175
135 3c1cf9fa bellard
#define MSR_IA32_SYSENTER_EIP           0x176
136 3c1cf9fa bellard
137 bc8a22cc bellard
#define EXCP00_DIVZ        0
138 bc8a22cc bellard
#define EXCP01_SSTP        1
139 bc8a22cc bellard
#define EXCP02_NMI        2
140 bc8a22cc bellard
#define EXCP03_INT3        3
141 bc8a22cc bellard
#define EXCP04_INTO        4
142 bc8a22cc bellard
#define EXCP05_BOUND        5
143 bc8a22cc bellard
#define EXCP06_ILLOP        6
144 bc8a22cc bellard
#define EXCP07_PREX        7
145 bc8a22cc bellard
#define EXCP08_DBLE        8
146 bc8a22cc bellard
#define EXCP09_XERR        9
147 bc8a22cc bellard
#define EXCP0A_TSS        10
148 bc8a22cc bellard
#define EXCP0B_NOSEG        11
149 bc8a22cc bellard
#define EXCP0C_STACK        12
150 bc8a22cc bellard
#define EXCP0D_GPF        13
151 bc8a22cc bellard
#define EXCP0E_PAGE        14
152 bc8a22cc bellard
#define EXCP10_COPR        16
153 bc8a22cc bellard
#define EXCP11_ALGN        17
154 bc8a22cc bellard
#define EXCP12_MCHK        18
155 0ecfa993 bellard
156 9de5e440 bellard
#define EXCP_INTERRUPT         256 /* async interruption */
157 66e85a21 bellard
#define EXCP_HLT        257 /* hlt instruction reached */
158 4c3a88a2 bellard
#define EXCP_DEBUG      258 /* cpu stopped after a breakpoint or singlestep */
159 4c3a88a2 bellard
160 4c3a88a2 bellard
#define MAX_BREAKPOINTS 32
161 0ecfa993 bellard
162 367e86e8 bellard
enum {
163 367e86e8 bellard
    CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
164 367e86e8 bellard
    CC_OP_EFLAGS,  /* all cc are explicitely computed, CC_SRC = flags */
165 367e86e8 bellard
    CC_OP_MUL, /* modify all flags, C, O = (CC_SRC != 0) */
166 367e86e8 bellard
167 367e86e8 bellard
    CC_OP_ADDB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
168 367e86e8 bellard
    CC_OP_ADDW,
169 367e86e8 bellard
    CC_OP_ADDL,
170 367e86e8 bellard
171 4b74fe1f bellard
    CC_OP_ADCB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
172 4b74fe1f bellard
    CC_OP_ADCW,
173 4b74fe1f bellard
    CC_OP_ADCL,
174 4b74fe1f bellard
175 367e86e8 bellard
    CC_OP_SUBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
176 367e86e8 bellard
    CC_OP_SUBW,
177 367e86e8 bellard
    CC_OP_SUBL,
178 367e86e8 bellard
179 4b74fe1f bellard
    CC_OP_SBBB, /* modify all flags, CC_DST = res, CC_SRC = src1 */
180 4b74fe1f bellard
    CC_OP_SBBW,
181 4b74fe1f bellard
    CC_OP_SBBL,
182 4b74fe1f bellard
183 367e86e8 bellard
    CC_OP_LOGICB, /* modify all flags, CC_DST = res */
184 367e86e8 bellard
    CC_OP_LOGICW,
185 367e86e8 bellard
    CC_OP_LOGICL,
186 367e86e8 bellard
187 4b74fe1f bellard
    CC_OP_INCB, /* modify all flags except, CC_DST = res, CC_SRC = C */
188 367e86e8 bellard
    CC_OP_INCW,
189 367e86e8 bellard
    CC_OP_INCL,
190 367e86e8 bellard
191 4b74fe1f bellard
    CC_OP_DECB, /* modify all flags except, CC_DST = res, CC_SRC = C  */
192 367e86e8 bellard
    CC_OP_DECW,
193 367e86e8 bellard
    CC_OP_DECL,
194 367e86e8 bellard
195 367e86e8 bellard
    CC_OP_SHLB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */
196 367e86e8 bellard
    CC_OP_SHLW,
197 367e86e8 bellard
    CC_OP_SHLL,
198 367e86e8 bellard
199 4b74fe1f bellard
    CC_OP_SARB, /* modify all flags, CC_DST = res, CC_SRC.lsb = C */
200 4b74fe1f bellard
    CC_OP_SARW,
201 4b74fe1f bellard
    CC_OP_SARL,
202 4b74fe1f bellard
203 367e86e8 bellard
    CC_OP_NB,
204 367e86e8 bellard
};
205 367e86e8 bellard
206 927f621e bellard
#ifdef __i386__
207 27362c82 bellard
#define USE_X86LDOUBLE
208 927f621e bellard
#endif
209 927f621e bellard
210 927f621e bellard
#ifdef USE_X86LDOUBLE
211 927f621e bellard
typedef long double CPU86_LDouble;
212 927f621e bellard
#else
213 927f621e bellard
typedef double CPU86_LDouble;
214 927f621e bellard
#endif
215 927f621e bellard
216 6dbad63e bellard
typedef struct SegmentCache {
217 13b55754 bellard
    uint32_t selector;
218 6dbad63e bellard
    uint8_t *base;
219 66e85a21 bellard
    uint32_t limit;
220 66e85a21 bellard
    uint32_t flags;
221 6dbad63e bellard
} SegmentCache;
222 6dbad63e bellard
223 ba1c6e37 bellard
typedef struct CPUX86State {
224 367e86e8 bellard
    /* standard registers */
225 367e86e8 bellard
    uint32_t regs[8];
226 dab2ed99 bellard
    uint32_t eip;
227 fc2b4c48 bellard
    uint32_t eflags; /* eflags register. During CPU emulation, CC
228 fc2b4c48 bellard
                        flags and DF are set to zero because they are
229 d34720fd bellard
                        stored elsewhere */
230 0ecfa993 bellard
231 0ecfa993 bellard
    /* emulator internal eflags handling */
232 367e86e8 bellard
    uint32_t cc_src;
233 367e86e8 bellard
    uint32_t cc_dst;
234 367e86e8 bellard
    uint32_t cc_op;
235 367e86e8 bellard
    int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
236 0ecfa993 bellard
237 927f621e bellard
    /* FPU state */
238 927f621e bellard
    unsigned int fpstt; /* top of stack index */
239 927f621e bellard
    unsigned int fpus;
240 927f621e bellard
    unsigned int fpuc;
241 0ecfa993 bellard
    uint8_t fptags[8];   /* 0 = valid, 1 = empty */
242 0ecfa993 bellard
    CPU86_LDouble fpregs[8];    
243 0ecfa993 bellard
244 367e86e8 bellard
    /* emulator internal variables */
245 927f621e bellard
    CPU86_LDouble ft0;
246 d014c98c bellard
    union {
247 d014c98c bellard
        float f;
248 d014c98c bellard
        double d;
249 d014c98c bellard
        int i32;
250 d014c98c bellard
        int64_t i64;
251 d014c98c bellard
    } fp_convert;
252 d57c4e01 bellard
    
253 6dbad63e bellard
    /* segments */
254 13b55754 bellard
    SegmentCache segs[6]; /* selector values */
255 13b55754 bellard
    SegmentCache ldt;
256 13b55754 bellard
    SegmentCache tr;
257 13b55754 bellard
    SegmentCache gdt; /* only base and limit are used */
258 13b55754 bellard
    SegmentCache idt; /* only base and limit are used */
259 3c1cf9fa bellard
260 3c1cf9fa bellard
    /* sysenter registers */
261 3c1cf9fa bellard
    uint32_t sysenter_cs;
262 3c1cf9fa bellard
    uint32_t sysenter_esp;
263 3c1cf9fa bellard
    uint32_t sysenter_eip;
264 6dbad63e bellard
    
265 9de5e440 bellard
    /* exception/interrupt handling */
266 0ecfa993 bellard
    jmp_buf jmp_env;
267 0ecfa993 bellard
    int exception_index;
268 9ba5695c bellard
    int error_code;
269 66e85a21 bellard
    int exception_is_int;
270 66e85a21 bellard
    int exception_next_eip;
271 ea041c0e bellard
    struct TranslationBlock *current_tb; /* currently executing TB */
272 13b55754 bellard
    uint32_t cr[5]; /* NOTE: cr1 is unused */
273 13b55754 bellard
    uint32_t dr[8]; /* debug registers */
274 68a79315 bellard
    int interrupt_request; 
275 66e85a21 bellard
    int user_mode_only; /* user mode only simulation */
276 4c3a88a2 bellard
277 4c3a88a2 bellard
    uint32_t breakpoints[MAX_BREAKPOINTS];
278 4c3a88a2 bellard
    int nb_breakpoints;
279 ea041c0e bellard
    
280 fc2b4c48 bellard
    /* user data */
281 fc2b4c48 bellard
    void *opaque;
282 ba1c6e37 bellard
} CPUX86State;
283 367e86e8 bellard
284 927f621e bellard
#ifndef IN_OP_I386
285 9ba5695c bellard
void cpu_x86_outb(CPUX86State *env, int addr, int val);
286 9ba5695c bellard
void cpu_x86_outw(CPUX86State *env, int addr, int val);
287 9ba5695c bellard
void cpu_x86_outl(CPUX86State *env, int addr, int val);
288 9ba5695c bellard
int cpu_x86_inb(CPUX86State *env, int addr);
289 9ba5695c bellard
int cpu_x86_inw(CPUX86State *env, int addr);
290 9ba5695c bellard
int cpu_x86_inl(CPUX86State *env, int addr);
291 927f621e bellard
#endif
292 367e86e8 bellard
293 ba1c6e37 bellard
CPUX86State *cpu_x86_init(void);
294 ba1c6e37 bellard
int cpu_x86_exec(CPUX86State *s);
295 ba1c6e37 bellard
void cpu_x86_close(CPUX86State *s);
296 66e85a21 bellard
int cpu_x86_get_pic_interrupt(CPUX86State *s);
297 ba1c6e37 bellard
298 6dbad63e bellard
/* needed to load some predefinied segment registers */
299 6dbad63e bellard
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector);
300 6dbad63e bellard
301 d0a1ffc9 bellard
/* simulate fsave/frstor */
302 d0a1ffc9 bellard
void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32);
303 d0a1ffc9 bellard
void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32);
304 d0a1ffc9 bellard
305 d691f669 bellard
/* you can call this signal handler from your SIGBUS and SIGSEGV
306 9de5e440 bellard
   signal handlers to inform the virtual CPU of exceptions. non zero
307 9de5e440 bellard
   is returned if the signal was handled by the virtual CPU.  */
308 9de5e440 bellard
struct siginfo;
309 9de5e440 bellard
int cpu_x86_signal_handler(int host_signum, struct siginfo *info, 
310 9de5e440 bellard
                           void *puc);
311 9de5e440 bellard
312 66e85a21 bellard
/* MMU defines */
313 66e85a21 bellard
void cpu_x86_init_mmu(CPUX86State *env);
314 66e85a21 bellard
extern int phys_ram_size;
315 66e85a21 bellard
extern int phys_ram_fd;
316 66e85a21 bellard
extern uint8_t *phys_ram_base;
317 66e85a21 bellard
318 f351077e bellard
/* used to debug */
319 f351077e bellard
#define X86_DUMP_FPU  0x0001 /* dump FPU state too */
320 f351077e bellard
#define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
321 f351077e bellard
void cpu_x86_dump_state(CPUX86State *env, FILE *f, int flags);
322 f351077e bellard
323 54936004 bellard
#define TARGET_PAGE_BITS 12
324 5a9fdfec bellard
#include "cpu-all.h"
325 54936004 bellard
326 367e86e8 bellard
#endif /* CPU_I386_H */