diff --git a/xtldr/modules/xtos/amd64/cpu.c b/xtldr/modules/xtos/amd64/cpu.c index b380692..04779fc 100644 --- a/xtldr/modules/xtos/amd64/cpu.c +++ b/xtldr/modules/xtos/amd64/cpu.c @@ -99,6 +99,9 @@ XtpInitializeGdtEntry(IN PKGDTENTRY Gdt, * @param Gdt * Supplies a pointer to memory area containing GDT to fill in. * + * @param Idt + * Supplies a pointer to memory area containing IDT to fill in. + * * @return This routine returns a status code. * * @since XT 1.0 @@ -107,11 +110,14 @@ XTCDECL EFI_STATUS XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings, IN PVOID *VirtualAddress, - OUT PKGDTENTRY *Gdt) + OUT PKGDTENTRY *Gdt, + OUT PKIDTENTRY *Idt) { - EFI_PHYSICAL_ADDRESS GdtAddress, TssAddress; + EFI_PHYSICAL_ADDRESS GdtAddress, IdtAddress, TssAddress; + KDESCRIPTOR OriginalIdt; PKTSS PhysicalTss, Tss; PKGDTENTRY GdtEntry; + PKIDTENTRY IdtEntry; EFI_STATUS Status; /* Print debug message */ @@ -175,6 +181,33 @@ XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings, /* Set next valid virtual address */ *VirtualAddress += (EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)) * EFI_PAGE_SIZE); + /* Print debug message */ + XtLdrProtocol->DbgPrint(L"Initializing Interrupt Descriptor Table (IDT)\n"); + + /* Allocate memory for IDT */ + Status = XtLdrProtocol->AllocatePages(EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)), &IdtAddress); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory allocation failure */ + XtLdrProtocol->DbgPrint(L"Failed to allocate pages for IDT (Status Code: %lx)\n", Status); + return Status; + } + + /* Set IDT entry and fill it with zeroes */ + IdtEntry = (PKIDTENTRY)(UINT_PTR)IdtAddress; + RtlZeroMemory(IdtEntry, EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)) * EFI_PAGE_SIZE); + + /* Stores IDT register into new IDT entry */ + HlStoreInterruptDescriptorTable(&OriginalIdt.Limit); + RtlCopyMemory(IdtEntry, OriginalIdt.Base, OriginalIdt.Limit + 1); + + /* Map IDT and set its virtual address */ + Status = XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, IdtEntry, + EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)), LoaderMemoryData); + *Idt = (PKIDTENTRY)*VirtualAddress; + + /* Set next valid virtual address */ + *VirtualAddress += (EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)) * EFI_PAGE_SIZE); + /* Return success */ return STATUS_EFI_SUCCESS; } @@ -185,21 +218,29 @@ XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings, * @param Gdt * Supplies a pointer to memory area containing GDT to load. * + * @param Idt + * Supplies a pointer to memory area containing IDT to load. + * * @return This routine does not return any value. * * @since XT 1.0 */ XTCDECL VOID -XtpLoadProcessorContext(IN PKGDTENTRY Gdt) +XtpLoadProcessorContext(IN PKGDTENTRY Gdt, + IN PKIDTENTRY Idt) { - KDESCRIPTOR GdtDescriptor; + KDESCRIPTOR GdtDescriptor, IdtDescriptor; GdtDescriptor.Base = Gdt; GdtDescriptor.Limit = 128 * sizeof(KGDTENTRY) - 1; - /* Load GDT and TSS */ + IdtDescriptor.Base = Idt; + IdtDescriptor.Limit = 256 * sizeof(KIDTENTRY) - 1; + + /* Load GDT, IDT and TSS */ HlLoadGlobalDescriptorTable(&GdtDescriptor.Limit); + HlLoadInterruptDescriptorTable(&IdtDescriptor.Limit); HlLoadTaskRegister((UINT32)KGDT_SYS_TSS); /* Re-enable IDE interrupts */ @@ -219,6 +260,9 @@ XtpLoadProcessorContext(IN PKGDTENTRY Gdt) * @param Gdt * Supplies a pointer to memory area containing GDT to fill in. * + * @param Idt + * Supplies a pointer to memory area containing IDT to fill in. + * * @return This routine returns a status code. * * @since XT 1.0 @@ -227,7 +271,8 @@ XTCDECL EFI_STATUS XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings, IN PVOID *VirtualAddress, - OUT PKGDTENTRY *Gdt) + OUT PKGDTENTRY *Gdt, + OUT PKIDTENTRY *Idt) { EFI_STATUS Status; @@ -238,7 +283,7 @@ XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings, HlClearInterruptFlag(); /* Initialize GDT */ - Status = XtpInitializeDescriptors(MemoryMappings, VirtualAddress, Gdt); + Status = XtpInitializeDescriptors(MemoryMappings, VirtualAddress, Gdt, Idt); if(Status != STATUS_EFI_SUCCESS) { /* GDT initialization failure */ diff --git a/xtldr/modules/xtos/i686/cpu.c b/xtldr/modules/xtos/i686/cpu.c index db7ef0b..5adfce1 100644 --- a/xtldr/modules/xtos/i686/cpu.c +++ b/xtldr/modules/xtos/i686/cpu.c @@ -98,6 +98,9 @@ XtpInitializeGdtEntry(IN PKGDTENTRY Gdt, * @param Gdt * Supplies a pointer to memory area containing GDT to fill in. * + * @param Idt + * Supplies a pointer to memory area containing IDT to fill in. + * * @return This routine returns a status code. * * @since XT 1.0 @@ -106,12 +109,15 @@ XTCDECL EFI_STATUS XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings, IN PVOID *VirtualAddress, - OUT PKGDTENTRY *Gdt) + OUT PKGDTENTRY *Gdt, + OUT PKIDTENTRY *Idt) { - EFI_PHYSICAL_ADDRESS GdtAddress, PcrAddress, TssAddress; + EFI_PHYSICAL_ADDRESS GdtAddress, IdtAddress, PcrAddress, TssAddress; + KDESCRIPTOR OriginalIdt; PKTSS PhysicalTss, Tss; PVOID PhysicalPcr, Pcr; PKGDTENTRY GdtEntry; + PKIDTENTRY IdtEntry; EFI_STATUS Status; /* Print debug message */ @@ -199,6 +205,32 @@ XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings, /* Set next valid virtual address */ *VirtualAddress += (EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)) * EFI_PAGE_SIZE); + /* Print debug message */ + XtLdrProtocol->DbgPrint(L"Initializing Interrupt Descriptor Table (IDT)\n"); + + /* Allocate memory for IDT */ + Status = XtLdrProtocol->AllocatePages(EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)), &IdtAddress); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory allocation failure */ + XtLdrProtocol->DbgPrint(L"Failed to allocate pages for IDT (Status Code: %lx)\n", Status); + return Status; + } + + /* Set IDT entry and fill it with zeroes */ + IdtEntry = (PKIDTENTRY)(UINT_PTR)IdtAddress; + RtlZeroMemory(IdtEntry, EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)) * EFI_PAGE_SIZE); + + /* Stores IDT register into new IDT entry */ + HlStoreInterruptDescriptorTable(&OriginalIdt.Limit); + RtlCopyMemory(IdtEntry, OriginalIdt.Base, OriginalIdt.Limit + 1); + + /* Map IDT and set its virtual address */ + Status = XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, IdtEntry, + EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)), LoaderMemoryData); + *Idt = (PKIDTENTRY)*VirtualAddress; + + /* Set next valid virtual address */ + *VirtualAddress += (EFI_SIZE_TO_PAGES(256 * sizeof(KIDTENTRY)) * EFI_PAGE_SIZE); /* Return success */ return STATUS_EFI_SUCCESS; } @@ -209,21 +241,29 @@ XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings, * @param Gdt * Supplies a pointer to memory area containing GDT to load. * + * @param Idt + * Supplies a pointer to memory area containing IDT to load. + * * @return This routine does not return any value. * * @since XT 1.0 */ XTCDECL VOID -XtpLoadProcessorContext(IN PKGDTENTRY Gdt) +XtpLoadProcessorContext(IN PKGDTENTRY Gdt, + IN PKIDTENTRY Idt) { - KDESCRIPTOR GdtDescriptor; + KDESCRIPTOR GdtDescriptor, IdtDescriptor; GdtDescriptor.Base = (PVOID)(ULONG_PTR)Gdt; GdtDescriptor.Limit = 128 * sizeof(KGDTENTRY) - 1; + IdtDescriptor.Base = Idt; + IdtDescriptor.Limit = 256 * sizeof(KIDTENTRY) - 1; + /* Load GDT and TSS */ HlLoadGlobalDescriptorTable(&GdtDescriptor.Limit); + HlLoadInterruptDescriptorTable(&IdtDescriptor.Limit); HlLoadTaskRegister((UINT32)KGDT_SYS_TSS); /* Load PCR in FS segment */ @@ -246,6 +286,9 @@ XtpLoadProcessorContext(IN PKGDTENTRY Gdt) * @param Gdt * Supplies a pointer to memory area containing GDT to fill in. * + * @param Idt + * Supplies a pointer to memory area containing IDT to fill in. + * * @return This routine returns a status code. * * @since XT 1.0 @@ -254,7 +297,8 @@ XTCDECL EFI_STATUS XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings, IN PVOID *VirtualAddress, - OUT PKGDTENTRY *Gdt) + OUT PKGDTENTRY *Gdt, + OUT PKIDTENTRY *Idt) { EFI_STATUS Status; @@ -265,7 +309,7 @@ XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings, HlClearInterruptFlag(); /* Initialize GDT */ - Status = XtpInitializeDescriptors(MemoryMappings, VirtualAddress, Gdt); + Status = XtpInitializeDescriptors(MemoryMappings, VirtualAddress, Gdt, Idt); if(Status != STATUS_EFI_SUCCESS) { /* GDT initialization failure */ diff --git a/xtldr/modules/xtos/includes/xtos.h b/xtldr/modules/xtos/includes/xtos.h index 0bcc18a..143dcf9 100644 --- a/xtldr/modules/xtos/includes/xtos.h +++ b/xtldr/modules/xtos/includes/xtos.h @@ -42,7 +42,8 @@ XTCDECL EFI_STATUS XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings, IN PVOID *VirtualAddress, - OUT PKGDTENTRY *Gdt); + OUT PKGDTENTRY *Gdt, + OUT PKIDTENTRY *Idt); XTCDECL EFI_STATUS @@ -59,13 +60,15 @@ XtpLoadModule(IN PEFI_FILE_HANDLE BootDir, XTCDECL VOID -XtpLoadProcessorContext(IN PKGDTENTRY Gdt); +XtpLoadProcessorContext(IN PKGDTENTRY Gdt, + IN PKIDTENTRY Idt); XTCDECL EFI_STATUS XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings, IN PVOID *VirtualAddress, - OUT PKGDTENTRY *Gdt); + OUT PKGDTENTRY *Gdt, + OUT PKIDTENTRY *Idt); XTCDECL EFI_STATUS diff --git a/xtldr/modules/xtos/xtos.c b/xtldr/modules/xtos/xtos.c index ef58bee..3d7755a 100644 --- a/xtldr/modules/xtos/xtos.c +++ b/xtldr/modules/xtos/xtos.c @@ -189,6 +189,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, ULONG KernelStackPages; EFI_STATUS Status; PKGDTENTRY Gdt; + PKIDTENTRY Idt; /* Initialize XTOS startup sequence */ XtLdrProtocol->DbgPrint(L"Initializing XTOS startup sequence\n"); @@ -259,7 +260,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, VirtualAddress += (KernelStackPages * EFI_PAGE_SIZE); /* Set processor context */ - Status = XtpSetProcessorContext(&MemoryMappings, &VirtualAddress, &Gdt); + Status = XtpSetProcessorContext(&MemoryMappings, &VirtualAddress, &Gdt, &Idt); if(Status != STATUS_EFI_SUCCESS) { /* Failed to set processor context */ @@ -278,7 +279,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, } /* Load processor context */ - XtpLoadProcessorContext(Gdt); + XtpLoadProcessorContext(Gdt, Idt); /* Call XTOS kernel */ XtLdrProtocol->DbgPrint(L"Booting the XTOS kernel\n");