Commit 66e85a21 authored by bellard's avatar bellard
Browse files

MMU support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@262 c046a42c-6fe2-441c-8c8c-71466251a162
parent 90a9fdae
......@@ -50,7 +50,8 @@
/* segment descriptor fields */
#define DESC_G_MASK (1 << 23)
#define DESC_B_MASK (1 << 22)
#define DESC_B_SHIFT 22
#define DESC_B_MASK (1 << DESC_B_SHIFT)
#define DESC_AVL_MASK (1 << 20)
#define DESC_P_MASK (1 << 15)
#define DESC_DPL_SHIFT 13
......@@ -95,6 +96,34 @@
#define CR4_PVI_MASK (1 << 1)
#define CR4_TSD_MASK (1 << 2)
#define CR4_DE_MASK (1 << 3)
#define CR4_PSE_MASK (1 << 4)
#define PG_PRESENT_BIT 0
#define PG_RW_BIT 1
#define PG_USER_BIT 2
#define PG_PWT_BIT 3
#define PG_PCD_BIT 4
#define PG_ACCESSED_BIT 5
#define PG_DIRTY_BIT 6
#define PG_PSE_BIT 7
#define PG_GLOBAL_BIT 8
#define PG_PRESENT_MASK (1 << PG_PRESENT_BIT)
#define PG_RW_MASK (1 << PG_RW_BIT)
#define PG_USER_MASK (1 << PG_USER_BIT)
#define PG_PWT_MASK (1 << PG_PWT_BIT)
#define PG_PCD_MASK (1 << PG_PCD_BIT)
#define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)
#define PG_DIRTY_MASK (1 << PG_DIRTY_BIT)
#define PG_PSE_MASK (1 << PG_PSE_BIT)
#define PG_GLOBAL_MASK (1 << PG_GLOBAL_BIT)
#define PG_ERROR_W_BIT 1
#define PG_ERROR_P_MASK 0x01
#define PG_ERROR_W_MASK (1 << PG_ERROR_W_BIT)
#define PG_ERROR_U_MASK 0x04
#define PG_ERROR_RSVD_MASK 0x08
#define EXCP00_DIVZ 0
#define EXCP01_SSTP 1
......@@ -116,6 +145,7 @@
#define EXCP12_MCHK 18
#define EXCP_INTERRUPT 256 /* async interruption */
#define EXCP_HLT 257 /* hlt instruction reached */
enum {
CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
......@@ -174,8 +204,8 @@ typedef double CPU86_LDouble;
typedef struct SegmentCache {
uint32_t selector;
uint8_t *base;
unsigned long limit;
uint8_t seg_32bit;
uint32_t limit;
uint32_t flags;
} SegmentCache;
typedef struct CPUX86State {
......@@ -219,9 +249,16 @@ typedef struct CPUX86State {
jmp_buf jmp_env;
int exception_index;
int error_code;
int exception_is_int;
int exception_next_eip;
uint32_t cr[5]; /* NOTE: cr1 is unused */
uint32_t dr[8]; /* debug registers */
int interrupt_request;
int interrupt_request; /* if true, will exit from cpu_exec() ASAP */
/* if true, will call cpu_x86_get_pic_interrupt() ASAP to get the
request interrupt number */
int hard_interrupt_request;
int user_mode_only; /* user mode only simulation */
/* user data */
void *opaque;
......@@ -240,6 +277,7 @@ CPUX86State *cpu_x86_init(void);
int cpu_x86_exec(CPUX86State *s);
void cpu_x86_interrupt(CPUX86State *s);
void cpu_x86_close(CPUX86State *s);
int cpu_x86_get_pic_interrupt(CPUX86State *s);
/* needed to load some predefinied segment registers */
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector);
......@@ -255,6 +293,13 @@ struct siginfo;
int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
void *puc);
/* MMU defines */
void cpu_x86_init_mmu(CPUX86State *env);
extern CPUX86State *global_env;
extern int phys_ram_size;
extern int phys_ram_fd;
extern uint8_t *phys_ram_base;
/* used to debug */
#define X86_DUMP_FPU 0x0001 /* dump FPU state too */
#define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
......
......@@ -30,7 +30,7 @@
#include "exec.h"
//#define DEBUG_TB_INVALIDATE
#define DEBUG_FLUSH
//#define DEBUG_FLUSH
/* make various TB consistency checks */
//#define DEBUG_TB_CHECK
......@@ -579,3 +579,33 @@ void cpu_abort(CPUState *env, const char *fmt, ...)
abort();
}
#ifdef TARGET_I386
/* unmap all maped pages and flush all associated code */
void page_unmap(void)
{
PageDesc *p, *pmap;
unsigned long addr;
int i, j, ret;
for(i = 0; i < L1_SIZE; i++) {
pmap = l1_map[i];
if (pmap) {
p = pmap;
for(j = 0;j < L2_SIZE; j++) {
if (p->flags & PAGE_VALID) {
addr = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS);
ret = munmap((void *)addr, TARGET_PAGE_SIZE);
if (ret != 0) {
fprintf(stderr, "Could not unmap page 0x%08lx\n", addr);
exit(1);
}
}
p++;
}
free(pmap);
l1_map[i] = NULL;
}
}
tb_flush();
}
#endif
......@@ -39,6 +39,7 @@ struct TranslationBlock;
extern uint16_t gen_opc_buf[OPC_BUF_SIZE];
extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
extern uint32_t gen_opc_pc[OPC_BUF_SIZE];
extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
#if defined(TARGET_I386)
......@@ -57,14 +58,16 @@ extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
extern FILE *logfile;
extern int loglevel;
int gen_intermediate_code(struct TranslationBlock *tb, int search_pc);
int gen_intermediate_code(struct TranslationBlock *tb);
int gen_intermediate_code_pc(struct TranslationBlock *tb);
void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf);
int cpu_gen_code(struct TranslationBlock *tb,
int max_code_size, int *gen_code_size_ptr);
int cpu_search_pc(struct TranslationBlock *tb,
uint32_t *found_pc, unsigned long searched_pc);
int cpu_restore_state(struct TranslationBlock *tb,
CPUState *env, unsigned long searched_pc);
void cpu_exec_init(void);
int page_unprotect(unsigned long address);
void page_unmap(void);
#define CODE_GEN_MAX_SIZE 65536
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment