#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) {
{
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;
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;
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;