On 11/17/2021 04:22 PM, Richard Henderson wrote:
> 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).
Sorry, I forgot this situation.
>
>>>> + 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;
> }
>
Thank you. I get it.
>
> r~