diff options
Diffstat (limited to 'exec.c')
| -rw-r--r-- | exec.c | 97 |
1 files changed, 63 insertions, 34 deletions
diff --git a/exec.c b/exec.c index f1777e6239..476b507e5e 100644 --- a/exec.c +++ b/exec.c @@ -33,6 +33,8 @@ #include "kvm.h" #include "hw/xen.h" #include "qemu-timer.h" +#include "memory.h" +#include "exec-memory.h" #if defined(CONFIG_USER_ONLY) #include <qemu.h> #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) @@ -109,6 +111,9 @@ int phys_ram_fd; static int in_migration; RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list) }; + +static MemoryRegion *system_memory; + #endif CPUState *first_cpu; @@ -197,6 +202,7 @@ typedef struct PhysPageDesc { static void *l1_phys_map[P_L1_SIZE]; static void io_mem_init(void); +static void memory_map_init(void); /* io memory support */ CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; @@ -571,6 +577,7 @@ void cpu_exec_init_all(unsigned long tb_size) code_gen_ptr = code_gen_buffer; page_init(); #if !defined(CONFIG_USER_ONLY) + memory_map_init(); io_mem_init(); #endif #if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE) @@ -2863,13 +2870,13 @@ static void *file_ram_alloc(RAMBlock *block, static ram_addr_t find_ram_offset(ram_addr_t size) { RAMBlock *block, *next_block; - ram_addr_t offset = 0, mingap = ULONG_MAX; + ram_addr_t offset = 0, mingap = RAM_ADDR_MAX; if (QLIST_EMPTY(&ram_list.blocks)) return 0; QLIST_FOREACH(block, &ram_list.blocks, next) { - ram_addr_t end, next = ULONG_MAX; + ram_addr_t end, next = RAM_ADDR_MAX; end = block->offset + block->length; @@ -2953,7 +2960,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name, abort(); } #else - if (xen_mapcache_enabled()) { + if (xen_enabled()) { xen_ram_alloc(new_block->offset, size); } else { new_block->host = qemu_vmalloc(size); @@ -3019,8 +3026,8 @@ void qemu_ram_free(ram_addr_t addr) #if defined(TARGET_S390X) && defined(CONFIG_KVM) munmap(block->host, block->length); #else - if (xen_mapcache_enabled()) { - qemu_invalidate_entry(block->host); + if (xen_enabled()) { + xen_invalidate_map_cache_entry(block->host); } else { qemu_vfree(block->host); } @@ -3081,7 +3088,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length) #endif } if (area != vaddr) { - fprintf(stderr, "Could not remap addr: %lx@%lx\n", + fprintf(stderr, "Could not remap addr: " + RAM_ADDR_FMT "@" RAM_ADDR_FMT "\n", length, addr); exit(1); } @@ -3112,15 +3120,16 @@ void *qemu_get_ram_ptr(ram_addr_t addr) QLIST_REMOVE(block, next); QLIST_INSERT_HEAD(&ram_list.blocks, block, next); } - if (xen_mapcache_enabled()) { + if (xen_enabled()) { /* We need to check if the requested address is in the RAM * because we don't want to map the entire memory in QEMU. * In that case just map until the end of the page. */ if (block->offset == 0) { - return qemu_map_cache(addr, 0, 0); + return xen_map_cache(addr, 0, 0); } else if (block->host == NULL) { - block->host = qemu_map_cache(block->offset, block->length, 1); + block->host = + xen_map_cache(block->offset, block->length, 1); } } return block->host + (addr - block->offset); @@ -3142,15 +3151,16 @@ void *qemu_safe_ram_ptr(ram_addr_t addr) QLIST_FOREACH(block, &ram_list.blocks, next) { if (addr - block->offset < block->length) { - if (xen_mapcache_enabled()) { + if (xen_enabled()) { /* We need to check if the requested address is in the RAM * because we don't want to map the entire memory in QEMU. * In that case just map until the end of the page. */ if (block->offset == 0) { - return qemu_map_cache(addr, 0, 0); + return xen_map_cache(addr, 0, 0); } else if (block->host == NULL) { - block->host = qemu_map_cache(block->offset, block->length, 1); + block->host = + xen_map_cache(block->offset, block->length, 1); } } return block->host + (addr - block->offset); @@ -3165,11 +3175,14 @@ void *qemu_safe_ram_ptr(ram_addr_t addr) /* Return a host pointer to guest's ram. Similar to qemu_get_ram_ptr * but takes a size argument */ -void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size) +void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size) { - if (xen_mapcache_enabled()) - return qemu_map_cache(addr, *size, 1); - else { + if (*size == 0) { + return NULL; + } + if (xen_enabled()) { + return xen_map_cache(addr, *size, 1); + } else { RAMBlock *block; QLIST_FOREACH(block, &ram_list.blocks, next) { @@ -3182,9 +3195,6 @@ void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size) fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr); abort(); - - *size = 0; - return NULL; } } @@ -3198,8 +3208,8 @@ int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr) RAMBlock *block; uint8_t *host = ptr; - if (xen_mapcache_enabled()) { - *ram_addr = qemu_ram_addr_from_mapcache(ptr); + if (xen_enabled()) { + *ram_addr = xen_ram_addr_from_mapcache(ptr); return 0; } @@ -3236,7 +3246,7 @@ static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr) printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); #endif #if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - do_unassigned_access(addr, 0, 0, 0, 1); + cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 1); #endif return 0; } @@ -3247,7 +3257,7 @@ static uint32_t unassigned_mem_readw(void *opaque, target_phys_addr_t addr) printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); #endif #if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - do_unassigned_access(addr, 0, 0, 0, 2); + cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 2); #endif return 0; } @@ -3258,7 +3268,7 @@ static uint32_t unassigned_mem_readl(void *opaque, target_phys_addr_t addr) printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); #endif #if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - do_unassigned_access(addr, 0, 0, 0, 4); + cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 4); #endif return 0; } @@ -3269,7 +3279,7 @@ static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_ printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val); #endif #if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - do_unassigned_access(addr, 1, 0, 0, 1); + cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 1); #endif } @@ -3279,7 +3289,7 @@ static void unassigned_mem_writew(void *opaque, target_phys_addr_t addr, uint32_ printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val); #endif #if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - do_unassigned_access(addr, 1, 0, 0, 2); + cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 2); #endif } @@ -3289,7 +3299,7 @@ static void unassigned_mem_writel(void *opaque, target_phys_addr_t addr, uint32_ printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val); #endif #if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - do_unassigned_access(addr, 1, 0, 0, 4); + cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 4); #endif } @@ -3805,6 +3815,18 @@ static void io_mem_init(void) DEVICE_NATIVE_ENDIAN); } +static void memory_map_init(void) +{ + system_memory = qemu_malloc(sizeof(*system_memory)); + memory_region_init(system_memory, "system", UINT64_MAX); + set_system_memory_map(system_memory); +} + +MemoryRegion *get_system_memory(void) +{ + return system_memory; +} + #endif /* !defined(CONFIG_USER_ONLY) */ /* physical memory access (slow version, mainly for debug) */ @@ -3856,7 +3878,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, uint8_t *ptr; uint32_t val; target_phys_addr_t page; - unsigned long pd; + ram_addr_t pd; PhysPageDesc *p; while (len > 0) { @@ -3896,7 +3918,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, l = 1; } } else { - unsigned long addr1; + ram_addr_t addr1; addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); /* RAM case */ ptr = qemu_get_ram_ptr(addr1); @@ -4050,7 +4072,9 @@ void *cpu_physical_memory_map(target_phys_addr_t addr, target_phys_addr_t page; unsigned long pd; PhysPageDesc *p; - target_phys_addr_t addr1 = addr; + ram_addr_t raddr = RAM_ADDR_MAX; + ram_addr_t rlen; + void *ret; while (len > 0) { page = addr & TARGET_PAGE_MASK; @@ -4078,13 +4102,18 @@ void *cpu_physical_memory_map(target_phys_addr_t addr, *plen = l; return bounce.buffer; } + if (!todo) { + raddr = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); + } len -= l; addr += l; todo += l; } - *plen = todo; - return qemu_ram_ptr_length(addr1, plen); + rlen = todo; + ret = qemu_ram_ptr_length(raddr, &rlen); + *plen = rlen; + return ret; } /* Unmaps a memory region previously mapped by cpu_physical_memory_map(). @@ -4113,8 +4142,8 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len, access_len -= l; } } - if (xen_mapcache_enabled()) { - qemu_invalidate_entry(buffer); + if (xen_enabled()) { + xen_invalidate_map_cache_entry(buffer); } return; } |