1 /* 2 * Copyright (c) 2020 Travis Geiselbrecht 3 * 4 * Use of this source code is governed by a MIT-style 5 * license that can be found in the LICENSE file or at 6 * https://opensource.org/licenses/MIT 7 */ 8 #pragma once 9 10 #if RISCV_MMU 11 12 #ifndef ASSEMBLY 13 #include <stdint.h> 14 #include <arch/defines.h> 15 16 // RISC-V specific mmu #defines and structures here 17 typedef uintptr_t riscv_pte_t; 18 #endif 19 20 #define KB (1024UL) 21 #define MB (1024UL*1024UL) 22 #define GB (1024UL*1024UL*1024UL) 23 24 // some constants based on our particular implementation 25 #if RISCV_MMU == 48 26 #define RISCV_MMU_PT_LEVELS 4 27 #define RISCV_MMU_PT_SHIFT 9 28 #define RISCV_MMU_PT_ENTRIES 512 // 1 << PT_SHIFT 29 #define RISCV_MMU_CANONICAL_MASK ((1UL << 48) - 1) 30 #define RISCV_MMU_PPN_BITS 56 31 #define RISCV_MMU_PHYSMAP_BASE_VIRT (KERNEL_ASPACE_BASE) 32 #define RISCV_MMU_PHYSMAP_PAGE_SIZE (1UL << 39) 33 #define RISCV_MMU_PHYSMAP_PAGE_COUNT 1 34 #elif RISCV_MMU == 39 35 #define RISCV_MMU_PT_LEVELS 3 36 #define RISCV_MMU_PT_SHIFT 9 37 #define RISCV_MMU_PT_ENTRIES 512 // 1 << PT_SHIFT 38 #define RISCV_MMU_CANONICAL_MASK ((1UL << 39) - 1) 39 #define RISCV_MMU_PPN_BITS 56 40 #define RISCV_MMU_PHYSMAP_BASE_VIRT (KERNEL_ASPACE_BASE) 41 #define RISCV_MMU_PHYSMAP_PAGE_SIZE (1UL << 30) 42 #define RISCV_MMU_PHYSMAP_PAGE_COUNT 64 43 #elif RISCV_MMU == 32 44 #define RISCV_MMU_PT_LEVELS 2 45 #define RISCV_MMU_PT_SHIFT 10 46 #define RISCV_MMU_PT_ENTRIES 1024 // 1 << PT_SHIFT 47 #define RISCV_MMU_CANONICAL_MASK UINT32_MASK 48 #define RISCV_MMU_PPN_BITS 32 49 #define RISCV_MMU_PHYSMAP_BASE_VIRT (KERNEL_ASPACE_BASE) 50 #define RISCV_MMU_PHYSMAP_PAGE_SIZE (1UL << 30) 51 #define RISCV_MMU_PHYSMAP_PAGE_COUNT 1 52 #else 53 #error implement 54 #endif 55 56 #define RISCV_MMU_PHYSMAP_SIZE (RISCV_MMU_PHYSMAP_PAGE_SIZE * RISCV_MMU_PHYSMAP_PAGE_COUNT) 57 58 // number of page table entries for the kernel and user half 59 // TODO: compute directly from KERNEL/USER_ASPACE_SIZE 60 #define RISCV_MMU_USER_PT_ENTRIES 256 61 #define RISCV_MMU_KERNEL_PT_ENTRIES 256 62 63 // page table bits 64 #define RISCV_PTE_V (1 << 0) // valid 65 #define RISCV_PTE_R (1 << 1) // read 66 #define RISCV_PTE_W (1 << 2) // write 67 #define RISCV_PTE_X (1 << 3) // execute 68 #define RISCV_PTE_PERM_MASK (0x7 << 1) 69 #define RISCV_PTE_U (1 << 4) // user 70 #define RISCV_PTE_G (1 << 5) // global 71 #define RISCV_PTE_A (1 << 6) // accessed 72 #define RISCV_PTE_D (1 << 7) // dirty 73 #define RISCV_PTE_RSW_MASK (3 << 8) // reserved for software 74 #define RISCV_PTE_PPN_SHIFT (10) 75 #define RISCV_PTE_PPN_MASK (((1UL << (RISCV_MMU_PPN_BITS - PAGE_SIZE_SHIFT)) - 1) << RISCV_PTE_PPN_SHIFT) 76 77 // riscv PPN is stored shifed over 2 from the natural alignment 78 #define RISCV_PTE_PPN(pte) (((pte) & RISCV_PTE_PPN_MASK) << (PAGE_SIZE_SHIFT - RISCV_PTE_PPN_SHIFT)) 79 #define RISCV_PTE_PPN_TO_PTE(paddr) (((paddr) >> PAGE_SIZE_SHIFT) << RISCV_PTE_PPN_SHIFT) 80 81 // SATP register, contains the current mmu mode, address space id, and 82 // pointer to root page table 83 #define RISCV_SATP_MODE_NONE (0UL) 84 #define RISCV_SATP_MODE_SV32 (1UL) 85 #define RISCV_SATP_MODE_SV39 (8UL) 86 #define RISCV_SATP_MODE_SV48 (9UL) 87 #define RISCV_SATP_MODE_SV57 (10UL) 88 #define RISCV_SATP_MODE_SV64 (11UL) 89 90 #if __riscv_xlen == 32 91 #define RISCV_SATP_MODE_SHIFT (31) 92 #define RISCV_SATP_ASID_SHIFT (22) 93 #define RISCV_SATP_ASID_SIZE (9) 94 #define RISCV_SATP_ASID_MASK ((1 << RISCV_SATP_ASID_SIZE) - 1) 95 96 #elif __riscv_xlen == 64 97 #define RISCV_SATP_MODE_SHIFT (60) 98 #define RISCV_SATP_ASID_SHIFT (44) 99 #define RISCV_SATP_ASID_SIZE (16) 100 #define RISCV_SATP_ASID_MASK ((1UL << RISCV_SATP_ASID_SIZE) - 1) 101 #endif 102 103 #endif // RISCV_MMU 104 105