On 03/08/2021 05:14, Richard Henderson wrote:
Signed-off-by: Richard Henderson <richard.hender...@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-ayl...@ilande.co.uk>
ATB,
Mark.