MIPS queue for September 12th, 2019

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJdenGiAAoJENSXKoln91plKOkIAIkLXa13c0JmZvNA4DjEOwS7
 FRDv/hdWVYALalzy+b51ppH/bZfOxe+5BZAxdMSCc84Tm9Jmqyerzp4PWkH2EeqG
 ChtUnkC2lZ6K3zAFIMIa8NhopayKbAMYV2w61J7u4Xk65xiH1M55DWjmwt70LiMW
 oUStum06paUadUUyZwNU3MTN1D9AHiezO6VQp9CCn1kvBf5u+bZSodcXsSo97YOF
 I4MLZlLuZ5sxCRvnMQfWlzykB8PDvIfH5/Dq/DXlkoJNS99vCVmNFE1dAX3NSqi8
 HQD3rkEY4TWTVD570oTtZCn+WBIgHbvbqojsmTlo3tFhWv2JEQdCKyz8+4isld8=
 =6NbW
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Peter Maydell 2019-09-13 16:04:46 +01:00
commit 138985c1ef
5 changed files with 48 additions and 36 deletions

View file

@ -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",

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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 */