mirror of
https://github.com/qemu/qemu.git
synced 2024-11-26 12:23:36 +08:00
target/sparc: Check for transaction failures in MXCC stream ASI accesses
Currently the ld/st_asi helper functions make calls to the ld*_phys() and st*_phys() functions for those ASIs which imply direct accesses to physical addresses. These implicitly rely on the unassigned_access hook to cause them to generate an MMU fault if the access fails. Switch to using the address_space_* functions instead, which return a MemTxResult that we can check. This means that when we switch SPARC over to using the do_transaction_failed hook we'll still get the same MMU faults we did before. This commit converts the ASIs which do MXCC stream source and destination accesses. It's not clear to me whether raising an MMU fault like this is the correct behaviour if we encounter a bus error, but we retain the same behaviour that the old unassigned_access hook would implement. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Message-id: 20190801183012.17564-4-peter.maydell@linaro.org
This commit is contained in:
parent
b9f5fdad49
commit
776095d3cd
@ -880,6 +880,9 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x01c00100: /* MXCC stream source */
|
case 0x01c00100: /* MXCC stream source */
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (size == 8) {
|
if (size == 8) {
|
||||||
env->mxccregs[0] = val;
|
env->mxccregs[0] = val;
|
||||||
} else {
|
} else {
|
||||||
@ -887,20 +890,27 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
|
|||||||
"%08x: unimplemented access size: %d\n", addr,
|
"%08x: unimplemented access size: %d\n", addr,
|
||||||
size);
|
size);
|
||||||
}
|
}
|
||||||
env->mxccdata[0] = ldq_phys(cs->as,
|
|
||||||
(env->mxccregs[0] & 0xffffffffULL) +
|
for (i = 0; i < 4; i++) {
|
||||||
0);
|
MemTxResult result;
|
||||||
env->mxccdata[1] = ldq_phys(cs->as,
|
hwaddr access_addr = (env->mxccregs[0] & 0xffffffffULL) + 8 * i;
|
||||||
(env->mxccregs[0] & 0xffffffffULL) +
|
|
||||||
8);
|
env->mxccdata[i] = address_space_ldq(cs->as,
|
||||||
env->mxccdata[2] = ldq_phys(cs->as,
|
access_addr,
|
||||||
(env->mxccregs[0] & 0xffffffffULL) +
|
MEMTXATTRS_UNSPECIFIED,
|
||||||
16);
|
&result);
|
||||||
env->mxccdata[3] = ldq_phys(cs->as,
|
if (result != MEMTX_OK) {
|
||||||
(env->mxccregs[0] & 0xffffffffULL) +
|
/* TODO: investigate whether this is the right behaviour */
|
||||||
24);
|
sparc_raise_mmu_fault(cs, access_addr, false, false,
|
||||||
|
false, size, GETPC());
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 0x01c00200: /* MXCC stream destination */
|
case 0x01c00200: /* MXCC stream destination */
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (size == 8) {
|
if (size == 8) {
|
||||||
env->mxccregs[1] = val;
|
env->mxccregs[1] = val;
|
||||||
} else {
|
} else {
|
||||||
@ -908,15 +918,22 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
|
|||||||
"%08x: unimplemented access size: %d\n", addr,
|
"%08x: unimplemented access size: %d\n", addr,
|
||||||
size);
|
size);
|
||||||
}
|
}
|
||||||
stq_phys(cs->as, (env->mxccregs[1] & 0xffffffffULL) + 0,
|
|
||||||
env->mxccdata[0]);
|
for (i = 0; i < 4; i++) {
|
||||||
stq_phys(cs->as, (env->mxccregs[1] & 0xffffffffULL) + 8,
|
MemTxResult result;
|
||||||
env->mxccdata[1]);
|
hwaddr access_addr = (env->mxccregs[1] & 0xffffffffULL) + 8 * i;
|
||||||
stq_phys(cs->as, (env->mxccregs[1] & 0xffffffffULL) + 16,
|
|
||||||
env->mxccdata[2]);
|
address_space_stq(cs->as, access_addr, env->mxccdata[i],
|
||||||
stq_phys(cs->as, (env->mxccregs[1] & 0xffffffffULL) + 24,
|
MEMTXATTRS_UNSPECIFIED, &result);
|
||||||
env->mxccdata[3]);
|
|
||||||
|
if (result != MEMTX_OK) {
|
||||||
|
/* TODO: investigate whether this is the right behaviour */
|
||||||
|
sparc_raise_mmu_fault(cs, access_addr, true, false,
|
||||||
|
false, size, GETPC());
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 0x01c00a00: /* MXCC control register */
|
case 0x01c00a00: /* MXCC control register */
|
||||||
if (size == 8) {
|
if (size == 8) {
|
||||||
env->mxccregs[3] = val;
|
env->mxccregs[3] = val;
|
||||||
|
Loading…
Reference in New Issue
Block a user