Improve mmu.h.
[pintos-anon] / src / threads / mmu.h
1 /*
2  * Copyright (C) 1997 Massachusetts Institute of Technology 
3  *
4  * This software is being provided by the copyright holders under the
5  * following license. By obtaining, using and/or copying this software,
6  * you agree that you have read, understood, and will comply with the
7  * following terms and conditions:
8  *
9  * Permission to use, copy, modify, distribute, and sell this software
10  * and its documentation for any purpose and without fee or royalty is
11  * hereby granted, provided that the full text of this NOTICE appears on
12  * ALL copies of the software and documentation or portions thereof,
13  * including modifications, that you make.
14  *
15  * THIS SOFTWARE IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO
16  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE,
17  * BUT NOT LIMITATION, COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR
18  * WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR
19  * THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY
20  * THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. COPYRIGHT
21  * HOLDERS WILL BEAR NO LIABILITY FOR ANY USE OF THIS SOFTWARE OR
22  * DOCUMENTATION.
23  *
24  * The name and trademarks of copyright holders may NOT be used in
25  * advertising or publicity pertaining to the software without specific,
26  * written prior permission. Title to copyright in this software and any
27  * associated documentation will at all times remain with copyright
28  * holders. See the file AUTHORS which should have accompanied this software
29  * for a list of all copyright holders.
30  *
31  * This file may be derived from previously copyrighted software. This
32  * copyright applies only to those changes made by the copyright
33  * holders listed in the AUTHORS file. The rest of this file is covered by
34  * the copyright notices, if any, listed below.
35  */
36
37
38 #ifndef _MMU_H_
39 #define _MMU_H_
40
41 #ifndef __ASSEMBLER__
42 #include <stdint.h>
43 #include "debug.h"
44 #endif
45
46 #define MASK(SHIFT, CNT) (((1ul << (CNT)) - 1) << (SHIFT))
47
48 /* Page offset (bits 0:11). */
49 #define PGSHIFT         0                  /* First offset bit. */
50 #define PGBITS          12                 /* Number of offset bits. */
51 #define PGMASK          MASK(PGSHIFT, PGBITS)
52 #define PGSIZE          (1 << PGBITS)
53
54 /* Page table (bits 12:21). */
55 #define PTSHIFT         PGBITS             /* First page table bit. */
56 #define PTBITS          10                 /* Number of page table bits. */
57 #define PTMASK          MASK(PTSHIFT, PTBITS)
58
59 /* Page directory (bits 22:31). */
60 #define PDSHIFT         (PTSHIFT + PTBITS) /* First page dir bit. */
61 #define PDBITS          10                 /* Number of page dir bits. */
62 #define PDMASK          MASK(PDSHIFT, PDBITS)
63
64 #ifndef __ASSEMBLER__
65 /* Offset within a page. */
66 static inline unsigned pg_ofs (void *va) { return (uintptr_t) va & PGMASK; }
67
68 /* Page number. */
69 static inline uintptr_t pg_no (void *va) { return (uintptr_t) va >> PTSHIFT; }
70
71 /* Page table number. */
72 static inline unsigned pt_no (void *va) {
73   return ((uintptr_t) va & PTMASK) >> PTSHIFT;
74 }
75
76 /* Page directory number. */
77 static inline uintptr_t pd_no (void *va) { return (uintptr_t) va >> PDSHIFT; }
78
79 /* Round up to nearest page boundary. */
80 static inline void *pg_round_up (void *va) {
81   return (void *) (((uintptr_t) va + PGSIZE - 1) & ~PGMASK);
82 }
83
84 /* Round down to nearest page boundary. */
85 static inline void *pg_round_down (void *va) {
86   return (void *) ((uintptr_t) va & ~PGMASK);
87 }
88
89 #define PHYS_BASE ((void *) 0xc0000000) /* Physical memory mapped here. */
90 #define KERN_BASE ((void *) 0xc0100000) /* Kernel loaded here. */
91
92 /* Returns kernel virtual address at which physical address PADDR
93    is mapped. */
94 static inline void *
95 ptov (uintptr_t paddr) 
96 {
97   ASSERT ((void *) paddr < PHYS_BASE);
98
99   return (void *) (paddr + PHYS_BASE);
100 }
101
102 /* Returns physical address at which kernel virtual address VADDR
103    is mapped. */
104 static inline uintptr_t
105 vtop (void *vaddr) 
106 {
107   ASSERT (vaddr >= PHYS_BASE);
108
109   return (uintptr_t) vaddr - (uintptr_t) PHYS_BASE;
110 }
111 #endif
112
113 /* Page Table/Directory Entry flags
114  *   these are defined by the hardware
115  */
116 #define PG_P 0x1               /* Present */
117 #define PG_W 0x2               /* Writeable */
118 #define PG_U 0x4               /* User */
119 #define PG_PWT 0x8             /* Write-Through */
120 #define PG_PCD 0x10            /* Cache-Disable */
121 #define PG_A 0x20              /* Accessed */
122 #define PG_D 0x40              /* Dirty */
123 #define PG_PS 0x80             /* Page Size */
124 #define PG_MBZ 0x180           /* Bits must be zero */
125 #define PG_USER 0xe00          /* Bits for user processes */
126 /*
127  * The PG_USER bits are not used by the kernel and they are
128  * not interpreted by the hardware.  The kernel allows 
129  * user processes to set them arbitrarily.
130  */
131
132
133
134 /* Control Register flags */
135 #define CR0_PE 0x1             /* Protection Enable */
136 #define CR0_MP 0x2             /* Monitor coProcessor */
137 #define CR0_EM 0x4             /* Emulation */
138 #define CR0_TS 0x8             /* Task Switched */
139 #define CR0_ET 0x10            /* Extension Type */
140 #define CR0_NE 0x20            /* Numeric Errror */
141 #define CR0_WP 0x10000         /* Write Protect */
142 #define CR0_AM 0x40000         /* Alignment Mask */
143 #define CR0_NW 0x20000000      /* Not Writethrough */
144 #define CR0_CD 0x40000000      /* Cache Disable */
145 #define CR0_PG 0x80000000      /* Paging */
146
147 #define CR4_PCE 0x100          /* Performance counter enable */
148 #define CR4_MCE 0x40           /* Machine Check Enable */
149 #define CR4_PSE 0x10           /* Page Size Extensions */
150 #define CR4_DE  0x08           /* Debugging Extensions */
151 #define CR4_TSD 0x04           /* Time Stamp Disable */
152 #define CR4_PVI 0x02           /* Protected-Mode Virtual Interrupts */
153 #define CR4_VME 0x01           /* V86 Mode Extensions */
154
155 /* EFLAGS Register. */
156 #define FLAG_CF   0x00000001    /* Carry Flag. */
157 #define FLAG_PF   0x00000004    /* Parity Flag. */
158 #define FLAG_AF   0x00000010    /* Auxiliary Carry Flag. */
159 #define FLAG_ZF   0x00000040    /* Zero Flag. */
160 #define FLAG_SF   0x00000080    /* Sign Flag. */
161 #define FLAG_TF   0x00000100    /* Trap Flag. */
162 #define FLAG_IF   0x00000200    /* Interrupt Flag. */
163 #define FLAG_DF   0x00000400    /* Direction Flag. */
164 #define FLAG_OF   0x00000800    /* Overflow Flag. */
165 #define FLAG_IOPL 0x00003000    /* I/O Privilege Level (2 bits). */
166 #define FLAG_IOPL_SHIFT 12
167 #define FLAG_NT   0x00004000    /* Nested Task. */
168 #define FLAG_RF   0x00010000    /* Resume Flag. */
169 #define FLAG_VM   0x00020000    /* Virtual 8086 Mode. */
170 #define FLAG_AC   0x00040000    /* Alignment Check. */
171 #define FLAG_VIF  0x00080000    /* Virtual Interrupt Flag. */
172 #define FLAG_VIP  0x00100000    /* Virtual Interrupt Pending. */
173 #define FLAG_ID   0x00200000    /* ID Flag. */
174
175 /* Page fault error codes */
176 #define FEC_PR 0x1             /* Page fault caused by protection violation */
177 #define FEC_WR 0x2             /* Page fault caused by a write */
178 #define FEC_U  0x4             /* Page fault occured while in user mode */
179
180
181 /* Application segment type bits */
182 #define STA_X 0x8              /* Executable segment */
183 #define STA_A 0x1              /* Accessed */
184
185 #define STA_C 0x4              /* Conforming code segment (executable only) */
186 #define STA_R 0x2              /* Readable (executable segments) */
187
188 #define STA_E 0x4              /* Expand down (non-executable segments) */
189 #define STA_W 0x2              /* Writeable (non-executable segments) */
190
191
192 /* Segment selectors. */
193 #define SEL_NULL        0x00    /* Null selector. */
194 #define SEL_KCSEG       0x08    /* Kernel code selector. */
195 #define SEL_KDSEG       0x10    /* Kernel data selector. */
196 #define SEL_UCSEG       0x18    /* Kernel code selector. */
197 #define SEL_UDSEG       0x20    /* Kernel data selector. */
198 #define SEL_TSS         0x28    /* Task-state segment. */
199 #define SEL_CNT         6       /* Number of segments. */
200
201 #ifndef __ASSEMBLER__
202 struct tss
203   {
204     uint16_t back_link, :16;
205     uint32_t esp0;
206     uint16_t ss0, :16;
207     uint32_t esp1;
208     uint16_t ss1, :16;
209     uint32_t esp2;
210     uint16_t ss2, :16;
211     uint32_t cr3;
212     uint32_t eip;
213     uint32_t eflags;
214     uint32_t eax, ecx, edx, ebx;
215     uint32_t esp, ebp, esi, edi;
216     uint16_t es, :16;
217     uint16_t cs, :16;
218     uint16_t ss, :16;
219     uint16_t ds, :16;
220     uint16_t fs, :16;
221     uint16_t gs, :16;
222     uint16_t ldt, :16;
223     uint16_t trace, bitmap;
224   };
225
226 enum seg_system
227   {
228     SYS_SYSTEM = 0,             /* System segment. */
229     SYS_CODE_DATA = 1           /* Code or data segment. */
230   };
231
232 enum seg_granularity
233   {
234     GRAN_BYTE = 0,              /* Limit has 1-byte granularity. */
235     GRAN_PAGE = 1               /* Limit has 4 kB granularity. */
236   };
237
238 enum seg_type
239   {
240     /* System segment types. */
241     TYPE_TSS_16_A = 1,          /* 16-bit TSS (available). */
242     TYPE_LDT = 2,               /* LDT. */
243     TYPE_TSS_16_B = 3,          /* 16-bit TSS (busy). */
244     TYPE_CALL_16 = 4,           /* 16-bit call gate. */
245     TYPE_TASK = 5,              /* Task gate. */
246     TYPE_INT_16 = 6,            /* 16-bit interrupt gate. */
247     TYPE_TRAP_16 = 7,           /* 16-bit trap gate. */
248     TYPE_TSS_32_A = 9,          /* 32-bit TSS (available). */
249     TYPE_TSS_32_B = 11,         /* 32-bit TSS (busy). */
250     TYPE_CALL_32 = 12,          /* 32-bit call gate. */
251     TYPE_INT_32 = 14,           /* 32-bit interrupt gate. */
252     TYPE_TRAP_32 = 15,          /* 32-bit trap gate. */
253
254     /* Code/data segment types. */
255     TYPE_CODE = 8,              /* 1=Code segment, 0=data segment. */
256     TYPE_ACCESSED = 1,          /* Set if accessed. */
257
258     /* Data segment types. */
259     TYPE_EXPAND_DOWN = 4,       /* 1=Expands up, 0=expands down. */
260     TYPE_WRITABLE = 2,          /* 1=Read/write, 0=read-only. */
261
262     /* Code segment types. */
263     TYPE_CONFORMING = 4,        /* 1=Conforming, 0=nonconforming. */
264     TYPE_READABLE = 2           /* 1=Exec/read, 0=exec-only. */
265   };
266
267 static inline uint64_t
268 make_dtr_operand (uint16_t limit, void *base)
269 {
270   return limit | ((uint64_t) (uint32_t) base << 16);
271 }
272 #endif
273
274 #endif /* !_MMU_H_ */