From 108c49b8a20a535219037b522019d9b57051e8e8 Mon Sep 17 00:00:00 2001 From: bellard Date: Sun, 24 Jul 2005 12:55:09 +0000 Subject: [PATCH] allow more than 32 bit of physical memory git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1526 c046a42c-6fe2-441c-8c8c-71466251a162 --- exec.c | 61 ++++++++++++++++++++++++++++++++++++---------------- softmmu_template.h | 20 ++++++++--------- 2 files changed, 52 insertions(+), 29 deletions(-) diff --git a/exec.c b/exec.c index 178c237..26abb0f 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 5076726..558bb8b 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 */ -- 1.7.9.5