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>
This commit is contained in:
parent
9852112ee4
commit
c0e0c6fe01
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user