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.
48 #define MASK(SHIFT, CNT) (((1ul << (CNT)) - 1) << (SHIFT))
50 /* Page offset (bits 0:11). */
51 #define PGSHIFT 0 /* First offset bit. */
52 #define PGBITS 12 /* Number of offset bits. */
53 #define PGMASK MASK(PGSHIFT, PGBITS)
54 #define PGSIZE (1 << PGBITS)
56 /* Page table (bits 12:21). */
57 #define PTSHIFT PGBITS /* First page table bit. */
58 #define PTBITS 10 /* Number of page table bits. */
59 #define PTMASK MASK(PTSHIFT, PTBITS)
61 /* Page directory (bits 22:31). */
62 #define PDSHIFT (PTSHIFT + PTBITS) /* First page dir bit. */
63 #define PDBITS 10 /* Number of page dir bits. */
64 #define PDMASK MASK(PDSHIFT, PDBITS)
67 /* Offset within a page. */
68 static inline unsigned pg_ofs (void *va) { return (uintptr_t) va & PGMASK; }
71 static inline uintptr_t pg_no (void *va) { return (uintptr_t) va >> PTSHIFT; }
73 /* Page table number. */
74 static inline unsigned pt_no (void *va) {
75 return ((uintptr_t) va & PTMASK) >> PTSHIFT;
78 /* Page directory number. */
79 static inline uintptr_t pd_no (void *va) { return (uintptr_t) va >> PDSHIFT; }
81 /* Round up to nearest page boundary. */
82 static inline void *pg_round_up (void *va) {
83 return (void *) (((uintptr_t) va + PGSIZE - 1) & ~PGMASK);
86 /* Round down to nearest page boundary. */
87 static inline void *pg_round_down (void *va) {
88 return (void *) ((uintptr_t) va & ~PGMASK);
91 #define PHYS_BASE ((void *) LOADER_PHYS_BASE)
93 /* Returns kernel virtual address at which physical address PADDR
96 ptov (uintptr_t paddr)
98 ASSERT ((void *) paddr < PHYS_BASE);
100 return (void *) (paddr + PHYS_BASE);
103 /* Returns physical address at which kernel virtual address VADDR
105 static inline uintptr_t
108 ASSERT (vaddr >= PHYS_BASE);
110 return (uintptr_t) vaddr - (uintptr_t) PHYS_BASE;
114 /* Page Table/Directory Entry flags
115 * these are defined by the hardware
117 #define PG_P 0x1 /* Present */
118 #define PG_W 0x2 /* Writeable */
119 #define PG_U 0x4 /* User */
120 #define PG_PWT 0x8 /* Write-Through */
121 #define PG_PCD 0x10 /* Cache-Disable */
122 #define PG_A 0x20 /* Accessed */
123 #define PG_D 0x40 /* Dirty */
124 #define PG_PS 0x80 /* Page Size */
125 #define PG_MBZ 0x180 /* Bits must be zero */
126 #define PG_USER 0xe00 /* Bits for user processes */
128 * The PG_USER bits are not used by the kernel and they are
129 * not interpreted by the hardware. The kernel allows
130 * user processes to set them arbitrarily.
135 /* Control Register flags */
136 #define CR0_PE 0x1 /* Protection Enable */
137 #define CR0_MP 0x2 /* Monitor coProcessor */
138 #define CR0_EM 0x4 /* Emulation */
139 #define CR0_TS 0x8 /* Task Switched */
140 #define CR0_ET 0x10 /* Extension Type */
141 #define CR0_NE 0x20 /* Numeric Errror */
142 #define CR0_WP 0x10000 /* Write Protect */
143 #define CR0_AM 0x40000 /* Alignment Mask */
144 #define CR0_NW 0x20000000 /* Not Writethrough */
145 #define CR0_CD 0x40000000 /* Cache Disable */
146 #define CR0_PG 0x80000000 /* Paging */
148 #define CR4_PCE 0x100 /* Performance counter enable */
149 #define CR4_MCE 0x40 /* Machine Check Enable */
150 #define CR4_PSE 0x10 /* Page Size Extensions */
151 #define CR4_DE 0x08 /* Debugging Extensions */
152 #define CR4_TSD 0x04 /* Time Stamp Disable */
153 #define CR4_PVI 0x02 /* Protected-Mode Virtual Interrupts */
154 #define CR4_VME 0x01 /* V86 Mode Extensions */
156 /* EFLAGS Register. */
157 #define FLAG_CF 0x00000001 /* Carry Flag. */
158 #define FLAG_PF 0x00000004 /* Parity Flag. */
159 #define FLAG_AF 0x00000010 /* Auxiliary Carry Flag. */
160 #define FLAG_ZF 0x00000040 /* Zero Flag. */
161 #define FLAG_SF 0x00000080 /* Sign Flag. */
162 #define FLAG_TF 0x00000100 /* Trap Flag. */
163 #define FLAG_IF 0x00000200 /* Interrupt Flag. */
164 #define FLAG_DF 0x00000400 /* Direction Flag. */
165 #define FLAG_OF 0x00000800 /* Overflow Flag. */
166 #define FLAG_IOPL 0x00003000 /* I/O Privilege Level (2 bits). */
167 #define FLAG_IOPL_SHIFT 12
168 #define FLAG_NT 0x00004000 /* Nested Task. */
169 #define FLAG_RF 0x00010000 /* Resume Flag. */
170 #define FLAG_VM 0x00020000 /* Virtual 8086 Mode. */
171 #define FLAG_AC 0x00040000 /* Alignment Check. */
172 #define FLAG_VIF 0x00080000 /* Virtual Interrupt Flag. */
173 #define FLAG_VIP 0x00100000 /* Virtual Interrupt Pending. */
174 #define FLAG_ID 0x00200000 /* ID Flag. */
176 /* Page fault error codes */
177 #define FEC_PR 0x1 /* Page fault caused by protection violation */
178 #define FEC_WR 0x2 /* Page fault caused by a write */
179 #define FEC_U 0x4 /* Page fault occured while in user mode */
182 /* Application segment type bits */
183 #define STA_X 0x8 /* Executable segment */
184 #define STA_A 0x1 /* Accessed */
186 #define STA_C 0x4 /* Conforming code segment (executable only) */
187 #define STA_R 0x2 /* Readable (executable segments) */
189 #define STA_E 0x4 /* Expand down (non-executable segments) */
190 #define STA_W 0x2 /* Writeable (non-executable segments) */
193 /* Segment selectors. */
194 #define SEL_NULL 0x00 /* Null selector. */
195 #define SEL_KCSEG 0x08 /* Kernel code selector. */
196 #define SEL_KDSEG 0x10 /* Kernel data selector. */
197 #define SEL_UCSEG 0x1B /* User code selector. */
198 #define SEL_UDSEG 0x23 /* User data selector. */
199 #define SEL_TSS 0x28 /* Task-state segment. */
200 #define SEL_CNT 6 /* Number of segments. */
202 #ifndef __ASSEMBLER__
205 uint16_t back_link, :16;
215 uint32_t eax, ecx, edx, ebx;
216 uint32_t esp, ebp, esi, edi;
224 uint16_t trace, bitmap;
229 SYS_SYSTEM = 0, /* System segment. */
230 SYS_CODE_DATA = 1 /* Code or data segment. */
235 GRAN_BYTE = 0, /* Limit has 1-byte granularity. */
236 GRAN_PAGE = 1 /* Limit has 4 kB granularity. */
241 /* System segment types. */
242 TYPE_TSS_16_A = 1, /* 16-bit TSS (available). */
243 TYPE_LDT = 2, /* LDT. */
244 TYPE_TSS_16_B = 3, /* 16-bit TSS (busy). */
245 TYPE_CALL_16 = 4, /* 16-bit call gate. */
246 TYPE_TASK = 5, /* Task gate. */
247 TYPE_INT_16 = 6, /* 16-bit interrupt gate. */
248 TYPE_TRAP_16 = 7, /* 16-bit trap gate. */
249 TYPE_TSS_32_A = 9, /* 32-bit TSS (available). */
250 TYPE_TSS_32_B = 11, /* 32-bit TSS (busy). */
251 TYPE_CALL_32 = 12, /* 32-bit call gate. */
252 TYPE_INT_32 = 14, /* 32-bit interrupt gate. */
253 TYPE_TRAP_32 = 15, /* 32-bit trap gate. */
255 /* Code/data segment types. */
256 TYPE_CODE = 8, /* 1=Code segment, 0=data segment. */
257 TYPE_ACCESSED = 1, /* Set if accessed. */
259 /* Data segment types. */
260 TYPE_EXPAND_DOWN = 4, /* 1=Expands up, 0=expands down. */
261 TYPE_WRITABLE = 2, /* 1=Read/write, 0=read-only. */
263 /* Code segment types. */
264 TYPE_CONFORMING = 4, /* 1=Conforming, 0=nonconforming. */
265 TYPE_READABLE = 2 /* 1=Exec/read, 0=exec-only. */
268 static inline uint64_t
269 make_dtr_operand (uint16_t limit, void *base)
271 return limit | ((uint64_t) (uint32_t) base << 16);
275 #endif /* !_MMU_H_ */