static void io_mem_init(void);
static void memory_map_init(void);
-static void *qemu_safe_ram_ptr(ram_addr_t addr);
static MemoryRegion io_mem_watch;
#endif
abort();
}
-CPUArchState *cpu_copy(CPUArchState *env)
+#if !defined(CONFIG_USER_ONLY)
+static RAMBlock *qemu_get_ram_block(ram_addr_t addr)
{
- CPUArchState *new_env = cpu_init(env->cpu_model_str);
-#if defined(TARGET_HAS_ICE)
- CPUBreakpoint *bp;
- CPUWatchpoint *wp;
-#endif
-
- /* Reset non arch specific state */
- cpu_reset(ENV_GET_CPU(new_env));
-
- /* Copy arch specific state into the new CPU */
- memcpy(new_env, env, sizeof(CPUArchState));
+ RAMBlock *block;
- /* Clone all break/watchpoints.
- Note: Once we support ptrace with hw-debug register access, make sure
- BP_CPU break/watchpoints are handled correctly on clone. */
- QTAILQ_INIT(&env->breakpoints);
- QTAILQ_INIT(&env->watchpoints);
-#if defined(TARGET_HAS_ICE)
- QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
- cpu_breakpoint_insert(new_env, bp->pc, bp->flags, NULL);
+ /* The list is protected by the iothread lock here. */
+ block = ram_list.mru_block;
+ if (block && addr - block->offset < block->length) {
+ goto found;
}
- QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
- cpu_watchpoint_insert(new_env, wp->vaddr, (~wp->len_mask) + 1,
- wp->flags, NULL);
+ QTAILQ_FOREACH(block, &ram_list.blocks, next) {
+ if (addr - block->offset < block->length) {
+ goto found;
+ }
}
-#endif
- return new_env;
+ fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
+ abort();
+
+found:
+ ram_list.mru_block = block;
+ return block;
}
-#if !defined(CONFIG_USER_ONLY)
static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t end,
uintptr_t length)
{
- uintptr_t start1;
+ RAMBlock *block;
+ ram_addr_t start1;
- /* we modify the TLB cache so that the dirty bit will be set again
- when accessing the range */
- start1 = (uintptr_t)qemu_safe_ram_ptr(start);
- /* Check that we don't span multiple blocks - this breaks the
- address comparisons below. */
- if ((uintptr_t)qemu_safe_ram_ptr(end - 1) - start1
- != (end - 1) - start) {
- abort();
- }
+ block = qemu_get_ram_block(start);
+ assert(block == qemu_get_ram_block(end - 1));
+ start1 = (uintptr_t)block->host + (start - block->offset);
cpu_tlb_reset_dirty_all(start1, length);
-
}
/* Note: start and end must be within the same ram block. */
uint16_t section);
static subpage_t *subpage_init(AddressSpace *as, hwaddr base);
-static void *(*phys_mem_alloc)(ram_addr_t size) = qemu_anon_ram_alloc;
+static void *(*phys_mem_alloc)(size_t size) = qemu_anon_ram_alloc;
/*
* Set a custom physical guest memory alloator.
* Accelerators with unusual needs may need this. Hopefully, we can
* get rid of it eventually.
*/
-void phys_mem_set_alloc(void *(*alloc)(ram_addr_t))
+void phys_mem_set_alloc(void *(*alloc)(size_t))
{
phys_mem_alloc = alloc;
}
}
#endif /* !_WIN32 */
-static RAMBlock *qemu_get_ram_block(ram_addr_t addr)
-{
- RAMBlock *block;
-
- /* The list is protected by the iothread lock here. */
- block = ram_list.mru_block;
- if (block && addr - block->offset < block->length) {
- goto found;
- }
- QTAILQ_FOREACH(block, &ram_list.blocks, next) {
- if (addr - block->offset < block->length) {
- goto found;
- }
- }
-
- fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
- abort();
-
-found:
- ram_list.mru_block = block;
- return block;
-}
-
/* Return a host pointer to ram allocated with qemu_ram_alloc.
With the exception of the softmmu code in this file, this should
only be used for local memory (e.g. video ram) that the device owns,
return block->host + (addr - block->offset);
}
-/* Return a host pointer to ram allocated with qemu_ram_alloc. Same as
- * qemu_get_ram_ptr but do not touch ram_list.mru_block.
- *
- * ??? Is this still necessary?
- */
-static void *qemu_safe_ram_ptr(ram_addr_t addr)
-{
- RAMBlock *block;
-
- /* The list is protected by the iothread lock here. */
- QTAILQ_FOREACH(block, &ram_list.blocks, next) {
- if (addr - block->offset < block->length) {
- 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 xen_map_cache(addr, 0, 0);
- } else if (block->host == NULL) {
- block->host =
- xen_map_cache(block->offset, block->length, 1);
- }
- }
- return block->host + (addr - block->offset);
- }
- }
-
- fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
- abort();
-
- return NULL;
-}
-
/* Return a host pointer to guest's ram. Similar to qemu_get_ram_ptr
* but takes a size argument */
static void *qemu_ram_ptr_length(ram_addr_t addr, hwaddr *size)
static void memory_map_init(void)
{
system_memory = g_malloc(sizeof(*system_memory));
- memory_region_init(system_memory, NULL, "system", INT64_MAX);
+
+ assert(TARGET_PHYS_ADDR_SPACE_BITS <= 64);
+
+ memory_region_init(system_memory, NULL, "system",
+ TARGET_PHYS_ADDR_SPACE_BITS == 64 ?
+ UINT64_MAX : (0x1ULL << TARGET_PHYS_ADDR_SPACE_BITS));
address_space_init(&address_space_memory, system_memory, "memory");
system_io = g_malloc(sizeof(*system_io));
if (bounce.buffer) {
return NULL;
}
- bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, TARGET_PAGE_SIZE);
+ /* Avoid unbounded allocations */
+ l = MIN(l, TARGET_PAGE_SIZE);
+ bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, l);
bounce.addr = addr;
bounce.len = l;