Re: [Qemu-devel] [PATCH 06/22] memory: dispatch unassigned accesses based on .valid.accepts
On 2013-05-30 23:03, Paolo Bonzini wrote: 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 r...@twiddle.net Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- exec.c | 36 memory.c | 28 ++-- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/exec.c b/exec.c index 785eeeb..c5100d6 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; -} - -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 +return false; } -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 99f046d..15da877 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; This changed the value read from unassigned memory from -1 to 0. Any particular reason or an unintentional change? Note that this also breaks unassigned portio accesses, specifically the case Stefan reported around IPMI access of the Linux kernel. Jan +} + +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); -- Siemens AG, Corporate Technology, CT RTC ITP SES-DE Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH 06/22] memory: dispatch unassigned accesses based on .valid.accepts
Il 16/07/2013 14:28, Jan Kiszka ha scritto: On 2013-05-30 23:03, Paolo Bonzini wrote: 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 r...@twiddle.net Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- exec.c | 36 memory.c | 28 ++-- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/exec.c b/exec.c index 785eeeb..c5100d6 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; -} - -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 +return false; } -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 99f046d..15da877 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; This changed the value read from unassigned memory from -1 to 0. Any particular reason or an unintentional change? Cut-and-paste (unassigned RAM used to return 0, invalid MMIO used to return -1, unifying the paths dropped the difference). I guess unassigned RAM can read as -1 just fine, so we can just change unassigned_mem_read to return -1. Paolo Jan +} + +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);
Re: [Qemu-devel] [PATCH 06/22] memory: dispatch unassigned accesses based on .valid.accepts
On 16 July 2013 13:33, Paolo Bonzini pbonz...@redhat.com wrote: Il 16/07/2013 14:28, Jan Kiszka ha scritto: This changed the value read from unassigned memory from -1 to 0. Any particular reason or an unintentional change? Cut-and-paste (unassigned RAM used to return 0, invalid MMIO used to return -1, unifying the paths dropped the difference). I guess unassigned RAM can read as -1 just fine, so we can just change unassigned_mem_read to return -1. Behaviour for accesses to unassigned addresses should really be both bus and CPU specific... thanks -- PMM
Re: [Qemu-devel] [PATCH 06/22] memory: dispatch unassigned accesses based on .valid.accepts
On 2013-07-16 14:38, Peter Maydell wrote: On 16 July 2013 13:33, Paolo Bonzini pbonz...@redhat.com wrote: Il 16/07/2013 14:28, Jan Kiszka ha scritto: This changed the value read from unassigned memory from -1 to 0. Any particular reason or an unintentional change? Cut-and-paste (unassigned RAM used to return 0, invalid MMIO used to return -1, unifying the paths dropped the difference). I guess unassigned RAM can read as -1 just fine, so we can just change unassigned_mem_read to return -1. Behaviour for accesses to unassigned addresses should really be both bus and CPU specific... Yes, that's what I was thinking as well when reading it. Still, lets restore what we did before, then refine. Jan -- Siemens AG, Corporate Technology, CT RTC ITP SES-DE Corporate Competence Center Embedded Linux
Re: [Qemu-devel] [PATCH 06/22] memory: dispatch unassigned accesses based on .valid.accepts
Il 01/06/2013 17:28, Blue Swirl ha scritto: This means that memory.c is getting knowledge about CPU types and it becomes more specific to current target. I think memory.c should be generic and target agnostic (maybe one day compiled just once) with exec.c implementing the target specific functionality. You're right, but the solution is simply to make cpu_unassigned_access a CPU method. Paolo
Re: [Qemu-devel] [PATCH 06/22] memory: dispatch unassigned accesses based on .valid.accepts
Am 03.06.2013 09:31, schrieb Paolo Bonzini: Il 01/06/2013 17:28, Blue Swirl ha scritto: This means that memory.c is getting knowledge about CPU types and it becomes more specific to current target. I think memory.c should be generic and target agnostic (maybe one day compiled just once) with exec.c implementing the target specific functionality. You're right, but the solution is simply to make cpu_unassigned_access a CPU method. I already have a patch queued to that effect on qom-cpu-10 branch that I needed to rebase after your merge. :) Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH 06/22] memory: dispatch unassigned accesses based on .valid.accepts
On Thu, May 30, 2013 at 9:03 PM, Paolo Bonzini pbonz...@redhat.com wrote: 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 r...@twiddle.net Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- exec.c | 36 memory.c | 28 ++-- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/exec.c b/exec.c index 785eeeb..c5100d6 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; -} - -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 +return false; } -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 99f046d..15da877 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); This means that memory.c is getting knowledge about CPU types and it becomes more specific to current target. I think memory.c should be generic and target agnostic (maybe one day compiled just once) with exec.c implementing the target specific functionality. +#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); -- 1.7.4.1
[Qemu-devel] [PATCH 06/22] 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 r...@twiddle.net Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- exec.c | 36 memory.c | 28 ++-- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/exec.c b/exec.c index 785eeeb..c5100d6 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; -} - -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 +return false; } -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 99f046d..15da877 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); -- 1.7.4.1
[Qemu-devel] [PATCH 06/22] 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. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- exec.c | 36 memory.c | 28 ++-- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/exec.c b/exec.c index 785eeeb..c5100d6 100644 --- a/exec.c +++ b/exec.c @@ -50,7 +50,6 @@ #include exec/memory-internal.h -//#define DEBUG_UNASSIGNED //#define DEBUG_SUBPAGE #if !defined(CONFIG_USER_ONLY) @@ -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; -} - -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 +return false; } -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 99f046d..15da877 100644 --- a/memory.c +++ b/memory.c @@ -22,6 +22,8 @@ #include exec/memory-internal.h +//#define DEBUG_UNASSIGNED + static unsigned memory_region_transaction_depth; static bool memory_region_update_pending; static bool global_dirty_log = false; @@ -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); -- 1.8.1.4