[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
Tue Aug 9 03:06:42 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 f2afdc68d26347165696c4ff0b2af99d89dd59a1
Author: Jonathan Neuschäfer <j.neuschaefer at gmx.net>
Date:   Tue Aug 9 02:07:12 2016 +0200

    [WIP] arch/riscv: Dump the page table structures after construction
    
    TODO: Make dumping optional, maybe through a Kconfig option
    TODO: Add a function that walks the page tables for one particular
          virtual address; call it from the trap handler, If the previous
          mode (MPP) accessed virtual memory
    TODO: Split out the part that changes physicalStart
    
    Change-Id: I52a863d8bc814ab3ed3a1f141d0a77edc6e4044d
    Signed-off-by: Jonathan Neuschäfer <j.neuschaefer at gmx.net>
---
 src/arch/riscv/include/vm.h     |  2 +-
 src/arch/riscv/virtual_memory.c | 77 +++++++++++++++++++++++++++++++++++------
 2 files changed, 67 insertions(+), 12 deletions(-)

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 f0cd5f6..8370415 100644
--- a/src/arch/riscv/virtual_memory.c
+++ b/src/arch/riscv/virtual_memory.c
@@ -23,11 +23,68 @@
 
 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)
+{
+	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)
@@ -113,19 +170,17 @@ 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();
 	printk(BIOS_DEBUG, "Finished initializing virtual memory, starting walk...\n");
-	walk_page_table();
+	dump_page_table();
 }
 
 void mstatus_init(void)
 {
-	// supervisor support is required
-
 	uintptr_t ms = 0;
 	ms = INSERT_FIELD(ms, MSTATUS_PRV, PRV_M);
 	ms = INSERT_FIELD(ms, MSTATUS_PRV1, PRV_S);



More information about the coreboot-gerrit mailing list