target/ppc: Use MMUAccessType in mmu-hash32.c

We must leave the 'int rwx' parameter to ppc_hash32_handle_mmu_fault
for now, but will clean that up later.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20210518201146.794854-5-richard.henderson@linaro.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Richard Henderson 2021-05-18 15:11:26 -05:00 committed by David Gibson
parent 59dec5bf5a
commit 31fa64ecfd
1 changed files with 29 additions and 24 deletions

View File

@ -153,16 +153,17 @@ static int hash32_bat_601_prot(PowerPCCPU *cpu,
return ppc_hash32_pp_prot(key, pp, 0);
}
static hwaddr ppc_hash32_bat_lookup(PowerPCCPU *cpu, target_ulong ea, int rwx,
int *prot)
static hwaddr ppc_hash32_bat_lookup(PowerPCCPU *cpu, target_ulong ea,
MMUAccessType access_type, int *prot)
{
CPUPPCState *env = &cpu->env;
target_ulong *BATlt, *BATut;
bool ifetch = access_type == MMU_INST_FETCH;
int i;
LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
rwx == 2 ? 'I' : 'D', ea);
if (rwx == 2) {
ifetch ? 'I' : 'D', ea);
if (ifetch) {
BATlt = env->IBAT[1];
BATut = env->IBAT[0];
} else {
@ -181,7 +182,7 @@ static hwaddr ppc_hash32_bat_lookup(PowerPCCPU *cpu, target_ulong ea, int rwx,
}
LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
" BATl " TARGET_FMT_lx "\n", __func__,
type == ACCESS_CODE ? 'I' : 'D', i, ea, batu, batl);
ifetch ? 'I' : 'D', i, ea, batu, batl);
if (mask && ((ea & mask) == (batu & BATU32_BEPI))) {
hwaddr raddr = (batl & mask) | (ea & ~mask);
@ -209,7 +210,7 @@ static hwaddr ppc_hash32_bat_lookup(PowerPCCPU *cpu, target_ulong ea, int rwx,
LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
" BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
TARGET_FMT_lx " " TARGET_FMT_lx "\n",
__func__, type == ACCESS_CODE ? 'I' : 'D', i, ea,
__func__, ifetch ? 'I' : 'D', i, ea,
*BATu, *BATl, BEPIu, BEPIl, bl);
}
}
@ -219,7 +220,8 @@ static hwaddr ppc_hash32_bat_lookup(PowerPCCPU *cpu, target_ulong ea, int rwx,
}
static int ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr,
target_ulong eaddr, int rwx,
target_ulong eaddr,
MMUAccessType access_type,
hwaddr *raddr, int *prot)
{
CPUState *cs = CPU(cpu);
@ -240,7 +242,7 @@ static int ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr,
return 0;
}
if (rwx == 2) {
if (access_type == MMU_INST_FETCH) {
/* No code fetch is allowed in direct-store areas */
cs->exception_index = POWERPC_EXCP_ISI;
env->error_code = 0x10000000;
@ -261,7 +263,7 @@ static int ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr,
/* lwarx, ldarx or srwcx. */
env->error_code = 0;
env->spr[SPR_DAR] = eaddr;
if (rwx == 1) {
if (access_type == MMU_DATA_STORE) {
env->spr[SPR_DSISR] = 0x06000000;
} else {
env->spr[SPR_DSISR] = 0x04000000;
@ -281,7 +283,7 @@ static int ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr,
cs->exception_index = POWERPC_EXCP_DSI;
env->error_code = 0;
env->spr[SPR_DAR] = eaddr;
if (rwx == 1) {
if (access_type == MMU_DATA_STORE) {
env->spr[SPR_DSISR] = 0x06100000;
} else {
env->spr[SPR_DSISR] = 0x04100000;
@ -291,14 +293,15 @@ static int ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr,
cpu_abort(cs, "ERROR: instruction should not need "
"address translation\n");
}
if ((rwx == 1 || key != 1) && (rwx == 0 || key != 0)) {
if ((access_type == MMU_DATA_STORE || key != 1) &&
(access_type == MMU_DATA_LOAD || key != 0)) {
*raddr = eaddr;
return 0;
} else {
cs->exception_index = POWERPC_EXCP_DSI;
env->error_code = 0;
env->spr[SPR_DAR] = eaddr;
if (rwx == 1) {
if (access_type == MMU_DATA_STORE) {
env->spr[SPR_DSISR] = 0x0a000000;
} else {
env->spr[SPR_DSISR] = 0x08000000;
@ -423,13 +426,15 @@ int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
ppc_hash_pte32_t pte;
int prot;
int need_prot;
MMUAccessType access_type;
hwaddr raddr;
assert((rwx == 0) || (rwx == 1) || (rwx == 2));
need_prot = prot_for_access_type(rwx);
access_type = rwx;
need_prot = prot_for_access_type(access_type);
/* 1. Handle real mode accesses */
if (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0))) {
if (access_type == MMU_INST_FETCH ? !msr_ir : !msr_dr) {
/* Translation is off */
raddr = eaddr;
tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
@ -440,17 +445,17 @@ int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
/* 2. Check Block Address Translation entries (BATs) */
if (env->nb_BATs != 0) {
raddr = ppc_hash32_bat_lookup(cpu, eaddr, rwx, &prot);
raddr = ppc_hash32_bat_lookup(cpu, eaddr, access_type, &prot);
if (raddr != -1) {
if (need_prot & ~prot) {
if (rwx == 2) {
if (access_type == MMU_INST_FETCH) {
cs->exception_index = POWERPC_EXCP_ISI;
env->error_code = 0x08000000;
} else {
cs->exception_index = POWERPC_EXCP_DSI;
env->error_code = 0;
env->spr[SPR_DAR] = eaddr;
if (rwx == 1) {
if (access_type == MMU_DATA_STORE) {
env->spr[SPR_DSISR] = 0x0a000000;
} else {
env->spr[SPR_DSISR] = 0x08000000;
@ -471,7 +476,7 @@ int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
/* 4. Handle direct store segments */
if (sr & SR32_T) {
if (ppc_hash32_direct_store(cpu, sr, eaddr, rwx,
if (ppc_hash32_direct_store(cpu, sr, eaddr, access_type,
&raddr, &prot) == 0) {
tlb_set_page(cs, eaddr & TARGET_PAGE_MASK,
raddr & TARGET_PAGE_MASK, prot, mmu_idx,
@ -483,7 +488,7 @@ int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
}
/* 5. Check for segment level no-execute violation */
if ((rwx == 2) && (sr & SR32_NX)) {
if (access_type == MMU_INST_FETCH && (sr & SR32_NX)) {
cs->exception_index = POWERPC_EXCP_ISI;
env->error_code = 0x10000000;
return 1;
@ -492,14 +497,14 @@ int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
/* 6. Locate the PTE in the hash table */
pte_offset = ppc_hash32_htab_lookup(cpu, sr, eaddr, &pte);
if (pte_offset == -1) {
if (rwx == 2) {
if (access_type == MMU_INST_FETCH) {
cs->exception_index = POWERPC_EXCP_ISI;
env->error_code = 0x40000000;
} else {
cs->exception_index = POWERPC_EXCP_DSI;
env->error_code = 0;
env->spr[SPR_DAR] = eaddr;
if (rwx == 1) {
if (access_type == MMU_DATA_STORE) {
env->spr[SPR_DSISR] = 0x42000000;
} else {
env->spr[SPR_DSISR] = 0x40000000;
@ -518,14 +523,14 @@ int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
if (need_prot & ~prot) {
/* Access right violation */
qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
if (rwx == 2) {
if (access_type == MMU_INST_FETCH) {
cs->exception_index = POWERPC_EXCP_ISI;
env->error_code = 0x08000000;
} else {
cs->exception_index = POWERPC_EXCP_DSI;
env->error_code = 0;
env->spr[SPR_DAR] = eaddr;
if (rwx == 1) {
if (access_type == MMU_DATA_STORE) {
env->spr[SPR_DSISR] = 0x0a000000;
} else {
env->spr[SPR_DSISR] = 0x08000000;
@ -542,7 +547,7 @@ int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
ppc_hash32_set_r(cpu, pte_offset, pte.pte1);
}
if (!(pte.pte1 & HPTE32_R_C)) {
if (rwx == 1) {
if (access_type == MMU_DATA_STORE) {
ppc_hash32_set_c(cpu, pte_offset, pte.pte1);
} else {
/*