On Tue, 14 Oct 2025 at 21:09, Richard Henderson
<[email protected]> wrote:
>
> Signed-off-by: Richard Henderson <[email protected]>
> ---
>  target/arm/tcg/tlb-insns.c | 93 ++++++++++++++++++++++++++++++--------
>  1 file changed, 74 insertions(+), 19 deletions(-)
>
> diff --git a/target/arm/tcg/tlb-insns.c b/target/arm/tcg/tlb-insns.c
> index f7510a1208..daadba7bfc 100644
> --- a/target/arm/tcg/tlb-insns.c
> +++ b/target/arm/tcg/tlb-insns.c
> @@ -918,16 +918,43 @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, 
> ARMMMUIdx mmuidx,
>      return ret;
>  }
>
> -static void do_rvae_write(CPUARMState *env, uint64_t value,
> -                          int idxmap, bool synced)
> +static TLBIRange tlbi_aa64_get_range128(CPUARMState *env, ARMMMUIdx mmuidx,
> +                                        uint64_t vallo, uint64_t valhi)
>  {
> -    ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap);
> -    TLBIRange range;
> -    int bits;
> +    uint64_t uaddr = extract64(valhi << 12, 0, 56);
> +    ARMVAParameters param = aa64_va_parameters(env, uaddr, mmuidx, true, 
> false);
> +    TLBIRange ret = { };
> +    unsigned page_size_granule = extract64(vallo, 46, 2);
> +    ARMGranuleSize gran = tlbi_range_tg_to_gran_size(page_size_granule);
>
> -    range = tlbi_aa64_get_range(env, one_idx, value);
> -    bits = tlbbits_for_regime(env, one_idx, range.base);
> +    /* The granule encoded in value must match the granule in use. */
> +    if (gran != param.gran) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
> +                      page_size_granule);

Having an early-return here would make this code more obviously
parallel with tlbi_aa64_get_range().

> +    } else {
> +        unsigned page_shift = arm_granule_bits(gran);
> +        unsigned num = extract64(vallo, 39, 5);
> +        unsigned scale = extract64(vallo, 44, 2);
> +        unsigned exponent = (5 * scale) + 1;
> +        uint64_t max = 1ull << 56;
>
> +        ret.length = (num + 1) << (exponent + page_shift);
> +        ret.length = MIN(ret.length, max - uaddr);
> +        /*
> +         * Note that TLBIPRange ignores the high bits, because the HW TLB
> +         * does not use it.  But the qemu softmmu tlb does, so sign-extend
> +         * if and only if the regime has two ranges.
> +         */
> +        ret.base = uaddr | (-(uint64_t)param.select << 56);

I think it would be clearer if we wrote this "sign extend
based on param.select" the same way that tlbi_aa64_get_range()
does".

Otherwise
Reviewed-by: Peter Maydell <[email protected]>

thanks
-- PMM

Reply via email to