mirror of https://github.com/xemu-project/xemu.git
allow more than 32 bit of physical memory
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1526 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
90f18422d9
commit
108c49b8a2
61
exec.c
61
exec.c
|
@ -51,6 +51,15 @@
|
||||||
#define MMAP_AREA_START 0x00000000
|
#define MMAP_AREA_START 0x00000000
|
||||||
#define MMAP_AREA_END 0xa8000000
|
#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 tbs[CODE_GEN_MAX_BLOCKS];
|
||||||
TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
|
TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
|
||||||
TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_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)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
virt_valid_tag = 1;
|
virt_valid_tag = 1;
|
||||||
#endif
|
#endif
|
||||||
l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(PhysPageDesc *));
|
l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(void *));
|
||||||
memset(l1_phys_map, 0, L1_SIZE * sizeof(PhysPageDesc *));
|
memset(l1_phys_map, 0, L1_SIZE * sizeof(void *));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline PageDesc *page_find_alloc(unsigned int index)
|
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));
|
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;
|
p = *lp;
|
||||||
if (!p) {
|
if (!p) {
|
||||||
/* allocate if not found */
|
/* 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);
|
p = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);
|
||||||
memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE);
|
memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE);
|
||||||
*lp = p;
|
*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;
|
return phys_page_find_alloc(index, 0);
|
||||||
|
|
||||||
p = l1_phys_map[index >> L2_BITS];
|
|
||||||
if (!p)
|
|
||||||
return 0;
|
|
||||||
return p + (index & (L2_SIZE - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
@ -1400,7 +1423,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
|
||||||
TranslationBlock *tb;
|
TranslationBlock *tb;
|
||||||
|
|
||||||
#if defined(DEBUG_TLB)
|
#if defined(DEBUG_TLB)
|
||||||
printf("tlb_flush_page: 0x%08x\n", addr);
|
printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr);
|
||||||
#endif
|
#endif
|
||||||
/* must reset current TB so that interrupts cannot modify the
|
/* must reset current TB so that interrupts cannot modify the
|
||||||
links while we are modifying them */
|
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,
|
static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
|
||||||
unsigned long start)
|
unsigned long start)
|
||||||
{
|
{
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
|
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;
|
TranslationBlock *first_tb;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
target_ulong address;
|
target_ulong address;
|
||||||
unsigned long addend;
|
target_phys_addr_t addend;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
p = phys_page_find(paddr >> TARGET_PAGE_BITS);
|
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)
|
#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);
|
vaddr, paddr, prot, is_user, (first_tb != NULL), is_softmmu, pd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1929,13 +1952,13 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
|
||||||
unsigned long size,
|
unsigned long size,
|
||||||
unsigned long phys_offset)
|
unsigned long phys_offset)
|
||||||
{
|
{
|
||||||
unsigned long addr, end_addr;
|
target_phys_addr_t addr, end_addr;
|
||||||
PhysPageDesc *p;
|
PhysPageDesc *p;
|
||||||
|
|
||||||
size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
|
size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
|
||||||
end_addr = start_addr + size;
|
end_addr = start_addr + size;
|
||||||
for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_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;
|
p->phys_offset = phys_offset;
|
||||||
if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM)
|
if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM)
|
||||||
phys_offset += TARGET_PAGE_SIZE;
|
phys_offset += TARGET_PAGE_SIZE;
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
|
static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
|
||||||
int is_user,
|
int is_user,
|
||||||
void *retaddr);
|
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)
|
target_ulong tlb_addr)
|
||||||
{
|
{
|
||||||
DATA_TYPE res;
|
DATA_TYPE res;
|
||||||
|
@ -76,7 +76,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
|
||||||
DATA_TYPE res;
|
DATA_TYPE res;
|
||||||
int index;
|
int index;
|
||||||
target_ulong tlb_addr;
|
target_ulong tlb_addr;
|
||||||
unsigned long physaddr;
|
target_phys_addr_t physaddr;
|
||||||
void *retaddr;
|
void *retaddr;
|
||||||
|
|
||||||
/* test if there is match for unaligned or IO access */
|
/* 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);
|
is_user, retaddr);
|
||||||
} else {
|
} else {
|
||||||
/* unaligned access in the same page */
|
/* 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 {
|
} else {
|
||||||
/* the page is not in the TLB : fill it */
|
/* 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;
|
DATA_TYPE res, res1, res2;
|
||||||
int index, shift;
|
int index, shift;
|
||||||
unsigned long physaddr;
|
target_phys_addr_t physaddr;
|
||||||
target_ulong tlb_addr, addr1, addr2;
|
target_ulong tlb_addr, addr1, addr2;
|
||||||
|
|
||||||
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
|
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;
|
res = (DATA_TYPE)res;
|
||||||
} else {
|
} else {
|
||||||
/* unaligned/aligned access in the same page */
|
/* 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 {
|
} else {
|
||||||
/* the page is not in the TLB : fill it */
|
/* 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,
|
int is_user,
|
||||||
void *retaddr);
|
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,
|
DATA_TYPE val,
|
||||||
target_ulong tlb_addr,
|
target_ulong tlb_addr,
|
||||||
void *retaddr)
|
void *retaddr)
|
||||||
|
@ -192,7 +192,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
|
||||||
DATA_TYPE val,
|
DATA_TYPE val,
|
||||||
int is_user)
|
int is_user)
|
||||||
{
|
{
|
||||||
unsigned long physaddr;
|
target_phys_addr_t physaddr;
|
||||||
target_ulong tlb_addr;
|
target_ulong tlb_addr;
|
||||||
void *retaddr;
|
void *retaddr;
|
||||||
int index;
|
int index;
|
||||||
|
@ -215,7 +215,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
|
||||||
is_user, retaddr);
|
is_user, retaddr);
|
||||||
} else {
|
} else {
|
||||||
/* aligned/unaligned access in the same page */
|
/* 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 {
|
} else {
|
||||||
/* the page is not in the TLB : fill it */
|
/* 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,
|
int is_user,
|
||||||
void *retaddr)
|
void *retaddr)
|
||||||
{
|
{
|
||||||
unsigned long physaddr;
|
target_phys_addr_t physaddr;
|
||||||
target_ulong tlb_addr;
|
target_ulong tlb_addr;
|
||||||
int index, i;
|
int index, i;
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* aligned/unaligned access in the same page */
|
/* 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 {
|
} else {
|
||||||
/* the page is not in the TLB : fill it */
|
/* the page is not in the TLB : fill it */
|
||||||
|
|
Loading…
Reference in New Issue