[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