[coreboot-gerrit] Change in coreboot[master]: arch/riscv: Don't set up virtual memory

Jonathan Neuschäfer (Code Review) gerrit at coreboot.org
Thu Feb 15 14:28:56 CET 2018


Jonathan Neuschäfer has uploaded this change for review. ( https://review.coreboot.org/23772


Change subject: arch/riscv: Don't set up virtual memory
......................................................................

arch/riscv: Don't set up virtual memory

Due to changes in the RISC-V Privileged Architecture specification,
Linux can now be started in physical memory and it will setup its own
page tables.

Thus we can delete most of virtual_memory.c.

Change-Id: I4e69d15f8ee540d2f98c342bc4ec0c00fb48def0
Signed-off-by: Jonathan Neuschäfer <j.neuschaefer at gmx.net>
---
M src/Kconfig
M src/arch/riscv/boot.c
M src/arch/riscv/include/vm.h
M src/arch/riscv/virtual_memory.c
4 files changed, 0 insertions(+), 266 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/72/23772/1

diff --git a/src/Kconfig b/src/Kconfig
index 459280d..02abed2 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -975,14 +975,6 @@
 	  Control debugging of the boot state machine.  When selected displays
 	  the state boundaries in ramstage.
 
-config DEBUG_PRINT_PAGE_TABLES
-	bool "Print 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.
-
 config DEBUG_ADA_CODE
 	bool "Compile debug code in Ada sources"
 	default n
diff --git a/src/arch/riscv/boot.c b/src/arch/riscv/boot.c
index ac095bb..b73f3ca 100644
--- a/src/arch/riscv/boot.c
+++ b/src/arch/riscv/boot.c
@@ -27,7 +27,6 @@
 
 	if (ENV_RAMSTAGE && prog_type(prog) == PROG_PAYLOAD) {
 		printk(BIOS_SPEW, "Config string: '%s'\n", config);
-		initVirtualMemory();
 		printk(BIOS_SPEW, "OK, let's go\n");
 		riscvpayload(config, doit);
 	}
diff --git a/src/arch/riscv/include/vm.h b/src/arch/riscv/include/vm.h
index 1a8f7ad..fd0a2c9 100644
--- a/src/arch/riscv/include/vm.h
+++ b/src/arch/riscv/include/vm.h
@@ -32,36 +32,11 @@
 #include <stdint.h>
 #include <arch/encoding.h>
 
-#define SUPERPAGE_SIZE ((uintptr_t)(RISCV_PGSIZE << RISCV_PGLEVEL_BITS))
-#define VM_CHOICE VM_SV39
-#define VA_BITS 39
-#define MEGAPAGE_SIZE (SUPERPAGE_SIZE << RISCV_PGLEVEL_BITS)
-
 #define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
 #define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
 
-#define supervisor_paddr_valid(start, length) \
-	((uintptr_t)(start) >= current.first_user_vaddr + current.bias \
-	 && (uintptr_t)(start) + (length) < mem_size \
-	 && (uintptr_t)(start) + (length) >= (uintptr_t)(start))
-
-typedef uintptr_t pte_t;
-extern pte_t* root_page_table;
-
-void initVirtualMemory(void);
-
-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 print_page_table(void);
-
-void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart,
-		pte_t *pageTableStart);
 void mstatus_init(void); // need to setup mstatus so we know we have virtual memory
 
-void flush_tlb(void);
-
 
 #define DEFINE_MPRV_READ(name, type, insn)				\
 	static inline type name(type *p);				\
diff --git a/src/arch/riscv/virtual_memory.c b/src/arch/riscv/virtual_memory.c
index 27b4b82..702d6b7 100644
--- a/src/arch/riscv/virtual_memory.c
+++ b/src/arch/riscv/virtual_memory.c
@@ -14,13 +14,9 @@
  * GNU General Public License for more details.
  */
 
-#include <arch/barrier.h>
 #include <arch/encoding.h>
-#include <atomic.h>
-#include <console/console.h>
 #include <stdint.h>
 #include <vm.h>
-#include <symbols.h>
 
 /* Delegate controls which traps are delegated to the payload. If you
  * wish to temporarily disable some or all delegation you can, in a
@@ -38,234 +34,6 @@
 	| (1 << CAUSE_USER_ECALL)
 	;
 
-pte_t* root_page_table;
-
-/* 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 print_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])) {
-			print_page_table_at((pte_t *)pointer, next_virt_addr, level + 1);
-		}
-	}
-}
-
-/* Print the page table structures to the console */
-void print_page_table(void) {
-	print_page_table_at((void *)(read_csr(sptbr) << RISCV_PGSHIFT), 0, 0);
-}
-
-void flush_tlb(void)
-{
-	asm volatile("sfence.vm");
-}
-
-size_t pte_ppn(pte_t pte)
-{
-	return pte >> PTE_PPN_SHIFT;
-}
-
-pte_t ptd_create(uintptr_t ppn)
-{
-	return (ppn << PTE_PPN_SHIFT) | PTE_V;
-}
-
-pte_t pte_create(uintptr_t ppn, int prot, int user)
-{
-	pte_t pte = (ppn << PTE_PPN_SHIFT) | PTE_R | PTE_V;
-	if (prot & PTE_W)
-		pte |= PTE_W;
-	if (prot & PTE_X)
-		pte |= PTE_X;
-	if (user)
-		pte |= PTE_U;
-	return pte;
-}
-
-// The current RISCV *physical* address space is this:
-// * 0 - 2 GiB: miscellaneous IO devices
-// * 2 GiB - 4 GiB DRAM
-// We have determined, also, that if code references a physical address
-// not backed by a device, we'll take a fault. In other words, we don't
-// need to finely map the memory-mapped devices as we would on an x86.
-// We can use GiB mappings for the IO space and we will take a trap
-// if we reference hardware that does not exist.
-//
-// The intent of the RISCV designers is that pages be set up in M mode
-// for lower privilege software. They have also told me that they
-// expect, unlike other platforms, that next level software use these
-// page tables.  Some kernels (Linux) prefer the old fashioned model,
-// where kernel starts with an identity (ID) map and sets up page tables as
-// it sees fit.  Other kernels (harvey) are fine with using whatever
-// firmware sets up.  We need to accommodate both. So, we set up the
-// identity map for Linux, but also set up the map for kernels that
-// are more willing to conform to the RISCV model.  The map is as
-// follows:
-//
-// ID map: map IO space and all of DRAM 1:1 using 1 GiB PTEs
-// I.e. we use 1 GiB PTEs for 4 GiB.
-// Linux/BSD uses this mapping just enough to replace it.
-//
-// Top 2G map: map the 2 Gib - 4 GiB of physical address space to
-// 0xffffffff_80000000. This will be needed until the GNU toolchain can compile
-// code to run at 0xffffffc000000000, i.e. the start of Sv39.
-//
-// Only Harvey/Plan 9 uses this Mapping, and temporarily.
-//
-// standard RISCV map long term: Map IO space, and all of DRAM, to the *lowest*
-// possible negative address for this implementation,
-// e.g. 0xffffffc000000000 for Sv39 CPUs. For now we can use GiB PTEs.
-//
-// RISCV map for now: map IO space, and all of DRAM, starting at
-// 0xffff_ffc0_0000_0000, i.e. just as for Sv39.
-//
-// It is our intent on Harvey (and eventually Akaros) that we use
-// this map, once the toolchain can correctly support it.
-// We have tested this arrangement and it lets us boot harvey to user mode.
-void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, pte_t *pt)
-{
-	// 0xFFF... - 0xFFFFFFFF81000000 - RISCV_PGSIZE
-	intptr_t memorySize = 0x7F000000;
-
-	// middle page table
-	pte_t* middle_pt = (void*)pt;
-	size_t num_middle_pts = 2; // 3 level page table, 39 bit virtual address space for now
-
-	// root page table
-	pte_t* root_pt = (void*)middle_pt + num_middle_pts * RISCV_PGSIZE;
-	memset(middle_pt, 0, (num_middle_pts + 1) * RISCV_PGSIZE); // 0's out middle_pt and root_pt
-	for (size_t i = 0; i < num_middle_pts; i++)
-		root_pt[(1<<RISCV_PGLEVEL_BITS)-num_middle_pts+i] = ptd_create(((uintptr_t)middle_pt >> RISCV_PGSHIFT) + i);
-
-	// fill the middle page table
-	for (uintptr_t vaddr = virtMemStart, paddr = physMemStart;
-			paddr < physMemStart + memorySize;
-			vaddr += SUPERPAGE_SIZE, paddr += SUPERPAGE_SIZE) {
-		int l2_shift = RISCV_PGLEVEL_BITS + RISCV_PGSHIFT;
-		size_t l2_idx = (virtMemStart >> l2_shift) & ((1 << RISCV_PGLEVEL_BITS)-1);
-		l2_idx += ((vaddr - virtMemStart) >> l2_shift);
-		middle_pt[l2_idx] = pte_create(paddr >> RISCV_PGSHIFT,
-					       PTE_U|PTE_R|PTE_W|PTE_X, 0);
-	}
-
-	// IO space. Identity mapped.
-	root_pt[0x000] = pte_create(0x00000000 >> RISCV_PGSHIFT,
-				PTE_R | PTE_W, 0);
-	root_pt[0x001] = pte_create(0x40000000 >> RISCV_PGSHIFT,
-				PTE_R | PTE_W, 0);
-	root_pt[0x002] = pte_create(0x80000000 >> RISCV_PGSHIFT,
-				PTE_R | PTE_W | PTE_X, 0);
-	root_pt[0x003] = pte_create(0xc0000000 >> RISCV_PGSHIFT,
-				PTE_R | PTE_W | PTE_X, 0);
-
-	// Negative address space map at 0xffffffc000000000
-	root_pt[0x100] = root_pt[0];
-	root_pt[0x101] = root_pt[1];
-	root_pt[0x102] = root_pt[2];
-	root_pt[0x103] = root_pt[3];
-
-	mb();
-	root_page_table = root_pt;
-	uintptr_t ptbr = ((uintptr_t) root_pt) >> RISCV_PGSHIFT;
-	write_csr(sptbr, ptbr);
-}
-
-void initVirtualMemory(void) {
-	uintptr_t ms;
-
-	ms = read_csr(mstatus);
-	ms = INSERT_FIELD(ms, MSTATUS_VM, VM_CHOICE);
-	write_csr(mstatus, ms);
-	ms = read_csr(mstatus);
-
-	if (EXTRACT_FIELD(ms, MSTATUS_VM) != VM_CHOICE) {
-		printk(BIOS_DEBUG, "We don't have virtual memory...\n");
-		return;
-	} else {
-		printk(BIOS_DEBUG, "-----------------------------\n");
-		printk(BIOS_DEBUG, "Virtual memory status enabled\n");
-		printk(BIOS_DEBUG, "-----------------------------\n");
-	}
-
-	// TODO: Figure out how to grab this from cbfs
-	// N.B. We used to map physical from 0x81000000,
-	// but since kernels need to be able to see the page tables
-	// created by firmware, we're going to map from start of RAM.
-	// All this is subject to change as we learn more. Much
-	// about RISCV is still in flux.
-	printk(BIOS_DEBUG, "Initializing virtual memory...\n");
-	uintptr_t physicalStart = 0x80000000;
-	uintptr_t virtualStart = 0xffffffff80000000;
-	init_vm(virtualStart, physicalStart, (pte_t *)_pagetables);
-	mb();
-	flush_tlb();
-
-#if IS_ENABLED(CONFIG_DEBUG_PRINT_PAGE_TABLES)
-	printk(BIOS_DEBUG, "Finished initializing virtual memory, starting walk...\n");
-	print_page_table();
-#else
-	printk(BIOS_DEBUG, "Finished initializing virtual memory\n");
-#endif
-}
-
 void mstatus_init(void)
 {
 	uintptr_t ms = 0;

-- 
To view, visit https://review.coreboot.org/23772
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4e69d15f8ee540d2f98c342bc4ec0c00fb48def0
Gerrit-Change-Number: 23772
Gerrit-PatchSet: 1
Gerrit-Owner: Jonathan Neuschäfer <j.neuschaefer at gmx.net>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20180215/575472d8/attachment-0001.html>


More information about the coreboot-gerrit mailing list