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 <sjitindarsi...@gmail.com>
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
signature.asc
Description: PGP signature