уторак, 16. јун 2020., Jiaxun Yang <jiaxun.y...@flygoat.com> је написао/ла:
> Our current code assumed the target page size is always 4k > when handling PageMask and VPN2, however, variable page size > was just added to mips target and that's nolonger true. > > Signed-off-by: Jiaxun Yang <jiaxun.y...@flygoat.com> > --- > v2: Remove Big Page support from this patch > --- > target/mips/cp0_helper.c | 41 ++++++++++++++++++++++++++++------------ Please do not use harcoded numbers, if possibe. Yours, Aleksandar > target/mips/cpu.h | 1 + > 2 files changed, 30 insertions(+), 12 deletions(-) > > diff --git a/target/mips/cp0_helper.c b/target/mips/cp0_helper.c > index bbf12e4a97..f6dc590315 100644 > --- a/target/mips/cp0_helper.c > +++ b/target/mips/cp0_helper.c > @@ -872,20 +872,37 @@ void helper_mtc0_memorymapid(CPUMIPSState *env, > target_ulong arg1) > } > } > > -void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t > *pagemask) > +void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1) > { > - uint64_t mask = arg1 >> (TARGET_PAGE_BITS + 1); > - if (!(env->insn_flags & ISA_MIPS32R6) || (arg1 == ~0) || > - (mask == 0x0000 || mask == 0x0003 || mask == 0x000F || > - mask == 0x003F || mask == 0x00FF || mask == 0x03FF || > - mask == 0x0FFF || mask == 0x3FFF || mask == 0xFFFF)) { > - env->CP0_PageMask = arg1 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1)); > + unsigned long mask; > + int maskbits; > + > + if (env->insn_flags & ISA_MIPS32R6) { > + return; > } > -} > + /* Don't care MASKX as we don't support 1KB page */ > + mask = extract32((uint32_t)arg1, CP0PM_MASK, 16); > + maskbits = find_first_zero_bit(&mask, 32); > > -void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1) > -{ > - update_pagemask(env, arg1, &env->CP0_PageMask); > + /* Ensure no more set bit after first zero */ > + if (mask >> maskbits) { > + goto invalid; > + } > + /* We don't support VTLB entry smaller than target page */ > + if ((maskbits + 12) < TARGET_PAGE_BITS) { > + goto invalid; > + } 12. > + env->CP0_PageMask = mask << CP0PM_MASK; > + > + return; > + > +invalid: > + /* > + * When invalid, ensure the value is bigger tan or equel to than or equal > + * the minimal but smaller than or equel to the maxium. equal > + */ > + maskbits = MIN(16, MAX(maskbits, TARGET_PAGE_BITS - 12)); > + env->CP0_PageMask = ((1 << (16 + 1)) - 1) << CP0PM_MASK; 16, 12, 16 + 1 ? > } > > void helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1) > @@ -1111,7 +1128,7 @@ void helper_mthc0_saar(CPUMIPSState *env, > target_ulong arg1) > void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1) > { > target_ulong old, val, mask; > - mask = (TARGET_PAGE_MASK << 1) | env->CP0_EntryHi_ASID_mask; > + mask = ~((1 << 14) - 1) | env->CP0_EntryHi_ASID_mask; 14. > if (((env->CP0_Config4 >> CP0C4_IE) & 0x3) >= 2) { > mask |= 1 << CP0EnHi_EHINV; > } > diff --git a/target/mips/cpu.h b/target/mips/cpu.h > index 7cf7f5239f..9c8bb23807 100644 > --- a/target/mips/cpu.h > +++ b/target/mips/cpu.h > @@ -618,6 +618,7 @@ struct CPUMIPSState { > * CP0 Register 5 > */ > int32_t CP0_PageMask; > +#define CP0PM_MASK 13 > int32_t CP0_PageGrain_rw_bitmask; > int32_t CP0_PageGrain; > #define CP0PG_RIE 31 > -- > 2.27.0.rc2 > >