summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/riscv/Makefile.inc1
-rw-r--r--src/arch/riscv/boot.c4
-rw-r--r--src/arch/riscv/bootblock.S11
-rw-r--r--src/arch/riscv/include/arch/memlayout.h4
-rw-r--r--src/arch/riscv/include/vm.h13
-rw-r--r--src/arch/riscv/payload.S28
-rw-r--r--src/arch/riscv/virtual_memory.c46
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);
}