arch/mmu.h contents now in ros/arch/mmu.h (XCC)
[akaros.git] / kern / arch / riscv / ros / mmu.h
1 /* Contains macros and constants for the kernel VM mapping, page tables,
2  * definitions for the RISC-V MMU, etc. */
3
4 #ifndef ROS_INC_ARCH_MMU_H
5 #define ROS_INC_ARCH_MMU_H
6
7 /* **************************************** */
8 /* Kernel Virtual Memory Mapping  (not really an MMU thing) */
9
10 // All physical memory mapped at this address
11 #ifdef __riscv64
12 # define KERNBASE       0xFFFFFF0000000000
13 # define ULIM           0x0000010000000000
14 # define KERN_LOAD_ADDR 0xFFFFFFFF80000000
15 # define KERN_VMAP_TOP          KERN_LOAD_ADDR // upper 2GB reserved (see mmu_init)
16 # define NPTLEVELS                       4
17 # define L1PGSHIFT              (12+9+9+9)
18 # define L1PGSIZE        (1L << L1PGSHIFT)
19 # define L2PGSHIFT                (12+9+9)
20 # define L2PGSIZE        (1L << L2PGSHIFT)
21 # define L3PGSHIFT                  (12+9)
22 # define L3PGSIZE        (1L << L3PGSHIFT)
23 # define L4PGSHIFT                    (12)
24 # define L4PGSIZE        (1L << L4PGSHIFT)
25 # define PGSHIFT                 L4PGSHIFT
26 # define PTSIZE                   L2PGSIZE
27 #else
28 # define KERNBASE               0x80000000
29 # define ULIM                   0x7F000000
30 # define KERN_LOAD_ADDR           KERNBASE
31 # define KERN_VMAP_TOP                  0xfec00000 /* using sparc's upper limit */
32 # define NPTLEVELS                       2
33 # define L1PGSHIFT                 (12+10)
34 # define L1PGSIZE         (1 << L1PGSHIFT)
35 # define L2PGSHIFT                      12
36 # define L2PGSIZE         (1 << L2PGSHIFT)
37 # define PGSHIFT                 L2PGSHIFT
38 # define PTSIZE                   L1PGSIZE
39 #endif
40
41 /* All arches must define this, which is the lower limit of their static
42  * mappings, and where the dynamic mappings will start. */
43 #define KERN_DYN_TOP    KERNBASE
44
45 /* **************************************** */
46 /* Page table constants, macros, etc */
47
48 #define PGSIZE (1 << PGSHIFT)
49
50 // RV64 virtual addresses are 48 bits, sign-extended out to 64 bits,
51 // creating a hole between 0x0000 7FFF FFFF FFFF and 0xFFFF 8000 0000 0000.
52 // Bits 11-0 are the page offset; L1/L2/L3/L4 page table indices are given
53 // by bits 47-39, 38-30, 29-21, and 20-12, respectively.
54 //
55 // In RV32, virtual addresses are 32 bits; bits 11-0 are the page offset;
56 // and L1/L2 page table indices are given by bits 31-22 and 21-12,
57 // respectively.
58 //
59 // In both cases, the last-level page size is 4KB, as is the page table size.
60
61 // page number field of address
62 #define LA2PPN(la)      (((uintptr_t) (la)) >> PGSHIFT)
63
64 // page number field of PPN
65 #define PTE2PPN(pte)    (((uintptr_t) (pte)) >> PTE_PPN_SHIFT)
66
67 // index into L1 PT
68 #define L1X(la)         ((((uintptr_t) (la)) >> L1PGSHIFT) & (NPTENTRIES-1))
69
70 // index into L2 PT
71 #define L2X(la)         ((((uintptr_t) (la)) >> L2PGSHIFT) & (NPTENTRIES-1))
72
73 #ifdef __riscv64
74 // index into L3 PT
75 #define L3X(la)         ((((uintptr_t) (la)) >> L3PGSHIFT) & (NPTENTRIES-1))
76
77 // index into L4 PT
78 #define L4X(la)         ((((uintptr_t) (la)) >> L4PGSHIFT) & (NPTENTRIES-1))
79
80 // construct linear address from indexes and offset
81 #define PGADDR(l1, l2, l3, l4, o) ((uintptr_t) ((l1) << L1PGSHIFT | (l2) << L2PGSHIFT | (l3) << L3PGSHIFT | (l4) << L4PGSHIFT | (o)))
82 #else
83 // construct linear address from indexes and offset
84 #define PGADDR(l1, l2, o) ((uintptr_t) ((l1) << L1PGSHIFT | (l2) << L2PGSHIFT | (o)))
85 #endif
86
87 // offset in page
88 #define PGOFF(la)       (((uintptr_t) (la)) & (PGSIZE-1))
89
90 // construct PTE from PPN and flags
91 #define PTE(ppn, flags) ((ppn) << PTE_PPN_SHIFT | (flags))
92
93 // construct PTD from physical address
94 #define PTD(pa) ((uintptr_t)(pa) | PTE_T)
95
96 // Page directory and page table constants
97 #define NPTENTRIES (PGSIZE/sizeof(pte_t))
98
99 // Page table/directory entry flags.
100 #define PTE_T    0x001 // Entry is a page Table descriptor
101 #define PTE_E    0x002 // Entry is a page table Entry
102 #define PTE_R    0x004 // Referenced
103 #define PTE_D    0x008 // Dirty
104 #define PTE_UX   0x010 // User eXecute permission
105 #define PTE_UW   0x020 // User Read permission
106 #define PTE_UR   0x040 // User Write permission
107 #define PTE_SX   0x080 // Supervisor eXecute permission
108 #define PTE_SW   0x100 // Supervisor Read permission
109 #define PTE_SR   0x200 // Supervisor Write permission
110 #define PTE_PERM (PTE_SR | PTE_SW | PTE_SX | PTE_UR | PTE_UW | PTE_UX)
111 #define PTE_PPN_SHIFT 12
112
113 // commly used access modes
114 #define PTE_KERN_RW     (PTE_SR | PTE_SW | PTE_SX)
115 #define PTE_KERN_RO     (PTE_SR | PTE_SX)
116 #define PTE_USER_RW     (PTE_SR | PTE_SW | PTE_UR | PTE_UW | PTE_UX)
117 #define PTE_USER_RO     (PTE_SR | PTE_UR | PTE_UX)
118
119 // x86 equivalencies
120 #define PTE_P      PTE_E
121 #define NPDENTRIES NPTENTRIES
122 #define PDX(la)    L1X(la)                      // for env stuff
123
124 // address in page table entry
125 #define PTE_ADDR(pte)   ((physaddr_t) (pte) & ~(PGSIZE-1))
126
127 // address in page table descriptor
128 #define PTD_ADDR(ptd)   PTE_ADDR(ptd)
129
130 // MMU Control Register flags
131 #define MMU_CR_E        0x00000001      // Protection Enable
132 #define MMU_CR_NF       0x00000002      // No Fault mode
133 #define MMU_CR_PSO      0x00000080      // Partial Store Order (TSO disabled)
134
135 // MMU Fault Status Register flags
136 #define MMU_FSR_USER    0x00000020      // Fault caused by user-space access
137 #define MMU_FSR_EX      0x00000040      // Fault occured in instruction-space
138 #define MMU_FSR_WR      0x00000080      // Fault caused by a store
139
140 // MMU Register Addresses
141 #define MMU_REG_CTRL    0x00000000      // MMU Control Register
142 #define MMU_REG_CTXTBL  0x00000100      // MMU Context Table Pointer Register
143 #define MMU_REG_CTX     0x00000200      // MMU Context Register
144 #define MMU_REG_FSR     0x00000300      // MMU Fault Status Register
145 #define MMU_REG_FAR     0x00000400      // MMU Fault Address Register
146
147 // we must guarantee that for any PTE, exactly one of the following is true
148 #define PAGE_PRESENT(pte) ((pte) & PTE_P)
149 #define PAGE_UNMAPPED(pte) ((pte) == 0)
150 #define PAGE_PAGED_OUT(pte) (!PAGE_PRESENT(pte) && !PAGE_UNMAPPED(pte))
151 #define NOVPT
152
153 #ifndef __ASSEMBLER__
154 typedef unsigned long pte_t;
155 typedef unsigned long pde_t;
156 #endif
157
158 #endif /* ROS_INC_ARCH_MMU_H */