aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-07-24 12:55:09 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-07-24 12:55:09 +0000
commit108c49b8a20a535219037b522019d9b57051e8e8 (patch)
tree754a6dc20462b3a5102a801bef137a15d4e313a9
parent90f18422d9d54237cbec19461321a9de1011ad8c (diff)
allow more than 32 bit of physical memory
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1526 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--exec.c61
-rw-r--r--softmmu_template.h20
2 files changed, 52 insertions, 29 deletions
diff --git a/exec.c b/exec.c
index 178c237fba..26abb0f1a6 100644
--- a/exec.c
+++ b/exec.c
@@ -51,6 +51,15 @@
#define MMAP_AREA_START 0x00000000
#define MMAP_AREA_END 0xa8000000
+#if defined(TARGET_SPARC64)
+#define TARGET_PHYS_ADDR_SPACE_BITS 41
+#elif defined(TARGET_PPC64)
+#define TARGET_PHYS_ADDR_SPACE_BITS 42
+#else
+/* Note: for compatibility with kqemu, we use 32 bits for x86_64 */
+#define TARGET_PHYS_ADDR_SPACE_BITS 32
+#endif
+
TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
@@ -184,8 +193,8 @@ static void page_init(void)
#if !defined(CONFIG_USER_ONLY)
virt_valid_tag = 1;
#endif
- l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(PhysPageDesc *));
- memset(l1_phys_map, 0, L1_SIZE * sizeof(PhysPageDesc *));
+ l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(void *));
+ memset(l1_phys_map, 0, L1_SIZE * sizeof(void *));
}
static inline PageDesc *page_find_alloc(unsigned int index)
@@ -213,29 +222,43 @@ static inline PageDesc *page_find(unsigned int index)
return p + (index & (L2_SIZE - 1));
}
-static inline PhysPageDesc *phys_page_find_alloc(unsigned int index)
+static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)
{
- PhysPageDesc **lp, *p;
+ void **lp, **p;
- lp = &l1_phys_map[index >> L2_BITS];
+ p = (void **)l1_phys_map;
+#if TARGET_PHYS_ADDR_SPACE_BITS > 32
+
+#if TARGET_PHYS_ADDR_SPACE_BITS > (32 + L1_BITS)
+#error unsupported TARGET_PHYS_ADDR_SPACE_BITS
+#endif
+ lp = p + ((index >> (L1_BITS + L2_BITS)) & (L1_SIZE - 1));
p = *lp;
if (!p) {
/* allocate if not found */
+ if (!alloc)
+ return NULL;
+ p = qemu_vmalloc(sizeof(void *) * L1_SIZE);
+ memset(p, 0, sizeof(void *) * L1_SIZE);
+ *lp = p;
+ }
+#endif
+ lp = p + ((index >> L2_BITS) & (L1_SIZE - 1));
+ p = *lp;
+ if (!p) {
+ /* allocate if not found */
+ if (!alloc)
+ return NULL;
p = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);
memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE);
*lp = p;
}
- return p + (index & (L2_SIZE - 1));
+ return ((PhysPageDesc *)p) + (index & (L2_SIZE - 1));
}
-static inline PhysPageDesc *phys_page_find(unsigned int index)
+static inline PhysPageDesc *phys_page_find(target_phys_addr_t index)
{
- PhysPageDesc *p;
-
- p = l1_phys_map[index >> L2_BITS];
- if (!p)
- return 0;
- return p + (index & (L2_SIZE - 1));
+ return phys_page_find_alloc(index, 0);
}
#if !defined(CONFIG_USER_ONLY)
@@ -1400,7 +1423,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
TranslationBlock *tb;
#if defined(DEBUG_TLB)
- printf("tlb_flush_page: 0x%08x\n", addr);
+ printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr);
#endif
/* must reset current TB so that interrupts cannot modify the
links while we are modifying them */
@@ -1567,7 +1590,7 @@ void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end,
}
static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
- unsigned long start)
+ unsigned long start)
{
unsigned long addr;
if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
@@ -1606,7 +1629,7 @@ int tlb_set_page(CPUState *env, target_ulong vaddr,
TranslationBlock *first_tb;
unsigned int index;
target_ulong address;
- unsigned long addend;
+ target_phys_addr_t addend;
int ret;
p = phys_page_find(paddr >> TARGET_PAGE_BITS);
@@ -1623,7 +1646,7 @@ int tlb_set_page(CPUState *env, target_ulong vaddr,
}
}
#if defined(DEBUG_TLB)
- printf("tlb_set_page: vaddr=0x%08x paddr=0x%08x prot=%x u=%d c=%d smmu=%d pd=0x%08x\n",
+ printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d c=%d smmu=%d pd=0x%08x\n",
vaddr, paddr, prot, is_user, (first_tb != NULL), is_softmmu, pd);
#endif
@@ -1929,13 +1952,13 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
unsigned long size,
unsigned long phys_offset)
{
- unsigned long addr, end_addr;
+ target_phys_addr_t addr, end_addr;
PhysPageDesc *p;
size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
end_addr = start_addr + size;
for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
- p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS);
+ p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
p->phys_offset = phys_offset;
if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM)
phys_offset += TARGET_PAGE_SIZE;
diff --git a/softmmu_template.h b/softmmu_template.h
index 5076726937..558bb8be85 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -48,7 +48,7 @@
static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
int is_user,
void *retaddr);
-static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr,
+static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
target_ulong tlb_addr)
{
DATA_TYPE res;
@@ -76,7 +76,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
DATA_TYPE res;
int index;
target_ulong tlb_addr;
- unsigned long physaddr;
+ target_phys_addr_t physaddr;
void *retaddr;
/* test if there is match for unaligned or IO access */
@@ -99,7 +99,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
is_user, retaddr);
} else {
/* unaligned access in the same page */
- res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
+ res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
}
} else {
/* the page is not in the TLB : fill it */
@@ -117,7 +117,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
{
DATA_TYPE res, res1, res2;
int index, shift;
- unsigned long physaddr;
+ target_phys_addr_t physaddr;
target_ulong tlb_addr, addr1, addr2;
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
@@ -148,7 +148,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
res = (DATA_TYPE)res;
} else {
/* unaligned/aligned access in the same page */
- res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
+ res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
}
} else {
/* the page is not in the TLB : fill it */
@@ -165,7 +165,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
int is_user,
void *retaddr);
-static inline void glue(io_write, SUFFIX)(unsigned long physaddr,
+static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
DATA_TYPE val,
target_ulong tlb_addr,
void *retaddr)
@@ -192,7 +192,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
DATA_TYPE val,
int is_user)
{
- unsigned long physaddr;
+ target_phys_addr_t physaddr;
target_ulong tlb_addr;
void *retaddr;
int index;
@@ -215,7 +215,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
is_user, retaddr);
} else {
/* aligned/unaligned access in the same page */
- glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val);
+ glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val);
}
} else {
/* the page is not in the TLB : fill it */
@@ -231,7 +231,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
int is_user,
void *retaddr)
{
- unsigned long physaddr;
+ target_phys_addr_t physaddr;
target_ulong tlb_addr;
int index, i;
@@ -259,7 +259,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
}
} else {
/* aligned/unaligned access in the same page */
- glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val);
+ glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val);
}
} else {
/* the page is not in the TLB : fill it */