mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-25 18:36:48 +00:00
target/sparc: Check for transaction failures in MMU passthrough ASIs
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 "MMU passthrough". Backports commit b9f5fdad49c74583dcf9fcba0805b148e3992e13 from qemu
This commit is contained in:
parent
0b48392779
commit
a9e087b252
|
@ -721,26 +721,36 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
|
|||
/* MMU passthrough, 0x100000000 to 0xfffffffff */
|
||||
case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
|
||||
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
|
||||
{
|
||||
MemTxResult result;
|
||||
hwaddr access_addr = (hwaddr)addr | ((hwaddr)(asi & 0xf) << 32);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
ret = ldub_phys(cs->as, (hwaddr)addr
|
||||
| ((hwaddr)(asi & 0xf) << 32));
|
||||
ret = address_space_ldub(cs->as, access_addr,
|
||||
MEMTXATTRS_UNSPECIFIED, &result);
|
||||
break;
|
||||
case 2:
|
||||
ret = lduw_phys(cs->as, (hwaddr)addr
|
||||
| ((hwaddr)(asi & 0xf) << 32));
|
||||
ret = address_space_lduw(cs->as, access_addr,
|
||||
MEMTXATTRS_UNSPECIFIED, &result);
|
||||
break;
|
||||
default:
|
||||
case 4:
|
||||
ret = ldl_phys(cs->as, (hwaddr)addr
|
||||
| ((hwaddr)(asi & 0xf) << 32));
|
||||
ret = address_space_ldl(cs->as, access_addr,
|
||||
MEMTXATTRS_UNSPECIFIED, &result);
|
||||
break;
|
||||
case 8:
|
||||
ret = ldq_phys(cs->as, (hwaddr)addr
|
||||
| ((hwaddr)(asi & 0xf) << 32));
|
||||
ret = address_space_ldq(cs->as, access_addr,
|
||||
MEMTXATTRS_UNSPECIFIED, &result);
|
||||
break;
|
||||
}
|
||||
|
||||
if (result != MEMTX_OK) {
|
||||
sparc_raise_mmu_fault(cs, access_addr, false, false, false,
|
||||
size, GETPC());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x30: /* Turbosparc secondary cache diagnostic */
|
||||
case 0x31: /* Turbosparc RAM snoop */
|
||||
case 0x32: /* Turbosparc page table descriptor diagnostic */
|
||||
|
@ -1058,25 +1068,32 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
|
|||
case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
|
||||
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
|
||||
{
|
||||
MemTxResult result;
|
||||
hwaddr access_addr = (hwaddr)addr | ((hwaddr)(asi & 0xf) << 32);
|
||||
|
||||
switch (size) {
|
||||
case 1:
|
||||
stb_phys(cs->as, (hwaddr)addr
|
||||
| ((hwaddr)(asi & 0xf) << 32), val);
|
||||
address_space_stb(cs->as, access_addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, &result);
|
||||
break;
|
||||
case 2:
|
||||
stw_phys(cs->as, (hwaddr)addr
|
||||
| ((hwaddr)(asi & 0xf) << 32), val);
|
||||
address_space_stw(cs->as, access_addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, &result);
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
stl_phys(cs->as, (hwaddr)addr
|
||||
| ((hwaddr)(asi & 0xf) << 32), val);
|
||||
address_space_stl(cs->as, access_addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, &result);
|
||||
break;
|
||||
case 8:
|
||||
stq_phys(cs->as, (hwaddr)addr
|
||||
| ((hwaddr)(asi & 0xf) << 32), val);
|
||||
address_space_stq(cs->as, access_addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, &result);
|
||||
break;
|
||||
}
|
||||
if (result != MEMTX_OK) {
|
||||
sparc_raise_mmu_fault(cs, access_addr, true, false, false,
|
||||
size, GETPC());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x30: /* store buffer tags or Turbosparc secondary cache diagnostic */
|
||||
|
|
Loading…
Reference in a new issue