With function loongarch_tlb_search(), it is to search TLB entry with
speficied virtual address, the difference is selection with asid and
global bit. Here add selection callback with asid and global bit.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/loongarch/tcg/tlb_helper.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index b46621f203..fda81f190a 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -21,6 +21,13 @@
#include "cpu-csr.h"
#include "tcg/tcg_loongarch.h"
+typedef bool (*tlb_match)(bool global, int asid, int tlb_asid);
+
+static bool tlb_match_any(bool global, int asid, int tlb_asid)
+{
+ return global || tlb_asid == asid;
+}
+
bool check_ps(CPULoongArchState *env, uint8_t tlb_ps)
{
if (tlb_ps >= 64) {
@@ -201,12 +208,15 @@ static bool loongarch_tlb_search(CPULoongArchState *env, vaddr vaddr,
{
LoongArchTLB *tlb;
uint16_t csr_asid, tlb_asid, stlb_idx;
- uint8_t tlb_e, tlb_ps, tlb_g, stlb_ps;
+ uint8_t tlb_e, tlb_ps, stlb_ps;
+ bool tlb_g;
int i, compare_shift;
uint64_t vpn, tlb_vppn;
+ tlb_match func;
+ func = tlb_match_any;
csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
- stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
+ stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
vpn = (vaddr & TARGET_VIRT_MASK) >> (stlb_ps + 1);
stlb_idx = vpn & 0xff; /* VA[25:15] <==> TLBIDX.index for 16KiB Page */
compare_shift = stlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
@@ -218,9 +228,9 @@ static bool loongarch_tlb_search(CPULoongArchState *env, vaddr vaddr,
if (tlb_e) {
tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
- tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
+ tlb_g = !!FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
- if ((tlb_g == 1 || tlb_asid == csr_asid) &&
+ if (func(tlb_g, csr_asid, tlb_asid) &&
(vpn == (tlb_vppn >> compare_shift))) {
*index = i * 256 + stlb_idx;
return true;
@@ -239,7 +249,7 @@ static bool loongarch_tlb_search(CPULoongArchState *env, vaddr vaddr,
tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
vpn = (vaddr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
- if ((tlb_g == 1 || tlb_asid == csr_asid) &&
+ if (func(tlb_g, csr_asid, tlb_asid) &&
(vpn == (tlb_vppn >> compare_shift))) {
*index = i;
return true;
--
2.39.3