Author: tkreuzer
Date: Wed Aug 20 17:48:47 2008
New Revision: 35493
URL:
http://svn.reactos.org/svn/reactos?rev=35493&view=rev
Log:
Setup a page for the Idt and a page for the gdt + tss. Setup the newly created gdt
accordingly. Set gdtr and idtr.
Modified:
branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/loader.c
branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/loader.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/…
==============================================================================
--- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/loader.c
[iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/arch/amd64/loader.c
[iso-8859-1] Wed Aug 20 17:48:47 2008
@@ -27,9 +27,11 @@
/* Page Directory and Tables for non-PAE Systems */
extern ULONG_PTR NextModuleBase;
extern ULONG_PTR KernelBase;
+ULONG_PTR GdtBase, IdtBase, TssBase;
extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
PPAGE_DIRECTORY_AMD64 pPML4;
+PVOID pIdt, pGdt;
/* FUNCTIONS *****************************************************************/
@@ -92,6 +94,8 @@
/* Set the new PML4 */
__writecr3((ULONGLONG)pPML4);
+ FrLdrSetupGdtIdt();
+
LoaderBlock.FrLdrDbgPrint = DbgPrint;
// DumpLoaderBlock();
@@ -220,5 +224,56 @@
DbgPrint("Could not map %d kernel pages.\n", KernelPages);
}
-}
-
+ /* Setup a page for the idt */
+ pIdt = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory);
+ IdtBase = KernelBase + KernelPages * PAGE_SIZE;
+ if (!FrLdrMapSinglePage(IdtBase, (ULONGLONG)pIdt))
+ {
+ DbgPrint("Could not map idt page.\n", KernelPages);
+ }
+
+ /* Setup a page for the gdt & tss */
+ pGdt = MmAllocateMemoryWithType(PAGE_SIZE, LoaderSpecialMemory);
+ GdtBase = IdtBase + PAGE_SIZE;
+ TssBase = GdtBase + 20 * sizeof(ULONG64); // FIXME: don't hardcode
+ if (!FrLdrMapSinglePage(GdtBase, (ULONGLONG)pGdt))
+ {
+ DbgPrint("Could not map idt page.\n", KernelPages);
+ }
+
+
+}
+
+VOID
+FrLdrSetupGdtIdt()
+{
+ PKGDTENTRY64 Entry;
+ KDESCRIPTOR Desc;
+
+ RtlZeroMemory(pGdt, PAGE_SIZE);
+
+ /* Setup KGDT_64_R0_CODE */
+ Entry = KiGetGdtEntry(pGdt, KGDT_64_R0_CODE);
+ *(PULONG64)Entry = 0x0020980000000000ULL;
+
+ /* Setup TSS entry */
+ Entry = KiGetGdtEntry(pGdt, KGDT_TSS);
+ KiInitGdtEntry(Entry, TssBase, I386_TSS, 0);
+
+ /* Setup the gdt descriptor */
+ Desc.Limit = 12 * sizeof(ULONG64) - 1;
+ Desc.Base = (PVOID)GdtBase;
+
+ /* Set the new Gdt */
+ __lgdt(&Desc.Limit);
+ DbgPrint("Gdtr.Base = %p\n", Desc.Base);
+
+ /* Setup the idt descriptor */
+ Desc.Limit = 12 * sizeof(ULONG64) - 1;
+ Desc.Base = (PVOID)IdtBase;
+
+ /* Set the new Idt */
+ __lidt(&Desc.Limit);
+ DbgPrint("Idtr.Base = %p\n", Desc.Base);
+
+}
Modified:
branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/…
==============================================================================
--- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h
[iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h
[iso-8859-1] Wed Aug 20 17:48:47 2008
@@ -51,6 +51,42 @@
HARDWARE_PTE Pde[512];
} PAGE_DIRECTORY_AMD64, *PPAGE_DIRECTORY_AMD64;
+VOID
+FORCEINLINE
+__lgdt(void *gdt)
+{
+ asm volatile ("lgdt %0\n" : : "m"(*(short*)gdt));
+}
+
+VOID
+FORCEINLINE
+__lidt(void *idt)
+{
+ asm volatile ("lidt %0\n" : : "m"(*(short*)idt));
+}
+
+PKGDTENTRY64
+FORCEINLINE
+KiGetGdtEntry(PVOID pGdt, USHORT Index)
+{
+ return (PKGDTENTRY64)((ULONG64)pGdt + (Index & ~RPL_MASK));
+}
+
+VOID
+FORCEINLINE
+KiInitGdtEntry(PKGDTENTRY64 Entry, ULONG64 Base, UCHAR Type, UCHAR Dpl)
+{
+ Entry->Bits.Type = Type;
+ Entry->Bits.Present = 1;
+ Entry->Bits.Dpl = Dpl;
+ Entry->BaseLow = (USHORT)(Base & 0xFFFF);
+ Entry->Bytes.BaseMiddle = (UCHAR)(Base >> 16);
+ Entry->Bytes.BaseHigh = (UCHAR)(Base >> 24);
+ Entry->BaseUpper = (ULONG)(Base >> 32);
+}
+
+VOID FrLdrSetupGdtIdt();
+
#endif
#endif /* __AMD64_AMD64_H_ */