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 | 50 | |
51 | 51 | /* segment descriptor fields */ |
52 | 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 | 55 | #define DESC_AVL_MASK (1 << 20) |
55 | 56 | #define DESC_P_MASK (1 << 15) |
56 | 57 | #define DESC_DPL_SHIFT 13 |
... | ... | @@ -95,6 +96,34 @@ |
95 | 96 | #define CR4_PVI_MASK (1 << 1) |
96 | 97 | #define CR4_TSD_MASK (1 << 2) |
97 | 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 | 128 | #define EXCP00_DIVZ 0 |
100 | 129 | #define EXCP01_SSTP 1 |
... | ... | @@ -116,6 +145,7 @@ |
116 | 145 | #define EXCP12_MCHK 18 |
117 | 146 | |
118 | 147 | #define EXCP_INTERRUPT 256 /* async interruption */ |
148 | +#define EXCP_HLT 257 /* hlt instruction reached */ | |
119 | 149 | |
120 | 150 | enum { |
121 | 151 | CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */ |
... | ... | @@ -174,8 +204,8 @@ typedef double CPU86_LDouble; |
174 | 204 | typedef struct SegmentCache { |
175 | 205 | uint32_t selector; |
176 | 206 | uint8_t *base; |
177 | - unsigned long limit; | |
178 | - uint8_t seg_32bit; | |
207 | + uint32_t limit; | |
208 | + uint32_t flags; | |
179 | 209 | } SegmentCache; |
180 | 210 | |
181 | 211 | typedef struct CPUX86State { |
... | ... | @@ -219,9 +249,16 @@ typedef struct CPUX86State { |
219 | 249 | jmp_buf jmp_env; |
220 | 250 | int exception_index; |
221 | 251 | int error_code; |
252 | + int exception_is_int; | |
253 | + int exception_next_eip; | |
254 | + | |
222 | 255 | uint32_t cr[5]; /* NOTE: cr1 is unused */ |
223 | 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 | 263 | /* user data */ |
227 | 264 | void *opaque; |
... | ... | @@ -240,6 +277,7 @@ CPUX86State *cpu_x86_init(void); |
240 | 277 | int cpu_x86_exec(CPUX86State *s); |
241 | 278 | void cpu_x86_interrupt(CPUX86State *s); |
242 | 279 | void cpu_x86_close(CPUX86State *s); |
280 | +int cpu_x86_get_pic_interrupt(CPUX86State *s); | |
243 | 281 | |
244 | 282 | /* needed to load some predefinied segment registers */ |
245 | 283 | void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector); |
... | ... | @@ -255,6 +293,13 @@ struct siginfo; |
255 | 293 | int cpu_x86_signal_handler(int host_signum, struct siginfo *info, |
256 | 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 | 303 | /* used to debug */ |
259 | 304 | #define X86_DUMP_FPU 0x0001 /* dump FPU state too */ |
260 | 305 | #define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */ | ... | ... |
exec.c
... | ... | @@ -30,7 +30,7 @@ |
30 | 30 | #include "exec.h" |
31 | 31 | |
32 | 32 | //#define DEBUG_TB_INVALIDATE |
33 | -#define DEBUG_FLUSH | |
33 | +//#define DEBUG_FLUSH | |
34 | 34 | |
35 | 35 | /* make various TB consistency checks */ |
36 | 36 | //#define DEBUG_TB_CHECK |
... | ... | @@ -579,3 +579,33 @@ void cpu_abort(CPUState *env, const char *fmt, ...) |
579 | 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 | 39 | extern uint16_t gen_opc_buf[OPC_BUF_SIZE]; |
40 | 40 | extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE]; |
41 | 41 | extern uint32_t gen_opc_pc[OPC_BUF_SIZE]; |
42 | +extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; | |
42 | 43 | extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; |
43 | 44 | |
44 | 45 | #if defined(TARGET_I386) |
... | ... | @@ -57,14 +58,16 @@ extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; |
57 | 58 | extern FILE *logfile; |
58 | 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 | 63 | void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf); |
62 | 64 | int cpu_gen_code(struct TranslationBlock *tb, |
63 | 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 | 68 | void cpu_exec_init(void); |
67 | 69 | int page_unprotect(unsigned long address); |
70 | +void page_unmap(void); | |
68 | 71 | |
69 | 72 | #define CODE_GEN_MAX_SIZE 65536 |
70 | 73 | #define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */ | ... | ... |