fixes towards risc-v user programs running
[akaros.git] / kern / arch / riscv / mmu.h
1 #ifndef ROS_ARCH_MMU_H
2 #define ROS_ARCH_MMU_H
3
4 /*
5  * This file contains definitions for the RISC-V MMU.
6  */
7
8 #include <ros/arch/mmu.h>
9
10 /*
11  *
12  *      Part 1.  Paging data structures and constants.
13  *
14  */
15
16 // RV64 virtual addresses are 48 bits, sign-extended out to 64 bits,
17 // creating a hole between 0x0000 7FFF FFFF FFFF and 0xFFFF 8000 0000 0000.
18 // Bits 11-0 are the page offset; L1/L2/L3/L4 page table indices are given
19 // by bits 47-39, 38-30, 29-21, and 20-12, respectively.
20 //
21 // In RV32, virtual addresses are 32 bits; bits 11-0 are the page offset;
22 // and L1/L2 page table indices are given by bits 31-22 and 21-12,
23 // respectively.
24 //
25 // In both cases, the last-level page size is 4KB, as is the page table size.
26
27 // page number field of address
28 #define LA2PPN(la)      (((uintptr_t) (la)) >> PGSHIFT)
29
30 // page number field of PPN
31 #define PTE2PPN(pte)    (((uintptr_t) (pte)) >> PTE_PPN_SHIFT)
32
33 // index into L1 PT
34 #define L1X(la)         ((((uintptr_t) (la)) >> L1PGSHIFT) & (NPTENTRIES-1))
35
36 // index into L2 PT
37 #define L2X(la)         ((((uintptr_t) (la)) >> L2PGSHIFT) & (NPTENTRIES-1))
38
39 #ifdef __riscv64
40 // index into L3 PT
41 #define L3X(la)         ((((uintptr_t) (la)) >> L3PGSHIFT) & (NPTENTRIES-1))
42
43 // index into L4 PT
44 #define L4X(la)         ((((uintptr_t) (la)) >> L4PGSHIFT) & (NPTENTRIES-1))
45
46 // construct linear address from indexes and offset
47 #define PGADDR(l1, l2, l3, l4, o) ((uintptr_t) ((l1) << L1PGSHIFT | (l2) << L2PGSHIFT | (l3) << L3PGSHIFT | (l4) << L4PGSHIFT | (o)))
48 #else
49 // construct linear address from indexes and offset
50 #define PGADDR(l1, l2, o) ((uintptr_t) ((l1) << L1PGSHIFT | (l2) << L2PGSHIFT | (o)))
51 #endif
52
53 // offset in page
54 #define PGOFF(la)       (((uintptr_t) (la)) & (PGSIZE-1))
55
56 // construct PTE from PPN and flags
57 #define PTE(ppn, flags) ((ppn) << PTE_PPN_SHIFT | (flags))
58
59 // construct PTD from physical address
60 #define PTD(pa) ((uintptr_t)(pa) | PTE_T)
61
62 // Page directory and page table constants
63 #define NPTENTRIES (PGSIZE/sizeof(pte_t))
64
65 // Page table/directory entry flags.
66 #define PTE_T    0x001 // Entry is a page Table descriptor
67 #define PTE_E    0x002 // Entry is a page table Entry
68 #define PTE_R    0x004 // Referenced
69 #define PTE_D    0x008 // Dirty
70 #define PTE_UX   0x010 // User eXecute permission
71 #define PTE_UW   0x020 // User Read permission
72 #define PTE_UR   0x040 // User Write permission
73 #define PTE_SX   0x080 // Supervisor eXecute permission
74 #define PTE_SW   0x100 // Supervisor Read permission
75 #define PTE_SR   0x200 // Supervisor Write permission
76 #define PTE_PERM (PTE_SR | PTE_SW | PTE_SX | PTE_UR | PTE_UW | PTE_UX)
77 #define PTE_PPN_SHIFT 12
78
79 // commly used access modes
80 #define PTE_KERN_RW     (PTE_SR | PTE_SW | PTE_SX)
81 #define PTE_KERN_RO     (PTE_SR | PTE_SX)
82 #define PTE_USER_RW     (PTE_SR | PTE_SW | PTE_UR | PTE_UW | PTE_UX)
83 #define PTE_USER_RO     (PTE_SR | PTE_UR | PTE_UX)
84
85 // x86 equivalencies
86 #define PTE_P      PTE_E
87 #define NPDENTRIES NPTENTRIES
88 #define PDX(la)    L1X(la)                      // for env stuff
89
90 // address in page table entry
91 #define PTE_ADDR(pte)   ((physaddr_t) (pte) & ~(PGSIZE-1))
92
93 // address in page table descriptor
94 #define PTD_ADDR(ptd)   PTE_ADDR(ptd)
95
96 // MMU Control Register flags
97 #define MMU_CR_E        0x00000001      // Protection Enable
98 #define MMU_CR_NF       0x00000002      // No Fault mode
99 #define MMU_CR_PSO      0x00000080      // Partial Store Order (TSO disabled)
100
101 // MMU Fault Status Register flags
102 #define MMU_FSR_USER    0x00000020      // Fault caused by user-space access
103 #define MMU_FSR_EX      0x00000040      // Fault occured in instruction-space
104 #define MMU_FSR_WR      0x00000080      // Fault caused by a store
105
106 // MMU Register Addresses
107 #define MMU_REG_CTRL    0x00000000      // MMU Control Register
108 #define MMU_REG_CTXTBL  0x00000100      // MMU Context Table Pointer Register
109 #define MMU_REG_CTX     0x00000200      // MMU Context Register
110 #define MMU_REG_FSR     0x00000300      // MMU Fault Status Register
111 #define MMU_REG_FAR     0x00000400      // MMU Fault Address Register
112
113 // we must guarantee that for any PTE, exactly one of the following is true
114 #define PAGE_PRESENT(pte) ((pte) & PTE_P)
115 #define PAGE_UNMAPPED(pte) ((pte) == 0)
116 #define PAGE_PAGED_OUT(pte) (!PAGE_PRESENT(pte) && !PAGE_UNMAPPED(pte))
117
118 #endif /* !ROS_INC_MMU_H */