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