Message ID | 20210803041443.55452-17-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | Unaligned access for user-only | expand |
On 03/08/2021 05:14, Richard Henderson wrote: > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/sparc/mmu_helper.c | 72 +++++++++++++++++++++++++-------------- > 1 file changed, 46 insertions(+), 26 deletions(-) > > diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c > index a44473a1c7..5b2fda534a 100644 > --- a/target/sparc/mmu_helper.c > +++ b/target/sparc/mmu_helper.c > @@ -526,16 +526,60 @@ static inline int ultrasparc_tag_match(SparcTLBEntry *tlb, > return 0; > } > > +static uint64_t build_sfsr(CPUSPARCState *env, int mmu_idx, int rw) > +{ > + uint64_t sfsr = SFSR_VALID_BIT; > + > + switch (mmu_idx) { > + case MMU_PHYS_IDX: > + sfsr |= SFSR_CT_NOTRANS; > + break; > + case MMU_USER_IDX: > + case MMU_KERNEL_IDX: > + sfsr |= SFSR_CT_PRIMARY; > + break; > + case MMU_USER_SECONDARY_IDX: > + case MMU_KERNEL_SECONDARY_IDX: > + sfsr |= SFSR_CT_SECONDARY; > + break; > + case MMU_NUCLEUS_IDX: > + sfsr |= SFSR_CT_NUCLEUS; > + break; > + default: > + g_assert_not_reached(); > + } > + > + if (rw == 1) { > + sfsr |= SFSR_WRITE_BIT; > + } else if (rw == 4) { > + sfsr |= SFSR_NF_BIT; > + } > + > + if (env->pstate & PS_PRIV) { > + sfsr |= SFSR_PR_BIT; > + } > + > + if (env->dmmu.sfsr & SFSR_VALID_BIT) { /* Fault status register */ > + sfsr |= SFSR_OW_BIT; /* overflow (not read before another fault) */ > + } > + > + /* FIXME: ASI field in SFSR must be set */ > + > + return sfsr; > +} > + > static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical, > int *prot, MemTxAttrs *attrs, > target_ulong address, int rw, int mmu_idx) > { > CPUState *cs = env_cpu(env); > unsigned int i; > + uint64_t sfsr; > uint64_t context; > - uint64_t sfsr = 0; > bool is_user = false; > > + sfsr = build_sfsr(env, mmu_idx, rw); > + > switch (mmu_idx) { > case MMU_PHYS_IDX: > g_assert_not_reached(); > @@ -544,29 +588,18 @@ static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical, > /* fallthru */ > case MMU_KERNEL_IDX: > context = env->dmmu.mmu_primary_context & 0x1fff; > - sfsr |= SFSR_CT_PRIMARY; > break; > case MMU_USER_SECONDARY_IDX: > is_user = true; > /* fallthru */ > case MMU_KERNEL_SECONDARY_IDX: > context = env->dmmu.mmu_secondary_context & 0x1fff; > - sfsr |= SFSR_CT_SECONDARY; > break; > - case MMU_NUCLEUS_IDX: > - sfsr |= SFSR_CT_NUCLEUS; > - /* FALLTHRU */ > default: > context = 0; > break; > } > > - if (rw == 1) { > - sfsr |= SFSR_WRITE_BIT; > - } else if (rw == 4) { > - sfsr |= SFSR_NF_BIT; > - } > - > for (i = 0; i < 64; i++) { > /* ctx match, vaddr match, valid? */ > if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) { > @@ -616,22 +649,9 @@ static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical, > return 0; > } > > - if (env->dmmu.sfsr & SFSR_VALID_BIT) { /* Fault status register */ > - sfsr |= SFSR_OW_BIT; /* overflow (not read before > - another fault) */ > - } > - > - if (env->pstate & PS_PRIV) { > - sfsr |= SFSR_PR_BIT; > - } > - > - /* FIXME: ASI field in SFSR must be set */ > - env->dmmu.sfsr = sfsr | SFSR_VALID_BIT; > - > + env->dmmu.sfsr = sfsr; > env->dmmu.sfar = address; /* Fault address register */ > - > env->dmmu.tag_access = (address & ~0x1fffULL) | context; > - > return 1; > } > } Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> ATB, Mark.
diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c index a44473a1c7..5b2fda534a 100644 --- a/target/sparc/mmu_helper.c +++ b/target/sparc/mmu_helper.c @@ -526,16 +526,60 @@ static inline int ultrasparc_tag_match(SparcTLBEntry *tlb, return 0; } +static uint64_t build_sfsr(CPUSPARCState *env, int mmu_idx, int rw) +{ + uint64_t sfsr = SFSR_VALID_BIT; + + switch (mmu_idx) { + case MMU_PHYS_IDX: + sfsr |= SFSR_CT_NOTRANS; + break; + case MMU_USER_IDX: + case MMU_KERNEL_IDX: + sfsr |= SFSR_CT_PRIMARY; + break; + case MMU_USER_SECONDARY_IDX: + case MMU_KERNEL_SECONDARY_IDX: + sfsr |= SFSR_CT_SECONDARY; + break; + case MMU_NUCLEUS_IDX: + sfsr |= SFSR_CT_NUCLEUS; + break; + default: + g_assert_not_reached(); + } + + if (rw == 1) { + sfsr |= SFSR_WRITE_BIT; + } else if (rw == 4) { + sfsr |= SFSR_NF_BIT; + } + + if (env->pstate & PS_PRIV) { + sfsr |= SFSR_PR_BIT; + } + + if (env->dmmu.sfsr & SFSR_VALID_BIT) { /* Fault status register */ + sfsr |= SFSR_OW_BIT; /* overflow (not read before another fault) */ + } + + /* FIXME: ASI field in SFSR must be set */ + + return sfsr; +} + static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical, int *prot, MemTxAttrs *attrs, target_ulong address, int rw, int mmu_idx) { CPUState *cs = env_cpu(env); unsigned int i; + uint64_t sfsr; uint64_t context; - uint64_t sfsr = 0; bool is_user = false; + sfsr = build_sfsr(env, mmu_idx, rw); + switch (mmu_idx) { case MMU_PHYS_IDX: g_assert_not_reached(); @@ -544,29 +588,18 @@ static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical, /* fallthru */ case MMU_KERNEL_IDX: context = env->dmmu.mmu_primary_context & 0x1fff; - sfsr |= SFSR_CT_PRIMARY; break; case MMU_USER_SECONDARY_IDX: is_user = true; /* fallthru */ case MMU_KERNEL_SECONDARY_IDX: context = env->dmmu.mmu_secondary_context & 0x1fff; - sfsr |= SFSR_CT_SECONDARY; break; - case MMU_NUCLEUS_IDX: - sfsr |= SFSR_CT_NUCLEUS; - /* FALLTHRU */ default: context = 0; break; } - if (rw == 1) { - sfsr |= SFSR_WRITE_BIT; - } else if (rw == 4) { - sfsr |= SFSR_NF_BIT; - } - for (i = 0; i < 64; i++) { /* ctx match, vaddr match, valid? */ if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) { @@ -616,22 +649,9 @@ static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical, return 0; } - if (env->dmmu.sfsr & SFSR_VALID_BIT) { /* Fault status register */ - sfsr |= SFSR_OW_BIT; /* overflow (not read before - another fault) */ - } - - if (env->pstate & PS_PRIV) { - sfsr |= SFSR_PR_BIT; - } - - /* FIXME: ASI field in SFSR must be set */ - env->dmmu.sfsr = sfsr | SFSR_VALID_BIT; - + env->dmmu.sfsr = sfsr; env->dmmu.sfar = address; /* Fault address register */ - env->dmmu.tag_access = (address & ~0x1fffULL) | context; - return 1; } }
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/sparc/mmu_helper.c | 72 +++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 26 deletions(-) -- 2.25.1