diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2023-06-20 23:10:43 +1000 |
---|---|---|
committer | Cédric Le Goater <clg@kaod.org> | 2023-06-25 22:41:30 +0200 |
commit | 5a5d3b23cb281d99ee6dd74afa41864428e35241 (patch) | |
tree | 11ff246b6108e853bfb38fa1a62509841c36111c /target/ppc/mmu-radix64.c | |
parent | 74574c3845a046174993092cdc3c03f481dc2cf3 (diff) |
target/ppc: Add SRR1 prefix indication to interrupt handlers
ISA v3.1 introduced prefix instructions. Among the changes, various
synchronous interrupts report whether they were caused by a prefix
instruction in (H)SRR1.
The case of instruction fetch that causes an HDSI due to access of a
process-scoped table faulting on the partition scoped translation is the
tricky one. As with ISIs and HISIs, this does not try to set the prefix
bit because there is no instruction image to be loaded. The HDSI needs
the originating access type to be passed through to the handler to
distinguish this from HDSIs that fault translating process scoped tables
originating from a load or store instruction (in that case the prefix
bit should be provided).
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
[ clg: checkpatch issues ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
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; } |