From b018ddf633f77195e9ae859c6d940a334e68879f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 24 May 2013 14:48:38 +0200 Subject: [PATCH] memory: dispatch unassigned accesses based on .valid.accepts This provides the basics for detecting accesses to unassigned memory as soon as they happen, and also for a simple implementation of address_space_access_valid. Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- exec.c | 36 ++++++++++++------------------------ memory.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/exec.c b/exec.c index 785eeebcbc..c5100d69df 100644 --- a/exec.c +++ b/exec.c @@ -1383,32 +1383,14 @@ ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr) return ram_addr; } -static uint64_t unassigned_mem_read(void *opaque, hwaddr addr, - unsigned size) +static bool unassigned_mem_accepts(void *opaque, hwaddr addr, + unsigned size, bool is_write) { -#ifdef DEBUG_UNASSIGNED - printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); -#endif -#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, size); -#endif - return 0; + return false; } -static void unassigned_mem_write(void *opaque, hwaddr addr, - uint64_t val, unsigned size) -{ -#ifdef DEBUG_UNASSIGNED - printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val); -#endif -#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) - cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, size); -#endif -} - -static const MemoryRegionOps unassigned_mem_ops = { - .read = unassigned_mem_read, - .write = unassigned_mem_write, +const MemoryRegionOps unassigned_mem_ops = { + .valid.accepts = unassigned_mem_accepts, .endianness = DEVICE_NATIVE_ENDIAN, }; @@ -1442,9 +1424,15 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr, tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr); } +static bool notdirty_mem_accepts(void *opaque, hwaddr addr, + unsigned size, bool is_write) +{ + return is_write; +} + static const MemoryRegionOps notdirty_mem_ops = { - .read = unassigned_mem_read, .write = notdirty_mem_write, + .valid.accepts = notdirty_mem_accepts, .endianness = DEVICE_NATIVE_ENDIAN, }; diff --git a/memory.c b/memory.c index 99f046d8bb..15da877554 100644 --- a/memory.c +++ b/memory.c @@ -814,6 +814,29 @@ void memory_region_init(MemoryRegion *mr, mr->flush_coalesced_mmio = false; } +static uint64_t unassigned_mem_read(void *opaque, hwaddr addr, + unsigned size) +{ +#ifdef DEBUG_UNASSIGNED + printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); +#endif +#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) + cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, size); +#endif + return 0; +} + +static void unassigned_mem_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ +#ifdef DEBUG_UNASSIGNED + printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val); +#endif +#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) + cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, size); +#endif +} + static bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr, unsigned size, @@ -847,7 +870,7 @@ static uint64_t memory_region_dispatch_read1(MemoryRegion *mr, uint64_t data = 0; if (!memory_region_access_valid(mr, addr, size, false)) { - return -1U; /* FIXME: better signalling */ + return unassigned_mem_read(mr, addr, size); } if (!mr->ops->read) { @@ -898,7 +921,8 @@ static void memory_region_dispatch_write(MemoryRegion *mr, unsigned size) { if (!memory_region_access_valid(mr, addr, size, true)) { - return; /* FIXME: better signalling */ + unassigned_mem_write(mr, addr, data, size); + return; } adjust_endianness(mr, &data, size);