[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