2 * Copyright (C) 1997 Massachusetts Institute of Technology
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:
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.
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
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.
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.
46 // +--------10------+-------10-------+---------12----------+
47 // | Page Directory | Page Table | Offset within Page |
48 // +----------------+----------------+---------------------+
50 #define PGSHIFT 12 /* LOG2(NBPG) */
51 #define NBPG (1 << PGSHIFT) /* bytes/page */
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
69 #define PDENO(va) ((uint32_t) (va) >> PDSHIFT)
71 #define PDROUNDUP(va) (((va) + PDMASK) & ~PDMASK)
73 #define PDROUNDDOWN(va) ((va) & ~PDMASK)
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
83 * Virtual memory map: Permissions
86 * 4 Gig --------> +------------------------------+
88 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
92 * |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| RW/--
94 * | Physical Memory | 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 * +------------------------------+
117 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
121 * |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
123 * UTEXT -------> +------------------------------+
125 * 0 ------------> +------------------------------+
129 #define PHYS_BASE 0xc0000000 /* All physical memory mapped here. */
130 #define KERN_BASE 0xc0100000 /* Kernel loaded here. */
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)
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.
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)
155 * Top of user VM. User can manipulate VA from UTOP-1 and down!
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)
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)
167 #ifndef __ASSEMBLER__
170 /* Kernel virtual address at which physical address PADDR is
173 ptov (uint32_t paddr)
175 ASSERT (paddr < PHYS_BASE);
177 return (void *) (paddr + PHYS_BASE);
180 /* Physical address at which kernel virtual address VADDR is
182 static inline uint32_t
185 ASSERT ((uint32_t) vaddr >= PHYS_BASE);
187 return (uint32_t) vaddr - PHYS_BASE;
191 #define PFM_NONE 0x0 /* No page faults expected. Must be a kernel bug */
192 #define PFM_KILL 0x1 /* On fault kill user process. */
196 * Macros to build GDT entries in assembly.
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)
208 /* Page Table/Directory Entry flags
209 * these are defined by the hardware
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 */
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.
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 */
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 */
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. */
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 */
276 /* Application segment type bits */
277 #define STA_X 0x8 /* Executable segment */
278 #define STA_A 0x1 /* Accessed */
280 #define STA_C 0x4 /* Conforming code segment (executable only) */
281 #define STA_R 0x2 /* Readable (executable segments) */
283 #define STA_E 0x4 /* Expand down (non-executable segments) */
284 #define STA_W 0x2 /* Writeable (non-executable segments) */
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. */
296 #ifndef __ASSEMBLER__
299 uint16_t back_link, :16;
309 uint32_t eax, ecx, edx, ebx;
310 uint32_t esp, ebp, esi, edi;
318 uint16_t trace, bitmap;
323 SYS_SYSTEM = 0, /* System segment. */
324 SYS_CODE_DATA = 1 /* Code or data segment. */
329 GRAN_BYTE = 0, /* Limit has 1-byte granularity. */
330 GRAN_PAGE = 1 /* Limit has 4 kB granularity. */
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. */
349 /* Code/data segment types. */
350 TYPE_CODE = 8, /* 1=Code segment, 0=data segment. */
351 TYPE_ACCESSED = 1, /* Set if accessed. */
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. */
357 /* Code segment types. */
358 TYPE_CONFORMING = 4, /* 1=Conforming, 0=nonconforming. */
359 TYPE_READABLE = 2 /* 1=Exec/read, 0=exec-only. */
362 static inline uint64_t
363 make_dtr_operand (uint16_t limit, void *base)
365 return limit | ((uint64_t) (uint32_t) base << 16);
369 #endif /* !_MMU_H_ */