Compare commits
1 Commits
master
...
wip/riscv3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94bce26b6f |
@@ -13,10 +13,12 @@
|
||||
#define REGOFF(x) ((x) * 4)
|
||||
#define STR sw
|
||||
#define LDR lw
|
||||
#define RISCV_XLEN_BYTES_LOG 2
|
||||
#else
|
||||
#define REGOFF(x) ((x) * 8)
|
||||
#define STR sd
|
||||
#define LDR ld
|
||||
#define RISCV_XLEN_BYTES_LOG 3
|
||||
#endif
|
||||
|
||||
#define RISCV_XLEN_BYTES (__riscv_xlen / 8)
|
||||
|
||||
@@ -12,15 +12,12 @@
|
||||
#ifndef ASSEMBLY
|
||||
#include <stdint.h>
|
||||
#include <arch/defines.h>
|
||||
#include <lk/utils.h>
|
||||
|
||||
// RISC-V specific mmu #defines and structures here
|
||||
typedef uintptr_t riscv_pte_t;
|
||||
#endif
|
||||
|
||||
#define KB (1024UL)
|
||||
#define MB (1024UL*1024UL)
|
||||
#define GB (1024UL*1024UL*1024UL)
|
||||
|
||||
// some constants based on our particular implementation
|
||||
#if RISCV_MMU == 48
|
||||
#define RISCV_MMU_PT_LEVELS 4
|
||||
@@ -44,7 +41,7 @@ typedef uintptr_t riscv_pte_t;
|
||||
#define RISCV_MMU_PT_LEVELS 2
|
||||
#define RISCV_MMU_PT_SHIFT 10
|
||||
#define RISCV_MMU_PT_ENTRIES 1024 // 1 << PT_SHIFT
|
||||
#define RISCV_MMU_CANONICAL_MASK UINT32_MASK
|
||||
#define RISCV_MMU_CANONICAL_MASK UINT32_MAX
|
||||
#define RISCV_MMU_PPN_BITS 32
|
||||
#define RISCV_MMU_PHYSMAP_BASE_VIRT (KERNEL_ASPACE_BASE)
|
||||
#define RISCV_MMU_PHYSMAP_PAGE_SIZE (1UL << 30)
|
||||
@@ -57,8 +54,9 @@ typedef uintptr_t riscv_pte_t;
|
||||
|
||||
// number of page table entries for the kernel and user half
|
||||
// TODO: compute directly from KERNEL/USER_ASPACE_SIZE
|
||||
#define RISCV_MMU_USER_PT_ENTRIES 256
|
||||
#define RISCV_MMU_KERNEL_PT_ENTRIES 256
|
||||
#define RISCV_MMU_USER_PT_ENTRIES (RISCV_MMU_PT_ENTRIES / 2)
|
||||
#define RISCV_MMU_KERNEL_PT_ENTRIES (RISCV_MMU_PT_ENTRIES / 2)
|
||||
#define RISCV_MMU_KERNEL_PT_ENTRY (RISCV_MMU_USER_PT_ENTRIES)
|
||||
|
||||
// page table bits
|
||||
#define RISCV_PTE_V (1 << 0) // valid
|
||||
|
||||
@@ -27,27 +27,23 @@
|
||||
|
||||
#include <kernel/vm.h>
|
||||
|
||||
#if __riscv_xlen == 32
|
||||
#error "32 bit mmu not supported yet"
|
||||
#endif
|
||||
|
||||
// global, generally referenced in start.S
|
||||
|
||||
// the one main kernel top page table, used by the kernel address space
|
||||
// when no user space is active. bottom user space parts are empty.
|
||||
riscv_pte_t kernel_pgtable[512] __ALIGNED(PAGE_SIZE);
|
||||
riscv_pte_t kernel_pgtable[RISCV_MMU_PT_ENTRIES] __ALIGNED(PAGE_SIZE);
|
||||
paddr_t kernel_pgtable_phys; // filled in by start.S
|
||||
|
||||
// trampoline top level page table is like the kernel page table but additionally
|
||||
// holds an identity map of the bottom RISCV_MMU_PHYSMAP_SIZE bytes of ram.
|
||||
// used at early bootup and when starting secondary processors.
|
||||
riscv_pte_t trampoline_pgtable[512] __ALIGNED(PAGE_SIZE);
|
||||
riscv_pte_t trampoline_pgtable[RISCV_MMU_PT_ENTRIES] __ALIGNED(PAGE_SIZE);
|
||||
paddr_t trampoline_pgtable_phys; // filled in by start.S
|
||||
|
||||
// pre-allocate kernel 2nd level page tables.
|
||||
// this makes it very easy to keep user space top level address space page tables
|
||||
// in sync, since they can simply take a copy of the kernel ones.
|
||||
riscv_pte_t kernel_l2_pgtable[512][RISCV_MMU_KERNEL_PT_ENTRIES] __ALIGNED(PAGE_SIZE);
|
||||
riscv_pte_t kernel_l2_pgtable[RISCV_MMU_PT_ENTRIES][RISCV_MMU_KERNEL_PT_ENTRIES] __ALIGNED(PAGE_SIZE);
|
||||
paddr_t kernel_l2_pgtable_phys; // filled in by start.S
|
||||
|
||||
// initial memory mappings. VM uses to construct mappings after the fact
|
||||
@@ -110,6 +106,8 @@ void riscv_set_satp(uint asid, paddr_t pt) {
|
||||
satp = RISCV_SATP_MODE_SV48 << RISCV_SATP_MODE_SHIFT;
|
||||
#elif RISCV_MMU == 39
|
||||
satp = RISCV_SATP_MODE_SV39 << RISCV_SATP_MODE_SHIFT;
|
||||
#elif RISCV_MMU == 32
|
||||
satp = RISCV_SATP_MODE_SV32 << RISCV_SATP_MODE_SHIFT;
|
||||
#endif
|
||||
|
||||
// make sure the asid is in range
|
||||
|
||||
@@ -157,31 +157,34 @@ LOCAL_FUNCTION(_mmu_init)
|
||||
|
||||
// store the physical address of the pgtable for future use
|
||||
lla t1, trampoline_pgtable_phys
|
||||
sd t0, (t1)
|
||||
STR t0, (t1)
|
||||
|
||||
// do the same for the main kernel pgtable
|
||||
lla t2, kernel_pgtable
|
||||
lla t1, kernel_pgtable_phys
|
||||
sd t2, (t1)
|
||||
STR t2, (t1)
|
||||
|
||||
// and the 2nd level tables
|
||||
lla t2, kernel_l2_pgtable
|
||||
lla t1, kernel_l2_pgtable_phys
|
||||
sd t2, (t1)
|
||||
STR t2, (t1)
|
||||
|
||||
// compute kernel pgtable pointer (index 256)
|
||||
addi t1, t0, (8 * 128)
|
||||
addi t1, t1, (8 * 128)
|
||||
// compute kernel pgtable pointer (index 256 or 512)
|
||||
li t1, RISCV_MMU_KERNEL_PT_ENTRY
|
||||
slli t1, t1, RISCV_XLEN_BYTES_LOG
|
||||
add t1, t1, t0
|
||||
|
||||
// page table entry: address 0, A, D, G, XWR, V
|
||||
li t2, (0 | (1<<7) | (1<<6) | (1<<5) | (1<<3) | (1<<2) | (1<<1) | (1<<0))
|
||||
li t2, (0 | RISCV_PTE_D | RISCV_PTE_A | RISCV_PTE_G | RISCV_PTE_X | RISCV_PTE_W | RISCV_PTE_R | RISCV_PTE_V)
|
||||
|
||||
// num interations and increment count
|
||||
#if RISCV_MMU == 48 || RISCV_MMU == 39
|
||||
#if RISCV_MMU == 48 || RISCV_MMU == 39 || RISCV_MMU == 32
|
||||
// RV48: map the first 512GB of the physical address space at the
|
||||
// bottom of the kernel address space using a single terapage
|
||||
// RV39: map the first 64GB of the physical address space at the
|
||||
// bottom of the kernel address space using 64 1GB gigapages
|
||||
// RV39: map the first 1GB of the physical address space at the
|
||||
// bottom of the kernel address space using 1GB gigapages
|
||||
li t3, RISCV_MMU_PHYSMAP_PAGE_COUNT
|
||||
li t4, (RISCV_MMU_PHYSMAP_PAGE_SIZE >> 2)
|
||||
#else
|
||||
@@ -192,11 +195,11 @@ LOCAL_FUNCTION(_mmu_init)
|
||||
// write both to t0 (index 0 of the kernel page table) and
|
||||
// t1 (starting index of kernel space)
|
||||
0:
|
||||
sd t2, (t1)
|
||||
sd t2, (t0)
|
||||
STR t2, (t1)
|
||||
STR t2, (t0)
|
||||
add t2, t2, t4
|
||||
addi t0, t0, 8
|
||||
addi t1, t1, 8
|
||||
addi t0, t0, RISCV_XLEN_BYTES
|
||||
addi t1, t1, RISCV_XLEN_BYTES
|
||||
addi t3, t3, -1
|
||||
bnez t3, 0b
|
||||
|
||||
@@ -212,6 +215,8 @@ LOCAL_FUNCTION(_mmu_init)
|
||||
li t2, (RISCV_SATP_MODE_SV48 << RISCV_SATP_MODE_SHIFT)
|
||||
#elif RISCV_MMU == 39
|
||||
li t2, (RISCV_SATP_MODE_SV39 << RISCV_SATP_MODE_SHIFT)
|
||||
#elif RISCV_MMU == 32
|
||||
li t2, (RISCV_SATP_MODE_SV32 << RISCV_SATP_MODE_SHIFT)
|
||||
#else
|
||||
#error implement
|
||||
#endif
|
||||
@@ -228,7 +233,7 @@ LOCAL_FUNCTION(_mmu_init)
|
||||
|
||||
// bounce to the high address
|
||||
lla t0, .Lhigh_addr
|
||||
ld t0, (t0)
|
||||
LDR t0, (t0)
|
||||
jr t0
|
||||
|
||||
// the full virtual address of the .Lhigh label
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <libfdt.h>
|
||||
#include <lk/cpp.h>
|
||||
#include <lk/err.h>
|
||||
#include <lk/utils.h>
|
||||
#include <lk/trace.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
@@ -89,7 +90,6 @@ status_t fdtwalk_setup_memory(const void *fdt, paddr_t fdt_phys, paddr_t default
|
||||
/* trim size on certain platforms */
|
||||
#if ARCH_ARM || (ARCH_RISCV && __riscv_xlen == 32)
|
||||
/* only use the first 1GB on ARM32 */
|
||||
const auto GB = 1024*1024*1024UL;
|
||||
if (mem[i].base - MEMBASE > GB) {
|
||||
printf("trimming memory to 1GB\n");
|
||||
continue;
|
||||
|
||||
11
project/qemu-virt-riscv32-supervisor-test.mk
Normal file
11
project/qemu-virt-riscv32-supervisor-test.mk
Normal file
@@ -0,0 +1,11 @@
|
||||
# main project for qemu-riscv32
|
||||
MODULES += \
|
||||
app/shell
|
||||
SUBARCH := 32
|
||||
RISCV_MODE := supervisor
|
||||
|
||||
include project/virtual/test.mk
|
||||
include project/virtual/fs.mk
|
||||
include project/virtual/minip.mk
|
||||
include project/target/qemu-virt-riscv.mk
|
||||
|
||||
Reference in New Issue
Block a user