qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC PATCH v2 09/30] target/loongarch: Add TLB instruction support


From: Richard Henderson
Subject: Re: [RFC PATCH v2 09/30] target/loongarch: Add TLB instruction support
Date: Wed, 17 Nov 2021 09:22:52 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.14.0

On 11/17/21 8:29 AM, yangxiaojuan wrote:
On 11/12/2021 02:14 AM, Richard Henderson wrote:
On 11/11/21 2:35 AM, Xiaojuan Yang wrote:
+static bool trans_tlbwr(DisasContext *ctx, arg_tlbwr *a)
+{
+    gen_helper_check_plv(cpu_env);
+    gen_helper_tlbwr(cpu_env);
+    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+    ctx->base.is_jmp = DISAS_EXIT;
+    return true;
+}

I think you can skip the EXIT if paging is disabled, which it usually will be 
in the software tlb handler.  You'd be able to tell with the mmu_idx being the 
one you use for paging disabled.

The paging disabled only enabled at the bios startup, we can get the phys 
address directly, tlbwr instruction will not be used when paging enabled.

Paging is also disabled during TLBRENTRY exception (see section 6.2.4 Hardware Exception Handling of TLB Refil Exception). It is this routine that will usually use tlbwr most often (although the kernel at PRV 0 is not prevented from doing so).

+    default:
+        do_raise_exception(env, EXCP_INE, GETPC());

You can detect this during translation, and dispatch to the appropriate invtlb 
sub-function.

oh, sorry, I don't quiet understand this. detect during the translation sees 
more complicated.

It is not more complex at all.  Less complex, I would say.

static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a)
{
    TCGv rj = gpr_src(ctx, a->rj, EXT_NONE);
    TCGv rk = gpr_src(ctx, a->rk, EXT_NONE);

    if (check_plv(ctx)) {
        return false;
    }

    switch (a->invop) {
    case 0:
    case 1:
        gen_helper_invtlb_all(cpu_env);
        break;
    case 2:
        gen_helper_invtlb_all_g(cpu_env, tcg_constant_i32(1));
        break;
    case 3:
        gen_helper_invtlb_all_g(cpu_env, tcg_constant_i32(0));
        break;
    case 4:
        gen_helper_invtlb_all_asid(cpu_env, rj);
        break;
    case 5:
        gen_helper_invtlb_page_asid(cpu_env, rj, rk);
        break;
    case 6:
        gen_helper_invtlb_page_asid_or_g(cpu_env, rj, rk);
        break;
    default:
        return false;
    }
    ctx->base.is_jmp = DISAS_STOP;
    return true;
}


r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]