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,6 +51,15 @@ | ||
| 51 | #define MMAP_AREA_START 0x00000000 | 51 | #define MMAP_AREA_START 0x00000000 |
| 52 | #define MMAP_AREA_END 0xa8000000 | 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 | TranslationBlock tbs[CODE_GEN_MAX_BLOCKS]; | 63 | TranslationBlock tbs[CODE_GEN_MAX_BLOCKS]; |
| 55 | TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE]; | 64 | TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE]; |
| 56 | TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; | 65 | TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; |
| @@ -184,8 +193,8 @@ static void page_init(void) | @@ -184,8 +193,8 @@ static void page_init(void) | ||
| 184 | #if !defined(CONFIG_USER_ONLY) | 193 | #if !defined(CONFIG_USER_ONLY) |
| 185 | virt_valid_tag = 1; | 194 | virt_valid_tag = 1; |
| 186 | #endif | 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 | static inline PageDesc *page_find_alloc(unsigned int index) | 200 | static inline PageDesc *page_find_alloc(unsigned int index) |
| @@ -213,29 +222,43 @@ static inline PageDesc *page_find(unsigned int index) | @@ -213,29 +222,43 @@ static inline PageDesc *page_find(unsigned int index) | ||
| 213 | return p + (index & (L2_SIZE - 1)); | 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 | p = *lp; | 236 | p = *lp; |
| 222 | if (!p) { | 237 | if (!p) { |
| 223 | /* allocate if not found */ | 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 | p = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE); | 252 | p = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE); |
| 225 | memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE); | 253 | memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE); |
| 226 | *lp = p; | 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 | #if !defined(CONFIG_USER_ONLY) | 264 | #if !defined(CONFIG_USER_ONLY) |
| @@ -1400,7 +1423,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr) | @@ -1400,7 +1423,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr) | ||
| 1400 | TranslationBlock *tb; | 1423 | TranslationBlock *tb; |
| 1401 | 1424 | ||
| 1402 | #if defined(DEBUG_TLB) | 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 | #endif | 1427 | #endif |
| 1405 | /* must reset current TB so that interrupts cannot modify the | 1428 | /* must reset current TB so that interrupts cannot modify the |
| 1406 | links while we are modifying them */ | 1429 | links while we are modifying them */ |
| @@ -1567,7 +1590,7 @@ void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end, | @@ -1567,7 +1590,7 @@ void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end, | ||
| 1567 | } | 1590 | } |
| 1568 | 1591 | ||
| 1569 | static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, | 1592 | static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, |
| 1570 | - unsigned long start) | 1593 | + unsigned long start) |
| 1571 | { | 1594 | { |
| 1572 | unsigned long addr; | 1595 | unsigned long addr; |
| 1573 | if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) { | 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,7 +1629,7 @@ int tlb_set_page(CPUState *env, target_ulong vaddr, | ||
| 1606 | TranslationBlock *first_tb; | 1629 | TranslationBlock *first_tb; |
| 1607 | unsigned int index; | 1630 | unsigned int index; |
| 1608 | target_ulong address; | 1631 | target_ulong address; |
| 1609 | - unsigned long addend; | 1632 | + target_phys_addr_t addend; |
| 1610 | int ret; | 1633 | int ret; |
| 1611 | 1634 | ||
| 1612 | p = phys_page_find(paddr >> TARGET_PAGE_BITS); | 1635 | p = phys_page_find(paddr >> TARGET_PAGE_BITS); |
| @@ -1623,7 +1646,7 @@ int tlb_set_page(CPUState *env, target_ulong vaddr, | @@ -1623,7 +1646,7 @@ int tlb_set_page(CPUState *env, target_ulong vaddr, | ||
| 1623 | } | 1646 | } |
| 1624 | } | 1647 | } |
| 1625 | #if defined(DEBUG_TLB) | 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 | vaddr, paddr, prot, is_user, (first_tb != NULL), is_softmmu, pd); | 1650 | vaddr, paddr, prot, is_user, (first_tb != NULL), is_softmmu, pd); |
| 1628 | #endif | 1651 | #endif |
| 1629 | 1652 | ||
| @@ -1929,13 +1952,13 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, | @@ -1929,13 +1952,13 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, | ||
| 1929 | unsigned long size, | 1952 | unsigned long size, |
| 1930 | unsigned long phys_offset) | 1953 | unsigned long phys_offset) |
| 1931 | { | 1954 | { |
| 1932 | - unsigned long addr, end_addr; | 1955 | + target_phys_addr_t addr, end_addr; |
| 1933 | PhysPageDesc *p; | 1956 | PhysPageDesc *p; |
| 1934 | 1957 | ||
| 1935 | size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; | 1958 | size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; |
| 1936 | end_addr = start_addr + size; | 1959 | end_addr = start_addr + size; |
| 1937 | for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) { | 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 | p->phys_offset = phys_offset; | 1962 | p->phys_offset = phys_offset; |
| 1940 | if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) | 1963 | if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) |
| 1941 | phys_offset += TARGET_PAGE_SIZE; | 1964 | phys_offset += TARGET_PAGE_SIZE; |
softmmu_template.h
| @@ -48,7 +48,7 @@ | @@ -48,7 +48,7 @@ | ||
| 48 | static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, | 48 | static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, |
| 49 | int is_user, | 49 | int is_user, |
| 50 | void *retaddr); | 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 | target_ulong tlb_addr) | 52 | target_ulong tlb_addr) |
| 53 | { | 53 | { |
| 54 | DATA_TYPE res; | 54 | DATA_TYPE res; |
| @@ -76,7 +76,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, | @@ -76,7 +76,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, | ||
| 76 | DATA_TYPE res; | 76 | DATA_TYPE res; |
| 77 | int index; | 77 | int index; |
| 78 | target_ulong tlb_addr; | 78 | target_ulong tlb_addr; |
| 79 | - unsigned long physaddr; | 79 | + target_phys_addr_t physaddr; |
| 80 | void *retaddr; | 80 | void *retaddr; |
| 81 | 81 | ||
| 82 | /* test if there is match for unaligned or IO access */ | 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,7 +99,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, | ||
| 99 | is_user, retaddr); | 99 | is_user, retaddr); |
| 100 | } else { | 100 | } else { |
| 101 | /* unaligned access in the same page */ | 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 | } else { | 104 | } else { |
| 105 | /* the page is not in the TLB : fill it */ | 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,7 +117,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, | ||
| 117 | { | 117 | { |
| 118 | DATA_TYPE res, res1, res2; | 118 | DATA_TYPE res, res1, res2; |
| 119 | int index, shift; | 119 | int index, shift; |
| 120 | - unsigned long physaddr; | 120 | + target_phys_addr_t physaddr; |
| 121 | target_ulong tlb_addr, addr1, addr2; | 121 | target_ulong tlb_addr, addr1, addr2; |
| 122 | 122 | ||
| 123 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | 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,7 +148,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, | ||
| 148 | res = (DATA_TYPE)res; | 148 | res = (DATA_TYPE)res; |
| 149 | } else { | 149 | } else { |
| 150 | /* unaligned/aligned access in the same page */ | 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 | } else { | 153 | } else { |
| 154 | /* the page is not in the TLB : fill it */ | 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,7 +165,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, | ||
| 165 | int is_user, | 165 | int is_user, |
| 166 | void *retaddr); | 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 | DATA_TYPE val, | 169 | DATA_TYPE val, |
| 170 | target_ulong tlb_addr, | 170 | target_ulong tlb_addr, |
| 171 | void *retaddr) | 171 | void *retaddr) |
| @@ -192,7 +192,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, | @@ -192,7 +192,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, | ||
| 192 | DATA_TYPE val, | 192 | DATA_TYPE val, |
| 193 | int is_user) | 193 | int is_user) |
| 194 | { | 194 | { |
| 195 | - unsigned long physaddr; | 195 | + target_phys_addr_t physaddr; |
| 196 | target_ulong tlb_addr; | 196 | target_ulong tlb_addr; |
| 197 | void *retaddr; | 197 | void *retaddr; |
| 198 | int index; | 198 | int index; |
| @@ -215,7 +215,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, | @@ -215,7 +215,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, | ||
| 215 | is_user, retaddr); | 215 | is_user, retaddr); |
| 216 | } else { | 216 | } else { |
| 217 | /* aligned/unaligned access in the same page */ | 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 | } else { | 220 | } else { |
| 221 | /* the page is not in the TLB : fill it */ | 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,7 +231,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, | ||
| 231 | int is_user, | 231 | int is_user, |
| 232 | void *retaddr) | 232 | void *retaddr) |
| 233 | { | 233 | { |
| 234 | - unsigned long physaddr; | 234 | + target_phys_addr_t physaddr; |
| 235 | target_ulong tlb_addr; | 235 | target_ulong tlb_addr; |
| 236 | int index, i; | 236 | int index, i; |
| 237 | 237 | ||
| @@ -259,7 +259,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, | @@ -259,7 +259,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, | ||
| 259 | } | 259 | } |
| 260 | } else { | 260 | } else { |
| 261 | /* aligned/unaligned access in the same page */ | 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 | } else { | 264 | } else { |
| 265 | /* the page is not in the TLB : fill it */ | 265 | /* the page is not in the TLB : fill it */ |