5a1ede95aa944d946091c3238365757378bfc934
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);