qemu-ppc
[Top][All Lists]
Advanced

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

Re: [Qemu-ppc] [Qemu-PPC] [PATCH 3/3] target/ppc: Add debug function to


From: David Gibson
Subject: Re: [Qemu-ppc] [Qemu-PPC] [PATCH 3/3] target/ppc: Add debug function to dump radix mmu translations
Date: Mon, 3 Jul 2017 17:51:21 +1000
User-agent: Mutt/1.8.0 (2017-02-23)

On Mon, Jul 03, 2017 at 04:19:48PM +1000, Suraj Jitindar Singh wrote:
> In target/ppc/mmu-hash64.c there already exists the function
> dump_slb() to dump the hash translation entries (for effective to
> virtual translation at least).
> 
> Implement the function ppc_radix64_dump() to allow all the kernel
> effective to real address mappings and corresponding ptes to be dumped.
> This is called when "info tlb" is invoked in the qemu console. Previously
> this command had no output when invoked with a radix guest.
> 
> Signed-off-by: Suraj Jitindar Singh <address@hidden>

This doesn't really seem equivalent to the other dump_mmu() paths.
For HPT, it just dumps the SLB, which is 32 entries.  The RPT is
likely to have thousands of PTEs.

Similarly the other embedded paths generally just dump a (software
loaded) TLB, which will have a fixed number of entries.  6xx dumps a
TLB and various metadata, but not its whole hash table.

In the other direction the info dumped for other platforms *is*
affected by the process context (or equivalent), whereas here you just
dump the RPT for the kernel (PID 0).

So instead of dumping the RPT itself, what I think you want is to
pretty print:
        PID
        LPID
        partition table entry 0
        partition table entry LPID
        process table entry 0
        process table entry PID

and maybe any other context relevant registers I've forgotten.

Obviously some of that will need to be omitted for the 'pseries' (vhyp
!= 0) case.

In fact most of the info above would make sense to always dump for a
v3.00 MMU, regardless of HPT vs RPT mode. Obviously dumping the SLB
only makes sense for HPT mode, though.

> ---
>  target/ppc/mmu-radix64.c | 49 
> ++++++++++++++++++++++++++++++++++++++++++++++++
>  target/ppc/mmu-radix64.h |  1 +
>  target/ppc/mmu_helper.c  |  2 +-
>  3 files changed, 51 insertions(+), 1 deletion(-)
> 
> diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
> index bbd37e3..f7eeead 100644
> --- a/target/ppc/mmu-radix64.c
> +++ b/target/ppc/mmu-radix64.c
> @@ -296,3 +296,52 @@ hwaddr ppc_radix64_get_phys_page_debug(PowerPCCPU *cpu, 
> target_ulong eaddr)
>  
>      return raddr & TARGET_PAGE_MASK;
>  }
> +
> +static void ppc_radix64_dump_level(FILE *f, fprintf_function cpu_fprintf,
> +                                   PowerPCCPU *cpu, uint64_t eaddr,
> +                                   uint64_t base_addr, uint64_t nls,
> +                                   uint64_t psize, int *num)
> +{
> +    CPUState *cs = CPU(cpu);
> +    uint64_t i, pte;
> +
> +    for (i = 0; i < (1 << nls); i++) {
> +        eaddr &= ~((1ULL << psize) - 1); /* Clear the low bits */
> +        eaddr |= (i << (psize - nls));
> +
> +        pte = ldq_phys(cs->as, base_addr + (i * sizeof(pte)));
> +        if (!(pte & R_PTE_VALID)) { /* Invalid Entry */
> +            continue;
> +        }
> +
> +        if (pte & R_PTE_LEAF) {
> +            uint64_t mask = (1ULL << (psize - nls)) - 1;
> +            cpu_fprintf(f, "%d\t0x%.16" PRIx64 " -> 0x%.16" PRIx64
> +                           " pte: 0x%.16" PRIx64 "\n", (*num)++,
> +                           eaddr, pte & R_PTE_RPN & ~mask, pte);
> +        } else {
> +            ppc_radix64_dump_level(f, cpu_fprintf, cpu, eaddr, pte & 
> R_PDE_NLB,
> +                                   pte & R_PDE_NLS, psize - nls, num);
> +        }
> +    }
> +}
> +
> +void ppc_radix64_dump(FILE *f, fprintf_function cpu_fprintf, PowerPCCPU *cpu)
> +{
> +    CPUState *cs = CPU(cpu);
> +    PPCVirtualHypervisorClass *vhc =
> +        PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
> +    uint64_t patbe, prtbe0;
> +    int num = 0;
> +
> +    /* Get Process Table */
> +    patbe = vhc->get_patbe(cpu->vhyp);
> +
> +    /* Load the first entry -> Guest kernel mappings (all we dump for now) */
> +    prtbe0 = ldq_phys(cs->as, patbe & PATBE1_R_PRTB);
> +
> +    cpu_fprintf(f, "\tEADDR\t\t      RADDR\n");
> +    ppc_radix64_dump_level(f, cpu_fprintf, cpu, 0ULL, prtbe0 & PRTBE_R_RPDB,
> +                           prtbe0 & PRTBE_R_RPDS, PRTBE_R_GET_RTS(prtbe0),
> +                           &num);
> +}
> diff --git a/target/ppc/mmu-radix64.h b/target/ppc/mmu-radix64.h
> index 0ecf063..c6c22bd 100644
> --- a/target/ppc/mmu-radix64.h
> +++ b/target/ppc/mmu-radix64.h
> @@ -47,6 +47,7 @@
>  int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
>                                   int mmu_idx);
>  hwaddr ppc_radix64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr);
> +void ppc_radix64_dump(FILE *f, fprintf_function cpu_fprintf, PowerPCCPU 
> *cpu);
>  
>  static inline int ppc_radix64_get_prot_eaa(uint64_t pte)
>  {
> diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> index b7b9088..9587b07 100644
> --- a/target/ppc/mmu_helper.c
> +++ b/target/ppc/mmu_helper.c
> @@ -1287,7 +1287,7 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, 
> CPUPPCState *env)
>          break;
>      case POWERPC_MMU_VER_3_00:
>          if (ppc64_radix_guest(ppc_env_get_cpu(env))) {
> -            /* TODO - Unsupported */
> +            ppc_radix64_dump(f, cpu_fprintf, ppc_env_get_cpu(env));
>          } else {
>              dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
>              break;

-- 
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]