diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2013-05-24 14:48:38 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2013-05-29 16:26:47 +0200 |
commit | b018ddf633f77195e9ae859c6d940a334e68879f (patch) | |
tree | 2b3ec449e0fc9f23145f12419f43deb2c8565e71 /memory.c | |
parent | bf8d5166395612b4e856fad57606eb0cff97ae2e (diff) | |
download | qemu-b018ddf633f77195e9ae859c6d940a334e68879f.tar.gz qemu-b018ddf633f77195e9ae859c6d940a334e68879f.tar.bz2 qemu-b018ddf633f77195e9ae859c6d940a334e68879f.zip |
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 <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'memory.c')
-rw-r--r-- | memory.c | 28 |
1 files changed, 26 insertions, 2 deletions
@@ -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); |