From 8f7641d91f0e4ef9df32d9a5019811d286ab2679 Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Mon, 29 Jan 2024 19:40:05 +0100 Subject: [PATCH] Pass memory mapping information to the kernel --- xtldr/modules/xtos_o/xtos.c | 71 ++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/xtldr/modules/xtos_o/xtos.c b/xtldr/modules/xtos_o/xtos.c index 2af2ae0..4231dce 100644 --- a/xtldr/modules/xtos_o/xtos.c +++ b/xtldr/modules/xtos_o/xtos.c @@ -48,6 +48,55 @@ XtGetDisplayInformation(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock, InformationBlock->Pitch = FrameBufferInfo->Pitch; } +XTCDECL +EFI_STATUS +XtGetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID VirtualAddress, + OUT PLIST_ENTRY MemoryDescriptorList) +{ + EFI_PHYSICAL_ADDRESS Address; + EFI_STATUS Status; + ULONGLONG Pages; + + Pages = (ULONGLONG)EFI_SIZE_TO_PAGES((PageMap->MapSize + 1) * sizeof(LOADER_MEMORY_MAPPING)); + + Status = XtLdrProtocol->Memory.AllocatePages(Pages, &Address); + if(Status != STATUS_EFI_SUCCESS) + { + return Status; + } + + Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, VirtualAddress, (PVOID)Address, Pages, LoaderMemoryData); + if(Status != STATUS_EFI_SUCCESS) + { + XtLdrProtocol->Memory.FreePages(Address, Pages); + return Status; + } + + PVOID PhysicalBase = (PVOID)Address; + + PLIST_ENTRY ListEntry; + ListEntry = PageMap->MemoryMap.Flink; + while(ListEntry != &PageMap->MemoryMap) + { + PXTBL_MEMORY_MAPPING MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry); + PLOADER_MEMORY_MAPPING MemoryDescriptor = (PLOADER_MEMORY_MAPPING)Address; + + MemoryDescriptor->MemoryType = MemoryMapping->MemoryType; + MemoryDescriptor->BasePage = (UINT_PTR)MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE; + MemoryDescriptor->PageCount = MemoryMapping->NumberOfPages; + + RtlInsertTailList(MemoryDescriptorList, &MemoryDescriptor->ListEntry); + + Address = Address + sizeof(LOADER_MEMORY_MAPPING); + ListEntry = ListEntry->Flink; + } + + XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, PhysicalBase, VirtualAddress); + + return STATUS_EFI_SUCCESS; +} + /** * Starts the operating system according to the provided parameters using XTOS boot protocol. * @@ -244,6 +293,15 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, /* Set next valid virtual address right after the kernel */ VirtualAddress += ImageContext->ImagePages * EFI_PAGE_SIZE; + /* Find and map APIC base address */ + Status = XtpInitializeApicBase(&PageMap); + if(Status != STATUS_EFI_SUCCESS) + { + /* Failed to setup kernel initialization block */ + XtLdrProtocol->Debug.Print(L"Failed to initialize APIC (Status Code: %lx)\n", Status); + return Status; + } + /* Store virtual address of kernel initialization block for future kernel call */ KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress; @@ -256,15 +314,6 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir, return Status; } - /* Find and map APIC base address */ - Status = XtpInitializeApicBase(&PageMap); - if(Status != STATUS_EFI_SUCCESS) - { - /* Failed to setup kernel initialization block */ - XtLdrProtocol->Debug.Print(L"Failed to initialize APIC (Status Code: %lx)\n", Status); - return Status; - } - /* Get kernel entry point */ XtPeCoffProtocol->GetEntryPoint(ImageContext, (PVOID)&KernelEntryPoint); @@ -446,6 +495,10 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap, *VirtualAddress += (UINT_PTR)(FrameBufferPages * EFI_PAGE_SIZE); } + /* Initialize memory descriptor list */ + RtlInitializeListHead(&LoaderBlock->MemoryDescriptorListHead); + XtGetMemoryDescriptorList(PageMap, *VirtualAddress, &LoaderBlock->MemoryDescriptorListHead); + /* Return success */ return STATUS_EFI_SUCCESS; }