On 2026/10/14 下午5:56, Bibo Mao wrote:
Sorry, to_guest is useful even if gtlb instruction is removed. I think that parameter to_guest should be changed as vm_level, the same name API set_sys(CPULoongArchState *env, int vm_level).On 2026/10/9 上午11:05, SignKirigami wrote:if gtlb instruction is removed, I think helper_invtlb_xxx APIs can be simplified and remove parameter to_guest.Add op 0x9, 0xa-0xf to instruction invtlb to support vm level 1. Signed-off-by: SignKirigami <[email protected]> Signed-off-by: Hengyu Yu <[email protected]> --- .../tcg/insn_trans/trans_privileged.c.inc | 34 +++++++++++++ target/loongarch/tcg/tlb_helper.c | 51 ++++++++++++++++--- 2 files changed, 77 insertions(+), 8 deletions(-)diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc b/target/loongarch/tcg/insn_trans/trans_privileged.c.incindex 493ed7f24b..00e8f61e42 100644 --- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc +++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc@@ -328,6 +328,10 @@ static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a)return false; } + if (!avail_LVZ(ctx) && a->imm > 0x6) { + return false; + } + switch (a->imm) { case 0x0: case 0x1:@@ -352,6 +356,36 @@ static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a)gen_helper_invtlb_page_asid_or_g(tcg_env, rj, rk, tcg_constant_i32(0)); break; + case 0x9: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + //TODO: refine 0x9-0x16 + gen_helper_invtlb_all(tcg_env, rj, tcg_constant_i32(0), + tcg_constant_i32(0)); + break; + case 0xa: + gen_helper_invtlb_all_g(tcg_env, rj, tcg_constant_i32(1), + tcg_constant_i32(1)); + break; + case 0xb: + gen_helper_invtlb_all_g(tcg_env, rj, tcg_constant_i32(0), + tcg_constant_i32(1)); + break; + case 0xc: + gen_helper_invtlb_all_asid(tcg_env, rj, tcg_constant_i32(1)); + break; + case 0xd:+ gen_helper_invtlb_page_asid(tcg_env, rj, rk, tcg_constant_i32(1));+ break; + case 0xe: + gen_helper_invtlb_page_asid_or_g(tcg_env, rj, rk, + tcg_constant_i32(1)); + break; default: return false; }diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.cindex 60c7193283..c02b7c2472 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c@@ -599,9 +599,18 @@ void helper_tlbflush(CPULoongArchState *env, uint32_t vm_level) void helper_invtlb_all(CPULoongArchState *env, target_ulong info, uint32_t op,uint32_t to_guest) { + uint16_t gid = to_guest ? (info & 0xff) : get_tgid(env); + + if (to_guest && env_vm_level(env) == VM_LEVEL1) { + do_raise_exception(env, EXCCODE_IPE, GETPC()); + } + + to_guest |= env_vm_level(env) == VM_LEVEL1; + for (int i = 0; i < LOONGARCH_TLB_MAX; i++) { - env->tlb[i].tlb_misc = FIELD_DP64(env->tlb[i].tlb_misc, - TLB_MISC, E, 0); + LoongArchTLB *tlb = &env->tlb[i];+ if ((op == 0 && to_guest == 0) || tlb_entry_matches_gid(tlb, gid))+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0); } tlb_flush(env_cpu(env)); }
Also I think that this patch should be split as smaller parts like comments with csrrd instruction, such as:
1. Existing invtlb() instruction with LVZ support. 2. More op code with invtlb() instruction.3. Add common API or new parameter vm_level with helper_intlb_xxx function.
Regards Bibo Mao
Regards Bibo Mao@@ -609,11 +618,19 @@ void helper_invtlb_all(CPULoongArchState *env, target_ulong info, uint32_t op, void helper_invtlb_all_g(CPULoongArchState *env, target_ulong info, uint32_t g,uint32_t to_guest) { + uint16_t gid = to_guest ? (info & 0xff) : get_tgid(env); + + if (to_guest && env_vm_level(env) == VM_LEVEL1) { + do_raise_exception(env, EXCCODE_IPE, GETPC()); + } + + to_guest |= env_vm_level(env) == VM_LEVEL1; + for (int i = 0; i < LOONGARCH_TLB_MAX; i++) { LoongArchTLB *tlb = &env->tlb[i]; uint8_t tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G); - if (tlb_g == g) { + if (tlb_g == g && tlb_entry_matches_gid(tlb, gid)) { tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0); } }@@ -624,13 +641,19 @@ void helper_invtlb_all_asid(CPULoongArchState *env, target_ulong info,uint32_t to_guest) { uint16_t asid = info & R_CSR_ASID_ASID_MASK; + uint16_t gid = to_guest ? ((info >> 16) & 0xff) : get_tgid(env); + + if (to_guest) { + do_raise_exception(env, EXCCODE_IPE, GETPC()); + } + to_guest |= env_vm_level(env); for (int i = 0; i < LOONGARCH_TLB_MAX; i++) { LoongArchTLB *tlb = &env->tlb[i]; uint8_t tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G); uint16_t tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID); - if (!tlb_g && (tlb_asid == asid)) {+ if (!tlb_g && tlb_asid == asid && tlb_entry_matches_gid(tlb, gid)) {tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 0); } }@@ -640,12 +663,19 @@ void helper_invtlb_all_asid(CPULoongArchState *env, target_ulong info,void helper_invtlb_page_asid(CPULoongArchState *env, target_ulong info, target_ulong addr, uint32_t to_guest) { - int asid = info & 0x3ff; + + uint16_t asid = info & R_CSR_ASID_ASID_MASK; + uint16_t gid = to_guest ? ((info >> 16) & 0xff) : get_tgid(env); const LoongArchTLB *tlb; tlb_match func; + if (to_guest && env_vm_level(env)) { + do_raise_exception(env, EXCCODE_IPE, GETPC()); + } + to_guest |= env_vm_level(env); + func = tlb_match_asid; - tlb = loongarch_tlb_search_cb(env, addr, asid, func, to_guest, 0); + tlb = loongarch_tlb_search_cb(env, addr, asid, func, to_guest, gid); if (tlb) { invalidate_tlb(env, tlb - env->tlb, to_guest); }@@ -654,13 +684,18 @@ void helper_invtlb_page_asid(CPULoongArchState *env, target_ulong info, void helper_invtlb_page_asid_or_g(CPULoongArchState *env, target_ulong info,target_ulong addr, uint32_t to_guest) { - int asid = info & 0x3ff; + uint16_t asid = info & R_CSR_ASID_ASID_MASK; + uint16_t gid = to_guest ? ((info >> 16) & 0xff) : get_tgid(env); const LoongArchTLB *tlb; tlb_match func; func = tlb_match_any; + if (to_guest) { + do_raise_exception(env, EXCCODE_IPE, GETPC()); + } + to_guest |= env_vm_level(env); tlb = loongarch_tlb_search_cb(env, addr, asid, func, - to_guest, 0); + to_guest, gid); if (tlb) { invalidate_tlb(env, tlb - env->tlb, to_guest); }
