diff --git a/xtldr/modules/xtos/CMakeLists.txt b/xtldr/modules/xtos/CMakeLists.txt index 695c2b6..78d0d21 100644 --- a/xtldr/modules/xtos/CMakeLists.txt +++ b/xtldr/modules/xtos/CMakeLists.txt @@ -10,7 +10,8 @@ include_directories( # Specify list of source code files list(APPEND XTLDR_XTOS_SOURCE ${XTLDR_SOURCE_DIR}/blproto.c - ${XTLDR_XTOS_SOURCE_DIR}/xtos.c) + ${XTLDR_XTOS_SOURCE_DIR}/xtos.c + ${XTLDR_XTOS_SOURCE_DIR}/${ARCH}/cpu.c) # Link bootloader executable add_executable(xtos ${XTLDR_XTOS_SOURCE}) diff --git a/xtldr/modules/xtos/amd64/cpu.c b/xtldr/modules/xtos/amd64/cpu.c new file mode 100644 index 0000000..b380692 --- /dev/null +++ b/xtldr/modules/xtos/amd64/cpu.c @@ -0,0 +1,251 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/xtos/amd64/cpu.c + * DESCRIPTION: XTOS AMD64 processor context + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Fills in an AMD64 GDT entry. + * + * @param Gdt + * Supplies a pointer to the GDT. + * + * @param Selector + * Specifies a segment selector of the GDT entry. + * + * @param Base + * Specifies a base address value of the descriptor. + * + * @param Limit + * Specifies a descriptor limit. + * + * @param Type + * Specifies a type of the descriptor. + * + * @param Dpl + * Specifies the descriptor privilege level. + * + * @param SegmentMode + * Specifies a segment mode of the descriptor. + * + * @return This routine does not return any value + * + * @since XT 1.0 + */ +XTCDECL +VOID +XtpInitializeGdtEntry(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONGLONG Base, + IN ULONG Limit, + IN UCHAR Type, + IN UCHAR Dpl, + IN UCHAR SegmentMode) +{ + PKGDTENTRY GdtEntry; + UCHAR Granularity; + + /* Set the granularity flag depending on descriptor limit */ + if(Limit < 0x100000) + { + /* Limit is in 1B blocks */ + Granularity = 0; + } + else + { + /* Limit is in 4KB blocks */ + Granularity = 1; + Limit >>= 12; + } + + /* Get GDT entry */ + GdtEntry = (PKGDTENTRY)((ULONG64)Gdt + (Selector & ~RPL_MASK)); + + /* Set GDT descriptor base */ + GdtEntry->BaseLow = Base & 0xFFFF; + GdtEntry->Bits.BaseMiddle = (Base >> 16) & 0xFF; + GdtEntry->Bits.BaseHigh = (Base >> 24) & 0xFF; + GdtEntry->BaseUpper = Base >> 32; + + /* Set descriptor limit */ + GdtEntry->LimitLow = Limit & 0xFFFF; + GdtEntry->Bits.LimitHigh = (Limit >> 16) & 0xF; + + /* Initialize GDT entry */ + GdtEntry->Bits.DefaultBig = (SegmentMode & 2); + GdtEntry->Bits.Dpl = (Dpl & 0x3); + GdtEntry->Bits.Granularity = Granularity; + GdtEntry->Bits.LongMode = (SegmentMode & 1); + GdtEntry->Bits.Present = (Type != 0); + GdtEntry->Bits.System = 0; + GdtEntry->Bits.Type = (Type & 0x1F); + GdtEntry->MustBeZero = 0; +} + +/** + * Initializes GDT and TSS descriptors. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param VirtualAddress + * Supplies a pointer to the next valid, free and available virtual address. + * + * @param Gdt + * Supplies a pointer to memory area containing GDT to fill in. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings, + IN PVOID *VirtualAddress, + OUT PKGDTENTRY *Gdt) +{ + EFI_PHYSICAL_ADDRESS GdtAddress, TssAddress; + PKTSS PhysicalTss, Tss; + PKGDTENTRY GdtEntry; + EFI_STATUS Status; + + /* Print debug message */ + XtLdrProtocol->DbgPrint(L"Initializing Task State Segment (TSS)\n"); + + /* Allocate memory for TSS */ + Status = XtLdrProtocol->AllocatePages(EFI_SIZE_TO_PAGES(sizeof(KTSS)), &TssAddress); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + XtLdrProtocol->DbgPrint(L"Failed to allocate pages for TSS (Status Code: %lx)\n", Status); + return Status; + } + + /* Set TSS and fill it with zeroes */ + PhysicalTss = (PKTSS)(UINT_PTR)TssAddress; + RtlZeroMemory(PhysicalTss, EFI_SIZE_TO_PAGES(sizeof(KTSS)) * EFI_PAGE_SIZE); + + /* Set RSP0 to point at the end of kernel startup stack */ + PhysicalTss->Rsp0 = (UINT_PTR)*VirtualAddress; + + /* Map TSS and set its virtual address */ + XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, PhysicalTss, + EFI_SIZE_TO_PAGES(sizeof(KTSS)), LoaderMemoryData); + Tss = (PKTSS)*VirtualAddress; + + /* Set next valid virtual address */ + *VirtualAddress += EFI_SIZE_TO_PAGES(sizeof(KTSS)) * EFI_PAGE_SIZE; + + /* Print debug message */ + XtLdrProtocol->DbgPrint(L"Initializing General Descriptor Table (GDT)\n"); + + /* Allocate memory for GDT */ + Status = XtLdrProtocol->AllocatePages(EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)), &GdtAddress); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory allocation failure */ + XtLdrProtocol->DbgPrint(L"Failed to allocate pages for GDT (Status Code: %lx)\n", Status); + return Status; + } + + /* Set GDT entry and fill it with zeroes */ + GdtEntry = (PKGDTENTRY)(UINT_PTR)GdtAddress; + RtlZeroMemory(GdtEntry, EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)) * EFI_PAGE_SIZE); + + /* Initialize GDT entries */ + XtpInitializeGdtEntry(GdtEntry, KGDT_NULL, 0x0, 0x0, 0, KGDT_DPL_SYSTEM, 0); + XtpInitializeGdtEntry(GdtEntry, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); + XtpInitializeGdtEntry(GdtEntry, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); + XtpInitializeGdtEntry(GdtEntry, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 0); + XtpInitializeGdtEntry(GdtEntry, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + XtpInitializeGdtEntry(GdtEntry, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); + XtpInitializeGdtEntry(GdtEntry, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + XtpInitializeGdtEntry(GdtEntry, KGDT_R0_LDT, 0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); + XtpInitializeGdtEntry(GdtEntry, KGDT_SYS_TSS, (ULONG_PTR)Tss, sizeof(KTSS), AMD64_TSS, KGDT_DPL_SYSTEM, 0); + + /* Map GDT and set its virtual address */ + Status = XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, GdtEntry, + EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)), LoaderMemoryData); + *Gdt = (PKGDTENTRY)*VirtualAddress; + + /* Set next valid virtual address */ + *VirtualAddress += (EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)) * EFI_PAGE_SIZE); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Loads previously prepared CPU context and performs architecture-specific tasks needed to boot XTOS. + * + * @param Gdt + * Supplies a pointer to memory area containing GDT to load. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +XtpLoadProcessorContext(IN PKGDTENTRY Gdt) +{ + KDESCRIPTOR GdtDescriptor; + + GdtDescriptor.Base = Gdt; + GdtDescriptor.Limit = 128 * sizeof(KGDTENTRY) - 1; + + /* Load GDT and TSS */ + HlLoadGlobalDescriptorTable(&GdtDescriptor.Limit); + HlLoadTaskRegister((UINT32)KGDT_SYS_TSS); + + /* Re-enable IDE interrupts */ + HlIoPortOutByte(0x376, 0); + HlIoPortOutByte(0x3F6, 0); +} + +/** + * Sets architecture specific processor context. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param VirtualAddress + * Supplies a pointer to the next valid, free and available virtual address. + * + * @param Gdt + * Supplies a pointer to memory area containing GDT to fill in. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings, + IN PVOID *VirtualAddress, + OUT PKGDTENTRY *Gdt) +{ + EFI_STATUS Status; + + /* Print debug message */ + XtLdrProtocol->DbgPrint(L"Setting processor context\n"); + + /* Disable interrupts */ + HlClearInterruptFlag(); + + /* Initialize GDT */ + Status = XtpInitializeDescriptors(MemoryMappings, VirtualAddress, Gdt); + if(Status != STATUS_EFI_SUCCESS) + { + /* GDT initialization failure */ + XtLdrProtocol->DbgPrint(L"Failed to initialize GDT (Status Code: %lx)\n", Status); + return Status; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} diff --git a/xtldr/modules/xtos/i686/cpu.c b/xtldr/modules/xtos/i686/cpu.c new file mode 100644 index 0000000..db7ef0b --- /dev/null +++ b/xtldr/modules/xtos/i686/cpu.c @@ -0,0 +1,278 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/modules/xtos/i686/cpu.c + * DESCRIPTION: XTOS i686 processor context + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Fills in an AMD64 GDT entry. + * + * @param Gdt + * Supplies a pointer to the GDT. + * + * @param Selector + * Specifies a segment selector of the GDT entry. + * + * @param Base + * Specifies a base address value of the descriptor. + * + * @param Limit + * Specifies a descriptor limit. + * + * @param Type + * Specifies a type of the descriptor. + * + * @param Dpl + * Specifies the descriptor privilege level. + * + * @param SegmentMode + * Specifies a segment mode of the descriptor. + * + * @return This routine does not return any value + * + * @since XT 1.0 + */ +XTCDECL +VOID +XtpInitializeGdtEntry(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONGLONG Base, + IN ULONG Limit, + IN UCHAR Type, + IN UCHAR Dpl, + IN UCHAR SegmentMode) +{ + PKGDTENTRY GdtEntry; + UCHAR Granularity; + + /* Set the granularity flag depending on descriptor limit */ + if(Limit < 0x100000) + { + /* Limit is in 1B blocks */ + Granularity = 0; + } + else + { + /* Limit is in 4KB blocks */ + Granularity = 1; + Limit >>= 12; + } + + /* Get GDT entry */ + GdtEntry = (PKGDTENTRY)((ULONG64)Gdt + (Selector & ~RPL_MASK)); + + /* Set GDT descriptor base */ + GdtEntry->BaseLow = Base & 0xFFFF; + GdtEntry->Bits.BaseMiddle = (Base >> 16) & 0xFF; + GdtEntry->Bits.BaseHigh = (Base >> 24) & 0xFF; + + /* Set descriptor limit */ + GdtEntry->LimitLow = Limit & 0xFFFF; + GdtEntry->Bits.LimitHigh = (Limit >> 16) & 0xF; + + /* Initialize GDT entry */ + GdtEntry->Bits.DefaultBig = (SegmentMode & 2); + GdtEntry->Bits.Dpl = (Dpl & 0x3); + GdtEntry->Bits.Granularity = Granularity; + GdtEntry->Bits.Reserved0 = 0; + GdtEntry->Bits.Present = (Type != 0); + GdtEntry->Bits.System = 0; + GdtEntry->Bits.Type = (Type & 0x1F); +} + +#define PCR_PAGES 7 +/** + * Initializes GDT, PCR and TSS descriptors. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param VirtualAddress + * Supplies a pointer to the next valid, free and available virtual address. + * + * @param Gdt + * Supplies a pointer to memory area containing GDT to fill in. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings, + IN PVOID *VirtualAddress, + OUT PKGDTENTRY *Gdt) +{ + EFI_PHYSICAL_ADDRESS GdtAddress, PcrAddress, TssAddress; + PKTSS PhysicalTss, Tss; + PVOID PhysicalPcr, Pcr; + PKGDTENTRY GdtEntry; + EFI_STATUS Status; + + /* Print debug message */ + XtLdrProtocol->DbgPrint(L"Initializing Task State Segment (TSS)\n"); + + /* Allocate memory for TSS */ + Status = XtLdrProtocol->AllocatePages(EFI_SIZE_TO_PAGES(sizeof(KTSS)), &TssAddress); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + XtLdrProtocol->DbgPrint(L"Failed to allocate pages for TSS (Status Code: %lx)\n", Status); + return Status; + } + + /* Set TSS and fill it with zeroes */ + PhysicalTss = (PKTSS)(UINT_PTR)TssAddress; + RtlZeroMemory(PhysicalTss, EFI_SIZE_TO_PAGES(sizeof(KTSS)) * EFI_PAGE_SIZE); + + /* Map TSS and set its virtual address */ + XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, PhysicalTss, + EFI_SIZE_TO_PAGES(sizeof(KTSS)), LoaderMemoryData); + Tss = (PKTSS)*VirtualAddress; + + /* Set next valid virtual address */ + *VirtualAddress += EFI_SIZE_TO_PAGES(sizeof(KTSS)) * EFI_PAGE_SIZE; + + /* Print debug message */ + XtLdrProtocol->DbgPrint(L"Initializing Processor Control Region (PCR)\n"); + + /* Allocate memory for PCR */ + Status = XtLdrProtocol->AllocatePages(PCR_PAGES, &PcrAddress); + if(Status != STATUS_EFI_SUCCESS) + { + /* Memory allocation failure */ + XtLdrProtocol->DbgPrint(L"Failed to allocate pages for PCR (Status Code: %lx)\n", Status); + return Status; + } + + /* Set PCR and fill it with zeroes */ + PhysicalPcr = (PVOID)(UINT_PTR)PcrAddress; + RtlZeroMemory(PhysicalPcr, PCR_PAGES * EFI_PAGE_SIZE); + + /* Map TSS and set its virtual address */ + XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, PhysicalPcr, + PCR_PAGES, LoaderStartupPcrPage); + Pcr = *VirtualAddress; + + /* Set next valid virtual address */ + *VirtualAddress += PCR_PAGES * EFI_PAGE_SIZE; + + /* Print debug message */ + XtLdrProtocol->DbgPrint(L"Initializing General Descriptor Table (GDT)\n"); + + /* Allocate memory for GDT */ + Status = XtLdrProtocol->AllocatePages(EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)), &GdtAddress); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory allocation failure */ + XtLdrProtocol->DbgPrint(L"Failed to allocate pages for GDT (Status Code: %lx)\n", Status); + return Status; + } + + /* Set GDT entry and fill it with zeroes */ + GdtEntry = (PKGDTENTRY)(UINT_PTR)GdtAddress; + RtlZeroMemory(GdtEntry, EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)) * EFI_PAGE_SIZE); + + /* Initialize GDT entries */ + XtpInitializeGdtEntry(GdtEntry, KGDT_NULL, 0x0, 0x0, 0, KGDT_DPL_SYSTEM, 0); + XtpInitializeGdtEntry(GdtEntry, KGDT_R0_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2); + XtpInitializeGdtEntry(GdtEntry, KGDT_R0_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); + XtpInitializeGdtEntry(GdtEntry, KGDT_R3_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); + XtpInitializeGdtEntry(GdtEntry, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + XtpInitializeGdtEntry(GdtEntry, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2); + XtpInitializeGdtEntry(GdtEntry, KGDT_R0_LDT, 0x0, 0x0, 0, KGDT_DPL_SYSTEM, 0); + XtpInitializeGdtEntry(GdtEntry, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0); + XtpInitializeGdtEntry(GdtEntry, KGDT_R0_PCR, (ULONG_PTR)Pcr, 0x1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); + XtpInitializeGdtEntry(GdtEntry, KGDT_SYS_TSS, (ULONG_PTR)Tss, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0); + XtpInitializeGdtEntry(GdtEntry, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0); + XtpInitializeGdtEntry(GdtEntry, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); + + /* Map GDT and set its virtual address */ + Status = XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, GdtEntry, + EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)), LoaderMemoryData); + *Gdt = (PKGDTENTRY)*VirtualAddress; + + /* Set next valid virtual address */ + *VirtualAddress += (EFI_SIZE_TO_PAGES(128 * sizeof(KGDTENTRY)) * EFI_PAGE_SIZE); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + +/** + * Loads previously prepared CPU context and performs architecture-specific tasks needed to boot XTOS. + * + * @param Gdt + * Supplies a pointer to memory area containing GDT to load. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +XtpLoadProcessorContext(IN PKGDTENTRY Gdt) +{ + KDESCRIPTOR GdtDescriptor; + + GdtDescriptor.Base = (PVOID)(ULONG_PTR)Gdt; + GdtDescriptor.Limit = 128 * sizeof(KGDTENTRY) - 1; + + /* Load GDT and TSS */ + HlLoadGlobalDescriptorTable(&GdtDescriptor.Limit); + HlLoadTaskRegister((UINT32)KGDT_SYS_TSS); + + /* Load PCR in FS segment */ + HlLoadSegment(SEGMENT_FS, KGDT_R0_PCR); + + /* Re-enable IDE interrupts */ + HlIoPortOutByte(0x376, 0); + HlIoPortOutByte(0x3F6, 0); +} + +/** + * Sets architecture specific processor context. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param VirtualAddress + * Supplies a pointer to the next valid, free and available virtual address. + * + * @param Gdt + * Supplies a pointer to memory area containing GDT to fill in. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings, + IN PVOID *VirtualAddress, + OUT PKGDTENTRY *Gdt) +{ + EFI_STATUS Status; + + /* Print debug message */ + XtLdrProtocol->DbgPrint(L"Setting processor context\n"); + + /* Disable interrupts */ + HlClearInterruptFlag(); + + /* Initialize GDT */ + Status = XtpInitializeDescriptors(MemoryMappings, VirtualAddress, Gdt); + if(Status != STATUS_EFI_SUCCESS) + { + /* GDT initialization failure */ + XtLdrProtocol->DbgPrint(L"Failed to initialize GDT (Status Code: %lx)\n", Status); + return Status; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} diff --git a/xtldr/modules/xtos/includes/xtos.h b/xtldr/modules/xtos/includes/xtos.h index c7cc3c9..0bcc18a 100644 --- a/xtldr/modules/xtos/includes/xtos.h +++ b/xtldr/modules/xtos/includes/xtos.h @@ -12,6 +12,9 @@ #include +/* EFI XT Loader Protocol */ +EXTERN PXT_BOOT_LOADER_PROTOCOL XtLdrProtocol; + /* XTOS kernel entry point */ typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters); @@ -25,6 +28,22 @@ EFI_STATUS XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters); +XTCDECL +VOID +XtpInitializeGdtEntry(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONGLONG Base, + IN ULONG Limit, + IN UCHAR Type, + IN UCHAR Dpl, + IN UCHAR SegmentMode); + +XTCDECL +EFI_STATUS +XtpInitializeDescriptors(IN PLIST_ENTRY MemoryMappings, + IN PVOID *VirtualAddress, + OUT PKGDTENTRY *Gdt); + XTCDECL EFI_STATUS XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings, @@ -38,6 +57,16 @@ XtpLoadModule(IN PEFI_FILE_HANDLE BootDir, IN LOADER_MEMORY_TYPE MemoryType, OUT PPECOFF_IMAGE_CONTEXT *ImageContext); +XTCDECL +VOID +XtpLoadProcessorContext(IN PKGDTENTRY Gdt); + +XTCDECL +EFI_STATUS +XtpSetProcessorContext(IN PLIST_ENTRY MemoryMappings, + IN PVOID *VirtualAddress, + OUT PKGDTENTRY *Gdt); + XTCDECL EFI_STATUS BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle, diff --git a/xtldr/modules/xtos/xtos.c b/xtldr/modules/xtos/xtos.c index 8151b96..ef58bee 100644 --- a/xtldr/modules/xtos/xtos.c +++ b/xtldr/modules/xtos/xtos.c @@ -188,6 +188,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, LIST_ENTRY MemoryMappings; ULONG KernelStackPages; EFI_STATUS Status; + PKGDTENTRY Gdt; /* Initialize XTOS startup sequence */ XtLdrProtocol->DbgPrint(L"Initializing XTOS startup sequence\n"); @@ -257,6 +258,15 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, KernelStackPages, LoaderStartupKernelStack); VirtualAddress += (KernelStackPages * EFI_PAGE_SIZE); + /* Set processor context */ + Status = XtpSetProcessorContext(&MemoryMappings, &VirtualAddress, &Gdt); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to set processor context */ + XtLdrProtocol->DbgPrint(L"Failed to set processor context (Status Code: %lx)\n", Status); + return Status; + } + /* Enable paging */ EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LoadedImageGuid, (PVOID*)&ImageProtocol); Status = XtLdrProtocol->EnablePaging(&MemoryMappings, VirtualAddress, ImageProtocol, &XtPageMap); @@ -267,6 +277,9 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, return Status; } + /* Load processor context */ + XtpLoadProcessorContext(Gdt); + /* Call XTOS kernel */ XtLdrProtocol->DbgPrint(L"Booting the XTOS kernel\n"); KernelEntryPoint(KernelParameters);