diff options
author | Hervé Poussineau <hpoussin@reactos.org> | 2013-11-04 23:26:17 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2013-11-21 17:39:22 +0100 |
commit | b6a06e72ef5e66e539012f63fca52c161c0d2496 (patch) | |
tree | 2bea5d12fc9f9f7e86ee557267c6ddd0c2e6264e | |
parent | b5fc314bcbb80f76b8deaf23a4c45767b87f750b (diff) |
mips jazz: do not raise data bus exception when accessing invalid addresses
MIPS Jazz chipset doesn't seem to raise data bus exceptions on invalid accesses.
However, there is no easy way to prevent them. Creating a big memory region
for the whole address space doesn't prevent memory core to directly call
unassigned_mem_read/write which in turn call cpu->do_unassigned_access,
which (for MIPS CPU) raise an data bus exception.
This fixes a MIPS Jazz regression introduced in c658b94f6e8c206c59d02aa6fbac285b86b53d2c.
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | hw/mips/mips_jazz.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c index 49bdd024ed..5f6dd9f588 100644 --- a/hw/mips/mips_jazz.c +++ b/hw/mips/mips_jazz.c @@ -108,6 +108,18 @@ static void cpu_request_exit(void *opaque, int irq, int level) } } +static CPUUnassignedAccess real_do_unassigned_access; +static void mips_jazz_do_unassigned_access(CPUState *cpu, hwaddr addr, + bool is_write, bool is_exec, + int opaque, unsigned size) +{ + if (!is_exec) { + /* ignore invalid access (ie do not raise exception) */ + return; + } + (*real_do_unassigned_access)(cpu, addr, is_write, is_exec, opaque, size); +} + static void mips_jazz_init(MemoryRegion *address_space, MemoryRegion *address_space_io, ram_addr_t ram_size, @@ -117,6 +129,7 @@ static void mips_jazz_init(MemoryRegion *address_space, char *filename; int bios_size, n; MIPSCPU *cpu; + CPUClass *cc; CPUMIPSState *env; qemu_irq *rc4030, *i8259; rc4030_dma *dmas; @@ -154,6 +167,17 @@ static void mips_jazz_init(MemoryRegion *address_space, env = &cpu->env; qemu_register_reset(main_cpu_reset, cpu); + /* Chipset returns 0 in invalid reads and do not raise data exceptions. + * However, we can't simply add a global memory region to catch + * everything, as memory core directly call unassigned_mem_read/write + * on some invalid accesses, which call do_unassigned_access on the + * CPU, which raise an exception. + * Handle that case by hijacking the do_unassigned_access method on + * the CPU, and do not raise exceptions for data access. */ + cc = CPU_GET_CLASS(cpu); + real_do_unassigned_access = cc->do_unassigned_access; + cc->do_unassigned_access = mips_jazz_do_unassigned_access; + /* allocate RAM */ memory_region_init_ram(ram, NULL, "mips_jazz.ram", ram_size); vmstate_register_ram_global(ram); |