diff options
Diffstat (limited to 'src/arch/riscv')
-rw-r--r-- | src/arch/riscv/Makefile.inc | 1 | ||||
-rw-r--r-- | src/arch/riscv/boot.c | 4 | ||||
-rw-r--r-- | src/arch/riscv/bootblock.S | 11 | ||||
-rw-r--r-- | src/arch/riscv/include/arch/memlayout.h | 4 | ||||
-rw-r--r-- | src/arch/riscv/include/vm.h | 13 | ||||
-rw-r--r-- | src/arch/riscv/payload.S | 28 | ||||
-rw-r--r-- | src/arch/riscv/virtual_memory.c | 46 |
7 files changed, 76 insertions, 31 deletions
diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc index 4bab459676..cf6ce99fb0 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 743549081d..ff1844eb0a 100644 --- a/src/arch/riscv/boot.c +++ b/src/arch/riscv/boot.c @@ -17,13 +17,17 @@ #include <vm.h> #include <arch/encoding.h> #include <rules.h> +#include <console/console.h> void arch_prog_run(struct prog *prog) { void (*doit)(void *) = prog_entry(prog); + void riscvpayload(void *); if (ENV_RAMSTAGE && prog_type(prog) == PROG_PAYLOAD) { initVirtualMemory(); + printk(BIOS_SPEW, "OK, let's go\n"); + riscvpayload(doit); } doit(prog_entry_arg(prog)); diff --git a/src/arch/riscv/bootblock.S b/src/arch/riscv/bootblock.S index 514511ed0d..63df92bb38 100644 --- a/src/arch/riscv/bootblock.S +++ b/src/arch/riscv/bootblock.S @@ -19,13 +19,16 @@ .section ".text._start", "ax", %progbits +.globl _stack +.global _estack .globl _start _start: -#define STACK_START 0x80800000 /* 2GiB + 8MiB */ -#define STACK_SIZE 0x0000fff0 - li sp, STACK_START + STACK_SIZE + + # N.B. This only works on low 4G of the address space + # and the stack must be page-aligned. + la sp, _estack # make room for HLS and initialize it addi sp, sp, -64 // MENTRY_FRAME_SIZE @@ -33,7 +36,7 @@ _start: call hls_init # poison the stack - li t1, STACK_START + la t1, _stack li t0, 0xdeadbeef sd t0, 0(t1) diff --git a/src/arch/riscv/include/arch/memlayout.h b/src/arch/riscv/include/arch/memlayout.h index 4d2af5953d..5d011418c4 100644 --- a/src/arch/riscv/include/arch/memlayout.h +++ b/src/arch/riscv/include/arch/memlayout.h @@ -18,8 +18,8 @@ #ifndef __ARCH_MEMLAYOUT_H #define __ARCH_MEMLAYOUT_H -/* TODO: Double-check that that's the correct alignment for our ABI. */ -#define STACK(addr, size) REGION(stack, addr, size, 8) +#define STACK(addr, size) REGION(stack, addr, size, 4096) +#define PAGETABLES(addr, size) REGION(pagetables, addr, size, 4096) /* TODO: Need to add DMA_COHERENT region like on ARM? */ diff --git a/src/arch/riscv/include/vm.h b/src/arch/riscv/include/vm.h index bee2ed4215..c3de47aa5c 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)))) @@ -66,7 +56,8 @@ 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, uintptr_t pageTableStart); +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); diff --git a/src/arch/riscv/payload.S b/src/arch/riscv/payload.S new file mode 100644 index 0000000000..3261a80c2b --- /dev/null +++ b/src/arch/riscv/payload.S @@ -0,0 +1,28 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + .global riscvpayload +riscvpayload: + /* Jump to a0 in S-mode */ + mv t0,a0 + 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 + + // We're still in toolchain no mans land. + .word 0x30200073 + //mret diff --git a/src/arch/riscv/virtual_memory.c b/src/arch/riscv/virtual_memory.c index be8b4884d4..999d73cec8 100644 --- a/src/arch/riscv/virtual_memory.c +++ b/src/arch/riscv/virtual_memory.c @@ -21,6 +21,7 @@ #include <console/console.h> #include <stdint.h> #include <vm.h> +#include <symbols.h> pte_t* root_page_table; @@ -94,7 +95,7 @@ static void print_page_table_at(pte_t *pt, intptr_t virt_addr, int level) /* Print the page table structures to the console */ void print_page_table(void) { - print_page_table_at(root_page_table, 0, 0); + print_page_table_at((void *)(read_csr(sptbr) << RISCV_PGSHIFT), 0, 0); } void flush_tlb(void) @@ -115,17 +116,17 @@ 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; return pte; } -void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, uintptr_t pageTableStart) { - pte_t* sbi_pt = (pte_t*) pageTableStart; +void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, pte_t *sbi_pt) +{ memset(sbi_pt, 0, RISCV_PGSIZE); // need to leave room for sbi page uintptr_t memorySize = 0x7F000000; // 0xFFF... - 0xFFFFFFFF81000000 - RISCV_PGSIZE @@ -147,21 +148,32 @@ 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_U|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_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, 0); + root_pt[1] = pte_create(0x40000000>>RISCV_PGSHIFT, + PTE_W|PTE_R, 0); + + // Start of RAM + root_pt[2] = pte_create(0x80000000>>RISCV_PGSHIFT, + PTE_W|PTE_R, 0); mb(); root_page_table = root_pt; uintptr_t ptbr = ((uintptr_t) root_pt) >> RISCV_PGSHIFT; @@ -185,12 +197,13 @@ 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; - init_vm(virtualStart, physicalStart, pageTableStart); + uintptr_t physicalStart = 0x81000000; + uintptr_t virtualStart = 0xffffffff81000000; + 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"); @@ -220,7 +233,12 @@ void mstatus_init(void) | (1 << CAUSE_USER_ECALL) ); + /* Enable all user/supervisor-mode counters */ - write_csr(mscounteren, 0b111); - write_csr(mucounteren, 0b111); + /* We'll turn these on once lowrisc gets their bitstream up to + * 1.9. Right now there's no agreement on the values for these + * architectural registers. + */ + //write_csr(mscounteren, 0b111); + //write_csr(mucounteren, 0b111); } |