mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 16:23:55 -06:00
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:
parent
59dec5bf5a
commit
31fa64ecfd
1 changed files with 29 additions and 24 deletions
|
@ -153,16 +153,17 @@ static int hash32_bat_601_prot(PowerPCCPU *cpu,
|
||||||
return ppc_hash32_pp_prot(key, pp, 0);
|
return ppc_hash32_pp_prot(key, pp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static hwaddr ppc_hash32_bat_lookup(PowerPCCPU *cpu, target_ulong ea, int rwx,
|
static hwaddr ppc_hash32_bat_lookup(PowerPCCPU *cpu, target_ulong ea,
|
||||||
int *prot)
|
MMUAccessType access_type, int *prot)
|
||||||
{
|
{
|
||||||
CPUPPCState *env = &cpu->env;
|
CPUPPCState *env = &cpu->env;
|
||||||
target_ulong *BATlt, *BATut;
|
target_ulong *BATlt, *BATut;
|
||||||
|
bool ifetch = access_type == MMU_INST_FETCH;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
|
LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
|
||||||
rwx == 2 ? 'I' : 'D', ea);
|
ifetch ? 'I' : 'D', ea);
|
||||||
if (rwx == 2) {
|
if (ifetch) {
|
||||||
BATlt = env->IBAT[1];
|
BATlt = env->IBAT[1];
|
||||||
BATut = env->IBAT[0];
|
BATut = env->IBAT[0];
|
||||||
} else {
|
} 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
|
LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
|
||||||
" BATl " TARGET_FMT_lx "\n", __func__,
|
" 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))) {
|
if (mask && ((ea & mask) == (batu & BATU32_BEPI))) {
|
||||||
hwaddr raddr = (batl & mask) | (ea & ~mask);
|
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
|
LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
|
||||||
" BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
|
" BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
|
||||||
TARGET_FMT_lx " " TARGET_FMT_lx "\n",
|
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);
|
*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,
|
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)
|
hwaddr *raddr, int *prot)
|
||||||
{
|
{
|
||||||
CPUState *cs = CPU(cpu);
|
CPUState *cs = CPU(cpu);
|
||||||
|
@ -240,7 +242,7 @@ static int ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rwx == 2) {
|
if (access_type == MMU_INST_FETCH) {
|
||||||
/* No code fetch is allowed in direct-store areas */
|
/* No code fetch is allowed in direct-store areas */
|
||||||
cs->exception_index = POWERPC_EXCP_ISI;
|
cs->exception_index = POWERPC_EXCP_ISI;
|
||||||
env->error_code = 0x10000000;
|
env->error_code = 0x10000000;
|
||||||
|
@ -261,7 +263,7 @@ static int ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr,
|
||||||
/* lwarx, ldarx or srwcx. */
|
/* lwarx, ldarx or srwcx. */
|
||||||
env->error_code = 0;
|
env->error_code = 0;
|
||||||
env->spr[SPR_DAR] = eaddr;
|
env->spr[SPR_DAR] = eaddr;
|
||||||
if (rwx == 1) {
|
if (access_type == MMU_DATA_STORE) {
|
||||||
env->spr[SPR_DSISR] = 0x06000000;
|
env->spr[SPR_DSISR] = 0x06000000;
|
||||||
} else {
|
} else {
|
||||||
env->spr[SPR_DSISR] = 0x04000000;
|
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;
|
cs->exception_index = POWERPC_EXCP_DSI;
|
||||||
env->error_code = 0;
|
env->error_code = 0;
|
||||||
env->spr[SPR_DAR] = eaddr;
|
env->spr[SPR_DAR] = eaddr;
|
||||||
if (rwx == 1) {
|
if (access_type == MMU_DATA_STORE) {
|
||||||
env->spr[SPR_DSISR] = 0x06100000;
|
env->spr[SPR_DSISR] = 0x06100000;
|
||||||
} else {
|
} else {
|
||||||
env->spr[SPR_DSISR] = 0x04100000;
|
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 "
|
cpu_abort(cs, "ERROR: instruction should not need "
|
||||||
"address translation\n");
|
"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;
|
*raddr = eaddr;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
cs->exception_index = POWERPC_EXCP_DSI;
|
cs->exception_index = POWERPC_EXCP_DSI;
|
||||||
env->error_code = 0;
|
env->error_code = 0;
|
||||||
env->spr[SPR_DAR] = eaddr;
|
env->spr[SPR_DAR] = eaddr;
|
||||||
if (rwx == 1) {
|
if (access_type == MMU_DATA_STORE) {
|
||||||
env->spr[SPR_DSISR] = 0x0a000000;
|
env->spr[SPR_DSISR] = 0x0a000000;
|
||||||
} else {
|
} else {
|
||||||
env->spr[SPR_DSISR] = 0x08000000;
|
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;
|
ppc_hash_pte32_t pte;
|
||||||
int prot;
|
int prot;
|
||||||
int need_prot;
|
int need_prot;
|
||||||
|
MMUAccessType access_type;
|
||||||
hwaddr raddr;
|
hwaddr raddr;
|
||||||
|
|
||||||
assert((rwx == 0) || (rwx == 1) || (rwx == 2));
|
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 */
|
/* 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 */
|
/* Translation is off */
|
||||||
raddr = eaddr;
|
raddr = eaddr;
|
||||||
tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
|
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) */
|
/* 2. Check Block Address Translation entries (BATs) */
|
||||||
if (env->nb_BATs != 0) {
|
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 (raddr != -1) {
|
||||||
if (need_prot & ~prot) {
|
if (need_prot & ~prot) {
|
||||||
if (rwx == 2) {
|
if (access_type == MMU_INST_FETCH) {
|
||||||
cs->exception_index = POWERPC_EXCP_ISI;
|
cs->exception_index = POWERPC_EXCP_ISI;
|
||||||
env->error_code = 0x08000000;
|
env->error_code = 0x08000000;
|
||||||
} else {
|
} else {
|
||||||
cs->exception_index = POWERPC_EXCP_DSI;
|
cs->exception_index = POWERPC_EXCP_DSI;
|
||||||
env->error_code = 0;
|
env->error_code = 0;
|
||||||
env->spr[SPR_DAR] = eaddr;
|
env->spr[SPR_DAR] = eaddr;
|
||||||
if (rwx == 1) {
|
if (access_type == MMU_DATA_STORE) {
|
||||||
env->spr[SPR_DSISR] = 0x0a000000;
|
env->spr[SPR_DSISR] = 0x0a000000;
|
||||||
} else {
|
} else {
|
||||||
env->spr[SPR_DSISR] = 0x08000000;
|
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 */
|
/* 4. Handle direct store segments */
|
||||||
if (sr & SR32_T) {
|
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) {
|
&raddr, &prot) == 0) {
|
||||||
tlb_set_page(cs, eaddr & TARGET_PAGE_MASK,
|
tlb_set_page(cs, eaddr & TARGET_PAGE_MASK,
|
||||||
raddr & TARGET_PAGE_MASK, prot, mmu_idx,
|
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 */
|
/* 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;
|
cs->exception_index = POWERPC_EXCP_ISI;
|
||||||
env->error_code = 0x10000000;
|
env->error_code = 0x10000000;
|
||||||
return 1;
|
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 */
|
/* 6. Locate the PTE in the hash table */
|
||||||
pte_offset = ppc_hash32_htab_lookup(cpu, sr, eaddr, &pte);
|
pte_offset = ppc_hash32_htab_lookup(cpu, sr, eaddr, &pte);
|
||||||
if (pte_offset == -1) {
|
if (pte_offset == -1) {
|
||||||
if (rwx == 2) {
|
if (access_type == MMU_INST_FETCH) {
|
||||||
cs->exception_index = POWERPC_EXCP_ISI;
|
cs->exception_index = POWERPC_EXCP_ISI;
|
||||||
env->error_code = 0x40000000;
|
env->error_code = 0x40000000;
|
||||||
} else {
|
} else {
|
||||||
cs->exception_index = POWERPC_EXCP_DSI;
|
cs->exception_index = POWERPC_EXCP_DSI;
|
||||||
env->error_code = 0;
|
env->error_code = 0;
|
||||||
env->spr[SPR_DAR] = eaddr;
|
env->spr[SPR_DAR] = eaddr;
|
||||||
if (rwx == 1) {
|
if (access_type == MMU_DATA_STORE) {
|
||||||
env->spr[SPR_DSISR] = 0x42000000;
|
env->spr[SPR_DSISR] = 0x42000000;
|
||||||
} else {
|
} else {
|
||||||
env->spr[SPR_DSISR] = 0x40000000;
|
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) {
|
if (need_prot & ~prot) {
|
||||||
/* Access right violation */
|
/* Access right violation */
|
||||||
qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
|
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;
|
cs->exception_index = POWERPC_EXCP_ISI;
|
||||||
env->error_code = 0x08000000;
|
env->error_code = 0x08000000;
|
||||||
} else {
|
} else {
|
||||||
cs->exception_index = POWERPC_EXCP_DSI;
|
cs->exception_index = POWERPC_EXCP_DSI;
|
||||||
env->error_code = 0;
|
env->error_code = 0;
|
||||||
env->spr[SPR_DAR] = eaddr;
|
env->spr[SPR_DAR] = eaddr;
|
||||||
if (rwx == 1) {
|
if (access_type == MMU_DATA_STORE) {
|
||||||
env->spr[SPR_DSISR] = 0x0a000000;
|
env->spr[SPR_DSISR] = 0x0a000000;
|
||||||
} else {
|
} else {
|
||||||
env->spr[SPR_DSISR] = 0x08000000;
|
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);
|
ppc_hash32_set_r(cpu, pte_offset, pte.pte1);
|
||||||
}
|
}
|
||||||
if (!(pte.pte1 & HPTE32_R_C)) {
|
if (!(pte.pte1 & HPTE32_R_C)) {
|
||||||
if (rwx == 1) {
|
if (access_type == MMU_DATA_STORE) {
|
||||||
ppc_hash32_set_c(cpu, pte_offset, pte.pte1);
|
ppc_hash32_set_c(cpu, pte_offset, pte.pte1);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue