4d6cec11d5a39181ef07ed5c328fe90ae84c656a
[akaros.git] / kern / arch / i686 / ros / mmu.h
1 #ifndef _ROS_INC_ARCH_MMU_H
2 #define _ROS_INC_ARCH_MMU_H
3
4 #ifndef __ASSEMBLER__
5 typedef unsigned long pte_t;
6 typedef unsigned long pde_t;
7 #endif
8
9 // All physical memory mapped at this address
10 #define KERNBASE        0xC0000000
11
12 // Use this if needed in annotations
13 #define IVY_KERNBASE (0xC000U << 16)
14
15 #define PTSHIFT 22
16 #define PTSIZE (1 << PTSHIFT)
17
18 #define PGSHIFT 12
19 #define PGSIZE (1 << PGSHIFT)
20
21 #define JPGSIZE PTSIZE
22
23
24 /* Segment descriptor and macros temporarily here.  Remove them when fixing x86
25  * TLS vulns (TLSV) */
26
27 // Global descriptor numbers
28 #define GD_NULL   0x00     // NULL descriptor
29 #define GD_KT     0x08     // kernel text
30 #define GD_KD     0x10     // kernel data
31 #define GD_UT     0x18     // user text
32 #define GD_UD     0x20     // user data
33 #define GD_TSS    0x28     // Task segment selector
34 #define GD_LDT    0x30     // local descriptor table
35
36 #ifdef __ASSEMBLER__
37
38 /*
39  * Macros to build GDT entries in assembly.
40  */
41 #define SEG_NULL                                                \
42         .word 0, 0;                                             \
43         .byte 0, 0, 0, 0
44 #define SEG(type,base,lim)                                      \
45         .word (((lim) >> 12) & 0xffff), ((base) & 0xffff);      \
46         .byte (((base) >> 16) & 0xff), (0x90 | (type)),         \
47                 (0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
48
49 #else   // not __ASSEMBLER__
50
51 #include <ros/common.h>
52
53 // Segment Descriptors
54 typedef struct Segdesc {
55         unsigned sd_lim_15_0 : 16;  // Low bits of segment limit
56         unsigned sd_base_15_0 : 16; // Low bits of segment base address
57         unsigned sd_base_23_16 : 8; // Middle bits of segment base address
58         unsigned sd_type : 4;       // Segment type (see STS_ constants)
59         unsigned sd_s : 1;          // 0 = system, 1 = application
60         unsigned sd_dpl : 2;        // Descriptor Privilege Level
61         unsigned sd_p : 1;          // Present
62         unsigned sd_lim_19_16 : 4;  // High bits of segment limit
63         unsigned sd_avl : 1;        // Unused (available for software use)
64         unsigned sd_rsv1 : 1;       // Reserved
65         unsigned sd_db : 1;         // 0 = 16-bit segment, 1 = 32-bit segment
66         unsigned sd_g : 1;          // Granularity: limit scaled by 4K when set
67         unsigned sd_base_31_24 : 8; // High bits of segment base address
68 } segdesc_t;
69 // Null segment
70 #define SEG_NULL        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
71 // Segment that is loadable but faults when used
72 #define SEG_FAULT       { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 }
73 // Normal segment
74 #define SEG(type, base, lim, dpl)                                                                       \
75 { ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,       \
76     type, 1, dpl, 1, (unsigned) (lim) >> 28, 0, 0, 1, 1,                        \
77     (unsigned) (base) >> 24 }
78 // System segment (LDT)
79 #define SEG_SYS(type, base, lim, dpl)                                                                   \
80 { ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,       \
81     type, 0, dpl, 1, (unsigned) (lim) >> 28, 0, 0, 1, 1,                        \
82     (unsigned) (base) >> 24 }
83
84 #define SEG16(type, base, lim, dpl)                                                             \
85 { (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,                       \
86     type, 1, dpl, 1, (unsigned) (lim) >> 16, 0, 0, 1, 0,                        \
87     (unsigned) (base) >> 24 }
88
89 #define SEG16ROINIT(seg,type,base,lim,dpl) \
90         {\
91                 (seg).sd_lim_15_0 = SINIT((lim) & 0xffff);\
92                 (seg).sd_base_15_0 = SINIT((base)&0xffff);\
93                 (seg).sd_base_23_16 = SINIT(((base)>>16)&0xff);\
94                 (seg).sd_type = SINIT(type);\
95                 (seg).sd_s = SINIT(1);\
96                 (seg).sd_dpl = SINIT(dpl);\
97                 (seg).sd_p = SINIT(1);\
98                 (seg).sd_lim_19_16 = SINIT((unsigned)(lim)>>16);\
99                 (seg).sd_avl = SINIT(0);\
100                 (seg).sd_rsv1 = SINIT(0);\
101                 (seg).sd_db = SINIT(1);\
102                 (seg).sd_g = SINIT(0);\
103                 (seg).sd_base_31_24 = SINIT((unsigned)(base)>> 24);\
104         }
105
106 #endif /* !__ASSEMBLER__ */
107
108 // Application segment type bits
109 #define STA_X           0x8         // Executable segment
110 #define STA_E           0x4         // Expand down (non-executable segments)
111 #define STA_C           0x4         // Conforming code segment (executable only)
112 #define STA_W           0x2         // Writeable (non-executable segments)
113 #define STA_R           0x2         // Readable (executable segments)
114 #define STA_A           0x1         // Accessed
115
116 // System segment type bits
117 #define STS_T16A        0x1         // Available 16-bit TSS
118 #define STS_LDT         0x2         // Local Descriptor Table
119 #define STS_T16B        0x3         // Busy 16-bit TSS
120 #define STS_CG16        0x4         // 16-bit Call Gate
121 #define STS_TG          0x5         // Task Gate / Coum Transmitions
122 #define STS_IG16        0x6         // 16-bit Interrupt Gate
123 #define STS_TG16        0x7         // 16-bit Trap Gate
124 #define STS_T32A        0x9         // Available 32-bit TSS
125 #define STS_T32B        0xB         // Busy 32-bit TSS
126 #define STS_CG32        0xC         // 32-bit Call Gate
127 #define STS_IG32        0xE         // 32-bit Interrupt Gate
128 #define STS_TG32        0xF         // 32-bit Trap Gate
129
130 #define SEG_COUNT       7               // Number of segments in the steady state
131 #define LDT_SIZE        (8192 * sizeof(segdesc_t))
132
133 #endif /* !ROS_INC_ARCH_MMU_H */