10c2a92df5f0b5a0f3c05c011887711365c9be84
[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 #endif
44
45 // An Address:
46 //  +--------10------+-------10-------+---------12----------+
47 //  | Page Directory |   Page Table   | Offset within Page  |
48 //  +----------------+----------------+---------------------+
49
50 #define PGSHIFT         12              /* LOG2(NBPG) */
51 #define NBPG            (1 << PGSHIFT)  /* bytes/page */
52
53 /* Page tables (selected by VA[31:22] and indexed by VA[21:12]) */
54 #define PGMASK (NBPG - 1)       /* Mask for page offset.  Terrible name! */
55 #define PGOFS(va) ((va) & PGMASK)
56 /* Page number of virtual page in the virtual page table. */
57 #define PGNO(va) ((uint32_t) (va) >> PGSHIFT)
58 /* Index of PTE for VA within the corresponding page table */
59 #define PTENO(va) (((uint32_t) (va) >> PGSHIFT) & 0x3ff)
60 /* Round up to a page */
61 #define PGROUNDUP(va) (((va) + PGMASK) & ~PGMASK)
62 /* Round down to a page */
63 #define PGROUNDDOWN(va) ((va) & ~PGMASK)
64 /* Page directories (indexed by VA[31:22]) */
65 #define PDSHIFT 22             /* LOG2(NBPD) */
66 #define NBPD (1 << PDSHIFT)    /* bytes/page dir */
67 #define PDMASK (NBPD-1)        /* byte offset into region mapped by
68                                   a page table */
69 #define PDENO(va) ((uint32_t) (va) >> PDSHIFT)
70 /* Round up  */
71 #define PDROUNDUP(va) (((va) + PDMASK) & ~PDMASK)
72 /* Round down */
73 #define PDROUNDDOWN(va) ((va) & ~PDMASK)
74
75 /* At IOPHYSMEM (640K) there is a 384K hole for I/O.  From the kernel,
76  * IOPHYSMEM can be addressed at KERNBASE + IOPHYSMEM.  The hole ends
77  * at physical address EXTPHYSMEM. */
78 #define IOPHYSMEM 0xa0000
79 #define EXTPHYSMEM 0x100000
80
81
82 /*
83  * Virtual memory map:                                Permissions
84  *                                                    kernel/user
85  *
86  *    4 Gig -------->  +------------------------------+
87  *                     |                              | RW/--
88  *                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
89  *                     :              .               :
90  *                     :              .               :
91  *                     :              .               :
92  *                     |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| RW/--
93  *                     |                              | RW/--
94  *                     |  Physical Memory             | RW/--
95  *                     |                              | RW/--
96  *    KERNBASE ----->  +------------------------------+
97  *                     |  Kernel Virtual Page Table   | RW/--   NBPD
98  *    VPT,KSTACKTOP--> +------------------------------+                 --+
99  *                     |        Kernel Stack          | RW/--  KSTKSIZE   |
100  *                     | - - - - - - - - - - - - - - -|                 NBPD
101  *                     |       Invalid memory         | --/--             |
102  *    ULIM     ------> +------------------------------+                 --+
103  *                     |      R/O User VPT            | R-/R-   NBPD
104  *    UVPT      ---->  +------------------------------+
105  *                     |        R/O PPAGE             | R-/R-   NBPD
106  *    UPPAGES   ---->  +------------------------------+
107  *                     |        R/O UENVS             | R-/R-   NBPD
108  * UTOP,UENVS -------> +------------------------------+
109  * UXSTACKTOP -/       |      user exception stack    | RW/RW   NBPG  
110  *                     +------------------------------+
111  *                     |       Invalid memory         | --/--   NBPG
112  *    USTACKTOP  ----> +------------------------------+
113  *                     |     normal user stack        | RW/RW   NBPG
114  *                     +------------------------------+
115  *                     |                              |
116  *                     |                              |
117  *                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118  *                     .                              .
119  *                     .                              .
120  *                     .                              .
121  *                     |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
122  *                     |                              |
123  *    UTEXT ------->   +------------------------------+
124  *                     |                              |  2 * NBPD
125  *    0 ------------>  +------------------------------+
126  */
127
128
129 #define PHYS_BASE       0xc0000000      /* All physical memory mapped here. */
130 #define KERN_BASE       0xc0100000      /* Kernel loaded here. */
131
132 /* Virtual page table.  Last entry of all PDEs contains a pointer to
133  * the PD itself, thereby turning the PD into a page table which
134  * maps all PTEs over the last 4 Megs of the virtual address space */
135 #define VPT (KERNBASE - NBPD)
136 #define KSTACKTOP VPT
137 #define KSTKSIZE (8 * NBPG)             /* size of a kernel stack */
138 #define ULIM (KSTACKTOP - NBPD) 
139
140 /*
141  * User read-only mappings! Anything below here til UTOP are readonly to user.
142  * They are global pages mapped in at env allocation time.
143  */
144
145 /* Same as VPT but read-only for users */
146 #define UVPT (ULIM - NBPD)
147 /* Read-only copies of all ppage structures */
148 #define UPPAGES (UVPT - NBPD)
149 /* Read only copy of the global env structures */
150 #define UENVS (UPPAGES - NBPD)
151
152
153
154 /*
155  * Top of user VM. User can manipulate VA from UTOP-1 and down!
156  */
157 #define UTOP UENVS
158 #define UXSTACKTOP (UTOP)           /* one page user exception stack */
159 /* leave top page invalid to guard against exception stack overflow */ 
160 #define USTACKTOP (UTOP - 2*NBPG)   /* top of the normal user stack */
161 #define UTEXT (2*NBPD)
162
163 /* Number of page tables for mapping physical memory at KERNBASE.
164  * (each PT contains 1K PTE's, for a total of 128 Megabytes mapped) */
165 #define NPPT ((-KERNBASE)>>PDSHIFT)
166
167 #ifndef __ASSEMBLER__
168 #include "debug.h"
169
170 /* Kernel virtual address at which physical address PADDR is
171    mapped. */
172 static inline void *
173 ptov (uint32_t paddr) 
174 {
175   ASSERT (paddr < PHYS_BASE);
176
177   return (void *) (paddr + PHYS_BASE);
178 }
179
180 /* Physical address at which kernel virtual address VADDR is
181    mapped. */
182 static inline uint32_t
183 vtop (void *vaddr) 
184 {
185   ASSERT ((uint32_t) vaddr >= PHYS_BASE);
186
187   return (uint32_t) vaddr - PHYS_BASE;
188 }
189 #endif
190
191 #define PFM_NONE 0x0     /* No page faults expected.  Must be a kernel bug */
192 #define PFM_KILL 0x1     /* On fault kill user process. */
193
194
195 /*
196  * Macros to build GDT entries in assembly.
197  */
198 #define SEG_NULL           \
199         .word 0, 0;        \
200         .byte 0, 0, 0, 0
201 #define SEG(type,base,lim)                                    \
202         .word ((lim)&0xffff), ((base)&0xffff);                \
203         .byte (((base)>>16)&0xff), (0x90|(type)),             \
204                 (0xc0|(((lim)>>16)&0xf)), (((base)>>24)&0xff)
205
206
207
208 /* Page Table/Directory Entry flags
209  *   these are defined by the hardware
210  */
211 #define PG_P 0x1               /* Present */
212 #define PG_W 0x2               /* Writeable */
213 #define PG_U 0x4               /* User */
214 #define PG_PWT 0x8             /* Write-Through */
215 #define PG_PCD 0x10            /* Cache-Disable */
216 #define PG_A 0x20              /* Accessed */
217 #define PG_D 0x40              /* Dirty */
218 #define PG_PS 0x80             /* Page Size */
219 #define PG_MBZ 0x180           /* Bits must be zero */
220 #define PG_USER 0xe00          /* Bits for user processes */
221 /*
222  * The PG_USER bits are not used by the kernel and they are
223  * not interpreted by the hardware.  The kernel allows 
224  * user processes to set them arbitrarily.
225  */
226
227
228
229 /* Control Register flags */
230 #define CR0_PE 0x1             /* Protection Enable */
231 #define CR0_MP 0x2             /* Monitor coProcessor */
232 #define CR0_EM 0x4             /* Emulation */
233 #define CR0_TS 0x8             /* Task Switched */
234 #define CR0_ET 0x10            /* Extension Type */
235 #define CR0_NE 0x20            /* Numeric Errror */
236 #define CR0_WP 0x10000         /* Write Protect */
237 #define CR0_AM 0x40000         /* Alignment Mask */
238 #define CR0_NW 0x20000000      /* Not Writethrough */
239 #define CR0_CD 0x40000000      /* Cache Disable */
240 #define CR0_PG 0x80000000      /* Paging */
241
242 #define CR4_PCE 0x100          /* Performance counter enable */
243 #define CR4_MCE 0x40           /* Machine Check Enable */
244 #define CR4_PSE 0x10           /* Page Size Extensions */
245 #define CR4_DE  0x08           /* Debugging Extensions */
246 #define CR4_TSD 0x04           /* Time Stamp Disable */
247 #define CR4_PVI 0x02           /* Protected-Mode Virtual Interrupts */
248 #define CR4_VME 0x01           /* V86 Mode Extensions */
249
250 /* EFLAGS Register. */
251 #define FLAG_CF   0x00000001    /* Carry Flag. */
252 #define FLAG_PF   0x00000004    /* Parity Flag. */
253 #define FLAG_AF   0x00000010    /* Auxiliary Carry Flag. */
254 #define FLAG_ZF   0x00000040    /* Zero Flag. */
255 #define FLAG_SF   0x00000080    /* Sign Flag. */
256 #define FLAG_TF   0x00000100    /* Trap Flag. */
257 #define FLAG_IF   0x00000200    /* Interrupt Flag. */
258 #define FLAG_DF   0x00000400    /* Direction Flag. */
259 #define FLAG_OF   0x00000800    /* Overflow Flag. */
260 #define FLAG_IOPL 0x00003000    /* I/O Privilege Level (2 bits). */
261 #define FLAG_IOPL_SHIFT 12
262 #define FLAG_NT   0x00004000    /* Nested Task. */
263 #define FLAG_RF   0x00010000    /* Resume Flag. */
264 #define FLAG_VM   0x00020000    /* Virtual 8086 Mode. */
265 #define FLAG_AC   0x00040000    /* Alignment Check. */
266 #define FLAG_VIF  0x00080000    /* Virtual Interrupt Flag. */
267 #define FLAG_VIP  0x00100000    /* Virtual Interrupt Pending. */
268 #define FLAG_ID   0x00200000    /* ID Flag. */
269
270 /* Page fault error codes */
271 #define FEC_PR 0x1             /* Page fault caused by protection violation */
272 #define FEC_WR 0x2             /* Page fault caused by a write */
273 #define FEC_U  0x4             /* Page fault occured while in user mode */
274
275
276 /* Application segment type bits */
277 #define STA_X 0x8              /* Executable segment */
278 #define STA_A 0x1              /* Accessed */
279
280 #define STA_C 0x4              /* Conforming code segment (executable only) */
281 #define STA_R 0x2              /* Readable (executable segments) */
282
283 #define STA_E 0x4              /* Expand down (non-executable segments) */
284 #define STA_W 0x2              /* Writeable (non-executable segments) */
285
286
287 /* Segment selectors. */
288 #define SEL_NULL        0x00    /* Null selector. */
289 #define SEL_KCSEG       0x08    /* Kernel code selector. */
290 #define SEL_KDSEG       0x10    /* Kernel data selector. */
291 #define SEL_UCSEG       0x18    /* Kernel code selector. */
292 #define SEL_UDSEG       0x20    /* Kernel data selector. */
293 #define SEL_TSS         0x28    /* Task-state segment. */
294 #define SEL_CNT         6       /* Number of segments. */
295
296 #ifndef __ASSEMBLER__
297 struct tss
298   {
299     uint16_t back_link, :16;
300     uint32_t esp0;
301     uint16_t ss0, :16;
302     uint32_t esp1;
303     uint16_t ss1, :16;
304     uint32_t esp2;
305     uint16_t ss2, :16;
306     uint32_t cr3;
307     uint32_t eip;
308     uint32_t eflags;
309     uint32_t eax, ecx, edx, ebx;
310     uint32_t esp, ebp, esi, edi;
311     uint16_t es, :16;
312     uint16_t cs, :16;
313     uint16_t ss, :16;
314     uint16_t ds, :16;
315     uint16_t fs, :16;
316     uint16_t gs, :16;
317     uint16_t ldt, :16;
318     uint16_t trace, bitmap;
319   };
320
321 enum seg_system
322   {
323     SYS_SYSTEM = 0,             /* System segment. */
324     SYS_CODE_DATA = 1           /* Code or data segment. */
325   };
326
327 enum seg_granularity
328   {
329     GRAN_BYTE = 0,              /* Limit has 1-byte granularity. */
330     GRAN_PAGE = 1               /* Limit has 4 kB granularity. */
331   };
332
333 enum seg_type
334   {
335     /* System segment types. */
336     TYPE_TSS_16_A = 1,          /* 16-bit TSS (available). */
337     TYPE_LDT = 2,               /* LDT. */
338     TYPE_TSS_16_B = 3,          /* 16-bit TSS (busy). */
339     TYPE_CALL_16 = 4,           /* 16-bit call gate. */
340     TYPE_TASK = 5,              /* Task gate. */
341     TYPE_INT_16 = 6,            /* 16-bit interrupt gate. */
342     TYPE_TRAP_16 = 7,           /* 16-bit trap gate. */
343     TYPE_TSS_32_A = 9,          /* 32-bit TSS (available). */
344     TYPE_TSS_32_B = 11,         /* 32-bit TSS (busy). */
345     TYPE_CALL_32 = 12,          /* 32-bit call gate. */
346     TYPE_INT_32 = 14,           /* 32-bit interrupt gate. */
347     TYPE_TRAP_32 = 15,          /* 32-bit trap gate. */
348
349     /* Code/data segment types. */
350     TYPE_CODE = 8,              /* 1=Code segment, 0=data segment. */
351     TYPE_ACCESSED = 1,          /* Set if accessed. */
352
353     /* Data segment types. */
354     TYPE_EXPAND_DOWN = 4,       /* 1=Expands up, 0=expands down. */
355     TYPE_WRITABLE = 2,          /* 1=Read/write, 0=read-only. */
356
357     /* Code segment types. */
358     TYPE_CONFORMING = 4,        /* 1=Conforming, 0=nonconforming. */
359     TYPE_READABLE = 2           /* 1=Exec/read, 0=exec-only. */
360   };
361
362 static inline uint64_t
363 make_dtr_operand (uint16_t limit, void *base)
364 {
365   return limit | ((uint64_t) (uint32_t) base << 16);
366 }
367 #endif
368
369 #endif /* !_MMU_H_ */