diff --git a/arch/riscv/include/arch/riscv/asm.h b/arch/riscv/include/arch/riscv/asm.h index ae526a4bd..f642d33dc 100644 --- a/arch/riscv/include/arch/riscv/asm.h +++ b/arch/riscv/include/arch/riscv/asm.h @@ -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) diff --git a/arch/riscv/include/arch/riscv/mmu.h b/arch/riscv/include/arch/riscv/mmu.h index 46c71fe9a..9c3d90749 100644 --- a/arch/riscv/include/arch/riscv/mmu.h +++ b/arch/riscv/include/arch/riscv/mmu.h @@ -12,15 +12,12 @@ #ifndef ASSEMBLY #include #include +#include // 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 diff --git a/arch/riscv/mmu.cpp b/arch/riscv/mmu.cpp index a7603d236..0d05e0e85 100644 --- a/arch/riscv/mmu.cpp +++ b/arch/riscv/mmu.cpp @@ -27,27 +27,23 @@ #include -#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 diff --git a/arch/riscv/start.S b/arch/riscv/start.S index 2394a62c5..1d95013b2 100644 --- a/arch/riscv/start.S +++ b/arch/riscv/start.S @@ -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 diff --git a/lib/fdtwalk/helpers.cpp b/lib/fdtwalk/helpers.cpp index ec765276e..2f7c118a5 100644 --- a/lib/fdtwalk/helpers.cpp +++ b/lib/fdtwalk/helpers.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -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; diff --git a/project/qemu-virt-riscv32-supervisor-test.mk b/project/qemu-virt-riscv32-supervisor-test.mk new file mode 100644 index 000000000..f8d6d95aa --- /dev/null +++ b/project/qemu-virt-riscv32-supervisor-test.mk @@ -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 +