diff options
Diffstat (limited to 'target/ppc/mmu-radix64.c')
-rw-r--r-- | target/ppc/mmu-radix64.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c index 1fc1ba3ecf..920084bd8f 100644 --- a/target/ppc/mmu-radix64.c +++ b/target/ppc/mmu-radix64.c @@ -145,6 +145,13 @@ static void ppc_radix64_raise_hsi(PowerPCCPU *cpu, MMUAccessType access_type, CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; + env->error_code = 0; + if (cause & DSISR_PRTABLE_FAULT) { + /* HDSI PRTABLE_FAULT gets the originating access type in error_code */ + env->error_code = access_type; + access_type = MMU_DATA_LOAD; + } + qemu_log_mask(CPU_LOG_MMU, "%s for %s @0x%"VADDR_PRIx" 0x%" HWADDR_PRIx" cause %08x\n", __func__, access_str(access_type), @@ -166,7 +173,6 @@ static void ppc_radix64_raise_hsi(PowerPCCPU *cpu, MMUAccessType access_type, env->spr[SPR_HDSISR] = cause; env->spr[SPR_HDAR] = eaddr; env->spr[SPR_ASDR] = g_raddr; - env->error_code = 0; break; default: g_assert_not_reached(); @@ -369,13 +375,14 @@ static bool validate_pate(PowerPCCPU *cpu, uint64_t lpid, ppc_v3_pate_t *pate) } static int ppc_radix64_partition_scoped_xlate(PowerPCCPU *cpu, - MMUAccessType access_type, + MMUAccessType orig_access_type, vaddr eaddr, hwaddr g_raddr, ppc_v3_pate_t pate, hwaddr *h_raddr, int *h_prot, int *h_page_size, bool pde_addr, int mmu_idx, bool guest_visible) { + MMUAccessType access_type = orig_access_type; int fault_cause = 0; hwaddr pte_addr; uint64_t pte; @@ -404,7 +411,8 @@ static int ppc_radix64_partition_scoped_xlate(PowerPCCPU *cpu, fault_cause |= DSISR_PRTABLE_FAULT; } if (guest_visible) { - ppc_radix64_raise_hsi(cpu, access_type, eaddr, g_raddr, fault_cause); + ppc_radix64_raise_hsi(cpu, orig_access_type, + eaddr, g_raddr, fault_cause); } return 1; } |