aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBibo Mao <maobibo@loongson.cn>2025-07-16 09:45:47 +0800
committerBibo Mao <maobibo@loongson.cn>2025-08-29 10:05:02 +0800
commit198c827ca5d3bee6aa0c498f25f5ea6928f57de2 (patch)
tree803795f62b8c78815dd1eb233fa601c0536b092c
parent982d7674ff4ed1affc4dadba2c6f6ab1b1df4e97 (diff)
downloadqemu-198c827ca5d3bee6aa0c498f25f5ea6928f57de2.zip
qemu-198c827ca5d3bee6aa0c498f25f5ea6928f57de2.tar.gz
qemu-198c827ca5d3bee6aa0c498f25f5ea6928f57de2.tar.bz2
target/loongarch: Set page size in TLB entry with STLB
With VTLB different TLB entry may have different page size, and page size is set in PS field of TLB entry. However with STLB, all the TLB entries have the same page size, page size comes from register CSR_STLBPS, PS field of TLB entry is not used. Here PS field of TLB entry is used with all TLB entries, even with STLB. It is convenient with TLB maintainance operation. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn>
-rw-r--r--target/loongarch/tcg/tlb_helper.c41
1 files changed, 10 insertions, 31 deletions
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 8872593..3ea0e15 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -110,11 +110,8 @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
if (!tlb_e) {
return;
}
- if (index >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
pagesize = MAKE_64BIT_MASK(tlb_ps, 1);
mask = MAKE_64BIT_MASK(0, tlb_ps + 1);
@@ -173,11 +170,8 @@ static void fill_tlb_entry(CPULoongArchState *env, int index)
lo1 = env->CSR_TLBELO1;
}
- /* Only MTLB has the ps fields */
- if (index >= LOONGARCH_STLB) {
- tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, csr_ps);
- }
-
+ /* Store page size in field PS */
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, csr_ps);
tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, VPPN, csr_vppn);
tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 1);
csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
@@ -283,12 +277,7 @@ void helper_tlbrd(CPULoongArchState *env)
index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX);
tlb = &env->tlb[index];
-
- if (index >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
if (!tlb_e) {
@@ -476,11 +465,8 @@ void helper_invtlb_page_asid(CPULoongArchState *env, target_ulong info,
if (!tlb_e) {
continue;
}
- if (i >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
vpn = (addr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
@@ -509,11 +495,8 @@ void helper_invtlb_page_asid_or_g(CPULoongArchState *env,
if (!tlb_e) {
continue;
}
- if (i >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
vpn = (addr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
@@ -673,11 +656,7 @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
uint64_t tlb_entry, tlb_ppn;
uint8_t tlb_ps, n, tlb_v, tlb_d, tlb_plv, tlb_nx, tlb_nr, tlb_rplv;
- if (index >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
n = (address >> tlb_ps) & 0x1;/* Odd or even */
tlb_entry = n ? tlb->tlb_entry1 : tlb->tlb_entry0;