mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-15 01:29:15 +00:00
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;
|
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,
|
static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical,
|
||||||
int *prot, MemTxAttrs *attrs,
|
int *prot, MemTxAttrs *attrs,
|
||||||
target_ulong address, int rw, int mmu_idx)
|
target_ulong address, int rw, int mmu_idx)
|
||||||
{
|
{
|
||||||
CPUState *cs = env_cpu(env);
|
CPUState *cs = env_cpu(env);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
uint64_t sfsr;
|
||||||
uint64_t context;
|
uint64_t context;
|
||||||
uint64_t sfsr = 0;
|
|
||||||
bool is_user = false;
|
bool is_user = false;
|
||||||
|
|
||||||
|
sfsr = build_sfsr(env, mmu_idx, rw);
|
||||||
|
|
||||||
switch (mmu_idx) {
|
switch (mmu_idx) {
|
||||||
case MMU_PHYS_IDX:
|
case MMU_PHYS_IDX:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
@ -520,29 +564,18 @@ static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical,
|
|||||||
/* fallthru */
|
/* fallthru */
|
||||||
case MMU_KERNEL_IDX:
|
case MMU_KERNEL_IDX:
|
||||||
context = env->dmmu.mmu_primary_context & 0x1fff;
|
context = env->dmmu.mmu_primary_context & 0x1fff;
|
||||||
sfsr |= SFSR_CT_PRIMARY;
|
|
||||||
break;
|
break;
|
||||||
case MMU_USER_SECONDARY_IDX:
|
case MMU_USER_SECONDARY_IDX:
|
||||||
is_user = true;
|
is_user = true;
|
||||||
/* fallthru */
|
/* fallthru */
|
||||||
case MMU_KERNEL_SECONDARY_IDX:
|
case MMU_KERNEL_SECONDARY_IDX:
|
||||||
context = env->dmmu.mmu_secondary_context & 0x1fff;
|
context = env->dmmu.mmu_secondary_context & 0x1fff;
|
||||||
sfsr |= SFSR_CT_SECONDARY;
|
|
||||||
break;
|
break;
|
||||||
case MMU_NUCLEUS_IDX:
|
|
||||||
sfsr |= SFSR_CT_NUCLEUS;
|
|
||||||
/* FALLTHRU */
|
|
||||||
default:
|
default:
|
||||||
context = 0;
|
context = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rw == 1) {
|
|
||||||
sfsr |= SFSR_WRITE_BIT;
|
|
||||||
} else if (rw == 4) {
|
|
||||||
sfsr |= SFSR_NF_BIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
/* ctx match, vaddr match, valid? */
|
/* ctx match, vaddr match, valid? */
|
||||||
if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (env->dmmu.sfsr & SFSR_VALID_BIT) { /* Fault status register */
|
env->dmmu.sfsr = sfsr;
|
||||||
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.sfar = address; /* Fault address register */
|
env->dmmu.sfar = address; /* Fault address register */
|
||||||
|
|
||||||
env->dmmu.tag_access = (address & ~0x1fffULL) | context;
|
env->dmmu.tag_access = (address & ~0x1fffULL) | context;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user