akaros/kern/arch/riscv/ros/mmu.h
<<
>>
Prefs
   1/* Contains macros and constants for the kernel VM mapping, page tables,
   2 * definitions for the RISC-V MMU, etc. */
   3
   4#pragma once
   5
   6/* **************************************** */
   7/* Kernel Virtual Memory Mapping  (not really an MMU thing) */
   8
   9// All physical memory mapped at this address
  10#ifdef __riscv64
  11# define KERNBASE       0xFFFFFC0000000000
  12# define ULIM           0x0000040000000000
  13# define KERN_LOAD_ADDR 0xFFFFFFFF80000000
  14# define KERN_VMAP_TOP      KERN_LOAD_ADDR // upper 2GB reserved (see mmu_init)
  15# define NPTLEVELS                       3
  16# define L1PGSHIFT              (13+10+10)
  17# define L1PGSIZE        (1L << L1PGSHIFT)
  18# define L2PGSHIFT                 (13+10)
  19# define L2PGSIZE        (1L << L2PGSHIFT)
  20# define L3PGSHIFT                    (13)
  21# define L3PGSIZE        (1L << L3PGSHIFT)
  22# define PGSHIFT                 L3PGSHIFT
  23# define PTSIZE                   L2PGSIZE
  24#else
  25# define KERNBASE               0x80000000
  26# define ULIM                   0x7F000000
  27# define KERN_LOAD_ADDR           KERNBASE
  28# define KERN_VMAP_TOP          0xfec00000
  29# define NPTLEVELS                       2
  30# define L1PGSHIFT                 (13+11)
  31# define L1PGSIZE         (1 << L1PGSHIFT)
  32# define L2PGSHIFT                      13
  33# define L2PGSIZE         (1 << L2PGSHIFT)
  34# define PGSHIFT                 L2PGSHIFT
  35# define PTSIZE                   L1PGSIZE
  36#endif
  37
  38/* This is the range of the dynamic virtual mappings. */
  39#define KERN_DYN_TOP    KERNBASE
  40#warning "pick a better DYN_BOT"
  41#define KERN_DYN_BOT    ULIM
  42
  43/* **************************************** */
  44/* Page table constants, macros, etc */
  45
  46#define PGSIZE (1 << PGSHIFT)
  47
  48// RV64 virtual addresses are 48 bits, sign-extended out to 64 bits,
  49// creating a hole between 0x0000 7FFF FFFF FFFF and 0xFFFF 8000 0000 0000.
  50// Bits 11-0 are the page offset; L1/L2/L3/L4 page table indices are given
  51// by bits 47-39, 38-30, 29-21, and 20-12, respectively.
  52//
  53// In RV32, virtual addresses are 32 bits; bits 11-0 are the page offset;
  54// and L1/L2 page table indices are given by bits 31-22 and 21-12,
  55// respectively.
  56//
  57// In both cases, the last-level page size is 4KB, as is the page table size.
  58
  59// page number field of address
  60#define LA2PPN(la)      (((uintptr_t) (la)) >> PGSHIFT)
  61
  62// page number field of PPN
  63#define PTE2PPN(pte)    (((uintptr_t) (pte)) >> PTE_PPN_SHIFT)
  64
  65// index into L1 PT
  66#define L1X(la)         ((((uintptr_t) (la)) >> L1PGSHIFT) & (NPTENTRIES-1))
  67
  68// index into L2 PT
  69#define L2X(la)         ((((uintptr_t) (la)) >> L2PGSHIFT) & (NPTENTRIES-1))
  70
  71#ifdef __riscv64
  72// index into L3 PT
  73#define L3X(la)         ((((uintptr_t) (la)) >> L3PGSHIFT) & (NPTENTRIES-1))
  74
  75// index into L4 PT
  76#define L4X(la)         ((((uintptr_t) (la)) >> L4PGSHIFT) & (NPTENTRIES-1))
  77
  78#endif
  79
  80// offset in page
  81#define PGOFF(la)       (((uintptr_t) (la)) & (PGSIZE-1))
  82
  83// construct PTD from physical address
  84#define PTD(pa) (((uintptr_t)(pa) >> PGSHIFT << PTE_PPN_SHIFT) | PTE_T)
  85
  86// Page directory and page table constants
  87#define NPTENTRIES (PGSIZE/sizeof(pte_t))
  88
  89// Page table/directory entry flags.
  90#define PTE_T    0x001 // Entry is a page Table descriptor
  91#define PTE_E    0x002 // Entry is a page table Entry
  92#define PTE_R    0x004 // Referenced
  93#define PTE_D    0x008 // Dirty
  94#define PTE_UX   0x010 // User eXecute permission
  95#define PTE_UW   0x020 // User Read permission
  96#define PTE_UR   0x040 // User Write permission
  97#define PTE_SX   0x080 // Supervisor eXecute permission
  98#define PTE_SW   0x100 // Supervisor Read permission
  99#define PTE_SR   0x200 // Supervisor Write permission
 100#define PTE_PERM (PTE_SR | PTE_SW | PTE_SX | PTE_UR | PTE_UW | PTE_UX)
 101#define PTE_PPN_SHIFT 13
 102#warning "Review RISCV PTE_modes, like NOCACHE/WRITECOMB"
 103#define PTE_NOCACHE     0 // PTE bits to turn off caching, if possible
 104#define PTE_WRITECOMB   0 // PTE bits to turn on write-combining, if possible
 105
 106// commly used access modes
 107
 108#warning "Review RISCV PTEs.  Maybe want PTE_E/PTE_R?"
 109        /* arch-indep code doesn't set PTE_P, it just sets a perm */
 110
 111
 112#define PTE_KERN_RW     (PTE_SR | PTE_SW | PTE_SX)
 113#define PTE_KERN_RO     (PTE_SR | PTE_SX)
 114#define PTE_USER_RW     (PTE_SR | PTE_SW | PTE_UR | PTE_UW | PTE_UX)
 115#define PTE_USER_RO     (PTE_SR | PTE_UR | PTE_UX)
 116#define PTE_NONE        0
 117
 118#warning "probably remove this"
 119// x86 equivalencies
 120#define PTE_P      PTE_E
 121
 122// address in page table entry
 123#define PTE_ADDR(pte)   ((physaddr_t) (pte) & ~(PGSIZE-1))
 124
 125// address in page table descriptor
 126#define PTD_ADDR(ptd)   PTE_ADDR(ptd)
 127
 128// MMU Control Register flags
 129#define MMU_CR_E        0x00000001      // Protection Enable
 130#define MMU_CR_NF       0x00000002      // No Fault mode
 131#define MMU_CR_PSO      0x00000080      // Partial Store Order (TSO disabled)
 132
 133// MMU Fault Status Register flags
 134#define MMU_FSR_USER    0x00000020      // Fault caused by user-space access
 135#define MMU_FSR_EX      0x00000040      // Fault occured in instruction-space
 136#define MMU_FSR_WR      0x00000080      // Fault caused by a store
 137
 138// MMU Register Addresses
 139#define MMU_REG_CTRL    0x00000000      // MMU Control Register
 140#define MMU_REG_CTXTBL  0x00000100      // MMU Context Table Pointer Register
 141#define MMU_REG_CTX     0x00000200      // MMU Context Register
 142#define MMU_REG_FSR     0x00000300      // MMU Fault Status Register
 143#define MMU_REG_FAR     0x00000400      // MMU Fault Address Register
 144
 145// we must guarantee that for any PTE, exactly one of the following is true
 146#define PAGE_PRESENT(pte) ((pte) & PTE_P)
 147#define PAGE_UNMAPPED(pte) ((pte) == 0)
 148#define PAGE_PAGED_OUT(pte) (!PAGE_PRESENT(pte) && !PAGE_UNMAPPED(pte))
 149#define NOVPT
 150
 151#ifndef __ASSEMBLER__
 152typedef unsigned long pte_t;
 153typedef unsigned long pgdir_t;
 154#endif
 155
 156/* Same as VPT but read-only for users */
 157#define UVPT            (ULIM - PTSIZE)
 158
 159/* Arbitrary boundary between the break and the start of
 160 * memory returned by calls to mmap with addr = 0 */
 161#define BRK_END 0x40000000
 162#warning "Check these addresses.  Seem to be small.  Are they 32 bit?"
 163/* Arbitrary boundary where the break (glibc's heap) starts.  You can safely
 164 * mmap with MAP_FIXED below this address. */
 165#define BRK_START               0x0000100000000000
 166