unbroke sparc front-end server protocol
[akaros.git] / kern / arch / sparc / mmu.h
1 #ifndef ROS_INC_MMU_H
2 #define ROS_INC_MMU_H
3
4 /*
5  * This file contains definitions for the x86 memory management unit (MMU),
6  * including paging- and segmentation-related data structures and constants,
7  * the %cr0, %cr4, and %eflags registers, and traps.
8  */
9
10 /*
11  *
12  *      Part 1.  Paging data structures and constants.
13  *
14  */
15
16 // A linear address 'la' has a four-part structure as follows:
17 //
18 // +--------8--------+------6------+------6------+-----------12----------+
19 // |  L1 Page Table  |    L2 PT    |    L3 PT    |  Offset within Page   |
20 // |      Index      |    Index    |    Index    |                       |
21 // +-----------------+-------------+-------------+-----------------------+
22 //  \--- L1X(la) --/  \- L2X(la) -/ \- L3X(la) -/ \----- PGOFF(la) -----/
23 //  \----------- PPN(la) -----------------------/
24 //
25 // The L1X, L2X, L3X, PGOFF, and PPN macros decompose linear addresses
26 // as shown.  To construct a linear address la from L1X(la), L2X(la),
27 // and PGOFF(la), use PGADDR(L1X(la), L2X(la), L3X(la), PGOFF(la)).
28
29 // page number field of address
30 #define PPN(la)         (((uintptr_t) (la)) >> L3PGSHIFT)
31
32 // index into L1 PT
33 #define L1X(la)         ((((uintptr_t) (la)) >> L1PGSHIFT) & 0xFF)
34
35 // index into L2 PT
36 #define L2X(la)         ((((uintptr_t) (la)) >> L2PGSHIFT) & 0x3F)
37
38 // index into L3 PT
39 #define L3X(la)         ((((uintptr_t) (la)) >> L3PGSHIFT) & 0x3F)
40
41 // offset in page
42 #define PGOFF(la)       (((uintptr_t) (la)) & 0xFFF)
43
44 // construct linear address from indexes and offset
45 #define PGADDR(l1, l2, l3, o) ((void*SNT) ((l1) << L1PGSHIFT | (l2) << L2PGSHIFT | (l3) << L3PGSHIFT | (o)))
46
47 // construct PTE from PPN and flags
48 #define PTE(ppn, flags) ((ppn) << 8 | (flags))
49
50 // construct PTD from physical address
51 #define PTD(pa) ((pa) >> 4 | PTE_PTD)
52
53 // Number of L1 page tables (contexts) the MMU can store at any time
54 #define NCONTEXTS       8
55
56 // Page directory and page table constants.
57 #define NL3ENTRIES      64              // # entries in an L3 page table
58 #define NL2ENTRIES      64              // # entries in an L2 page table
59 #define NL1ENTRIES      256             // # entries in an L1 page table
60
61 #define L3PGSIZE        4096            // bytes mapped by an L3 page
62 #define L3PGSHIFT       12              // log2(L3PGSIZE)
63
64 #define L2PGSIZE        (4096*64)       // bytes mapped by an L2 page
65 #define L2PGSHIFT       (12+6)          // log2(L2PGSIZE)
66
67 #define L1PGSIZE        (4096*64*64)    // bytes mapped by an L1 page
68 #define L1PGSHIFT       (12+6+6)        // log2(L1PGSIZE)
69
70 // The only page size we actually support for now is L3
71 #define PGSIZE          L3PGSIZE
72 #define PGSHIFT         L3PGSHIFT
73
74 // Page table/directory entry flags.
75 #define PTE_PTD         0x001   // Entry is a Page Table Descriptor
76 #define PTE_PTE         0x002   // Entry is a Page Table Entry
77 #define PTE_R           0x020   // Referenced
78 #define PTE_M           0x040   // Modified
79 #define PTE_C           0x080   // Cacheable
80
81 // commly used access modes
82 #define PTE_KERN_RW     (7 << 2)                // Kernel Read/Write
83 #define PTE_KERN_RO     (6 << 2)                // Kernel Read-Only
84 #define PTE_USER_RW     (3 << 2)                // Kernel/User Read/Write
85 #define PTE_USER_RO     (2 << 2)                // Kernel/User Read-Only
86
87 // x86 equivalencies
88 #define PTE_P           PTE_PTE                 // present <=> PTE
89 #define PTSIZE          L1PGSIZE                // dunno yet
90 #define NPDENTRIES      NL1ENTRIES              // this either
91 #define PDX(la)         L1X(la)                 // for env stuff
92 #define PTX(la)         L3X(la)                 // same
93
94 #define PTE_ACC(PTE)    (((PTE) & 0x1C) >> 2)   // Access bits
95
96 // based upon PTE and Supervisor bit, can I read/write/execute this page?
97 #define PTE_RD(PTE,S)   (PTE_ACC(PTE) != 4 && (PTE_ACC(PTE) < 6 || (S)))
98 #define PTE_WR(PTE,S)   ((PTE_ACC(PTE) & 0x1) && (PTE_ACC(PTE) < 4 || (S)))
99 #define PTE_EX(PTE,S)   (PTE_ACC(PTE) == 4 || (PTE_ACC(PTE) & 0x2) && (PTE_ACC(PTE) < 4 || (S)))
100
101 // +-----+-------------------+
102 // |     |   Allowed Access  |
103 // | ACC +------+------------+
104 // |     | User | Supervisor |
105 // +-----+------+------------+
106 // |  0  |  R-- |  R--       |
107 // |  1  |  RW- |  RW-       |
108 // |  2  |  R-X |  R-X       |
109 // |  3  |  RWX |  RWX       |
110 // |  4  |  --X |  --X       |
111 // |  5  |  R-- |  RW-       |
112 // |  6  |  --- |  R-X       |
113 // |  7  |  --- |  RWX       |
114 // +-----+------+------------+
115
116 // address in page table entry
117 #define PTE_ADDR(pte)   (((physaddr_t) (pte) & ~0xFF) << 4)
118
119 // address in page table descriptor
120 #define PTD_ADDR(ptd)   (((physaddr_t) (ptd) & ~0x3) << 4)
121
122 // MMU Control Register flags
123 #define MMU_CR_E        0x00000001      // Protection Enable
124 #define MMU_CR_NF       0x00000002      // No Fault mode
125 #define MMU_CR_PSO      0x00000080      // Partial Store Order (TSO disabled)
126
127 // MMU Fault Status Register flags
128 #define MMU_FSR_USER    0x00000020      // Fault caused by user-space access
129 #define MMU_FSR_EX      0x00000040      // Fault occured in instruction-space
130 #define MMU_FSR_WR      0x00000080      // Fault caused by a store
131
132 // MMU Register Addresses
133 #define MMU_REG_CTRL    0x00000000      // MMU Control Register
134 #define MMU_REG_CTXTBL  0x00000100      // MMU Context Table Pointer Register
135 #define MMU_REG_CTX     0x00000200      // MMU Context Register
136 #define MMU_REG_FSR     0x00000300      // MMU Fault Status Register
137 #define MMU_REG_FAR     0x00000400      // MMU Fault Address Register
138
139 #endif /* !ROS_INC_MMU_H */