target/sparc: Split out build_sfsr

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
master
Richard Henderson 2021-07-30 07:55:06 -10:00
parent 9852112ee4
commit c0e0c6fe01
1 changed files with 46 additions and 26 deletions

View File

@ -502,16 +502,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();
@ -520,29 +564,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)) {
@ -592,22 +625,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;
}
}