According to chapter 13.3 of the UltraSPARC T1 Supplement to the UltraSPARC Architecture 2005, only the sun4u format is available for data-access loads.
Store UA2005 entries in the sun4u format to simplify processing. Signed-off-by: Artyom Tarasenko <atar4q...@gmail.com> --- target-sparc/ldst_helper.c | 51 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c index efdbabc..e267195 100644 --- a/target-sparc/ldst_helper.c +++ b/target-sparc/ldst_helper.c @@ -204,12 +204,33 @@ static void demap_tlb(SparcTLBEntry *tlb, target_ulong demap_addr, } } +static uint64_t sun4v_tte_to_sun4u(CPUSPARCState *env, uint64_t tag, + uint64_t sun4v_tte) +{ + uint64_t sun4u_tte; + if (!(cpu_has_hypervisor(env) && (tag & TLB_UST1_IS_SUN4V_BIT))) { + /* is already in the sun4u format */ + return sun4v_tte; + } + sun4u_tte = TTE_PA(sun4v_tte) | (sun4v_tte & TTE_VALID_BIT); + sun4u_tte |= (sun4v_tte & 3ULL) << 61; + sun4u_tte |= (sun4v_tte & TTE_NFO_BIT_UA2005) >> 2; + sun4u_tte |= (sun4v_tte & TTE_USED_BIT_UA2005) >> 6; + sun4u_tte |= (sun4v_tte & TTE_W_OK_BIT_UA2005) >> 5; + sun4u_tte |= (sun4v_tte & TTE_SIDEEFFECT_BIT_UA2005) >> 8; + sun4u_tte |= (sun4v_tte & TTE_PRIV_BIT_UA2005) >> 6; + sun4u_tte |= (sun4v_tte & TTE_LOCKED_BIT_UA2005) >> 55; + return sun4u_tte; +} + static void replace_tlb_1bit_lru(SparcTLBEntry *tlb, uint64_t tlb_tag, uint64_t tlb_tte, - const char *strmmu, CPUSPARCState *env1) + const char *strmmu, CPUSPARCState *env1, + uint64_t addr) { unsigned int i, replace_used; + tlb_tte = sun4v_tte_to_sun4u(env1, addr, tlb_tte); if (cpu_has_hypervisor(env1)) { uint64_t new_vaddr = tlb_tag & ~0x1fffULL; uint64_t new_size = 1024ULL * (8 << 3 * TTE_PGSIZE(tlb_tte)); @@ -2075,7 +2096,11 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val, return; } case ASI_ITLB_DATA_IN: /* I-MMU data in */ - replace_tlb_1bit_lru(env->itlb, env->immu.tag_access, val, "immu", env); + /* ignore real translation entries */ + if (!(addr & TLB_UST1_IS_REAL_BIT)) { + replace_tlb_1bit_lru(env->itlb, env->immu.tag_access, + val, "immu", env, addr); + } return; case ASI_ITLB_DATA_ACCESS: /* I-MMU data access */ { @@ -2083,8 +2108,11 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val, unsigned int i = (addr >> 3) & 0x3f; - replace_tlb_entry(&env->itlb[i], env->immu.tag_access, val, env); - + /* ignore real translation entries */ + if (!(addr & TLB_UST1_IS_REAL_BIT)) { + replace_tlb_entry(&env->itlb[i], env->immu.tag_access, + sun4v_tte_to_sun4u(env, addr, val), env); + } #ifdef DEBUG_MMU DPRINTF_MMU("immu data access replaced entry [%i]\n", i); dump_mmu(stdout, fprintf, env); @@ -2152,14 +2180,21 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val, return; } case ASI_DTLB_DATA_IN: /* D-MMU data in */ - replace_tlb_1bit_lru(env->dtlb, env->dmmu.tag_access, val, "dmmu", env); - return; + /* ignore real translation entries */ + if (!(addr & TLB_UST1_IS_REAL_BIT)) { + replace_tlb_1bit_lru(env->dtlb, env->dmmu.tag_access, + val, "dmmu", env, addr); + } + return; case ASI_DTLB_DATA_ACCESS: /* D-MMU data access */ { unsigned int i = (addr >> 3) & 0x3f; - replace_tlb_entry(&env->dtlb[i], env->dmmu.tag_access, val, env); - + /* ignore real translation entries */ + if (!(addr & TLB_UST1_IS_REAL_BIT)) { + replace_tlb_entry(&env->dtlb[i], env->dmmu.tag_access, + sun4v_tte_to_sun4u(env, addr, val), env); + } #ifdef DEBUG_MMU DPRINTF_MMU("dmmu data access replaced entry [%i]\n", i); dump_mmu(stdout, fprintf, env); -- 2.7.2