3 * Copyright (C) 2000 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * PROJECT: ReactOS kernel
21 * FILE: ntoskrnl/ke/gdt.c
22 * PURPOSE: GDT managment
23 * PROGRAMMER: David Welch (welch@cwcom.net)
28 /* INCLUDES *****************************************************************/
30 #include <ddk/ntddk.h>
31 #include <internal/ke.h>
32 #include <internal/ps.h>
33 #include <internal/i386/segment.h>
36 #include <internal/debug.h>
38 /* GLOBALS *******************************************************************/
40 PUSHORT KiGdtArray[MAXIMUM_PROCESSORS];
42 USHORT KiBootGdt[11 * 4] =
44 0x0, 0x0, 0x0, 0x0, /* Null */
45 0xffff, 0x0, 0x9a00, 0xcf, /* Kernel CS */
46 0xffff, 0x0, 0x9200, 0xcf, /* Kernel DS */
47 0x0, 0x0, 0xfa00, 0xcc, /* User CS */
48 0x0, 0x0, 0xf200, 0xcc, /* User DS */
49 0x0, 0x0, 0x0, 0x0, /* TSS */
50 0x1000, 0x0000, 0x9200, 0xff00, /* PCR */
51 0x1000, 0x0, 0xf200, 0x0, /* TEB */
52 0x0, 0x0, 0x0, 0x0, /* Reserved */
53 0x0, 0x0, 0x0, 0x0, /* LDT */
54 0x0, 0x0, 0x0, 0x0 /* Trap TSS */
61 } __attribute__((packed)) KiGdtDescriptor = { 11 * 8, (ULONG)KiBootGdt };
63 static KSPIN_LOCK GdtLock;
65 /* FUNCTIONS *****************************************************************/
68 KiGdtPrepareForApplicationProcessorInit(ULONG Id)
70 KiGdtArray[Id] = ExAllocatePool(NonPagedPool, sizeof(USHORT) * 4 * 11);
74 KiInitializeGdt(PKPCR Pcr)
81 } __attribute__((packed)) Descriptor;
87 KiGdtArray[0] = KiBootGdt;
94 Gdt = KiGdtArray[Pcr->ProcessorNumber];
97 DbgPrint("No GDT (%d)\n", Pcr->ProcessorNumber);
102 * Copy the boot processor's GDT onto this processor's GDT. Note that
103 * the only entries that can change are the PCR, TEB and LDT descriptors.
104 * We will be initializing these later so their current values are
107 memcpy(Gdt, KiBootGdt, sizeof(USHORT) * 4 * 11);
111 * Set the base address of the PCR
114 Entry = PCR_SELECTOR / 2;
115 Gdt[Entry + 1] = ((ULONG)Base) & 0xffff;
117 Gdt[Entry + 2] = Gdt[Entry + 2] & ~(0xff);
118 Gdt[Entry + 2] = Gdt[Entry + 2] | ((((ULONG)Base) & 0xff0000) >> 16);
120 Gdt[Entry + 3] = Gdt[Entry + 3] & ~(0xff00);
121 Gdt[Entry + 3] = Gdt[Entry + 3] | ((((ULONG)Base) & 0xff000000) >> 16);
126 Descriptor.Length = 8 * 11;
127 Descriptor.Base = (ULONG)Gdt;
128 __asm__ ("lgdt %0\n\t" : /* no output */ : "m" (Descriptor));
131 * Reload the selectors
133 __asm__ ("movl %0, %%ds\n\t"
138 : "a" (KERNEL_DS), "b" (PCR_SELECTOR));
139 __asm__ ("pushl %0\n\t"
148 KeSetBaseGdtSelector(ULONG Entry,
152 PUSHORT Gdt = KeGetCurrentKPCR()->GDT;
154 DPRINT("KeSetBaseGdtSelector(Entry %x, Base %x)\n",
157 KeAcquireSpinLock(&GdtLock, &oldIrql);
159 Entry = (Entry & (~0x3)) / 2;
161 Gdt[Entry + 1] = ((ULONG)Base) & 0xffff;
163 Gdt[Entry + 2] = Gdt[Entry + 2] & ~(0xff);
164 Gdt[Entry + 2] = Gdt[Entry + 2] |
165 ((((ULONG)Base) & 0xff0000) >> 16);
167 Gdt[Entry + 3] = Gdt[Entry + 3] & ~(0xff00);
168 Gdt[Entry + 3] = Gdt[Entry + 3] |
169 ((((ULONG)Base) & 0xff000000) >> 16);
171 DPRINT("%x %x %x %x\n",
177 KeReleaseSpinLock(&GdtLock, oldIrql);
181 KeSetGdtSelector(ULONG Entry,
186 PULONG Gdt = (PULONG) KeGetCurrentKPCR()->GDT;
188 DPRINT("KeSetGdtSelector(Entry %x, Value1 %x, Value2 %x)\n",
189 Entry, Value1, Value2);
191 KeAcquireSpinLock(&GdtLock, &oldIrql);
193 Entry = (Entry & (~0x3)) / 4;
196 Gdt[Entry + 1] = Value2;
202 KeReleaseSpinLock(&GdtLock, oldIrql);
206 KeDumpGdtSelector(ULONG Entry)
211 a = KiBootGdt[Entry*4];
212 b = KiBootGdt[Entry*4 + 1];
213 c = KiBootGdt[Entry*4 + 2];
214 d = KiBootGdt[Entry*4 + 3];
216 DbgPrint("Base: %x\n", b + ((c & 0xff) * (1 << 16)) +
217 ((d & 0xff00) * (1 << 16)));
218 RawLimit = a + ((d & 0xf) * (1 << 16));
221 DbgPrint("Limit: %x\n", RawLimit * 4096);
225 DbgPrint("Limit: %x\n", RawLimit);
227 DbgPrint("Accessed: %d\n", (c & 0x100) >> 8);
228 DbgPrint("Type: %x\n", (c & 0xe00) >> 9);
229 DbgPrint("System: %d\n", (c & 0x1000) >> 12);
230 DbgPrint("DPL: %d\n", (c & 0x6000) >> 13);
231 DbgPrint("Present: %d\n", (c & 0x8000) >> 15);
232 DbgPrint("AVL: %x\n", (d & 0x10) >> 4);
233 DbgPrint("D: %d\n", (d & 0x40) >> 6);
234 DbgPrint("G: %d\n", (d & 0x80) >> 7);