aboutsummaryrefslogtreecommitdiff
path: root/exec.c
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2010-03-12 16:54:58 +0000
committerPaul Brook <paul@codesourcery.com>2010-03-12 17:23:50 +0000
commit41c1b1c9ebb45b97795fa9e58eaa6fedc4eafe0e (patch)
tree1386b3cb0d216dcb9a56f91fc38046ebc696cbd3 /exec.c
parent376a790970de7e84170ee9360b6ff53ecfa4a1be (diff)
Add tb_page_addr_t
The page tracking code in exec.c is used by both userspace and system emulation. Userspace emulation uses it to track virtual pages, and system emulation to track ram pages. Introduce a new type to hold this kind of address. Signed-off-by: Paul Brook <paul@codesourcery.com>
Diffstat (limited to 'exec.c')
-rw-r--r--exec.c57
1 files changed, 31 insertions, 26 deletions
diff --git a/exec.c b/exec.c
index 246e9701fd..c7697acace 100644
--- a/exec.c
+++ b/exec.c
@@ -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;