[coreboot-gerrit] Patch set updated for coreboot: [WIP] arch/riscv: Dump the page table structures after construction

Jonathan Neuschäfer (j.neuschaefer@gmx.net) gerrit at coreboot.org
Sat Aug 13 04:27:12 CEST 2016


Jonathan Neuschäfer (j.neuschaefer at gmx.net) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16015

-gerrit

commit aef086c1bb1dd3bcc389275fd74175fb523ff5a7
Author: Jonathan Neuschäfer <j.neuschaefer at gmx.net>
Date:   Sat Aug 13 04:20:07 2016 +0200

    [WIP] arch/riscv: Dump the page table structures after construction
    
    TODO: Split out the part that changes physicalStart
    
    Change-Id: I52a863d8bc814ab3ed3a1f141d0a77edc6e4044d
    Signed-off-by: Jonathan Neuschäfer <j.neuschaefer at gmx.net>
---
 src/Kconfig                     |  8 ++++
 src/arch/riscv/include/vm.h     |  2 +-
 src/arch/riscv/virtual_memory.c | 91 ++++++++++++++++++++++++++++++++++++-----
 3 files changed, 89 insertions(+), 12 deletions(-)

diff --git a/src/Kconfig b/src/Kconfig
index 001132e..c01c6ec 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -1118,6 +1118,14 @@ config DEBUG_BOOT_STATE
 	  Control debugging of the boot state machine.  When selected displays
 	  the state boundaries in ramstage.
 
+config DEBUG_DUMP_PAGE_TABLES
+	bool "Dump the page tables after construction"
+	default n
+	depends on ARCH_RISCV
+	help
+	  After the page tables have been built, print them on the debug
+	  console.
+
 endmenu
 
 # These probably belong somewhere else, but they are needed somewhere.
diff --git a/src/arch/riscv/include/vm.h b/src/arch/riscv/include/vm.h
index 5bf03c7..cd82b0a 100644
--- a/src/arch/riscv/include/vm.h
+++ b/src/arch/riscv/include/vm.h
@@ -63,7 +63,7 @@ size_t pte_ppn(pte_t pte);
 pte_t ptd_create(uintptr_t ppn);
 pte_t pte_create(uintptr_t ppn, int prot, int user);
 
-void walk_page_table(void);
+void dump_page_table(void);
 
 void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, uintptr_t pageTableStart);
 void mstatus_init(void); // need to setup mstatus so we know we have virtual memory
diff --git a/src/arch/riscv/virtual_memory.c b/src/arch/riscv/virtual_memory.c
index bbbba7a..18d9237 100644
--- a/src/arch/riscv/virtual_memory.c
+++ b/src/arch/riscv/virtual_memory.c
@@ -23,11 +23,77 @@
 
 pte_t* root_page_table;
 
-void walk_page_table(void) {
-	// TODO: implement a full walk to make sure memory was set up
-	//const size_t pte_per_page = RISCV_PGSIZE/sizeof(void*);
-	pte_t* t = root_page_table;
-	printk(BIOS_DEBUG, "root_page_table: %p\n", t);
+/* Indent the following text by 2*level spaces */
+static void indent(int level)
+{
+	int i;
+	for (i = 0; i < level; i++)
+		printk(BIOS_DEBUG, "  ");
+}
+
+/*
+ * Convert a page table index at a given page table level to a virtual address
+ * offset
+ */
+static uintptr_t index_to_virt_addr(int index, int level)
+{
+	/*
+	 * Index is at most RISCV_PGLEVEL_BITS bits wide (not considering the
+	 * leading zeroes. If level==0, the below expression thus shifts index
+	 * into the highest bits of a 64-bit number, and then shifts it down
+	 * with sign extension.
+	 *
+	 * If level>0, then the expression should work as expected, without any
+	 * magic.
+	 */
+	return ((intptr_t)index)
+		<< (64 - RISCV_PGLEVEL_BITS - level * RISCV_PGLEVEL_BITS)
+		>> (64 - VA_BITS);
+}
+
+/* Dump the page table structures to the console -- helper function */
+static void dump_page_table_at(pte_t *pt, intptr_t virt_addr, int level)
+{
+	int i;
+
+	indent(level);
+	printk(BIOS_DEBUG, "Level %d page table at 0x%p\n", level, pt);
+
+	for (i = 0; i < RISCV_PGSIZE/sizeof(pte_t); i++) {
+		char urwx[8];
+		uintptr_t pointer;
+		intptr_t next_virt_addr;
+
+		if (!(pt[i] & PTE_V))
+			continue;
+
+		urwx[0] = (pt[i] & PTE_U)? 'u' : '-';
+		urwx[1] = (pt[i] & PTE_R)? 'r' : '-';
+		urwx[2] = (pt[i] & PTE_W)? 'w' : '-';
+		urwx[3] = (pt[i] & PTE_X)? 'x' : '-';
+		urwx[4] = '\0';
+
+		next_virt_addr = virt_addr + index_to_virt_addr(i, level);
+
+		pointer = ((uintptr_t)pt[i] >> 10) << RISCV_PGSHIFT;
+
+		indent(level+1);
+		printk(BIOS_DEBUG, "Valid PTE at index %d (0x%016zx -> 0x%zx), ",
+				i, (size_t) next_virt_addr, (size_t) pointer);
+		if (PTE_TABLE(pt[i]))
+			printk(BIOS_DEBUG, "page table\n");
+		else
+			printk(BIOS_DEBUG, "protections %s\n", urwx);
+
+		if (PTE_TABLE(pt[i])) {
+			dump_page_table_at((pte_t *)pointer, next_virt_addr, level + 1);
+		}
+	}
+}
+
+/* Dump the page table structures to the console */
+void dump_page_table(void) {
+	dump_page_table_at(root_page_table, 0, 0);
 }
 
 void flush_tlb(void)
@@ -119,19 +185,22 @@ void initVirtualMemory(void) {
 	}
 
 	printk(BIOS_DEBUG, "Initializing virtual memory...\n");
-	uintptr_t physicalStart = 0x1000000; // TODO: Figure out how to grab this from cbfs
-	uintptr_t virtualStart = 0xffffffff81000000;
-	uintptr_t pageTableStart = 0x1400000;
+	uintptr_t physicalStart = 0x90000000; // TODO: Figure out how to grab this from cbfs
+	uintptr_t virtualStart = 0xffffffff80000000;
+	uintptr_t pageTableStart = 0x91400000;
 	init_vm(virtualStart, physicalStart, pageTableStart);
 	mb();
+
+#if IS_ENABLED(CONFIG_DEBUG_DUMP_PAGE_TABLES)
 	printk(BIOS_DEBUG, "Finished initializing virtual memory, starting walk...\n");
-	walk_page_table();
+	dump_page_table();
+#else
+	printk(BIOS_DEBUG, "Finished initializing virtual memory\n");
+#endif
 }
 
 void mstatus_init(void)
 {
-	// supervisor support is required
-
 	uintptr_t ms = 0;
 	ms = INSERT_FIELD(ms, MSTATUS_FS, 3);
 	ms = INSERT_FIELD(ms, MSTATUS_XS, 3);



More information about the coreboot-gerrit mailing list