Commit 108c49b8a20a535219037b522019d9b57051e8e8
1 parent
90f18422
allow more than 32 bit of physical memory
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1526 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
52 additions
and
29 deletions
exec.c
| ... | ... | @@ -51,6 +51,15 @@ |
| 51 | 51 | #define MMAP_AREA_START 0x00000000 |
| 52 | 52 | #define MMAP_AREA_END 0xa8000000 |
| 53 | 53 | |
| 54 | +#if defined(TARGET_SPARC64) | |
| 55 | +#define TARGET_PHYS_ADDR_SPACE_BITS 41 | |
| 56 | +#elif defined(TARGET_PPC64) | |
| 57 | +#define TARGET_PHYS_ADDR_SPACE_BITS 42 | |
| 58 | +#else | |
| 59 | +/* Note: for compatibility with kqemu, we use 32 bits for x86_64 */ | |
| 60 | +#define TARGET_PHYS_ADDR_SPACE_BITS 32 | |
| 61 | +#endif | |
| 62 | + | |
| 54 | 63 | TranslationBlock tbs[CODE_GEN_MAX_BLOCKS]; |
| 55 | 64 | TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE]; |
| 56 | 65 | TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; |
| ... | ... | @@ -184,8 +193,8 @@ static void page_init(void) |
| 184 | 193 | #if !defined(CONFIG_USER_ONLY) |
| 185 | 194 | virt_valid_tag = 1; |
| 186 | 195 | #endif |
| 187 | - l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(PhysPageDesc *)); | |
| 188 | - memset(l1_phys_map, 0, L1_SIZE * sizeof(PhysPageDesc *)); | |
| 196 | + l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(void *)); | |
| 197 | + memset(l1_phys_map, 0, L1_SIZE * sizeof(void *)); | |
| 189 | 198 | } |
| 190 | 199 | |
| 191 | 200 | static inline PageDesc *page_find_alloc(unsigned int index) |
| ... | ... | @@ -213,29 +222,43 @@ static inline PageDesc *page_find(unsigned int index) |
| 213 | 222 | return p + (index & (L2_SIZE - 1)); |
| 214 | 223 | } |
| 215 | 224 | |
| 216 | -static inline PhysPageDesc *phys_page_find_alloc(unsigned int index) | |
| 225 | +static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc) | |
| 217 | 226 | { |
| 218 | - PhysPageDesc **lp, *p; | |
| 227 | + void **lp, **p; | |
| 219 | 228 | |
| 220 | - lp = &l1_phys_map[index >> L2_BITS]; | |
| 229 | + p = (void **)l1_phys_map; | |
| 230 | +#if TARGET_PHYS_ADDR_SPACE_BITS > 32 | |
| 231 | + | |
| 232 | +#if TARGET_PHYS_ADDR_SPACE_BITS > (32 + L1_BITS) | |
| 233 | +#error unsupported TARGET_PHYS_ADDR_SPACE_BITS | |
| 234 | +#endif | |
| 235 | + lp = p + ((index >> (L1_BITS + L2_BITS)) & (L1_SIZE - 1)); | |
| 221 | 236 | p = *lp; |
| 222 | 237 | if (!p) { |
| 223 | 238 | /* allocate if not found */ |
| 239 | + if (!alloc) | |
| 240 | + return NULL; | |
| 241 | + p = qemu_vmalloc(sizeof(void *) * L1_SIZE); | |
| 242 | + memset(p, 0, sizeof(void *) * L1_SIZE); | |
| 243 | + *lp = p; | |
| 244 | + } | |
| 245 | +#endif | |
| 246 | + lp = p + ((index >> L2_BITS) & (L1_SIZE - 1)); | |
| 247 | + p = *lp; | |
| 248 | + if (!p) { | |
| 249 | + /* allocate if not found */ | |
| 250 | + if (!alloc) | |
| 251 | + return NULL; | |
| 224 | 252 | p = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE); |
| 225 | 253 | memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE); |
| 226 | 254 | *lp = p; |
| 227 | 255 | } |
| 228 | - return p + (index & (L2_SIZE - 1)); | |
| 256 | + return ((PhysPageDesc *)p) + (index & (L2_SIZE - 1)); | |
| 229 | 257 | } |
| 230 | 258 | |
| 231 | -static inline PhysPageDesc *phys_page_find(unsigned int index) | |
| 259 | +static inline PhysPageDesc *phys_page_find(target_phys_addr_t index) | |
| 232 | 260 | { |
| 233 | - PhysPageDesc *p; | |
| 234 | - | |
| 235 | - p = l1_phys_map[index >> L2_BITS]; | |
| 236 | - if (!p) | |
| 237 | - return 0; | |
| 238 | - return p + (index & (L2_SIZE - 1)); | |
| 261 | + return phys_page_find_alloc(index, 0); | |
| 239 | 262 | } |
| 240 | 263 | |
| 241 | 264 | #if !defined(CONFIG_USER_ONLY) |
| ... | ... | @@ -1400,7 +1423,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr) |
| 1400 | 1423 | TranslationBlock *tb; |
| 1401 | 1424 | |
| 1402 | 1425 | #if defined(DEBUG_TLB) |
| 1403 | - printf("tlb_flush_page: 0x%08x\n", addr); | |
| 1426 | + printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr); | |
| 1404 | 1427 | #endif |
| 1405 | 1428 | /* must reset current TB so that interrupts cannot modify the |
| 1406 | 1429 | links while we are modifying them */ |
| ... | ... | @@ -1567,7 +1590,7 @@ void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end, |
| 1567 | 1590 | } |
| 1568 | 1591 | |
| 1569 | 1592 | static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, |
| 1570 | - unsigned long start) | |
| 1593 | + unsigned long start) | |
| 1571 | 1594 | { |
| 1572 | 1595 | unsigned long addr; |
| 1573 | 1596 | if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) { |
| ... | ... | @@ -1606,7 +1629,7 @@ int tlb_set_page(CPUState *env, target_ulong vaddr, |
| 1606 | 1629 | TranslationBlock *first_tb; |
| 1607 | 1630 | unsigned int index; |
| 1608 | 1631 | target_ulong address; |
| 1609 | - unsigned long addend; | |
| 1632 | + target_phys_addr_t addend; | |
| 1610 | 1633 | int ret; |
| 1611 | 1634 | |
| 1612 | 1635 | p = phys_page_find(paddr >> TARGET_PAGE_BITS); |
| ... | ... | @@ -1623,7 +1646,7 @@ int tlb_set_page(CPUState *env, target_ulong vaddr, |
| 1623 | 1646 | } |
| 1624 | 1647 | } |
| 1625 | 1648 | #if defined(DEBUG_TLB) |
| 1626 | - printf("tlb_set_page: vaddr=0x%08x paddr=0x%08x prot=%x u=%d c=%d smmu=%d pd=0x%08x\n", | |
| 1649 | + printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d c=%d smmu=%d pd=0x%08x\n", | |
| 1627 | 1650 | vaddr, paddr, prot, is_user, (first_tb != NULL), is_softmmu, pd); |
| 1628 | 1651 | #endif |
| 1629 | 1652 | |
| ... | ... | @@ -1929,13 +1952,13 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, |
| 1929 | 1952 | unsigned long size, |
| 1930 | 1953 | unsigned long phys_offset) |
| 1931 | 1954 | { |
| 1932 | - unsigned long addr, end_addr; | |
| 1955 | + target_phys_addr_t addr, end_addr; | |
| 1933 | 1956 | PhysPageDesc *p; |
| 1934 | 1957 | |
| 1935 | 1958 | size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; |
| 1936 | 1959 | end_addr = start_addr + size; |
| 1937 | 1960 | for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) { |
| 1938 | - p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS); | |
| 1961 | + p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1); | |
| 1939 | 1962 | p->phys_offset = phys_offset; |
| 1940 | 1963 | if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) |
| 1941 | 1964 | phys_offset += TARGET_PAGE_SIZE; | ... | ... |
softmmu_template.h
| ... | ... | @@ -48,7 +48,7 @@ |
| 48 | 48 | static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, |
| 49 | 49 | int is_user, |
| 50 | 50 | void *retaddr); |
| 51 | -static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr, | |
| 51 | +static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr, | |
| 52 | 52 | target_ulong tlb_addr) |
| 53 | 53 | { |
| 54 | 54 | DATA_TYPE res; |
| ... | ... | @@ -76,7 +76,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, |
| 76 | 76 | DATA_TYPE res; |
| 77 | 77 | int index; |
| 78 | 78 | target_ulong tlb_addr; |
| 79 | - unsigned long physaddr; | |
| 79 | + target_phys_addr_t physaddr; | |
| 80 | 80 | void *retaddr; |
| 81 | 81 | |
| 82 | 82 | /* 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, |
| 99 | 99 | is_user, retaddr); |
| 100 | 100 | } else { |
| 101 | 101 | /* unaligned access in the same page */ |
| 102 | - res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr); | |
| 102 | + res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr); | |
| 103 | 103 | } |
| 104 | 104 | } else { |
| 105 | 105 | /* 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, |
| 117 | 117 | { |
| 118 | 118 | DATA_TYPE res, res1, res2; |
| 119 | 119 | int index, shift; |
| 120 | - unsigned long physaddr; | |
| 120 | + target_phys_addr_t physaddr; | |
| 121 | 121 | target_ulong tlb_addr, addr1, addr2; |
| 122 | 122 | |
| 123 | 123 | 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, |
| 148 | 148 | res = (DATA_TYPE)res; |
| 149 | 149 | } else { |
| 150 | 150 | /* unaligned/aligned access in the same page */ |
| 151 | - res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr); | |
| 151 | + res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr); | |
| 152 | 152 | } |
| 153 | 153 | } else { |
| 154 | 154 | /* the page is not in the TLB : fill it */ |
| ... | ... | @@ -165,7 +165,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, |
| 165 | 165 | int is_user, |
| 166 | 166 | void *retaddr); |
| 167 | 167 | |
| 168 | -static inline void glue(io_write, SUFFIX)(unsigned long physaddr, | |
| 168 | +static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr, | |
| 169 | 169 | DATA_TYPE val, |
| 170 | 170 | target_ulong tlb_addr, |
| 171 | 171 | void *retaddr) |
| ... | ... | @@ -192,7 +192,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, |
| 192 | 192 | DATA_TYPE val, |
| 193 | 193 | int is_user) |
| 194 | 194 | { |
| 195 | - unsigned long physaddr; | |
| 195 | + target_phys_addr_t physaddr; | |
| 196 | 196 | target_ulong tlb_addr; |
| 197 | 197 | void *retaddr; |
| 198 | 198 | int index; |
| ... | ... | @@ -215,7 +215,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, |
| 215 | 215 | is_user, retaddr); |
| 216 | 216 | } else { |
| 217 | 217 | /* aligned/unaligned access in the same page */ |
| 218 | - glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val); | |
| 218 | + glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val); | |
| 219 | 219 | } |
| 220 | 220 | } else { |
| 221 | 221 | /* the page is not in the TLB : fill it */ |
| ... | ... | @@ -231,7 +231,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, |
| 231 | 231 | int is_user, |
| 232 | 232 | void *retaddr) |
| 233 | 233 | { |
| 234 | - unsigned long physaddr; | |
| 234 | + target_phys_addr_t physaddr; | |
| 235 | 235 | target_ulong tlb_addr; |
| 236 | 236 | int index, i; |
| 237 | 237 | |
| ... | ... | @@ -259,7 +259,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, |
| 259 | 259 | } |
| 260 | 260 | } else { |
| 261 | 261 | /* aligned/unaligned access in the same page */ |
| 262 | - glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val); | |
| 262 | + glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val); | |
| 263 | 263 | } |
| 264 | 264 | } else { |
| 265 | 265 | /* the page is not in the TLB : fill it */ | ... | ... |