mirror of https://gitee.com/openkylin/qemu.git
target/ppc: Use MMUAccessType in mmu-hash64.c
We must leave the 'int rwx' parameter to ppc_hash64_handle_mmu_fault for now, but will clean that up later. Signed-off-by: Ricgard Henderson <richard.henderson@linaro.org> Message-Id: <20210518201146.794854-4-richard.henderson@linaro.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
13c5fdbac6
commit
59dec5bf5a
|
@ -877,10 +877,12 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
|
||||||
hwaddr ptex;
|
hwaddr ptex;
|
||||||
ppc_hash_pte64_t pte;
|
ppc_hash_pte64_t pte;
|
||||||
int exec_prot, pp_prot, amr_prot, prot;
|
int exec_prot, pp_prot, amr_prot, prot;
|
||||||
|
MMUAccessType access_type;
|
||||||
int need_prot;
|
int need_prot;
|
||||||
hwaddr raddr;
|
hwaddr raddr;
|
||||||
|
|
||||||
assert((rwx == 0) || (rwx == 1) || (rwx == 2));
|
assert((rwx == 0) || (rwx == 1) || (rwx == 2));
|
||||||
|
access_type = rwx;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note on LPCR usage: 970 uses HID4, but our special variant of
|
* Note on LPCR usage: 970 uses HID4, but our special variant of
|
||||||
|
@ -891,7 +893,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* 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 supposedly "off", but in real mode the top 4
|
* Translation is supposedly "off", but in real mode the top 4
|
||||||
* effective address bits are (mostly) ignored
|
* effective address bits are (mostly) ignored
|
||||||
|
@ -924,14 +926,19 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
|
||||||
|
|
||||||
/* Emulated old-style RMO mode, bounds check against RMLS */
|
/* Emulated old-style RMO mode, bounds check against RMLS */
|
||||||
if (raddr >= limit) {
|
if (raddr >= limit) {
|
||||||
if (rwx == 2) {
|
switch (access_type) {
|
||||||
|
case MMU_INST_FETCH:
|
||||||
ppc_hash64_set_isi(cs, SRR1_PROTFAULT);
|
ppc_hash64_set_isi(cs, SRR1_PROTFAULT);
|
||||||
} else {
|
break;
|
||||||
int dsisr = DSISR_PROTFAULT;
|
case MMU_DATA_LOAD:
|
||||||
if (rwx == 1) {
|
ppc_hash64_set_dsi(cs, eaddr, DSISR_PROTFAULT);
|
||||||
dsisr |= DSISR_ISSTORE;
|
break;
|
||||||
}
|
case MMU_DATA_STORE:
|
||||||
ppc_hash64_set_dsi(cs, eaddr, dsisr);
|
ppc_hash64_set_dsi(cs, eaddr,
|
||||||
|
DSISR_PROTFAULT | DSISR_ISSTORE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -954,13 +961,19 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
/* Segment still not found, generate the appropriate interrupt */
|
/* Segment still not found, generate the appropriate interrupt */
|
||||||
if (rwx == 2) {
|
switch (access_type) {
|
||||||
|
case MMU_INST_FETCH:
|
||||||
cs->exception_index = POWERPC_EXCP_ISEG;
|
cs->exception_index = POWERPC_EXCP_ISEG;
|
||||||
env->error_code = 0;
|
env->error_code = 0;
|
||||||
} else {
|
break;
|
||||||
|
case MMU_DATA_LOAD:
|
||||||
|
case MMU_DATA_STORE:
|
||||||
cs->exception_index = POWERPC_EXCP_DSEG;
|
cs->exception_index = POWERPC_EXCP_DSEG;
|
||||||
env->error_code = 0;
|
env->error_code = 0;
|
||||||
env->spr[SPR_DAR] = eaddr;
|
env->spr[SPR_DAR] = eaddr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -968,7 +981,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
|
||||||
skip_slb_search:
|
skip_slb_search:
|
||||||
|
|
||||||
/* 3. Check for segment level no-execute violation */
|
/* 3. Check for segment level no-execute violation */
|
||||||
if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
|
if (access_type == MMU_INST_FETCH && (slb->vsid & SLB_VSID_N)) {
|
||||||
ppc_hash64_set_isi(cs, SRR1_NOEXEC_GUARD);
|
ppc_hash64_set_isi(cs, SRR1_NOEXEC_GUARD);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -976,14 +989,18 @@ skip_slb_search:
|
||||||
/* 4. Locate the PTE in the hash table */
|
/* 4. Locate the PTE in the hash table */
|
||||||
ptex = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte, &apshift);
|
ptex = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte, &apshift);
|
||||||
if (ptex == -1) {
|
if (ptex == -1) {
|
||||||
if (rwx == 2) {
|
switch (access_type) {
|
||||||
|
case MMU_INST_FETCH:
|
||||||
ppc_hash64_set_isi(cs, SRR1_NOPTE);
|
ppc_hash64_set_isi(cs, SRR1_NOPTE);
|
||||||
} else {
|
break;
|
||||||
int dsisr = DSISR_NOPTE;
|
case MMU_DATA_LOAD:
|
||||||
if (rwx == 1) {
|
ppc_hash64_set_dsi(cs, eaddr, DSISR_NOPTE);
|
||||||
dsisr |= DSISR_ISSTORE;
|
break;
|
||||||
}
|
case MMU_DATA_STORE:
|
||||||
ppc_hash64_set_dsi(cs, eaddr, dsisr);
|
ppc_hash64_set_dsi(cs, eaddr, DSISR_NOPTE | DSISR_ISSTORE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -997,11 +1014,11 @@ skip_slb_search:
|
||||||
amr_prot = ppc_hash64_amr_prot(cpu, pte);
|
amr_prot = ppc_hash64_amr_prot(cpu, pte);
|
||||||
prot = exec_prot & pp_prot & amr_prot;
|
prot = exec_prot & pp_prot & amr_prot;
|
||||||
|
|
||||||
need_prot = prot_for_access_type(rwx);
|
need_prot = prot_for_access_type(access_type);
|
||||||
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) {
|
||||||
int srr1 = 0;
|
int srr1 = 0;
|
||||||
if (PAGE_EXEC & ~exec_prot) {
|
if (PAGE_EXEC & ~exec_prot) {
|
||||||
srr1 |= SRR1_NOEXEC_GUARD; /* Access violates noexec or guard */
|
srr1 |= SRR1_NOEXEC_GUARD; /* Access violates noexec or guard */
|
||||||
|
@ -1017,7 +1034,7 @@ skip_slb_search:
|
||||||
if (need_prot & ~pp_prot) {
|
if (need_prot & ~pp_prot) {
|
||||||
dsisr |= DSISR_PROTFAULT;
|
dsisr |= DSISR_PROTFAULT;
|
||||||
}
|
}
|
||||||
if (rwx == 1) {
|
if (access_type == MMU_DATA_STORE) {
|
||||||
dsisr |= DSISR_ISSTORE;
|
dsisr |= DSISR_ISSTORE;
|
||||||
}
|
}
|
||||||
if (need_prot & ~amr_prot) {
|
if (need_prot & ~amr_prot) {
|
||||||
|
@ -1036,7 +1053,7 @@ skip_slb_search:
|
||||||
ppc_hash64_set_r(cpu, ptex, pte.pte1);
|
ppc_hash64_set_r(cpu, ptex, pte.pte1);
|
||||||
}
|
}
|
||||||
if (!(pte.pte1 & HPTE64_R_C)) {
|
if (!(pte.pte1 & HPTE64_R_C)) {
|
||||||
if (rwx == 1) {
|
if (access_type == MMU_DATA_STORE) {
|
||||||
ppc_hash64_set_c(cpu, ptex, pte.pte1);
|
ppc_hash64_set_c(cpu, ptex, pte.pte1);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue