Commit 66e85a21c7f65540ac1976ed29ed9973089fe1f1

Authored by bellard
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 */
... ...
... ... @@ -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
... ...
... ... @@ -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 */
... ...