[PATCH 0/5] [ppc32] update vtop

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

 



This patch update ppc32 vtop.
 - Translate kvaddr for fsl-booke by using TLBCAM setting
 - Remove PMD from display because virtual address bit is not assigned
 - Fixup displayed PHYSICAL values of fsl-booke PTE format
 - Fixup bug for page flags setup which I made previous patch

Updated command images are below.

- kvaddr can be translated by using TLBCAM

crash> sym powerpc_base_platform
c0913024 (S) powerpc_base_platform
crash> vtop c0913024
VIRTUAL   PHYSICAL
c0913024  913024

PAGE DIRECTORY: c08d1000
  PGD: c08d2810 => 0

  TLBCAM[0]: MAS0     MAS1     MAS2     MAS3     MAS7
             10000001 c0000900 c0000004 15       0
             VIRTUAL RANGE : c0000000 - cfffffff
             PHYSICAL RANGE: 0 - fffffff
  => VIRTUAL  PHYSICAL TLBCAM-OFFSET
     c0913024 913024   9515044

  PAGE     PHYSICAL   MAPPING    INDEX CNT FLAGS
d0012260     913000         0         0  1 400

Next,
- vtop won't display PMD
- physical address is not equal to PTE
- FLAGS can be handled well

crash> vtop -c 4145 10000000
VIRTUAL   PHYSICAL
10000000  ef448000

PAGE DIRECTORY: e85c4000
  PGD: e85c4200 => e873c000
  PTE: e873c000 => ef44824020d
 PAGE: ef448000

    PTE      PHYSICAL  FLAGS
ef44824020d  ef448000  (PRESENT|USER|COHERENT|ACCESSED)

  VMA       START      END    FLAGS  FILE
ea1d3960  10000000  10af9000 8001875  /tmp/toshi/crash

However, ... could not read vtop'd physical address data from /dev/mem now.

crash> rd -p ef448000
rd: read error: physical address: ef448000  type: "32-bit PHYSADDR"

Although my environment tends to set higher PTE value,
PFN is valid physical scope number, my maximum is 4GB.

crash> log | grep totalpages
On node 0 totalpages: 1048576
crash> eval 1048576
hexadecimal: 100000  (1MB)
    decimal: 1048576
      octal: 4000000
     binary: 00000000000100000000000000000000

Is there any constraint in "rd" or is my "/dev/mem" something wrong?

Thanks,
Toshi

Toshikazu Nakayama (5):
  ppc32: add macros for machdep flags about ppc32 pte
  ppc32: add special vtop for FSL BOOKE
  ppc32: Ignore PMD
  ppc32: fixup vtop display items
  ppc32: fix page flags setup macro

 defs.h |   10 ++++
 ppc.c  |  162 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 143 insertions(+), 29 deletions(-)

Date: Wed, 21 Mar 2012 13:58:06 +0900
Subject: [PATCH 1/5] ppc32: add macros for machdep flags about ppc32 pte

Add IS_PAE() and IS_BOOKE() macros which can switch the way of
page table translation.

Signed-off-by: suzuki@xxxxxxxxxx
Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx>
---
 defs.h |    3 +++
 ppc.c  |   14 +++++++-------
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/defs.h b/defs.h
index 2c8fae1..c742f21 100755
--- a/defs.h
+++ b/defs.h
@@ -2663,6 +2663,9 @@ struct machine_specific {
 	ulong _page_shared;
 };
 
+/* machdep flags for ppc32 specific */
+#define IS_PAE()		(machdep->flags & PAE)
+#define IS_BOOKE()		(machdep->flags & CPU_BOOKE)
 /* Page translation bits */
 #define PPC_PLATFORM		(machdep->machspec->platform)
 #define PTE_SIZE		(machdep->machspec->pte_size)
diff --git a/ppc.c b/ppc.c
index 7037207..17d4218 100755
--- a/ppc.c
+++ b/ppc.c
@@ -118,7 +118,7 @@ probe_ppce500_platform(char *name)
 {
 	if (STRNEQ(name, "ppce500mc")) {
 		PPC_PLATFORM = strdup(name);
-		if (machdep->flags & PAE) {
+		if (IS_PAE()) {
 			PTE_RPN_SHIFT = BOOKE3E_PTE_RPN_SHIFT;
 			PLATFORM_PAGE_FLAGS_SETUP(BOOK3E);
 		} else
@@ -132,7 +132,7 @@ probe_ppce500_platform(char *name)
 static int
 probe_default_platform(char *name)
 {
-	if (machdep->flags & PAE) {
+	if (IS_PAE()) {
 		error(INFO, "platform \"%s\" 64bit PTE fall through\n", name);
 		error(INFO, "vmalloc translation could not work!\n");
 	}
@@ -326,9 +326,9 @@ ppc_dump_machdep_table(ulong arg)
         fprintf(fp, "              flags: %lx (", machdep->flags);
 	if (machdep->flags & KSYMS_START)
 		fprintf(fp, "%sKSYMS_START", others++ ? "|" : "");
-	if (machdep->flags & PAE)
+	if (IS_PAE())
 		fprintf(fp, "%sPAE", others++ ? "|" : "");
-	if (machdep->flags & CPU_BOOKE)
+	if (IS_BOOKE())
 		fprintf(fp, "%sCPU_BOOKE", others++ ? "|" : "");
         fprintf(fp, ")\n");
 
@@ -428,7 +428,7 @@ ppc_pgd_vtop(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 
 	page_middle = (ulong *)pgd_pte;
 
-	if (machdep->flags & CPU_BOOKE)
+	if (IS_BOOKE())
 		page_table = (ulong *)((ulong)page_middle + ((ulong)BTOP(vaddr) & (PTRS_PER_PTE - 1)) * PTE_SIZE);
 	else {
 		page_table = (ulong *)((pgd_pte & (ulong)machdep->pagemask) + machdep->kvbase);
@@ -440,7 +440,7 @@ ppc_pgd_vtop(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 			(ulong)page_table);
 
         FILL_PTBL(PAGEBASE((ulong)page_table), KVADDR, PAGESIZE());
-	if (machdep->flags & PAE)
+	if (IS_PAE())
 		pte = ULONGLONG(machdep->ptbl + PAGEOFFSET((ulong)page_table));
 
 	else	/* Defaults to ulong */
@@ -782,7 +782,7 @@ ppc_translate_pte(ulong pte32, void *physaddr, ulonglong pte64)
         char *arglist[MAXARGS];
 	ulonglong paddr;
 
-	if (!(machdep->flags & PAE))
+	if (!IS_PAE())
 		pte64 = pte32;
 
         paddr = PAGEBASE(pte64);
-- 
1.7.0.4

Date: Wed, 21 Mar 2012 15:50:28 +0900
Subject: [PATCH 2/5] ppc32: add special vtop for FSL BOOKE

FSL BOOKE MMU architecture own special address translation with TLBCAM
which do not require the basic page table setup for memory access.
Since the most kernel virtual address is set as TLBCAM region,
those vtop can not resolve physical address from basic ppc vtop routine.
Try to resolve it via TLBCAM if pgd entry is null.

[before] kvtop failed because of no page table
crash> vtop c0000000
VIRTUAL   PHYSICAL
c0000000  0

PAGE DIRECTORY: c08d1000
  PGD: c08d2800 => 0

  PAGE     PHYSICAL   MAPPING    INDEX CNT FLAGS
d0000000          0         0         0  1 400

[after] kvtop search from TLBCAM if mapped

crash> vtop c0000000
VIRTUAL   PHYSICAL
c0000000  0

PAGE DIRECTORY: c08d1000
  PGD: c08d2800 => 0

  TLBCAM[0]: MAS0     MAS1     MAS2     MAS3     MAS7
             10000001 c0000900 c0000004 15       0
             VIRTUAL RANGE : c0000000 - cfffffff
             PHYSICAL RANGE: 0 - fffffff
  => VIRTUAL  PHYSICAL TLBCAM-OFFSET
     c0000000 0        0

  PAGE     PHYSICAL   MAPPING    INDEX CNT FLAGS
d0000000          0         0         0  1 400

Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx>
---
 defs.h |    7 ++++
 ppc.c  |  112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 118 insertions(+), 1 deletions(-)

diff --git a/defs.h b/defs.h
index c742f21..a3a40e0 100755
--- a/defs.h
+++ b/defs.h
@@ -2661,6 +2661,10 @@ struct machine_specific {
 	ulong _page_accessed;
 	ulong _page_hwwrite;
 	ulong _page_shared;
+
+	/* platform special vtop */
+	int (*vtop_special)(ulong vaddr, physaddr_t *paddr, int verbose);
+	void *mmu_special;
 };
 
 /* machdep flags for ppc32 specific */
@@ -2676,6 +2680,9 @@ struct machine_specific {
 #define PGDIR_SHIFT		(PAGE_SHIFT + PTE_SHIFT)
 #define PTRS_PER_PGD		(1 << (32 - PGDIR_SHIFT))
 #define PTRS_PER_PTE		(1 << PTE_SHIFT)
+/* special vtop */
+#define VTOP_SPECIAL		(machdep->machspec->vtop_special)
+#define MMU_SPECIAL		(machdep->machspec->mmu_special)
 
 /* PFN shifts */
 #define BOOKE3E_PTE_RPN_SHIFT	(24)
diff --git a/ppc.c b/ppc.c
index 17d4218..11fe22f 100755
--- a/ppc.c
+++ b/ppc.c
@@ -113,6 +113,107 @@ probe_ppc44x_platform(char *name)
 	return FALSE;
 }
 
+struct fsl_booke_tlbcam {
+#define NUM_TLBCAMS	(64)
+#define LAST_TLBCAM	(0x40)
+	uint index;
+	struct {
+		ulong start;
+		ulong limit;
+		physaddr_t phys;
+	} tlbcamrange;
+	struct {
+		uint MAS0;
+		uint MAS1;
+		ulong MAS2;
+		uint MAS3;
+		uint MAS7;
+	} tlbcam;
+};
+
+static int
+fsl_booke_vtop(ulong vaddr, physaddr_t *paddr, int verbose)
+{
+	struct fsl_booke_tlbcam *fsl_mmu;
+	int i, found;
+
+	if (CRASHDEBUG(1))
+		fprintf(fp, "[Searching tlbcam address mapping]\n");
+	fsl_mmu = MMU_SPECIAL;
+	for (i = 0, found = FALSE;;i++, fsl_mmu++) {
+		if (vaddr >= fsl_mmu->tlbcamrange.start &&
+		    vaddr < fsl_mmu->tlbcamrange.limit) {
+			*paddr = fsl_mmu->tlbcamrange.phys +
+				 (vaddr - fsl_mmu->tlbcamrange.start);
+			found = TRUE;
+			break;
+		}
+		if (fsl_mmu->index & LAST_TLBCAM)
+			break;
+	}
+	if (found && verbose) {
+		/* TLBCAM segment attributes */
+		fprintf(fp, "\n  TLBCAM[%u]: MAS0     MAS1     MAS2     "
+			"MAS3     MAS7\n",
+			(fsl_mmu->index & ~LAST_TLBCAM));
+		fprintf(fp, "             %-8lx %-8lx %-8lx %-8lx %-8lx\n",
+			fsl_mmu->tlbcam.MAS0, fsl_mmu->tlbcam.MAS1,
+			fsl_mmu->tlbcam.MAS2, fsl_mmu->tlbcam.MAS3,
+			fsl_mmu->tlbcam.MAS7);
+		/* TLBCAM range */
+		fprintf(fp, "             VIRTUAL RANGE : %lx - %lx\n",
+			fsl_mmu->tlbcamrange.start, fsl_mmu->tlbcamrange.limit);
+		fprintf(fp, "             PHYSICAL RANGE: %llx - %llx\n",
+			fsl_mmu->tlbcamrange.phys,
+			fsl_mmu->tlbcamrange.phys + (fsl_mmu->tlbcamrange.limit
+				- fsl_mmu->tlbcamrange.start));
+		/* translated addr and its tlbcam's offset. */
+		fprintf(fp, "  => VIRTUAL  PHYSICAL TLBCAM-OFFSET\n");
+		fprintf(fp, "     %-8lx %-8llx %lu\n", vaddr, *paddr,
+			vaddr - fsl_mmu->tlbcamrange.start);
+	}
+	if (CRASHDEBUG(1))
+		fprintf(fp, "[tlbcam search end]\n");
+
+	return found;
+}
+
+static void
+fsl_booke_mmu_setup(void)
+{
+	struct fsl_booke_tlbcam *fsl_mmu;
+	uint i, tlbcam_index;
+	ulong tlbcam_addrs, TLBCAM;
+
+	readmem(symbol_value("tlbcam_index"), KVADDR, &tlbcam_index,
+		sizeof(uint), "tlbcam_index", FAULT_ON_ERROR);
+	if (tlbcam_index != 0 && tlbcam_index < NUM_TLBCAMS) {
+		fsl_mmu = calloc(tlbcam_index, sizeof(*fsl_mmu));
+		if (!fsl_mmu) {
+			error(FATAL, "fsl_mmu calloc() failed\n");
+			return;
+		}
+		tlbcam_addrs = symbol_value("tlbcam_addrs");
+		TLBCAM = symbol_value("TLBCAM");
+		for (i = 0; i < tlbcam_index; i++) {
+			fsl_mmu[i].index = i;
+			readmem(tlbcam_addrs +
+					i * sizeof(fsl_mmu[i].tlbcamrange),
+				KVADDR, &fsl_mmu[i].tlbcamrange,
+				sizeof(fsl_mmu[i].tlbcamrange), "tlbcam_addrs",
+				FAULT_ON_ERROR);
+			readmem(TLBCAM + i * sizeof(fsl_mmu[i].tlbcam), KVADDR,
+				&fsl_mmu[i].tlbcam, sizeof(fsl_mmu[i].tlbcam),
+				"TLBCAM", FAULT_ON_ERROR);
+		}
+		fsl_mmu[i - 1].index |= LAST_TLBCAM;
+		MMU_SPECIAL = fsl_mmu;
+		VTOP_SPECIAL = fsl_booke_vtop;
+	} else
+		error(INFO, "[%s]: can't setup tlbcam: tlbcam_index=%u\n",
+			PPC_PLATFORM, tlbcam_index);
+}
+
 static int
 probe_ppce500_platform(char *name)
 {
@@ -123,6 +224,7 @@ probe_ppce500_platform(char *name)
 			PLATFORM_PAGE_FLAGS_SETUP(BOOK3E);
 		} else
 			PLATFORM_PAGE_FLAGS_SETUP(FSL_BOOKE);
+		fsl_booke_mmu_setup();
 
 		return TRUE;
 	}
@@ -423,8 +525,16 @@ ppc_pgd_vtop(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	if (verbose)
 		fprintf(fp, "  PGD: %lx => %lx\n", (ulong)page_dir, pgd_pte);
 
-	if (!pgd_pte)
+	if (!pgd_pte) {
+		if (VTOP_SPECIAL)
+			/*
+			 * This ppc platform have special address mapping
+			 * between vaddr and paddr which can not search from
+			 * standard page table.
+			 */
+			return VTOP_SPECIAL(vaddr, paddr, verbose);
 		goto no_page;
+	}
 
 	page_middle = (ulong *)pgd_pte;
 
-- 
1.7.0.4

Date: Thu, 22 Mar 2012 11:26:44 +0900
Subject: [PATCH 3/5] ppc32: Ignore PMD

>From linux/arch/powerpc/include/asm/pgtable-ppc32.h
 #include <asm-generic/pgtable-nopmd.h>

All powerpc 32bit never use pmd because that is the same shift value as pgd.
I'm not sure whether PMD model was presence in powerpc 32bit...
But at least, there is no more virtual address bits to provide for PMD
then cleanup verbose message.

[before] PMD translation is being done with page-shift & PTRS_PER_PTE where
         is conventionally for PTE.

crash> vtop f99b77fc
VIRTUAL   PHYSICAL
f99b77fc  ffa417fc

PAGE DIRECTORY: c08d1000
  PGD: c08d2f30 => eb151000
  PMD: eb151000 => eb151db8
  PTE: eb151db8 => ffa41241255
 PAGE: ffa41241000

    PTE       PHYSICAL    FLAGS
ffa41241255  ffa41241000  (PRESENT|RW|NO_CACHE)

[after] Directly do PTE translation from PGD.

crash> vtop f99b77fc
VIRTUAL   PHYSICAL
f99b77fc  ffa417fc

PAGE DIRECTORY: c08d1000
  PGD: c08d2f30 => eb151000
  PTE: eb151000 => ffa41241255
 PAGE: ffa41241000

    PTE       PHYSICAL    FLAGS
ffa41241255  ffa41241000  (PRESENT|RW|NO_CACHE)

Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx>
---
 ppc.c |   28 +++++++++-------------------
 1 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/ppc.c b/ppc.c
index 11fe22f..dca19b7 100755
--- a/ppc.c
+++ b/ppc.c
@@ -504,9 +504,7 @@ static int
 ppc_pgd_vtop(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 {
 	ulong *page_dir;
-	ulong *page_middle;
-	ulong *page_table;
-	ulong pgd_pte;
+	ulong pgd_pte, page_table, pte_index;
 	ulonglong pte;
 
 	if (verbose)
@@ -536,28 +534,20 @@ ppc_pgd_vtop(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 		goto no_page;
 	}
 
-	page_middle = (ulong *)pgd_pte;
-
+	page_table = pgd_pte;
 	if (IS_BOOKE())
-		page_table = (ulong *)((ulong)page_middle + ((ulong)BTOP(vaddr) & (PTRS_PER_PTE - 1)) * PTE_SIZE);
-	else {
-		page_table = (ulong *)((pgd_pte & (ulong)machdep->pagemask) + machdep->kvbase);
-		page_table = (ulong *)((ulong)page_table + ((ulong)BTOP(vaddr) & (PTRS_PER_PTE-1)) * PTE_SIZE);
-	}
+		page_table = VTOP(page_table);
 
-	if (verbose)
-		fprintf(fp, "  PMD: %lx => %lx\n", (ulong)page_middle, 
-			(ulong)page_table);
-
-        FILL_PTBL(PAGEBASE((ulong)page_table), KVADDR, PAGESIZE());
+        FILL_PTBL(PAGEBASE((ulong)page_table), PHYSADDR, PAGESIZE());
+	pte_index = (vaddr >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
 	if (IS_PAE())
-		pte = ULONGLONG(machdep->ptbl + PAGEOFFSET((ulong)page_table));
+		pte = ULONGLONG(machdep->ptbl + PTE_SIZE * pte_index);
 
-	else	/* Defaults to ulong */
-	        pte = ULONG(machdep->ptbl + PAGEOFFSET((ulong)page_table));
+	else
+	        pte = ULONG(machdep->ptbl + PTE_SIZE * pte_index);
 
 	if (verbose) 
-		fprintf(fp, "  PTE: %lx => %llx\n", (ulong)page_table, pte);
+		fprintf(fp, "  PTE: %lx => %llx\n", pgd_pte, pte);
 
 	if (!(pte & _PAGE_PRESENT)) { 
 		if (pte && verbose) {
-- 
1.7.0.4

Date: Thu, 22 Mar 2012 15:02:58 +0900
Subject: [PATCH 4/5] ppc32: fixup vtop display items

Should translate with RPN_SHIFT before vtop dispaly PAGE and PHYSICAL.

Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx>
---
 ppc.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/ppc.c b/ppc.c
index dca19b7..512bfdd 100755
--- a/ppc.c
+++ b/ppc.c
@@ -558,7 +558,7 @@ ppc_pgd_vtop(ulong *pgd, ulong vaddr, physaddr_t *paddr, int verbose)
 	}
 
 	if (verbose) {
-		fprintf(fp, " PAGE: %llx\n\n", PAGEBASE(pte));
+		fprintf(fp, " PAGE: %llx\n\n", PAGEBASE(ppc_pte_physaddr(pte)));
 		ppc_translate_pte((ulong)pte, 0, pte);
 	}
 
@@ -885,7 +885,7 @@ ppc_translate_pte(ulong pte32, void *physaddr, ulonglong pte64)
 	if (!IS_PAE())
 		pte64 = pte32;
 
-        paddr = PAGEBASE(pte64);
+        paddr = PAGEBASE(ppc_pte_physaddr(pte64));
 	page_present = (pte64 & _PAGE_PRESENT);
 
 	if (physaddr) {
-- 
1.7.0.4

Date: Thu, 22 Mar 2012 17:07:11 +0900
Subject: [PATCH 5/5] ppc32: fix page flags setup macro

Must append do-while.

Signed-off-by: Toshikazu Nakayama <nakayama.ts@xxxxxxxxxxxxxx>
---
 ppc.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/ppc.c b/ppc.c
index 512bfdd..8d54fff 100755
--- a/ppc.c
+++ b/ppc.c
@@ -88,6 +88,7 @@ probe_func_t probe_platforms[] = {
 
 /* Don't forget page flags definitions for each platform */
 #define PLATFORM_PAGE_FLAGS_SETUP(PLT)		\
+do {						\
 	_PAGE_PRESENT = PLT##_PAGE_PRESENT;	\
 	_PAGE_USER = PLT##_PAGE_USER;		\
 	_PAGE_RW = PLT##_PAGE_RW;		\
@@ -98,7 +99,9 @@ probe_func_t probe_platforms[] = {
 	_PAGE_DIRTY = PLT##_PAGE_DIRTY;		\
 	_PAGE_ACCESSED = PLT##_PAGE_ACCESSED;	\
 	_PAGE_HWWRITE = PLT##_PAGE_HWWRITE;	\
-	_PAGE_SHARED = PLT##_PAGE_SHARED;
+	_PAGE_SHARED = PLT##_PAGE_SHARED;	\
+} while (0)
+
 static int
 probe_ppc44x_platform(char *name)
 {
-- 
1.7.0.4

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux