On Wed, Jun 02, 2021 at 04:26:04PM -0300, Lucas Mateus Castro (alqotel) wrote: > Moved helpers from target/ppc/mmu-hash64.c to target/ppc/mmu_helpers.c > and removed #ifdef CONFIG_TCG and #include exec/helper-proto.h from > mmu-hash64.c > > Signed-off-by: Lucas Mateus Castro (alqotel) > <lucas.ara...@eldorado.org.br>
I'd prefer not to do this. These helpers used to be in mmu_helper.c, along with most of the stuff in mmu-*.[ch]. I think the division by MMU model is more important than the TCG/!TCG distinction, so I'd prefer to keep these here, even if it means ifdefs. Eventually we could consider splitting each of the individual MMU files into TCG/!TCG parts, but I don't want to go back to having all the helpers for umpteen very different MMU models all lumped into one giant file. > --- > I had to turn slb_lookup in a non static function as it had calls from > the code that was moved to mmu_helper.c and from the code that wasn't > moved. > > Also perhaps it would be best to create a new file to move the mmu-hash > functions that are not compiled in !TCG, personally I thought that > moving the helpers in mmu-hash64 to mmu_helpers the better choice. > --- > target/ppc/mmu-hash64.c | 219 +--------------------------------------- > target/ppc/mmu-hash64.h | 1 + > target/ppc/mmu_helper.c | 209 ++++++++++++++++++++++++++++++++++++++ > 3 files changed, 211 insertions(+), 218 deletions(-) > > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c > index 708dffc31b..d2ded71107 100644 > --- a/target/ppc/mmu-hash64.c > +++ b/target/ppc/mmu-hash64.c > @@ -32,10 +32,6 @@ > #include "mmu-book3s-v3.h" > #include "helper_regs.h" > > -#ifdef CONFIG_TCG > -#include "exec/helper-proto.h" > -#endif > - > /* #define DEBUG_SLB */ > > #ifdef DEBUG_SLB > @@ -48,7 +44,7 @@ > * SLB handling > */ > > -static ppc_slb_t *slb_lookup(PowerPCCPU *cpu, target_ulong eaddr) > +ppc_slb_t *slb_lookup(PowerPCCPU *cpu, target_ulong eaddr) > { > CPUPPCState *env = &cpu->env; > uint64_t esid_256M, esid_1T; > @@ -100,114 +96,6 @@ void dump_slb(PowerPCCPU *cpu) > } > } > > -#ifdef CONFIG_TCG > -void helper_slbia(CPUPPCState *env, uint32_t ih) > -{ > - PowerPCCPU *cpu = env_archcpu(env); > - int starting_entry; > - int n; > - > - /* > - * slbia must always flush all TLB (which is equivalent to ERAT in ppc > - * architecture). Matching on SLB_ESID_V is not good enough, because > slbmte > - * can overwrite a valid SLB without flushing its lookaside information. > - * > - * It would be possible to keep the TLB in synch with the SLB by flushing > - * when a valid entry is overwritten by slbmte, and therefore slbia would > - * not have to flush unless it evicts a valid SLB entry. However it is > - * expected that slbmte is more common than slbia, and slbia is usually > - * going to evict valid SLB entries, so that tradeoff is unlikely to be a > - * good one. > - * > - * ISA v2.05 introduced IH field with values 0,1,2,6. These all > invalidate > - * the same SLB entries (everything but entry 0), but differ in what > - * "lookaside information" is invalidated. TCG can ignore this and flush > - * everything. > - * > - * ISA v3.0 introduced additional values 3,4,7, which change what SLBs > are > - * invalidated. > - */ > - > - env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH; > - > - starting_entry = 1; /* default for IH=0,1,2,6 */ > - > - if (env->mmu_model == POWERPC_MMU_3_00) { > - switch (ih) { > - case 0x7: > - /* invalidate no SLBs, but all lookaside information */ > - return; > - > - case 0x3: > - case 0x4: > - /* also considers SLB entry 0 */ > - starting_entry = 0; > - break; > - > - case 0x5: > - /* treat undefined values as ih==0, and warn */ > - qemu_log_mask(LOG_GUEST_ERROR, > - "slbia undefined IH field %u.\n", ih); > - break; > - > - default: > - /* 0,1,2,6 */ > - break; > - } > - } > - > - for (n = starting_entry; n < cpu->hash64_opts->slb_size; n++) { > - ppc_slb_t *slb = &env->slb[n]; > - > - if (!(slb->esid & SLB_ESID_V)) { > - continue; > - } > - if (env->mmu_model == POWERPC_MMU_3_00) { > - if (ih == 0x3 && (slb->vsid & SLB_VSID_C) == 0) { > - /* preserves entries with a class value of 0 */ > - continue; > - } > - } > - > - slb->esid &= ~SLB_ESID_V; > - } > -} > - > -static void __helper_slbie(CPUPPCState *env, target_ulong addr, > - target_ulong global) > -{ > - PowerPCCPU *cpu = env_archcpu(env); > - ppc_slb_t *slb; > - > - slb = slb_lookup(cpu, addr); > - if (!slb) { > - return; > - } > - > - if (slb->esid & SLB_ESID_V) { > - slb->esid &= ~SLB_ESID_V; > - > - /* > - * XXX: given the fact that segment size is 256 MB or 1TB, > - * and we still don't have a tlb_flush_mask(env, n, mask) > - * in QEMU, we just invalidate all TLBs > - */ > - env->tlb_need_flush |= > - (global == false ? TLB_NEED_LOCAL_FLUSH : TLB_NEED_GLOBAL_FLUSH); > - } > -} > - > -void helper_slbie(CPUPPCState *env, target_ulong addr) > -{ > - __helper_slbie(env, addr, false); > -} > - > -void helper_slbieg(CPUPPCState *env, target_ulong addr) > -{ > - __helper_slbie(env, addr, true); > -} > -#endif > - > int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot, > target_ulong esid, target_ulong vsid) > { > @@ -260,102 +148,6 @@ int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot, > return 0; > } > > -#ifdef CONFIG_TCG > -static int ppc_load_slb_esid(PowerPCCPU *cpu, target_ulong rb, > - target_ulong *rt) > -{ > - CPUPPCState *env = &cpu->env; > - int slot = rb & 0xfff; > - ppc_slb_t *slb = &env->slb[slot]; > - > - if (slot >= cpu->hash64_opts->slb_size) { > - return -1; > - } > - > - *rt = slb->esid; > - return 0; > -} > - > -static int ppc_load_slb_vsid(PowerPCCPU *cpu, target_ulong rb, > - target_ulong *rt) > -{ > - CPUPPCState *env = &cpu->env; > - int slot = rb & 0xfff; > - ppc_slb_t *slb = &env->slb[slot]; > - > - if (slot >= cpu->hash64_opts->slb_size) { > - return -1; > - } > - > - *rt = slb->vsid; > - return 0; > -} > - > -static int ppc_find_slb_vsid(PowerPCCPU *cpu, target_ulong rb, > - target_ulong *rt) > -{ > - CPUPPCState *env = &cpu->env; > - ppc_slb_t *slb; > - > - if (!msr_is_64bit(env, env->msr)) { > - rb &= 0xffffffff; > - } > - slb = slb_lookup(cpu, rb); > - if (slb == NULL) { > - *rt = (target_ulong)-1ul; > - } else { > - *rt = slb->vsid; > - } > - return 0; > -} > - > -void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs) > -{ > - PowerPCCPU *cpu = env_archcpu(env); > - > - if (ppc_store_slb(cpu, rb & 0xfff, rb & ~0xfffULL, rs) < 0) { > - raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_INVAL, GETPC()); > - } > -} > - > -target_ulong helper_load_slb_esid(CPUPPCState *env, target_ulong rb) > -{ > - PowerPCCPU *cpu = env_archcpu(env); > - target_ulong rt = 0; > - > - if (ppc_load_slb_esid(cpu, rb, &rt) < 0) { > - raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_INVAL, GETPC()); > - } > - return rt; > -} > - > -target_ulong helper_find_slb_vsid(CPUPPCState *env, target_ulong rb) > -{ > - PowerPCCPU *cpu = env_archcpu(env); > - target_ulong rt = 0; > - > - if (ppc_find_slb_vsid(cpu, rb, &rt) < 0) { > - raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_INVAL, GETPC()); > - } > - return rt; > -} > - > -target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb) > -{ > - PowerPCCPU *cpu = env_archcpu(env); > - target_ulong rt = 0; > - > - if (ppc_load_slb_vsid(cpu, rb, &rt) < 0) { > - raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, > - POWERPC_EXCP_INVAL, GETPC()); > - } > - return rt; > -} > -#endif > - > /* Check No-Execute or Guarded Storage */ > static inline int ppc_hash64_pte_noexec_guard(PowerPCCPU *cpu, > ppc_hash_pte64_t pte) > @@ -1146,15 +938,6 @@ void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu, > target_ulong ptex, > cpu->env.tlb_need_flush = TLB_NEED_GLOBAL_FLUSH | TLB_NEED_LOCAL_FLUSH; > } > > -#ifdef CONFIG_TCG > -void helper_store_lpcr(CPUPPCState *env, target_ulong val) > -{ > - PowerPCCPU *cpu = env_archcpu(env); > - > - ppc_store_lpcr(cpu, val); > -} > -#endif > - > void ppc_hash64_init(PowerPCCPU *cpu) > { > CPUPPCState *env = &cpu->env; > diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h > index 4b8b8e7950..44fd7c9d35 100644 > --- a/target/ppc/mmu-hash64.h > +++ b/target/ppc/mmu-hash64.h > @@ -7,6 +7,7 @@ > void dump_slb(PowerPCCPU *cpu); > int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot, > target_ulong esid, target_ulong vsid); > +ppc_slb_t *slb_lookup(PowerPCCPU *cpu, target_ulong eaddr); > hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr); > int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr address, int rw, > int mmu_idx); > diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c > index dbf7b398cd..6db2678a89 100644 > --- a/target/ppc/mmu_helper.c > +++ b/target/ppc/mmu_helper.c > @@ -1361,3 +1361,211 @@ void helper_check_tlb_flush_global(CPUPPCState *env) > > > /*****************************************************************************/ > > +#if defined(TARGET_PPC64) > +void helper_slbia(CPUPPCState *env, uint32_t ih) > +{ > + PowerPCCPU *cpu = env_archcpu(env); > + int starting_entry; > + int n; > + > + /* > + * slbia must always flush all TLB (which is equivalent to ERAT in ppc > + * architecture). Matching on SLB_ESID_V is not good enough, because > slbmte > + * can overwrite a valid SLB without flushing its lookaside information. > + * > + * It would be possible to keep the TLB in synch with the SLB by flushing > + * when a valid entry is overwritten by slbmte, and therefore slbia would > + * not have to flush unless it evicts a valid SLB entry. However it is > + * expected that slbmte is more common than slbia, and slbia is usually > + * going to evict valid SLB entries, so that tradeoff is unlikely to be a > + * good one. > + * > + * ISA v2.05 introduced IH field with values 0,1,2,6. These all > invalidate > + * the same SLB entries (everything but entry 0), but differ in what > + * "lookaside information" is invalidated. TCG can ignore this and flush > + * everything. > + * > + * ISA v3.0 introduced additional values 3,4,7, which change what SLBs > are > + * invalidated. > + */ > + > + env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH; > + > + starting_entry = 1; /* default for IH=0,1,2,6 */ > + > + if (env->mmu_model == POWERPC_MMU_3_00) { > + switch (ih) { > + case 0x7: > + /* invalidate no SLBs, but all lookaside information */ > + return; > + > + case 0x3: > + case 0x4: > + /* also considers SLB entry 0 */ > + starting_entry = 0; > + break; > + > + case 0x5: > + /* treat undefined values as ih==0, and warn */ > + qemu_log_mask(LOG_GUEST_ERROR, > + "slbia undefined IH field %u.\n", ih); > + break; > + > + default: > + /* 0,1,2,6 */ > + break; > + } > + } > + > + for (n = starting_entry; n < cpu->hash64_opts->slb_size; n++) { > + ppc_slb_t *slb = &env->slb[n]; > + > + if (!(slb->esid & SLB_ESID_V)) { > + continue; > + } > + if (env->mmu_model == POWERPC_MMU_3_00) { > + if (ih == 0x3 && (slb->vsid & SLB_VSID_C) == 0) { > + /* preserves entries with a class value of 0 */ > + continue; > + } > + } > + > + slb->esid &= ~SLB_ESID_V; > + } > +} > + > +static void __helper_slbie(CPUPPCState *env, target_ulong addr, > + target_ulong global) > +{ > + PowerPCCPU *cpu = env_archcpu(env); > + ppc_slb_t *slb; > + > + slb = slb_lookup(cpu, addr); > + if (!slb) { > + return; > + } > + > + if (slb->esid & SLB_ESID_V) { > + slb->esid &= ~SLB_ESID_V; > + > + /* > + * XXX: given the fact that segment size is 256 MB or 1TB, > + * and we still don't have a tlb_flush_mask(env, n, mask) > + * in QEMU, we just invalidate all TLBs > + */ > + env->tlb_need_flush |= > + (global == false ? TLB_NEED_LOCAL_FLUSH : TLB_NEED_GLOBAL_FLUSH); > + } > +} > + > +void helper_slbie(CPUPPCState *env, target_ulong addr) > +{ > + __helper_slbie(env, addr, false); > +} > + > +void helper_slbieg(CPUPPCState *env, target_ulong addr) > +{ > + __helper_slbie(env, addr, true); > +} > + > +static int ppc_load_slb_esid(PowerPCCPU *cpu, target_ulong rb, > + target_ulong *rt) > +{ > + CPUPPCState *env = &cpu->env; > + int slot = rb & 0xfff; > + ppc_slb_t *slb = &env->slb[slot]; > + > + if (slot >= cpu->hash64_opts->slb_size) { > + return -1; > + } > + > + *rt = slb->esid; > + return 0; > +} > + > +static int ppc_load_slb_vsid(PowerPCCPU *cpu, target_ulong rb, > + target_ulong *rt) > +{ > + CPUPPCState *env = &cpu->env; > + int slot = rb & 0xfff; > + ppc_slb_t *slb = &env->slb[slot]; > + > + if (slot >= cpu->hash64_opts->slb_size) { > + return -1; > + } > + > + *rt = slb->vsid; > + return 0; > +} > + > +static int ppc_find_slb_vsid(PowerPCCPU *cpu, target_ulong rb, > + target_ulong *rt) > +{ > + CPUPPCState *env = &cpu->env; > + ppc_slb_t *slb; > + > + if (!msr_is_64bit(env, env->msr)) { > + rb &= 0xffffffff; > + } > + slb = slb_lookup(cpu, rb); > + if (slb == NULL) { > + *rt = (target_ulong)-1ul; > + } else { > + *rt = slb->vsid; > + } > + return 0; > +} > + > +void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs) > +{ > + PowerPCCPU *cpu = env_archcpu(env); > + > + if (ppc_store_slb(cpu, rb & 0xfff, rb & ~0xfffULL, rs) < 0) { > + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_INVAL, GETPC()); > + } > +} > + > +target_ulong helper_load_slb_esid(CPUPPCState *env, target_ulong rb) > +{ > + PowerPCCPU *cpu = env_archcpu(env); > + target_ulong rt = 0; > + > + if (ppc_load_slb_esid(cpu, rb, &rt) < 0) { > + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_INVAL, GETPC()); > + } > + return rt; > +} > + > +target_ulong helper_find_slb_vsid(CPUPPCState *env, target_ulong rb) > +{ > + PowerPCCPU *cpu = env_archcpu(env); > + target_ulong rt = 0; > + > + if (ppc_find_slb_vsid(cpu, rb, &rt) < 0) { > + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_INVAL, GETPC()); > + } > + return rt; > +} > + > +target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb) > +{ > + PowerPCCPU *cpu = env_archcpu(env); > + target_ulong rt = 0; > + > + if (ppc_load_slb_vsid(cpu, rb, &rt) < 0) { > + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, > + POWERPC_EXCP_INVAL, GETPC()); > + } > + return rt; > +} > + > +void helper_store_lpcr(CPUPPCState *env, target_ulong val) > +{ > + PowerPCCPU *cpu = env_archcpu(env); > + > + ppc_store_lpcr(cpu, val); > +} > +#endif -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
signature.asc
Description: PGP signature