diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 8690105..b6b3586 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -80,6 +80,7 @@ typedef VOID (*PBL_GET_MAPPINGS_COUNT)(IN PXTBL_PAGE_MAPPING PageMap, OUT PULONG typedef EFI_STATUS (*PBL_GET_MEMORY_MAP)(OUT PEFI_MEMORY_MAP MemoryMap); typedef PLIST_ENTRY (*PBL_GET_MODULES_LIST)(); typedef INT_PTR (*PBL_GET_SECURE_BOOT_STATUS)(); +typedef PVOID (*PBL_GET_VIRTUAL_ADDRESS)(IN PXTBL_PAGE_MAPPING PageMap, IN PVOID PhysicalAddress); typedef VOID (*PBL_INITIALIZE_PAGE_MAP)(OUT PXTBL_PAGE_MAPPING PageMap, IN SHORT PageMapLevel, IN PAGE_SIZE PageSize); typedef EFI_STATUS (*PBL_INSTALL_XT_PROTOCOL)(IN PVOID Interface, IN PEFI_GUID Guid); typedef EFI_STATUS (*PBL_INVOKE_BOOT_PROTOCOL)(IN PLIST_ENTRY OptionsList); @@ -92,6 +93,7 @@ typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, O typedef EFI_STATUS (*PBL_OPEN_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef EFI_STATUS (*PBL_OPEN_PROTOCOL_HANDLE)(IN EFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid); typedef PVOID (*PBL_PHYSICAL_ADDRESS_TO_VIRTUAL)(IN PVOID PhysicalAddress, IN PVOID PhysicalBase, IN PVOID VirtualBase); +typedef EFI_STATUS (*PBL_PHYSICAL_LIST_TO_VIRTUAL)(IN PXTBL_PAGE_MAPPING PageMap, IN OUT PLIST_ENTRY ListHead, IN PVOID PhysicalBase, IN PVOID VirtualBase); typedef EFI_STATUS (*PBL_POWER_SYSTEM)(); typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize); typedef EFI_STATUS (*PBL_REGISTER_BOOT_PROTOCOL)(IN PWCHAR SystemType, IN PEFI_GUID BootProtocolGuid); @@ -312,11 +314,13 @@ typedef struct _XTBL_LOADER_PROTOCOL PBL_FREE_POOL FreePool; PBL_GET_MAPPINGS_COUNT GetMappingsCount; PBL_GET_MEMORY_MAP GetMemoryMap; + PBL_GET_VIRTUAL_ADDRESS GetVirtualAddress; PBL_INITIALIZE_PAGE_MAP InitializePageMap; PBL_MAP_EFI_MEMORY MapEfiMemory; PBL_MAP_PAGE MapPage; PBL_MAP_VIRTUAL_MEMORY MapVirtualMemory; PBL_PHYSICAL_ADDRESS_TO_VIRTUAL PhysicalAddressToVirtual; + PBL_PHYSICAL_LIST_TO_VIRTUAL PhysicalListToVirtual; PBL_SET_MEMORY SetMemory; PBL_ZERO_MEMORY ZeroMemory; } Memory; diff --git a/xtldr/includes/xtldr.h b/xtldr/includes/xtldr.h index 5943350..2221809 100644 --- a/xtldr/includes/xtldr.h +++ b/xtldr/includes/xtldr.h @@ -152,6 +152,11 @@ XTCDECL INT_PTR BlGetSecureBootStatus(); +XTCDECL +PVOID +BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID PhysicalAddress); + XTCDECL EFI_STATUS BlGetVolumeDevicePath(IN PWCHAR SystemPath, @@ -253,6 +258,13 @@ BlPhysicalAddressToVirtual(IN PVOID PhysicalAddress, IN PVOID PhysicalBase, IN PVOID VirtualBase); +XTCDECL +EFI_STATUS +BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, + IN OUT PLIST_ENTRY ListHead, + IN PVOID PhysicalBase, + IN PVOID VirtualBase); + XTCDECL VOID BlQueryConsoleMode(OUT PUINT_PTR ResX, diff --git a/xtldr/memory.c b/xtldr/memory.c index 1425e33..0b62b66 100644 --- a/xtldr/memory.c +++ b/xtldr/memory.c @@ -176,6 +176,54 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) return STATUS_EFI_SUCCESS; } +/** + * Attempts to find a virtual address of the specified physical address in memory mappings. + * + * @param PageMap + * Supplies a pointer to the page mapping structure. + * + * @param PhysicalAddress + * Supplies a physical address to search for in the mappings. + * + * @return This routine returns a corresponding virtual address found in the mappings. + * + * @since XT 1.0 + */ +XTCDECL +PVOID +BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap, + IN PVOID PhysicalAddress) +{ + PLOADER_MEMORY_MAPPING Mapping; + PLIST_ENTRY ListEntry; + + /* Iterate over memory mappings in order to find descriptor containing a physical address */ + ListEntry = PageMap->MemoryMap.Flink; + while(ListEntry != &PageMap->MemoryMap) + { + /* Get mapping from linked list */ + Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry); + + /* Make sure any virtual address is set */ + if(Mapping->VirtualAddress) + { + /* Check if provided physical address is in range of this mapping */ + if((PhysicalAddress >= Mapping->PhysicalAddress) && + (PhysicalAddress < Mapping->PhysicalAddress + (Mapping->NumberOfPages * EFI_PAGE_SIZE))) + { + /* Calculate virtual address based on the mapping and return it */ + return PhysicalAddress - Mapping->PhysicalAddress + Mapping->VirtualAddress; + } + } + + /* Get next element from the list */ + ListEntry = ListEntry->Flink; + } + + /* Mapping not found, return 0 */ + return 0; +} + /** * Initializes the page mapping structures. * @@ -514,6 +562,82 @@ BlPhysicalAddressToVirtual(IN PVOID PhysicalAddress, return (PUCHAR)VirtualBase + ((PUCHAR)PhysicalAddress - (PUCHAR)PhysicalBase); } +/** + * Converts whole linked list addressing from physical to virtual for future use after enabling paging. + * + * @param PageMap + * Supplies a pointer to the page mapping structure. + * + * @param ListHead + * Supplies a pointer to a structure that serves as the list header. + * + * @param PhysicalBase + * Supplies a physical base address. + * + * @param VirtualBase + * Supplies a virtual base address. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, + IN OUT PLIST_ENTRY ListHead, + IN PVOID PhysicalBase, + IN PVOID VirtualBase) +{ + PLIST_ENTRY ListEntry, NextEntry; + + /* Make sure list is properly initialized */ + if(ListHead->Flink == 0 || ListHead->Blink == 0) + { + /* List not initialized, return error code */ + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Iterate through all elements */ + ListEntry = ListHead->Flink; + while(ListEntry != ListHead) + { + /* Save physical address of the next element */ + NextEntry = ListEntry->Flink; + + /* Convert the address of this element to VirtualAddress */ + if(ListEntry->Flink == ListHead) + { + /* Convert list head */ + ListEntry->Flink = ListHead->Flink->Blink; + } + else + { + /* Convert list entry */ + ListEntry->Flink = BlPhysicalAddressToVirtual(ListEntry->Flink, (PVOID)PhysicalBase, VirtualBase); + } + if(ListEntry->Blink == ListHead) + { + /* Find virtual address of list head */ + ListEntry->Blink = BlGetVirtualAddress(PageMap, ListEntry->Blink); + } + else + { + /* Convert list entry */ + ListEntry->Blink = BlPhysicalAddressToVirtual(ListEntry->Blink, (PVOID)PhysicalBase, VirtualBase); + } + + /* Get to the next element*/ + ListEntry = NextEntry; + } + + /* Convert list head */ + ListHead->Flink = BlPhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase); + ListHead->Blink = BlPhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase); + + /* Return success */ + return STATUS_EFI_SUCCESS; +} + /** * Converts EFI memory type to XTLDR memory type. * diff --git a/xtldr/protocol.c b/xtldr/protocol.c index 5f8fe15..7b07c26 100644 --- a/xtldr/protocol.c +++ b/xtldr/protocol.c @@ -632,11 +632,13 @@ BlpInstallXtLoaderProtocol() BlpLdrProtocol.Memory.FreePool = BlFreeMemoryPool; BlpLdrProtocol.Memory.GetMappingsCount = BlGetMappingsCount; BlpLdrProtocol.Memory.GetMemoryMap = BlGetMemoryMap; + BlpLdrProtocol.Memory.GetVirtualAddress = BlGetVirtualAddress; BlpLdrProtocol.Memory.InitializePageMap = BlInitializePageMap; BlpLdrProtocol.Memory.MapEfiMemory = BlMapEfiMemory; BlpLdrProtocol.Memory.MapPage = BlMapPage; BlpLdrProtocol.Memory.MapVirtualMemory = BlMapVirtualMemory; BlpLdrProtocol.Memory.PhysicalAddressToVirtual = BlPhysicalAddressToVirtual; + BlpLdrProtocol.Memory.PhysicalListToVirtual = BlPhysicalListToVirtual; BlpLdrProtocol.Memory.SetMemory = RtlSetMemory; BlpLdrProtocol.Memory.ZeroMemory = RtlZeroMemory; BlpLdrProtocol.Protocol.Close = BlCloseProtocol;