diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-09-13 16:04:46 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-09-13 16:04:46 +0100 |
commit | 138985c1ef8b66e4e5b383354e133e05d01d0b5f (patch) | |
tree | 2f7b666292ff96a04efb229c305469595b188d94 | |
parent | 85182c96de61f0b600bbe834d5a23e713162e892 (diff) | |
parent | d1cc1533509012916dceeb7f23accda8a9fee85c (diff) |
Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-sep-12-2019' into staging
MIPS queue for September 12th, 2019
# gpg: Signature made Thu 12 Sep 2019 17:26:10 BST
# gpg: using RSA key D4972A8967F75A65
# gpg: Good signature from "Aleksandar Markovic <amarkovic@wavecomp.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8526 FBF1 5DA3 811F 4A01 DD75 D497 2A89 67F7 5A65
* remotes/amarkovic/tags/mips-queue-sep-12-2019:
target/mips: gdbstub: Revert commit 8e0b373
hw/mips/mips_jazz: Remove no-longer-necessary override of do_unassigned_access
target/mips: Switch to do_transaction_failed() hook
hw/mips/mips_jazz: Override do_transaction_failed hook
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/mips/mips_jazz.c | 47 | ||||
-rw-r--r-- | target/mips/cpu.c | 2 | ||||
-rw-r--r-- | target/mips/gdbstub.c | 3 | ||||
-rw-r--r-- | target/mips/internal.h | 8 | ||||
-rw-r--r-- | target/mips/op_helper.c | 24 |
5 files changed, 48 insertions, 36 deletions
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c index 388c15c376..c967b97d80 100644 --- a/hw/mips/mips_jazz.c +++ b/hw/mips/mips_jazz.c @@ -111,16 +111,26 @@ static const MemoryRegionOps dma_dummy_ops = { #define MAGNUM_BIOS_SIZE_MAX 0x7e000 #define MAGNUM_BIOS_SIZE (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX) -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) +static void (*real_do_transaction_failed)(CPUState *cpu, hwaddr physaddr, + vaddr addr, unsigned size, + MMUAccessType access_type, + int mmu_idx, MemTxAttrs attrs, + MemTxResult response, + uintptr_t retaddr); + +static void mips_jazz_do_transaction_failed(CPUState *cs, hwaddr physaddr, + vaddr addr, unsigned size, + MMUAccessType access_type, + int mmu_idx, MemTxAttrs attrs, + MemTxResult response, + uintptr_t retaddr) { - if (!is_exec) { + if (access_type != MMU_INST_FETCH) { /* ignore invalid access (ie do not raise exception) */ return; } - (*real_do_unassigned_access)(cpu, addr, is_write, is_exec, opaque, size); + (*real_do_transaction_failed)(cs, physaddr, addr, size, access_type, + mmu_idx, attrs, response, retaddr); } static void mips_jazz_init(MachineState *machine, @@ -157,16 +167,25 @@ static void mips_jazz_init(MachineState *machine, env = &cpu->env; qemu_register_reset(main_cpu_reset, cpu); - /* Chipset returns 0 in invalid reads and do not raise data exceptions. + /* + * 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. */ + * everything, as this would make all accesses including instruction + * accesses be ignored and not raise exceptions. + * So instead we hijack the do_transaction_failed method on the CPU, and + * do not raise exceptions for data access. + * + * NOTE: this behaviour of raising exceptions for bad instruction + * fetches but not bad data accesses was added in commit 54e755588cf1e9 + * to restore behaviour broken by c658b94f6e8c206, but it is not clear + * whether the real hardware behaves this way. It is possible that + * real hardware ignores bad instruction fetches as well -- if so then + * we could replace this hijacking of CPU methods with a simple global + * memory region that catches all memory accesses, as we do on Malta. + */ cc = CPU_GET_CLASS(cpu); - real_do_unassigned_access = cc->do_unassigned_access; - cc->do_unassigned_access = mips_jazz_do_unassigned_access; + real_do_transaction_failed = cc->do_transaction_failed; + cc->do_transaction_failed = mips_jazz_do_transaction_failed; /* allocate RAM */ memory_region_allocate_system_memory(ram, NULL, "mips_jazz.ram", diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 3ffa342187..bbcf7ca463 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -202,7 +202,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data) cc->gdb_read_register = mips_cpu_gdb_read_register; cc->gdb_write_register = mips_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY - cc->do_unassigned_access = mips_cpu_unassigned_access; + cc->do_transaction_failed = mips_cpu_do_transaction_failed; cc->do_unaligned_access = mips_cpu_do_unaligned_access; cc->get_phys_page_debug = mips_cpu_get_phys_page_debug; cc->vmsd = &vmstate_mips_cpu; diff --git a/target/mips/gdbstub.c b/target/mips/gdbstub.c index ebcc98bdde..bbb2544939 100644 --- a/target/mips/gdbstub.c +++ b/target/mips/gdbstub.c @@ -38,7 +38,7 @@ int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) return gdb_get_regl(mem_buf, (int32_t)env->active_fpu.fcr0); default: if (env->CP0_Status & (1 << CP0St_FR)) { - return gdb_get_reg64(mem_buf, + return gdb_get_regl(mem_buf, env->active_fpu.fpr[n - 38].d); } else { return gdb_get_regl(mem_buf, @@ -99,7 +99,6 @@ int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) break; default: if (env->CP0_Status & (1 << CP0St_FR)) { - uint64_t tmp = ldq_p(mem_buf); env->active_fpu.fpr[n - 38].d = tmp; } else { env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp; diff --git a/target/mips/internal.h b/target/mips/internal.h index ae29b578a4..685e8d67e9 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -139,9 +139,11 @@ void r4k_helper_tlbinv(CPUMIPSState *env); void r4k_helper_tlbinvf(CPUMIPSState *env); void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra); -void mips_cpu_unassigned_access(CPUState *cpu, hwaddr addr, - bool is_write, bool is_exec, int unused, - unsigned size); +void mips_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, + vaddr addr, unsigned size, + MMUAccessType access_type, + int mmu_idx, MemTxAttrs attrs, + MemTxResult response, uintptr_t retaddr); hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address, int rw); #endif diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index 01b9e78bf3..4de64657ef 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -2668,27 +2668,19 @@ void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr, do_raise_exception_err(env, excp, error_code, retaddr); } -void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr, - bool is_write, bool is_exec, int unused, - unsigned size) +void mips_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, + vaddr addr, unsigned size, + MMUAccessType access_type, + int mmu_idx, MemTxAttrs attrs, + MemTxResult response, uintptr_t retaddr) { MIPSCPU *cpu = MIPS_CPU(cs); CPUMIPSState *env = &cpu->env; - /* - * Raising an exception with KVM enabled will crash because it won't be from - * the main execution loop so the longjmp won't have a matching setjmp. - * Until we can trigger a bus error exception through KVM lets just ignore - * the access. - */ - if (kvm_enabled()) { - return; - } - - if (is_exec) { - raise_exception(env, EXCP_IBE); + if (access_type == MMU_INST_FETCH) { + do_raise_exception(env, EXCP_IBE, retaddr); } else { - raise_exception(env, EXCP_DBE); + do_raise_exception(env, EXCP_DBE, retaddr); } } #endif /* !CONFIG_USER_ONLY */ |