*old = new;
}
-void helper_tlbfill(CPULoongArchState *env)
+static int get_tlb_random_index(CPULoongArchState *env, vaddr addr,
+ int pagesize)
{
- uint64_t address, entryhi;
+ uint64_t address;
int index, set, i, stlb_idx;
- uint16_t pagesize, stlb_ps;
- uint16_t asid, tlb_asid;
+ uint16_t asid, tlb_asid, stlb_ps;
LoongArchTLB *tlb;
uint8_t tlb_e, tlb_g;
- if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
- entryhi = env->CSR_TLBREHI;
- /* Validity of pagesize is checked in helper_ldpte() */
- pagesize = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS);
- } else {
- entryhi = env->CSR_TLBEHI;
- /* Validity of pagesize is checked in helper_tlbrd() */
- pagesize = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
- }
-
/* Validity of stlb_ps is checked in helper_csrwr_stlbps() */
stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
if (pagesize == stlb_ps) {
/* Only write into STLB bits [47:13] */
- address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_64_VPPN_SHIFT);
+ address = addr & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_64_VPPN_SHIFT);
set = -1;
stlb_idx = (address >> (stlb_ps + 1)) & 0xff; /* [0,255] */
for (i = 0; i < 8; ++i) {
}
}
+ return index;
+}
+
+void helper_tlbfill(CPULoongArchState *env)
+{
+ vaddr entryhi;
+ int index, pagesize;
+
+ if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
+ entryhi = env->CSR_TLBREHI;
+ /* Validity of pagesize is checked in helper_ldpte() */
+ pagesize = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS);
+ } else {
+ entryhi = env->CSR_TLBEHI;
+ /* Validity of pagesize is checked in helper_tlbrd() */
+ pagesize = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
+ }
+
+ index = get_tlb_random_index(env, entryhi, pagesize);
invalidate_tlb(env, index);
fill_tlb_entry(env, env->tlb + index);
}