3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ke/i386/gdt.c
6 * PURPOSE: GDT managment
8 * PROGRAMMERS: David Welch (welch@cwcom.net)
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 /* GLOBALS *******************************************************************/
19 PUSHORT KiGdtArray
[MAXIMUM_PROCESSORS
];
21 USHORT KiBootGdt
[11 * 4] =
23 0x0, 0x0, 0x0, 0x0, /* Null */
24 0xffff, 0x0, 0x9a00, 0xcf, /* Kernel CS */
25 0xffff, 0x0, 0x9200, 0xcf, /* Kernel DS */
26 0xffff, 0x0, 0xfa00, 0xcf, /* User CS */
27 0xffff, 0x0, 0xf200, 0xcf, /* User DS */
28 0x0, 0x0, 0x0, 0x0, /* TSS */
29 0x0fff, 0x0000, 0x9200, 0xff00, /* PCR */
30 0x0fff, 0x0, 0xf200, 0x0, /* TEB */
31 0x0, 0x0, 0x0, 0x0, /* Reserved */
32 0x0, 0x0, 0x0, 0x0, /* LDT */
33 0x0, 0x0, 0x0, 0x0 /* Trap TSS */
39 struct LocalGdtDescriptor_t
43 } KiGdtDescriptor
= { 11 * 8, (ULONG
)KiBootGdt
};
48 static KSPIN_LOCK GdtLock
;
50 /* FUNCTIONS *****************************************************************/
53 KiGdtPrepareForApplicationProcessorInit(ULONG Id
)
55 KiGdtArray
[Id
] = ExAllocatePool(NonPagedPool
, sizeof(USHORT
) * 4 * 11);
59 KiInitializeGdt(PKPCR Pcr
)
62 struct LocalGdtDescriptor_t Descriptor
;
68 KiGdtArray
[0] = KiBootGdt
;
75 Gdt
= KiGdtArray
[Pcr
->Number
];
78 DbgPrint("No GDT (%d)\n", Pcr
->Number
);
83 * Copy the boot processor's GDT onto this processor's GDT. Note that
84 * the only entries that can change are the PCR, TEB and LDT descriptors.
85 * We will be initializing these later so their current values are
88 memcpy(Gdt
, KiBootGdt
, sizeof(USHORT
) * 4 * 11);
92 * Set the base address of the PCR
95 Entry
= KGDT_R0_PCR
/ 2;
96 Gdt
[Entry
+ 1] = (USHORT
)(((ULONG
)Base
) & 0xffff);
98 Gdt
[Entry
+ 2] = Gdt
[Entry
+ 2] & ~(0xff);
99 Gdt
[Entry
+ 2] = (USHORT
)(Gdt
[Entry
+ 2] | ((((ULONG
)Base
) & 0xff0000) >> 16));
101 Gdt
[Entry
+ 3] = Gdt
[Entry
+ 3] & ~(0xff00);
102 Gdt
[Entry
+ 3] = (USHORT
)(Gdt
[Entry
+ 3] | ((((ULONG
)Base
) & 0xff000000) >> 16));
107 Descriptor
.Length
= 8 * 11;
108 Descriptor
.Base
= (ULONG
)Gdt
;
109 #if defined(__GNUC__)
110 __asm__ ("lgdt %0\n\t" : /* no output */ : "m" (Descriptor
));
113 * Reload the selectors
115 __asm__ ("movl %0, %%ds\n\t"
120 : "a" (KGDT_R0_DATA
), "d" (KGDT_R0_PCR
));
121 __asm__ ("pushl %0\n\t"
126 : "a" (KGDT_R0_CODE
));
127 #elif defined(_MSC_VER)
131 mov ax
, KGDT_R0_DATA
;
143 #error Unknown compiler for inline assembler
152 KeI386FlatToGdtSelector(
166 KeI386ReleaseGdtSelectors(
168 IN ULONG NumOfSelectors
179 KeI386AllocateGdtSelectors(
181 IN ULONG NumOfSelectors
189 KeSetBaseGdtSelector(ULONG Entry
,
195 DPRINT("KeSetBaseGdtSelector(Entry %x, Base %x)\n",
198 KeAcquireSpinLock(&GdtLock
, &oldIrql
);
200 Gdt
= KeGetCurrentKPCR()->GDT
;
201 Entry
= (Entry
& (~0x3)) / 2;
203 Gdt
[Entry
+ 1] = (USHORT
)(((ULONG
)Base
) & 0xffff);
205 Gdt
[Entry
+ 2] = Gdt
[Entry
+ 2] & ~(0xff);
206 Gdt
[Entry
+ 2] = (USHORT
)(Gdt
[Entry
+ 2] |
207 ((((ULONG
)Base
) & 0xff0000) >> 16));
209 Gdt
[Entry
+ 3] = Gdt
[Entry
+ 3] & ~(0xff00);
210 Gdt
[Entry
+ 3] = (USHORT
)(Gdt
[Entry
+ 3] |
211 ((((ULONG
)Base
) & 0xff000000) >> 16));
213 DPRINT("%x %x %x %x\n",
219 KeReleaseSpinLock(&GdtLock
, oldIrql
);
223 KeSetGdtSelector(ULONG Entry
,
230 DPRINT("KeSetGdtSelector(Entry %x, Value1 %x, Value2 %x)\n",
231 Entry
, Value1
, Value2
);
233 KeAcquireSpinLock(&GdtLock
, &oldIrql
);
235 Gdt
= (PULONG
) KeGetCurrentKPCR()->GDT
;
236 Entry
= (Entry
& (~0x3)) / 4;
239 Gdt
[Entry
+ 1] = Value2
;
245 KeReleaseSpinLock(&GdtLock
, oldIrql
);
249 KeDumpGdtSelector(ULONG Entry
)
254 a
= KiBootGdt
[Entry
*4];
255 b
= KiBootGdt
[Entry
*4 + 1];
256 c
= KiBootGdt
[Entry
*4 + 2];
257 d
= KiBootGdt
[Entry
*4 + 3];
259 DbgPrint("Base: %x\n", b
+ ((c
& 0xff) * (1 << 16)) +
260 ((d
& 0xff00) * (1 << 16)));
261 RawLimit
= a
+ ((d
& 0xf) * (1 << 16));
264 DbgPrint("Limit: %x\n", RawLimit
* 4096);
268 DbgPrint("Limit: %x\n", RawLimit
);
270 DbgPrint("Accessed: %d\n", (c
& 0x100) >> 8);
271 DbgPrint("Type: %x\n", (c
& 0xe00) >> 9);
272 DbgPrint("System: %d\n", (c
& 0x1000) >> 12);
273 DbgPrint("DPL: %d\n", (c
& 0x6000) >> 13);
274 DbgPrint("Present: %d\n", (c
& 0x8000) >> 15);
275 DbgPrint("AVL: %x\n", (d
& 0x10) >> 4);
276 DbgPrint("D: %d\n", (d
& 0x40) >> 6);
277 DbgPrint("G: %d\n", (d
& 0x80) >> 7);