<p>Jonathan Neuschäfer has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/23772">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">arch/riscv: Don't set up virtual memory<br><br>Due to changes in the RISC-V Privileged Architecture specification,<br>Linux can now be started in physical memory and it will setup its own<br>page tables.<br><br>Thus we can delete most of virtual_memory.c.<br><br>Change-Id: I4e69d15f8ee540d2f98c342bc4ec0c00fb48def0<br>Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net><br>---<br>M src/Kconfig<br>M src/arch/riscv/boot.c<br>M src/arch/riscv/include/vm.h<br>M src/arch/riscv/virtual_memory.c<br>4 files changed, 0 insertions(+), 266 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/72/23772/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/Kconfig b/src/Kconfig</span><br><span>index 459280d..02abed2 100644</span><br><span>--- a/src/Kconfig</span><br><span>+++ b/src/Kconfig</span><br><span>@@ -975,14 +975,6 @@</span><br><span> Control debugging of the boot state machine. When selected displays</span><br><span> the state boundaries in ramstage.</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-config DEBUG_PRINT_PAGE_TABLES</span><br><span style="color: hsl(0, 100%, 40%);">- bool "Print the page tables after construction"</span><br><span style="color: hsl(0, 100%, 40%);">- default n</span><br><span style="color: hsl(0, 100%, 40%);">- depends on ARCH_RISCV</span><br><span style="color: hsl(0, 100%, 40%);">- help</span><br><span style="color: hsl(0, 100%, 40%);">- After the page tables have been built, print them on the debug</span><br><span style="color: hsl(0, 100%, 40%);">- console.</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> config DEBUG_ADA_CODE</span><br><span> bool "Compile debug code in Ada sources"</span><br><span> default n</span><br><span>diff --git a/src/arch/riscv/boot.c b/src/arch/riscv/boot.c</span><br><span>index ac095bb..b73f3ca 100644</span><br><span>--- a/src/arch/riscv/boot.c</span><br><span>+++ b/src/arch/riscv/boot.c</span><br><span>@@ -27,7 +27,6 @@</span><br><span> </span><br><span> if (ENV_RAMSTAGE && prog_type(prog) == PROG_PAYLOAD) {</span><br><span> printk(BIOS_SPEW, "Config string: '%s'\n", config);</span><br><span style="color: hsl(0, 100%, 40%);">- initVirtualMemory();</span><br><span> printk(BIOS_SPEW, "OK, let's go\n");</span><br><span> riscvpayload(config, doit);</span><br><span> }</span><br><span>diff --git a/src/arch/riscv/include/vm.h b/src/arch/riscv/include/vm.h</span><br><span>index 1a8f7ad..fd0a2c9 100644</span><br><span>--- a/src/arch/riscv/include/vm.h</span><br><span>+++ b/src/arch/riscv/include/vm.h</span><br><span>@@ -32,36 +32,11 @@</span><br><span> #include <stdint.h></span><br><span> #include <arch/encoding.h></span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define SUPERPAGE_SIZE ((uintptr_t)(RISCV_PGSIZE << RISCV_PGLEVEL_BITS))</span><br><span style="color: hsl(0, 100%, 40%);">-#define VM_CHOICE VM_SV39</span><br><span style="color: hsl(0, 100%, 40%);">-#define VA_BITS 39</span><br><span style="color: hsl(0, 100%, 40%);">-#define MEGAPAGE_SIZE (SUPERPAGE_SIZE << RISCV_PGLEVEL_BITS)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> #define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))</span><br><span> #define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define supervisor_paddr_valid(start, length) \</span><br><span style="color: hsl(0, 100%, 40%);">- ((uintptr_t)(start) >= current.first_user_vaddr + current.bias \</span><br><span style="color: hsl(0, 100%, 40%);">- && (uintptr_t)(start) + (length) < mem_size \</span><br><span style="color: hsl(0, 100%, 40%);">- && (uintptr_t)(start) + (length) >= (uintptr_t)(start))</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-typedef uintptr_t pte_t;</span><br><span style="color: hsl(0, 100%, 40%);">-extern pte_t* root_page_table;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void initVirtualMemory(void);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-size_t pte_ppn(pte_t pte);</span><br><span style="color: hsl(0, 100%, 40%);">-pte_t ptd_create(uintptr_t ppn);</span><br><span style="color: hsl(0, 100%, 40%);">-pte_t pte_create(uintptr_t ppn, int prot, int user);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void print_page_table(void);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart,</span><br><span style="color: hsl(0, 100%, 40%);">- pte_t *pageTableStart);</span><br><span> void mstatus_init(void); // need to setup mstatus so we know we have virtual memory</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void flush_tlb(void);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> </span><br><span> #define DEFINE_MPRV_READ(name, type, insn) \</span><br><span> static inline type name(type *p); \</span><br><span>diff --git a/src/arch/riscv/virtual_memory.c b/src/arch/riscv/virtual_memory.c</span><br><span>index 27b4b82..702d6b7 100644</span><br><span>--- a/src/arch/riscv/virtual_memory.c</span><br><span>+++ b/src/arch/riscv/virtual_memory.c</span><br><span>@@ -14,13 +14,9 @@</span><br><span> * GNU General Public License for more details.</span><br><span> */</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#include <arch/barrier.h></span><br><span> #include <arch/encoding.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <atomic.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <console/console.h></span><br><span> #include <stdint.h></span><br><span> #include <vm.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <symbols.h></span><br><span> </span><br><span> /* Delegate controls which traps are delegated to the payload. If you</span><br><span> * wish to temporarily disable some or all delegation you can, in a</span><br><span>@@ -38,234 +34,6 @@</span><br><span> | (1 << CAUSE_USER_ECALL)</span><br><span> ;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-pte_t* root_page_table;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Indent the following text by 2*level spaces */</span><br><span style="color: hsl(0, 100%, 40%);">-static void indent(int level)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int i;</span><br><span style="color: hsl(0, 100%, 40%);">- for (i = 0; i < level; i++)</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, " ");</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">- * Convert a page table index at a given page table level to a virtual address</span><br><span style="color: hsl(0, 100%, 40%);">- * offset</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-static uintptr_t index_to_virt_addr(int index, int level)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- /*</span><br><span style="color: hsl(0, 100%, 40%);">- * Index is at most RISCV_PGLEVEL_BITS bits wide (not considering the</span><br><span style="color: hsl(0, 100%, 40%);">- * leading zeroes. If level==0, the below expression thus shifts index</span><br><span style="color: hsl(0, 100%, 40%);">- * into the highest bits of a 64-bit number, and then shifts it down</span><br><span style="color: hsl(0, 100%, 40%);">- * with sign extension.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * If level>0, then the expression should work as expected, without any</span><br><span style="color: hsl(0, 100%, 40%);">- * magic.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">- return ((intptr_t)index)</span><br><span style="color: hsl(0, 100%, 40%);">- << (64 - RISCV_PGLEVEL_BITS - level * RISCV_PGLEVEL_BITS)</span><br><span style="color: hsl(0, 100%, 40%);">- >> (64 - VA_BITS);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Dump the page table structures to the console -- helper function */</span><br><span style="color: hsl(0, 100%, 40%);">-static void print_page_table_at(pte_t *pt, intptr_t virt_addr, int level)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int i;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- indent(level);</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "Level %d page table at 0x%p\n", level, pt);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (i = 0; i < RISCV_PGSIZE / sizeof(pte_t); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">- char urwx[8];</span><br><span style="color: hsl(0, 100%, 40%);">- uintptr_t pointer;</span><br><span style="color: hsl(0, 100%, 40%);">- intptr_t next_virt_addr;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(pt[i] & PTE_V))</span><br><span style="color: hsl(0, 100%, 40%);">- continue;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- urwx[0] = (pt[i] & PTE_U)? 'u' : '-';</span><br><span style="color: hsl(0, 100%, 40%);">- urwx[1] = (pt[i] & PTE_R)? 'r' : '-';</span><br><span style="color: hsl(0, 100%, 40%);">- urwx[2] = (pt[i] & PTE_W)? 'w' : '-';</span><br><span style="color: hsl(0, 100%, 40%);">- urwx[3] = (pt[i] & PTE_X)? 'x' : '-';</span><br><span style="color: hsl(0, 100%, 40%);">- urwx[4] = '\0';</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- next_virt_addr = virt_addr + index_to_virt_addr(i, level);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- pointer = ((uintptr_t)pt[i] >> 10) << RISCV_PGSHIFT;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- indent(level + 1);</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "Valid PTE at index %d (0x%016zx -> 0x%zx), ",</span><br><span style="color: hsl(0, 100%, 40%);">- i, (size_t) next_virt_addr, (size_t) pointer);</span><br><span style="color: hsl(0, 100%, 40%);">- if (PTE_TABLE(pt[i]))</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "page table\n");</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "protections %s\n", urwx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (PTE_TABLE(pt[i])) {</span><br><span style="color: hsl(0, 100%, 40%);">- print_page_table_at((pte_t *)pointer, next_virt_addr, level + 1);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Print the page table structures to the console */</span><br><span style="color: hsl(0, 100%, 40%);">-void print_page_table(void) {</span><br><span style="color: hsl(0, 100%, 40%);">- print_page_table_at((void *)(read_csr(sptbr) << RISCV_PGSHIFT), 0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void flush_tlb(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- asm volatile("sfence.vm");</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-size_t pte_ppn(pte_t pte)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return pte >> PTE_PPN_SHIFT;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-pte_t ptd_create(uintptr_t ppn)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return (ppn << PTE_PPN_SHIFT) | PTE_V;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-pte_t pte_create(uintptr_t ppn, int prot, int user)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- pte_t pte = (ppn << PTE_PPN_SHIFT) | PTE_R | PTE_V;</span><br><span style="color: hsl(0, 100%, 40%);">- if (prot & PTE_W)</span><br><span style="color: hsl(0, 100%, 40%);">- pte |= PTE_W;</span><br><span style="color: hsl(0, 100%, 40%);">- if (prot & PTE_X)</span><br><span style="color: hsl(0, 100%, 40%);">- pte |= PTE_X;</span><br><span style="color: hsl(0, 100%, 40%);">- if (user)</span><br><span style="color: hsl(0, 100%, 40%);">- pte |= PTE_U;</span><br><span style="color: hsl(0, 100%, 40%);">- return pte;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-// The current RISCV *physical* address space is this:</span><br><span style="color: hsl(0, 100%, 40%);">-// * 0 - 2 GiB: miscellaneous IO devices</span><br><span style="color: hsl(0, 100%, 40%);">-// * 2 GiB - 4 GiB DRAM</span><br><span style="color: hsl(0, 100%, 40%);">-// We have determined, also, that if code references a physical address</span><br><span style="color: hsl(0, 100%, 40%);">-// not backed by a device, we'll take a fault. In other words, we don't</span><br><span style="color: hsl(0, 100%, 40%);">-// need to finely map the memory-mapped devices as we would on an x86.</span><br><span style="color: hsl(0, 100%, 40%);">-// We can use GiB mappings for the IO space and we will take a trap</span><br><span style="color: hsl(0, 100%, 40%);">-// if we reference hardware that does not exist.</span><br><span style="color: hsl(0, 100%, 40%);">-//</span><br><span style="color: hsl(0, 100%, 40%);">-// The intent of the RISCV designers is that pages be set up in M mode</span><br><span style="color: hsl(0, 100%, 40%);">-// for lower privilege software. They have also told me that they</span><br><span style="color: hsl(0, 100%, 40%);">-// expect, unlike other platforms, that next level software use these</span><br><span style="color: hsl(0, 100%, 40%);">-// page tables. Some kernels (Linux) prefer the old fashioned model,</span><br><span style="color: hsl(0, 100%, 40%);">-// where kernel starts with an identity (ID) map and sets up page tables as</span><br><span style="color: hsl(0, 100%, 40%);">-// it sees fit. Other kernels (harvey) are fine with using whatever</span><br><span style="color: hsl(0, 100%, 40%);">-// firmware sets up. We need to accommodate both. So, we set up the</span><br><span style="color: hsl(0, 100%, 40%);">-// identity map for Linux, but also set up the map for kernels that</span><br><span style="color: hsl(0, 100%, 40%);">-// are more willing to conform to the RISCV model. The map is as</span><br><span style="color: hsl(0, 100%, 40%);">-// follows:</span><br><span style="color: hsl(0, 100%, 40%);">-//</span><br><span style="color: hsl(0, 100%, 40%);">-// ID map: map IO space and all of DRAM 1:1 using 1 GiB PTEs</span><br><span style="color: hsl(0, 100%, 40%);">-// I.e. we use 1 GiB PTEs for 4 GiB.</span><br><span style="color: hsl(0, 100%, 40%);">-// Linux/BSD uses this mapping just enough to replace it.</span><br><span style="color: hsl(0, 100%, 40%);">-//</span><br><span style="color: hsl(0, 100%, 40%);">-// Top 2G map: map the 2 Gib - 4 GiB of physical address space to</span><br><span style="color: hsl(0, 100%, 40%);">-// 0xffffffff_80000000. This will be needed until the GNU toolchain can compile</span><br><span style="color: hsl(0, 100%, 40%);">-// code to run at 0xffffffc000000000, i.e. the start of Sv39.</span><br><span style="color: hsl(0, 100%, 40%);">-//</span><br><span style="color: hsl(0, 100%, 40%);">-// Only Harvey/Plan 9 uses this Mapping, and temporarily.</span><br><span style="color: hsl(0, 100%, 40%);">-//</span><br><span style="color: hsl(0, 100%, 40%);">-// standard RISCV map long term: Map IO space, and all of DRAM, to the *lowest*</span><br><span style="color: hsl(0, 100%, 40%);">-// possible negative address for this implementation,</span><br><span style="color: hsl(0, 100%, 40%);">-// e.g. 0xffffffc000000000 for Sv39 CPUs. For now we can use GiB PTEs.</span><br><span style="color: hsl(0, 100%, 40%);">-//</span><br><span style="color: hsl(0, 100%, 40%);">-// RISCV map for now: map IO space, and all of DRAM, starting at</span><br><span style="color: hsl(0, 100%, 40%);">-// 0xffff_ffc0_0000_0000, i.e. just as for Sv39.</span><br><span style="color: hsl(0, 100%, 40%);">-//</span><br><span style="color: hsl(0, 100%, 40%);">-// It is our intent on Harvey (and eventually Akaros) that we use</span><br><span style="color: hsl(0, 100%, 40%);">-// this map, once the toolchain can correctly support it.</span><br><span style="color: hsl(0, 100%, 40%);">-// We have tested this arrangement and it lets us boot harvey to user mode.</span><br><span style="color: hsl(0, 100%, 40%);">-void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, pte_t *pt)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- // 0xFFF... - 0xFFFFFFFF81000000 - RISCV_PGSIZE</span><br><span style="color: hsl(0, 100%, 40%);">- intptr_t memorySize = 0x7F000000;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- // middle page table</span><br><span style="color: hsl(0, 100%, 40%);">- pte_t* middle_pt = (void*)pt;</span><br><span style="color: hsl(0, 100%, 40%);">- size_t num_middle_pts = 2; // 3 level page table, 39 bit virtual address space for now</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- // root page table</span><br><span style="color: hsl(0, 100%, 40%);">- pte_t* root_pt = (void*)middle_pt + num_middle_pts * RISCV_PGSIZE;</span><br><span style="color: hsl(0, 100%, 40%);">- memset(middle_pt, 0, (num_middle_pts + 1) * RISCV_PGSIZE); // 0's out middle_pt and root_pt</span><br><span style="color: hsl(0, 100%, 40%);">- for (size_t i = 0; i < num_middle_pts; i++)</span><br><span style="color: hsl(0, 100%, 40%);">- root_pt[(1<<RISCV_PGLEVEL_BITS)-num_middle_pts+i] = ptd_create(((uintptr_t)middle_pt >> RISCV_PGSHIFT) + i);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- // fill the middle page table</span><br><span style="color: hsl(0, 100%, 40%);">- for (uintptr_t vaddr = virtMemStart, paddr = physMemStart;</span><br><span style="color: hsl(0, 100%, 40%);">- paddr < physMemStart + memorySize;</span><br><span style="color: hsl(0, 100%, 40%);">- vaddr += SUPERPAGE_SIZE, paddr += SUPERPAGE_SIZE) {</span><br><span style="color: hsl(0, 100%, 40%);">- int l2_shift = RISCV_PGLEVEL_BITS + RISCV_PGSHIFT;</span><br><span style="color: hsl(0, 100%, 40%);">- size_t l2_idx = (virtMemStart >> l2_shift) & ((1 << RISCV_PGLEVEL_BITS)-1);</span><br><span style="color: hsl(0, 100%, 40%);">- l2_idx += ((vaddr - virtMemStart) >> l2_shift);</span><br><span style="color: hsl(0, 100%, 40%);">- middle_pt[l2_idx] = pte_create(paddr >> RISCV_PGSHIFT,</span><br><span style="color: hsl(0, 100%, 40%);">- PTE_U|PTE_R|PTE_W|PTE_X, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- // IO space. Identity mapped.</span><br><span style="color: hsl(0, 100%, 40%);">- root_pt[0x000] = pte_create(0x00000000 >> RISCV_PGSHIFT,</span><br><span style="color: hsl(0, 100%, 40%);">- PTE_R | PTE_W, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- root_pt[0x001] = pte_create(0x40000000 >> RISCV_PGSHIFT,</span><br><span style="color: hsl(0, 100%, 40%);">- PTE_R | PTE_W, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- root_pt[0x002] = pte_create(0x80000000 >> RISCV_PGSHIFT,</span><br><span style="color: hsl(0, 100%, 40%);">- PTE_R | PTE_W | PTE_X, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- root_pt[0x003] = pte_create(0xc0000000 >> RISCV_PGSHIFT,</span><br><span style="color: hsl(0, 100%, 40%);">- PTE_R | PTE_W | PTE_X, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- // Negative address space map at 0xffffffc000000000</span><br><span style="color: hsl(0, 100%, 40%);">- root_pt[0x100] = root_pt[0];</span><br><span style="color: hsl(0, 100%, 40%);">- root_pt[0x101] = root_pt[1];</span><br><span style="color: hsl(0, 100%, 40%);">- root_pt[0x102] = root_pt[2];</span><br><span style="color: hsl(0, 100%, 40%);">- root_pt[0x103] = root_pt[3];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- mb();</span><br><span style="color: hsl(0, 100%, 40%);">- root_page_table = root_pt;</span><br><span style="color: hsl(0, 100%, 40%);">- uintptr_t ptbr = ((uintptr_t) root_pt) >> RISCV_PGSHIFT;</span><br><span style="color: hsl(0, 100%, 40%);">- write_csr(sptbr, ptbr);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void initVirtualMemory(void) {</span><br><span style="color: hsl(0, 100%, 40%);">- uintptr_t ms;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ms = read_csr(mstatus);</span><br><span style="color: hsl(0, 100%, 40%);">- ms = INSERT_FIELD(ms, MSTATUS_VM, VM_CHOICE);</span><br><span style="color: hsl(0, 100%, 40%);">- write_csr(mstatus, ms);</span><br><span style="color: hsl(0, 100%, 40%);">- ms = read_csr(mstatus);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (EXTRACT_FIELD(ms, MSTATUS_VM) != VM_CHOICE) {</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "We don't have virtual memory...\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "-----------------------------\n");</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "Virtual memory status enabled\n");</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "-----------------------------\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- // TODO: Figure out how to grab this from cbfs</span><br><span style="color: hsl(0, 100%, 40%);">- // N.B. We used to map physical from 0x81000000,</span><br><span style="color: hsl(0, 100%, 40%);">- // but since kernels need to be able to see the page tables</span><br><span style="color: hsl(0, 100%, 40%);">- // created by firmware, we're going to map from start of RAM.</span><br><span style="color: hsl(0, 100%, 40%);">- // All this is subject to change as we learn more. Much</span><br><span style="color: hsl(0, 100%, 40%);">- // about RISCV is still in flux.</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "Initializing virtual memory...\n");</span><br><span style="color: hsl(0, 100%, 40%);">- uintptr_t physicalStart = 0x80000000;</span><br><span style="color: hsl(0, 100%, 40%);">- uintptr_t virtualStart = 0xffffffff80000000;</span><br><span style="color: hsl(0, 100%, 40%);">- init_vm(virtualStart, physicalStart, (pte_t *)_pagetables);</span><br><span style="color: hsl(0, 100%, 40%);">- mb();</span><br><span style="color: hsl(0, 100%, 40%);">- flush_tlb();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#if IS_ENABLED(CONFIG_DEBUG_PRINT_PAGE_TABLES)</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "Finished initializing virtual memory, starting walk...\n");</span><br><span style="color: hsl(0, 100%, 40%);">- print_page_table();</span><br><span style="color: hsl(0, 100%, 40%);">-#else</span><br><span style="color: hsl(0, 100%, 40%);">- printk(BIOS_DEBUG, "Finished initializing virtual memory\n");</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> void mstatus_init(void)</span><br><span> {</span><br><span> uintptr_t ms = 0;</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/23772">change 23772</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/23772"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I4e69d15f8ee540d2f98c342bc4ec0c00fb48def0 </div>
<div style="display:none"> Gerrit-Change-Number: 23772 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Jonathan Neuschäfer <j.neuschaefer@gmx.net> </div>