qemu-ppc
[Top][All Lists]
Advanced

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

Re: [Qemu-ppc] [PATCH v4 3/5] target/ppc: add hash MMU definitions for I


From: David Gibson
Subject: Re: [Qemu-ppc] [PATCH v4 3/5] target/ppc: add hash MMU definitions for ISA v3.0
Date: Thu, 3 May 2018 10:48:54 +1000
User-agent: Mutt/1.9.3 (2018-01-21)

On Tue, Apr 24, 2018 at 01:30:43PM +0200, Cédric Le Goater wrote:
> The HPTE bits definitions are slightly modified in ISA v3.0. Let's add
> some helpers to hide the differences in the hash MMU code.
> 
> Signed-off-by: Cédric Le Goater <address@hidden>
> ---
>  hw/ppc/spapr_hcall.c    |  5 +++--
>  target/ppc/mmu-hash64.c | 30 ++++++++++++++++++++++--------
>  target/ppc/mmu-hash64.h | 30 ++++++++++++++++++++++++++++++
>  3 files changed, 55 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index 16bccdd5c012..929f4e05492d 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -94,7 +94,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, 
> sPAPRMachineState *spapr,
>          return H_PARAMETER;
>      }
>  
> -    raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << apshift) - 1);
> +    raddr = (ptel & ppc_hash64_hpte_r_rpn(cpu)) & ~((1ULL << apshift) - 1);

Doesn't H_ENTER always use the old format?  I thought it did that so
PAPR guests never saw the new format, only powernv.

>      if (is_ram_address(spapr, raddr)) {
>          /* Regular RAM - should have WIMG=0010 */
> @@ -586,7 +586,8 @@ static int rehash_hpte(PowerPCCPU *cpu,
>  
>      base_pg_shift = ppc_hash64_hpte_page_shift_noslb(cpu, pte0, pte1);
>      assert(base_pg_shift); /* H_ENTER shouldn't allow a bad encoding */
> -    avpn = HPTE64_V_AVPN_VAL(pte0) & ~(((1ULL << base_pg_shift) - 1) >> 23);
> +    avpn = ppc_hash64_hpte_v_avpn_val(cpu, pte0) &
> +        ~(((1ULL << base_pg_shift) - 1) >> 23);

Likwise rehash_hpte is only used for PAPR guests, so I don't think it
needs to handle the new format.

>      if (pte0 & HPTE64_V_SECONDARY) {
>          pteg = ~pteg;
> diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> index a1db20e3a8ed..ecea2ae04dd3 100644
> --- a/target/ppc/mmu-hash64.c
> +++ b/target/ppc/mmu-hash64.c
> @@ -452,7 +452,8 @@ void ppc_hash64_unmap_hptes(PowerPCCPU *cpu, const 
> ppc_hash_pte64_t *hptes,
>                          false, n * HASH_PTE_SIZE_64);
>  }
>  
> -static unsigned hpte_page_shift(const PPCHash64SegmentPageSizes *sps,
> +static unsigned hpte_page_shift(PowerPCCPU *cpu,
> +                                const PPCHash64SegmentPageSizes *sps,
>                                  uint64_t pte0, uint64_t pte1)
>  {
>      int i;
> @@ -479,7 +480,7 @@ static unsigned hpte_page_shift(const 
> PPCHash64SegmentPageSizes *sps,
>              continue;
>          }
>  
> -        mask = ((1ULL << ps->page_shift) - 1) & HPTE64_R_RPN;
> +        mask = ((1ULL << ps->page_shift) - 1) & ppc_hash64_hpte_r_rpn(cpu);
>  
>          if ((pte1 & mask) == ((uint64_t)ps->pte_enc << HPTE64_R_RPN_SHIFT)) {
>              return ps->page_shift;
> @@ -489,6 +490,18 @@ static unsigned hpte_page_shift(const 
> PPCHash64SegmentPageSizes *sps,
>      return 0; /* Bad page size encoding */
>  }
>  
> +static bool ppc_hash64_hpte_v_compare(PowerPCCPU *cpu, target_ulong pte0,
> +                                      target_ulong ptem)
> +{
> +    CPUPPCState *env = &cpu->env;
> +
> +    if (env->mmu_model & POWERPC_MMU_3_00) {
> +        return HPTE64_V_COMPARE_3_0(pte0, ptem);
> +    } else {
> +        return HPTE64_V_COMPARE(pte0, ptem);
> +    }
> +}

Ugh, and here we get more complications, because I guess we need to
check for (mmu_model == 3.00) && (!vhyp) to exclude PAPR guests.  And
a bunch of similar places.

> +
>  static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
>                                       const PPCHash64SegmentPageSizes *sps,
>                                       target_ulong ptem,
> @@ -509,8 +522,8 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, 
> hwaddr hash,
>          pte1 = ppc_hash64_hpte1(cpu, pteg, i);
>  
>          /* This compares V, B, H (secondary) and the AVPN */
> -        if (HPTE64_V_COMPARE(pte0, ptem)) {
> -            *pshift = hpte_page_shift(sps, pte0, pte1);
> +        if (ppc_hash64_hpte_v_compare(cpu, pte0, ptem)) {
> +            *pshift = hpte_page_shift(cpu, sps, pte0, pte1);
>              /*
>               * If there is no match, ignore the PTE, it could simply
>               * be for a different segment size encoding and the
> @@ -570,7 +583,8 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu,
>          epn = (eaddr & ~SEGMENT_MASK_256M) & epnmask;
>          hash = vsid ^ (epn >> sps->page_shift);
>      }
> -    ptem = (slb->vsid & SLB_VSID_PTEM) | ((epn >> 16) & HPTE64_V_AVPN);
> +    ptem = (slb->vsid & SLB_VSID_PTEM) | ((epn >> 16) &
> +                                          ppc_hash64_hpte_v_avpn(cpu));
>      ptem |= HPTE64_V_VALID;
>  
>      /* Page address translation */
> @@ -624,7 +638,7 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
>              break;
>          }
>  
> -        shift = hpte_page_shift(sps, pte0, pte1);
> +        shift = hpte_page_shift(cpu, sps, pte0, pte1);
>          if (shift) {
>              return shift;
>          }
> @@ -860,7 +874,7 @@ skip_slb_search:
>  
>      /* 7. Determine the real address from the PTE */
>  
> -    raddr = deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, eaddr);
> +    raddr = deposit64(pte.pte1 & ppc_hash64_hpte_r_rpn(cpu), 0, apshift, 
> eaddr);
>  
>      tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
>                   prot, mmu_idx, 1ULL << apshift);
> @@ -910,7 +924,7 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, 
> target_ulong addr)
>          return -1;
>      }
>  
> -    return deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, addr)
> +    return deposit64(pte.pte1 & ppc_hash64_hpte_r_rpn(cpu), 0, apshift, addr)
>          & TARGET_PAGE_MASK;
>  }
>  
> diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
> index 53dcec5b9316..a3a0de452b94 100644
> --- a/target/ppc/mmu-hash64.h
> +++ b/target/ppc/mmu-hash64.h
> @@ -70,8 +70,12 @@ void ppc_hash64_finalize(PowerPCCPU *cpu);
>  #define HPTE64_V_SSIZE_SHIFT    62
>  #define HPTE64_V_AVPN_SHIFT     7
>  #define HPTE64_V_AVPN           0x3fffffffffffff80ULL
> +#define HPTE64_V_AVPN_3_0       0x000fffffffffff80ULL
>  #define HPTE64_V_AVPN_VAL(x)    (((x) & HPTE64_V_AVPN) >> 
> HPTE64_V_AVPN_SHIFT)
> +#define HPTE64_V_AVPN_VAL_3_0(x)                        \
> +    (((x) & HPTE64_V_AVPN_3_0) >> HPTE64_V_AVPN_SHIFT)
>  #define HPTE64_V_COMPARE(x, y)  (!(((x) ^ (y)) & 0xffffffffffffff83ULL))
> +#define HPTE64_V_COMPARE_3_0(x, y)  (!(((x) ^ (y)) & 0x3fffffffffffff83ULL))
>  #define HPTE64_V_BOLTED         0x0000000000000010ULL
>  #define HPTE64_V_LARGE          0x0000000000000004ULL
>  #define HPTE64_V_SECONDARY      0x0000000000000002ULL
> @@ -82,6 +86,7 @@ void ppc_hash64_finalize(PowerPCCPU *cpu);
>  #define HPTE64_R_KEY_HI         0x3000000000000000ULL
>  #define HPTE64_R_RPN_SHIFT      12
>  #define HPTE64_R_RPN            0x0ffffffffffff000ULL
> +#define HPTE64_R_RPN_3_0        0x01fffffffffff000ULL
>  #define HPTE64_R_FLAGS          0x00000000000003ffULL
>  #define HPTE64_R_PP             0x0000000000000003ULL
>  #define HPTE64_R_N              0x0000000000000004ULL
> @@ -99,6 +104,31 @@ void ppc_hash64_finalize(PowerPCCPU *cpu);
>  #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
>  #define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
>  
> +static inline target_ulong ppc_hash64_hpte_r_rpn(PowerPCCPU *cpu)
> +{
> +    CPUPPCState *env = &cpu->env;
> +
> +    return env->mmu_model & POWERPC_MMU_3_00 ?
> +        HPTE64_R_RPN_3_0 : HPTE64_R_RPN;
> +}
> +
> +static inline target_ulong ppc_hash64_hpte_v_avpn(PowerPCCPU *cpu)
> +{
> +    CPUPPCState *env = &cpu->env;
> +
> +    return env->mmu_model & POWERPC_MMU_3_00 ?
> +        HPTE64_V_AVPN_3_0 : HPTE64_V_AVPN;
> +}
> +
> +static inline target_ulong ppc_hash64_hpte_v_avpn_val(PowerPCCPU *cpu,
> +                                                      target_ulong pte0)
> +{
> +    CPUPPCState *env = &cpu->env;
> +
> +    return env->mmu_model & POWERPC_MMU_3_00 ?
> +        HPTE64_V_AVPN_VAL_3_0(pte0) : HPTE64_V_AVPN_VAL(pte0);
> +}
> +
>  static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
>  {
>      if (cpu->vhyp) {

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


reply via email to

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