Commit 66e85a21c7f65540ac1976ed29ed9973089fe1f1
1 parent
90a9fdae
MMU support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@262 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
86 additions
and
8 deletions
cpu-i386.h
@@ -50,7 +50,8 @@ | @@ -50,7 +50,8 @@ | ||
50 | 50 | ||
51 | /* segment descriptor fields */ | 51 | /* segment descriptor fields */ |
52 | #define DESC_G_MASK (1 << 23) | 52 | #define DESC_G_MASK (1 << 23) |
53 | -#define DESC_B_MASK (1 << 22) | 53 | +#define DESC_B_SHIFT 22 |
54 | +#define DESC_B_MASK (1 << DESC_B_SHIFT) | ||
54 | #define DESC_AVL_MASK (1 << 20) | 55 | #define DESC_AVL_MASK (1 << 20) |
55 | #define DESC_P_MASK (1 << 15) | 56 | #define DESC_P_MASK (1 << 15) |
56 | #define DESC_DPL_SHIFT 13 | 57 | #define DESC_DPL_SHIFT 13 |
@@ -95,6 +96,34 @@ | @@ -95,6 +96,34 @@ | ||
95 | #define CR4_PVI_MASK (1 << 1) | 96 | #define CR4_PVI_MASK (1 << 1) |
96 | #define CR4_TSD_MASK (1 << 2) | 97 | #define CR4_TSD_MASK (1 << 2) |
97 | #define CR4_DE_MASK (1 << 3) | 98 | #define CR4_DE_MASK (1 << 3) |
99 | +#define CR4_PSE_MASK (1 << 4) | ||
100 | + | ||
101 | +#define PG_PRESENT_BIT 0 | ||
102 | +#define PG_RW_BIT 1 | ||
103 | +#define PG_USER_BIT 2 | ||
104 | +#define PG_PWT_BIT 3 | ||
105 | +#define PG_PCD_BIT 4 | ||
106 | +#define PG_ACCESSED_BIT 5 | ||
107 | +#define PG_DIRTY_BIT 6 | ||
108 | +#define PG_PSE_BIT 7 | ||
109 | +#define PG_GLOBAL_BIT 8 | ||
110 | + | ||
111 | +#define PG_PRESENT_MASK (1 << PG_PRESENT_BIT) | ||
112 | +#define PG_RW_MASK (1 << PG_RW_BIT) | ||
113 | +#define PG_USER_MASK (1 << PG_USER_BIT) | ||
114 | +#define PG_PWT_MASK (1 << PG_PWT_BIT) | ||
115 | +#define PG_PCD_MASK (1 << PG_PCD_BIT) | ||
116 | +#define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT) | ||
117 | +#define PG_DIRTY_MASK (1 << PG_DIRTY_BIT) | ||
118 | +#define PG_PSE_MASK (1 << PG_PSE_BIT) | ||
119 | +#define PG_GLOBAL_MASK (1 << PG_GLOBAL_BIT) | ||
120 | + | ||
121 | +#define PG_ERROR_W_BIT 1 | ||
122 | + | ||
123 | +#define PG_ERROR_P_MASK 0x01 | ||
124 | +#define PG_ERROR_W_MASK (1 << PG_ERROR_W_BIT) | ||
125 | +#define PG_ERROR_U_MASK 0x04 | ||
126 | +#define PG_ERROR_RSVD_MASK 0x08 | ||
98 | 127 | ||
99 | #define EXCP00_DIVZ 0 | 128 | #define EXCP00_DIVZ 0 |
100 | #define EXCP01_SSTP 1 | 129 | #define EXCP01_SSTP 1 |
@@ -116,6 +145,7 @@ | @@ -116,6 +145,7 @@ | ||
116 | #define EXCP12_MCHK 18 | 145 | #define EXCP12_MCHK 18 |
117 | 146 | ||
118 | #define EXCP_INTERRUPT 256 /* async interruption */ | 147 | #define EXCP_INTERRUPT 256 /* async interruption */ |
148 | +#define EXCP_HLT 257 /* hlt instruction reached */ | ||
119 | 149 | ||
120 | enum { | 150 | enum { |
121 | CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */ | 151 | CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */ |
@@ -174,8 +204,8 @@ typedef double CPU86_LDouble; | @@ -174,8 +204,8 @@ typedef double CPU86_LDouble; | ||
174 | typedef struct SegmentCache { | 204 | typedef struct SegmentCache { |
175 | uint32_t selector; | 205 | uint32_t selector; |
176 | uint8_t *base; | 206 | uint8_t *base; |
177 | - unsigned long limit; | ||
178 | - uint8_t seg_32bit; | 207 | + uint32_t limit; |
208 | + uint32_t flags; | ||
179 | } SegmentCache; | 209 | } SegmentCache; |
180 | 210 | ||
181 | typedef struct CPUX86State { | 211 | typedef struct CPUX86State { |
@@ -219,9 +249,16 @@ typedef struct CPUX86State { | @@ -219,9 +249,16 @@ typedef struct CPUX86State { | ||
219 | jmp_buf jmp_env; | 249 | jmp_buf jmp_env; |
220 | int exception_index; | 250 | int exception_index; |
221 | int error_code; | 251 | int error_code; |
252 | + int exception_is_int; | ||
253 | + int exception_next_eip; | ||
254 | + | ||
222 | uint32_t cr[5]; /* NOTE: cr1 is unused */ | 255 | uint32_t cr[5]; /* NOTE: cr1 is unused */ |
223 | uint32_t dr[8]; /* debug registers */ | 256 | uint32_t dr[8]; /* debug registers */ |
224 | - int interrupt_request; | 257 | + int interrupt_request; /* if true, will exit from cpu_exec() ASAP */ |
258 | + /* if true, will call cpu_x86_get_pic_interrupt() ASAP to get the | ||
259 | + request interrupt number */ | ||
260 | + int hard_interrupt_request; | ||
261 | + int user_mode_only; /* user mode only simulation */ | ||
225 | 262 | ||
226 | /* user data */ | 263 | /* user data */ |
227 | void *opaque; | 264 | void *opaque; |
@@ -240,6 +277,7 @@ CPUX86State *cpu_x86_init(void); | @@ -240,6 +277,7 @@ CPUX86State *cpu_x86_init(void); | ||
240 | int cpu_x86_exec(CPUX86State *s); | 277 | int cpu_x86_exec(CPUX86State *s); |
241 | void cpu_x86_interrupt(CPUX86State *s); | 278 | void cpu_x86_interrupt(CPUX86State *s); |
242 | void cpu_x86_close(CPUX86State *s); | 279 | void cpu_x86_close(CPUX86State *s); |
280 | +int cpu_x86_get_pic_interrupt(CPUX86State *s); | ||
243 | 281 | ||
244 | /* needed to load some predefinied segment registers */ | 282 | /* needed to load some predefinied segment registers */ |
245 | void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector); | 283 | void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector); |
@@ -255,6 +293,13 @@ struct siginfo; | @@ -255,6 +293,13 @@ struct siginfo; | ||
255 | int cpu_x86_signal_handler(int host_signum, struct siginfo *info, | 293 | int cpu_x86_signal_handler(int host_signum, struct siginfo *info, |
256 | void *puc); | 294 | void *puc); |
257 | 295 | ||
296 | +/* MMU defines */ | ||
297 | +void cpu_x86_init_mmu(CPUX86State *env); | ||
298 | +extern CPUX86State *global_env; | ||
299 | +extern int phys_ram_size; | ||
300 | +extern int phys_ram_fd; | ||
301 | +extern uint8_t *phys_ram_base; | ||
302 | + | ||
258 | /* used to debug */ | 303 | /* used to debug */ |
259 | #define X86_DUMP_FPU 0x0001 /* dump FPU state too */ | 304 | #define X86_DUMP_FPU 0x0001 /* dump FPU state too */ |
260 | #define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */ | 305 | #define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */ |
exec.c
@@ -30,7 +30,7 @@ | @@ -30,7 +30,7 @@ | ||
30 | #include "exec.h" | 30 | #include "exec.h" |
31 | 31 | ||
32 | //#define DEBUG_TB_INVALIDATE | 32 | //#define DEBUG_TB_INVALIDATE |
33 | -#define DEBUG_FLUSH | 33 | +//#define DEBUG_FLUSH |
34 | 34 | ||
35 | /* make various TB consistency checks */ | 35 | /* make various TB consistency checks */ |
36 | //#define DEBUG_TB_CHECK | 36 | //#define DEBUG_TB_CHECK |
@@ -579,3 +579,33 @@ void cpu_abort(CPUState *env, const char *fmt, ...) | @@ -579,3 +579,33 @@ void cpu_abort(CPUState *env, const char *fmt, ...) | ||
579 | abort(); | 579 | abort(); |
580 | } | 580 | } |
581 | 581 | ||
582 | +#ifdef TARGET_I386 | ||
583 | +/* unmap all maped pages and flush all associated code */ | ||
584 | +void page_unmap(void) | ||
585 | +{ | ||
586 | + PageDesc *p, *pmap; | ||
587 | + unsigned long addr; | ||
588 | + int i, j, ret; | ||
589 | + | ||
590 | + for(i = 0; i < L1_SIZE; i++) { | ||
591 | + pmap = l1_map[i]; | ||
592 | + if (pmap) { | ||
593 | + p = pmap; | ||
594 | + for(j = 0;j < L2_SIZE; j++) { | ||
595 | + if (p->flags & PAGE_VALID) { | ||
596 | + addr = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS); | ||
597 | + ret = munmap((void *)addr, TARGET_PAGE_SIZE); | ||
598 | + if (ret != 0) { | ||
599 | + fprintf(stderr, "Could not unmap page 0x%08lx\n", addr); | ||
600 | + exit(1); | ||
601 | + } | ||
602 | + } | ||
603 | + p++; | ||
604 | + } | ||
605 | + free(pmap); | ||
606 | + l1_map[i] = NULL; | ||
607 | + } | ||
608 | + } | ||
609 | + tb_flush(); | ||
610 | +} | ||
611 | +#endif |
exec.h
@@ -39,6 +39,7 @@ struct TranslationBlock; | @@ -39,6 +39,7 @@ struct TranslationBlock; | ||
39 | extern uint16_t gen_opc_buf[OPC_BUF_SIZE]; | 39 | extern uint16_t gen_opc_buf[OPC_BUF_SIZE]; |
40 | extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE]; | 40 | extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE]; |
41 | extern uint32_t gen_opc_pc[OPC_BUF_SIZE]; | 41 | extern uint32_t gen_opc_pc[OPC_BUF_SIZE]; |
42 | +extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; | ||
42 | extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; | 43 | extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; |
43 | 44 | ||
44 | #if defined(TARGET_I386) | 45 | #if defined(TARGET_I386) |
@@ -57,14 +58,16 @@ extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; | @@ -57,14 +58,16 @@ extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; | ||
57 | extern FILE *logfile; | 58 | extern FILE *logfile; |
58 | extern int loglevel; | 59 | extern int loglevel; |
59 | 60 | ||
60 | -int gen_intermediate_code(struct TranslationBlock *tb, int search_pc); | 61 | +int gen_intermediate_code(struct TranslationBlock *tb); |
62 | +int gen_intermediate_code_pc(struct TranslationBlock *tb); | ||
61 | void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf); | 63 | void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf); |
62 | int cpu_gen_code(struct TranslationBlock *tb, | 64 | int cpu_gen_code(struct TranslationBlock *tb, |
63 | int max_code_size, int *gen_code_size_ptr); | 65 | int max_code_size, int *gen_code_size_ptr); |
64 | -int cpu_search_pc(struct TranslationBlock *tb, | ||
65 | - uint32_t *found_pc, unsigned long searched_pc); | 66 | +int cpu_restore_state(struct TranslationBlock *tb, |
67 | + CPUState *env, unsigned long searched_pc); | ||
66 | void cpu_exec_init(void); | 68 | void cpu_exec_init(void); |
67 | int page_unprotect(unsigned long address); | 69 | int page_unprotect(unsigned long address); |
70 | +void page_unmap(void); | ||
68 | 71 | ||
69 | #define CODE_GEN_MAX_SIZE 65536 | 72 | #define CODE_GEN_MAX_SIZE 65536 |
70 | #define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */ | 73 | #define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */ |