diff options
Diffstat (limited to 'exec.c')
-rw-r--r-- | exec.c | 57 |
1 files changed, 31 insertions, 26 deletions
@@ -135,16 +135,14 @@ typedef struct PageDesc { #endif } PageDesc; -typedef struct PhysPageDesc { - /* offset in host memory of the page + io_index in the low bits */ - ram_addr_t phys_offset; - ram_addr_t region_offset; -} PhysPageDesc; - -/* In system mode we want L1_MAP to be based on physical addresses, +/* In system mode we want L1_MAP to be based on ram offsets, while in user mode we want it to be based on virtual addresses. */ #if !defined(CONFIG_USER_ONLY) +#if HOST_LONG_BITS < TARGET_PHYS_ADDR_SPACE_BITS +# define L1_MAP_ADDR_SPACE_BITS HOST_LONG_BITS +#else # define L1_MAP_ADDR_SPACE_BITS TARGET_PHYS_ADDR_SPACE_BITS +#endif #else # define L1_MAP_ADDR_SPACE_BITS TARGET_VIRT_ADDR_SPACE_BITS #endif @@ -188,6 +186,12 @@ unsigned long qemu_host_page_mask; static void *l1_map[V_L1_SIZE]; #if !defined(CONFIG_USER_ONLY) +typedef struct PhysPageDesc { + /* offset in host memory of the page + io_index in the low bits */ + ram_addr_t phys_offset; + ram_addr_t region_offset; +} PhysPageDesc; + /* This is a multi-level map on the physical address space. The bottom level has pointers to PhysPageDesc. */ static void *l1_phys_map[P_L1_SIZE]; @@ -301,8 +305,12 @@ static void page_init(void) #endif } -static PageDesc *page_find_alloc(target_ulong index, int alloc) +static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc) { + PageDesc *pd; + void **lp; + int i; + #if defined(CONFIG_USER_ONLY) /* We can't use qemu_malloc because it may recurse into a locked mutex. Neither can we record the new pages we reserve while allocating a @@ -328,10 +336,6 @@ static PageDesc *page_find_alloc(target_ulong index, int alloc) do { P = qemu_mallocz(SIZE); } while (0) #endif - PageDesc *pd; - void **lp; - int i; - /* Level 1. Always allocated. */ lp = l1_map + ((index >> V_L1_SHIFT) & (V_L1_SIZE - 1)); @@ -374,7 +378,7 @@ static PageDesc *page_find_alloc(target_ulong index, int alloc) return pd + (index & (L2_SIZE - 1)); } -static inline PageDesc *page_find(target_ulong index) +static inline PageDesc *page_find(tb_page_addr_t index) { return page_find_alloc(index, 0); } @@ -791,12 +795,12 @@ static inline void tb_reset_jump(TranslationBlock *tb, int n) tb_set_jmp_target(tb, n, (unsigned long)(tb->tc_ptr + tb->tb_next_offset[n])); } -void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr) +void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr) { CPUState *env; PageDesc *p; unsigned int h, n1; - target_phys_addr_t phys_pc; + tb_page_addr_t phys_pc; TranslationBlock *tb1, *tb2; /* remove the TB from the hash list */ @@ -908,10 +912,11 @@ TranslationBlock *tb_gen_code(CPUState *env, { TranslationBlock *tb; uint8_t *tc_ptr; - target_ulong phys_pc, phys_page2, virt_page2; + tb_page_addr_t phys_pc, phys_page2; + target_ulong virt_page2; int code_gen_size; - phys_pc = get_phys_addr_code(env, pc); + phys_pc = get_page_addr_code(env, pc); tb = tb_alloc(pc); if (!tb) { /* flush must be done */ @@ -933,9 +938,9 @@ TranslationBlock *tb_gen_code(CPUState *env, virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK; phys_page2 = -1; if ((pc & TARGET_PAGE_MASK) != virt_page2) { - phys_page2 = get_phys_addr_code(env, virt_page2); + phys_page2 = get_page_addr_code(env, virt_page2); } - tb_link_phys(tb, phys_pc, phys_page2); + tb_link_page(tb, phys_pc, phys_page2); return tb; } @@ -944,12 +949,12 @@ TranslationBlock *tb_gen_code(CPUState *env, the same physical page. 'is_cpu_write_access' should be true if called from a real cpu write access: the virtual CPU will exit the current TB if code is modified inside this TB. */ -void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end, +void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, int is_cpu_write_access) { TranslationBlock *tb, *tb_next, *saved_tb; CPUState *env = cpu_single_env; - target_ulong tb_start, tb_end; + tb_page_addr_t tb_start, tb_end; PageDesc *p; int n; #ifdef TARGET_HAS_PRECISE_SMC @@ -1051,7 +1056,7 @@ void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t } /* len must be <= 8 and start must be a multiple of len */ -static inline void tb_invalidate_phys_page_fast(target_phys_addr_t start, int len) +static inline void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len) { PageDesc *p; int offset, b; @@ -1078,7 +1083,7 @@ static inline void tb_invalidate_phys_page_fast(target_phys_addr_t start, int le } #if !defined(CONFIG_SOFTMMU) -static void tb_invalidate_phys_page(target_phys_addr_t addr, +static void tb_invalidate_phys_page(tb_page_addr_t addr, unsigned long pc, void *puc) { TranslationBlock *tb; @@ -1140,7 +1145,7 @@ static void tb_invalidate_phys_page(target_phys_addr_t addr, /* add the tb in the target page and protect it if necessary */ static inline void tb_alloc_page(TranslationBlock *tb, - unsigned int n, target_ulong page_addr) + unsigned int n, tb_page_addr_t page_addr) { PageDesc *p; TranslationBlock *last_first_tb; @@ -1221,8 +1226,8 @@ void tb_free(TranslationBlock *tb) /* add a new TB and link it to the physical page tables. phys_page2 is (-1) to indicate that only one page contains the TB. */ -void tb_link_phys(TranslationBlock *tb, - target_ulong phys_pc, target_ulong phys_page2) +void tb_link_page(TranslationBlock *tb, + tb_page_addr_t phys_pc, tb_page_addr_t phys_page2) { unsigned int h; TranslationBlock **ptb; |