[coreboot-gerrit] New patch to review for coreboot: RISCV: changes to get us into supervisor mode, with a kernel.

Ronald G. Minnich (rminnich@gmail.com) gerrit at coreboot.org
Sun Oct 9 16:33:45 CEST 2016


Ronald G. Minnich (rminnich at gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16954

-gerrit

commit 003993d75d8950edfd66e7cdee98d45435a6c2ed
Author: Ronald G. Minnich <rminnich at gmail.com>
Date:   Sun Oct 9 07:33:05 2016 -0700

    RISCV: changes to get us into supervisor mode, with a kernel.
    
    We can load simple s-mode kernels but linux is exploding at present
    when it tries to zero BSS.
    
    Change-Id: Ief93d2ad63ac481e5669ca10a66942bced511a83
    Signed-off-by: Ronald G. Minnich <rminnich at gmail.com>
---
 src/arch/riscv/Makefile.inc     |  1 +
 src/arch/riscv/boot.c           |  4 ++++
 src/arch/riscv/include/vm.h     | 10 ----------
 src/arch/riscv/payload.S        | 20 ++++++++++++++++++++
 src/arch/riscv/virtual_memory.c | 30 ++++++++++++++++++++++--------
 src/soc/lowrisc/lowrisc/Kconfig |  1 +
 6 files changed, 48 insertions(+), 18 deletions(-)

diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc
index 4bab459..cf6ce99 100644
--- a/src/arch/riscv/Makefile.inc
+++ b/src/arch/riscv/Makefile.inc
@@ -96,6 +96,7 @@ ramstage-y += misc.c
 ramstage-y += boot.c
 ramstage-y += tables.c
 ramstage-y += sbi.S
+ramstage-y += payload.S
 ramstage-y += \
 	$(top)/src/lib/memchr.c \
 	$(top)/src/lib/memcmp.c \
diff --git a/src/arch/riscv/boot.c b/src/arch/riscv/boot.c
index 7435490..35a9123 100644
--- a/src/arch/riscv/boot.c
+++ b/src/arch/riscv/boot.c
@@ -13,6 +13,7 @@
  * GNU General Public License for more details.
  */
 
+#include <lib.h>
 #include <program_loading.h>
 #include <vm.h>
 #include <arch/encoding.h>
@@ -21,9 +22,12 @@
 void arch_prog_run(struct prog *prog)
 {
 	void (*doit)(void *) = prog_entry(prog);
+	void riscvpayload(void);
 
 	if (ENV_RAMSTAGE && prog_type(prog) == PROG_PAYLOAD) {
+		hexdump((void *)0x81000000, 128);
 		initVirtualMemory();
+		riscvpayload();
 	}
 
 	doit(prog_entry_arg(prog));
diff --git a/src/arch/riscv/include/vm.h b/src/arch/riscv/include/vm.h
index bee2ed4..6472cad 100644
--- a/src/arch/riscv/include/vm.h
+++ b/src/arch/riscv/include/vm.h
@@ -37,16 +37,6 @@
 #define VA_BITS 39
 #define MEGAPAGE_SIZE (SUPERPAGE_SIZE << RISCV_PGLEVEL_BITS)
 
-#define PROT_READ 1
-#define PROT_WRITE 2
-#define PROT_EXEC 4
-
-#define MAP_PRIVATE 0x2
-#define MAP_FIXED 0x10
-#define MAP_ANONYMOUS 0x20
-#define MAP_POPULATE 0x8000
-#define MREMAP_FIXED 0x2
-
 #define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
 #define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
 
diff --git a/src/arch/riscv/payload.S b/src/arch/riscv/payload.S
new file mode 100644
index 0000000..6d604bb
--- /dev/null
+++ b/src/arch/riscv/payload.S
@@ -0,0 +1,20 @@
+.global riscvpayload
+riscvpayload:
+	/* Jump to 0xffffffff81000000 in S-mode */
+	li t0, 0xffffffff81000000
+	csrw mepc, t0
+	csrr t0, mstatus
+	li t1, ~(3<<11)
+	and t0, t0, t1
+	li t2,  (1<<11)
+	or t0, t0, t2
+	csrw mstatus, t0
+
+#if 0 // remove for testing.
+.L2:
+	li	a5,1107296256
+	li	a4,48
+	sw	a4,0(a5)
+	j	.L2
+#endif
+	mret
diff --git a/src/arch/riscv/virtual_memory.c b/src/arch/riscv/virtual_memory.c
index a0731e6..7fb1a8e 100644
--- a/src/arch/riscv/virtual_memory.c
+++ b/src/arch/riscv/virtual_memory.c
@@ -115,9 +115,9 @@ pte_t ptd_create(uintptr_t ppn)
 pte_t pte_create(uintptr_t ppn, int prot, int user)
 {
 	pte_t pte = (ppn << PTE_PPN_SHIFT) | PTE_R | PTE_V;
-	if (prot & PROT_WRITE)
+	if (prot & PTE_W)
 		pte |= PTE_W;
-	if (prot & PROT_EXEC)
+	if (prot & PTE_X)
 		pte |= PTE_X;
 	if (user)
 		pte |= PTE_U;
@@ -147,21 +147,31 @@ void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, uintptr_t pageTable
 		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, PROT_READ|PROT_WRITE|PROT_EXEC, 0);
+		middle_pt[l2_idx] = pte_create(paddr >> RISCV_PGSHIFT,
+					       PTE_R|PTE_W|PTE_X, 0);
 	}
 
 	// map SBI at top of vaddr space
-	uintptr_t num_sbi_pages = 1; // only need to map a single page for sbi interface
+	// only need to map a single page for sbi interface
+	uintptr_t num_sbi_pages = 1;
 	uintptr_t sbiStartAddress = (uintptr_t) &sbi_page;
 	uintptr_t sbiAddr = sbiStartAddress;
 	for (uintptr_t i = 0; i < num_sbi_pages; i++) {
 		uintptr_t idx = (1 << RISCV_PGLEVEL_BITS) - num_sbi_pages + i;
-		sbi_pt[idx] = pte_create(sbiAddr >> RISCV_PGSHIFT, PROT_READ|PROT_EXEC, 0);
+		sbi_pt[idx] = pte_create(sbiAddr >> RISCV_PGSHIFT,
+					 PTE_W|PTE_R|PTE_X, 0);
 		sbiAddr += RISCV_PGSIZE;
 	}
 	pte_t* sbi_pte = middle_pt + ((num_middle_pts << RISCV_PGLEVEL_BITS)-1);
 	*sbi_pte = ptd_create((uintptr_t)sbi_pt >> RISCV_PGSHIFT);
 
+	// IO space.
+
+	root_pt[0] = pte_create(0, PTE_W|PTE_R|PTE_X, 0);
+	root_pt[1] = pte_create(0x40000000>>RISCV_PGSHIFT,
+				PTE_W|PTE_R|PTE_X, 0);
+	root_pt[2] = pte_create(0x80000000>>RISCV_PGSHIFT,
+				PTE_W|PTE_R|PTE_X, 0);
 	mb();
 	root_page_table = root_pt;
 	uintptr_t ptbr = ((uintptr_t) root_pt) >> RISCV_PGSHIFT;
@@ -185,12 +195,14 @@ void initVirtualMemory(void) {
 		printk(BIOS_DEBUG, "-----------------------------\n");
 	}
 
+	// TODO: Figure out how to grab this from cbfs
 	printk(BIOS_DEBUG, "Initializing virtual memory...\n");
-	uintptr_t physicalStart = 0x90000000; // TODO: Figure out how to grab this from cbfs
-	uintptr_t virtualStart = 0xffffffff80000000;
-	uintptr_t pageTableStart = 0x91400000;
+	uintptr_t physicalStart = 0x81000000;
+	uintptr_t virtualStart = 0xffffffff81000000;
+	uintptr_t pageTableStart = 0x80800000;
 	init_vm(virtualStart, physicalStart, pageTableStart);
 	mb();
+	flush_tlb();
 
 #if IS_ENABLED(CONFIG_DEBUG_PRINT_PAGE_TABLES)
 	printk(BIOS_DEBUG, "Finished initializing virtual memory, starting walk...\n");
@@ -211,6 +223,7 @@ void mstatus_init(void)
 	set_csr(mie, MIP_MSIP);
 
 	/* Configure which exception causes are delegated to supervisor mode */
+/*
 	set_csr(medeleg,  (1 << CAUSE_MISALIGNED_FETCH)
 			| (1 << CAUSE_FAULT_FETCH)
 			| (1 << CAUSE_ILLEGAL_INSTRUCTION)
@@ -220,6 +233,7 @@ void mstatus_init(void)
 			| (1 << CAUSE_USER_ECALL)
 	);
 
+*/
 	/* Enable all user/supervisor-mode counters */
 	//write_csr(mscounteren, 0b111);
 	//write_csr(mucounteren, 0b111);
diff --git a/src/soc/lowrisc/lowrisc/Kconfig b/src/soc/lowrisc/lowrisc/Kconfig
index eb76412..528e744 100644
--- a/src/soc/lowrisc/lowrisc/Kconfig
+++ b/src/soc/lowrisc/lowrisc/Kconfig
@@ -5,6 +5,7 @@ config SOC_LOWRISC_LOWRISC
 	select ARCH_ROMSTAGE_RISCV
 	select ARCH_RAMSTAGE_RISCV
 	select BOOTBLOCK_CONSOLE
+	select DRIVERS_UART_8250MEM_32
 	bool
 	default n
 



More information about the coreboot-gerrit mailing list