diff --git a/boot/xtldr/includes/xtldr.hh b/boot/xtldr/includes/xtldr.hh index cb91068..bc42aab 100644 --- a/boot/xtldr/includes/xtldr.hh +++ b/boot/xtldr/includes/xtldr.hh @@ -177,7 +177,8 @@ class Memory IN SHORT PageMapLevel, IN PAGE_SIZE PageSize); STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, - IN OUT PVOID *MemoryMapAddress, + IN OUT PVOID *BaseAddress, + IN BOOLEAN IdentityMapping, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine); STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, diff --git a/boot/xtldr/memory.cc b/boot/xtldr/memory.cc index 7a765b0..f3cc773 100644 --- a/boot/xtldr/memory.cc +++ b/boot/xtldr/memory.cc @@ -314,9 +314,12 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap, * @param PageMap * Supplies a pointer to the page mapping structure. * - * @param MemoryMapAddress + * @param BaseAddress * Supplies a virtual address, where EFI memory will be mapped. * + * @param IdentityMapping + * Specifies whether EFI non-free memory should be mapped by identity or sequential mapping. + * * @param GetMemoryTypeRoutine * Supplies a pointer to the routine which will be used to match EFI memory type to the OS memory type. * @@ -327,7 +330,8 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap, XTCDECL EFI_STATUS Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, - IN OUT PVOID *MemoryMapAddress, + IN OUT PVOID *BaseAddress, + IN BOOLEAN IdentityMapping, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine) { ULONGLONG MaxAddress, VirtualAddress; @@ -339,7 +343,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, SIZE_T Index; /* Set virtual address as specified in argument */ - VirtualAddress = (ULONGLONG)*MemoryMapAddress; + VirtualAddress = (ULONGLONG)*BaseAddress; /* Check if custom memory type routine is specified */ if(GetMemoryTypeRoutine == NULLPTR) @@ -419,12 +423,22 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, } else if(MemoryType != LoaderFree) { - /* Add any non-free memory mapping */ - Status = MapVirtualMemory(PageMap, VirtualAddress, Descriptor->PhysicalStart, - Descriptor->NumberOfPages, MemoryType); + /* Check mapping strategy */ + if(IdentityMapping) + { + /* Add any non-free memory using identity mapping */ + Status = MapVirtualMemory(PageMap, Descriptor->PhysicalStart + KSEG0_BASE, Descriptor->PhysicalStart, + Descriptor->NumberOfPages, MemoryType); + } + else + { + /* Add any non-free memory using sequential mapping */ + Status = MapVirtualMemory(PageMap, VirtualAddress, Descriptor->PhysicalStart, + Descriptor->NumberOfPages, MemoryType); - /* Update virtual address */ - VirtualAddress = VirtualAddress + (Descriptor->NumberOfPages * MM_PAGE_SIZE); + /* Update virtual address */ + VirtualAddress = VirtualAddress + (Descriptor->NumberOfPages * MM_PAGE_SIZE); + } } else { @@ -462,7 +476,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, } /* Store next valid virtual address and return success */ - *MemoryMapAddress = (PVOID)VirtualAddress; + *BaseAddress = (PVOID)VirtualAddress; return STATUS_EFI_SUCCESS; } diff --git a/boot/xtldr/modules/xtos_o/amd64/memory.cc b/boot/xtldr/modules/xtos_o/amd64/memory.cc index 02335aa..4ec271c 100644 --- a/boot/xtldr/modules/xtos_o/amd64/memory.cc +++ b/boot/xtldr/modules/xtos_o/amd64/memory.cc @@ -10,6 +10,21 @@ #include +/** + * Determines the appropriate EFI memory mapping strategy for the AMD64 architecture. + * + * @return This routine returns TRUE, what results in an identity mapping. + * + * @since XT 1.0 + */ +XTCDECL +BOOLEAN +Xtos::DetermineMappingStrategy() +{ + /* Use an identity mapping strategy */ + return TRUE; +} + /** * Determines the appropriate paging level (PML) for the AMD64 architecture. * diff --git a/boot/xtldr/modules/xtos_o/i686/memory.cc b/boot/xtldr/modules/xtos_o/i686/memory.cc index 44ee233..e4fbdf3 100644 --- a/boot/xtldr/modules/xtos_o/i686/memory.cc +++ b/boot/xtldr/modules/xtos_o/i686/memory.cc @@ -9,6 +9,21 @@ #include +/** + * Determines the appropriate EFI memory mapping strategy for the i686 architecture. + * + * @return This routine returns FALSE, what results in a sequential mapping. + * + * @since XT 1.0 + */ +XTCDECL +BOOLEAN +Xtos::DetermineMappingStrategy() +{ + /* Use a sequential mapping strategy */ + return FALSE; +} + /** * Determines the appropriate paging level (PML) for the i686 architecture. * diff --git a/boot/xtldr/modules/xtos_o/includes/xtos.hh b/boot/xtldr/modules/xtos_o/includes/xtos.hh index 4d70606..708ce14 100644 --- a/boot/xtldr/modules/xtos_o/includes/xtos.hh +++ b/boot/xtldr/modules/xtos_o/includes/xtos.hh @@ -39,6 +39,7 @@ class Xtos IN UINT NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType); STATIC XTCDECL LOADER_MEMORY_TYPE ConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType); + STATIC XTCDECL BOOLEAN DetermineMappingStrategy(); STATIC XTCDECL ULONG DeterminePagingLevel(IN CONST PWCHAR Parameters); STATIC XTCDECL EFI_STATUS EnablePaging(IN PXTBL_PAGE_MAPPING PageMap); STATIC XTCDECL VOID GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource, diff --git a/boot/xtldr/modules/xtos_o/xtos.cc b/boot/xtldr/modules/xtos_o/xtos.cc index aabecb9..bf20174 100644 --- a/boot/xtldr/modules/xtos_o/xtos.cc +++ b/boot/xtldr/modules/xtos_o/xtos.cc @@ -618,6 +618,7 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir, EFI_HANDLE ProtocolHandle; EFI_STATUS Status; XTBL_PAGE_MAPPING PageMap; + BOOLEAN IdentityMapping; /* Initialize XTOS startup sequence */ XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n"); @@ -634,18 +635,30 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir, /* Close FrameBuffer protocol */ XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid); + /* Determine whether to use a sequential or an identity mapping strategy */ + IdentityMapping = DetermineMappingStrategy(); + /* Set base virtual memory area for the kernel mappings */ VirtualAddress = (PVOID)(KSEG0_BASE); /* Initialize virtual memory mappings */ XtLdrProtocol->Memory.InitializePageMap(&PageMap, DeterminePagingLevel(Parameters->Parameters), Size4K); - Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualAddress, NULLPTR); + /* Map all EFI memory regions */ + Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualAddress, IdentityMapping, NULLPTR); if(Status != STATUS_EFI_SUCCESS) { + /* Mapping failed */ return Status; } + /* Check mapping strategy */ + if(IdentityMapping) + { + /* Adjust virtual address to skip the identity-mapped physical range */ + VirtualAddress = (PVOID)((ULONGLONG)VirtualAddress + 0x800000000); + } + /* Load the kernel */ Status = LoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext); if(Status != STATUS_EFI_SUCCESS) diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 1f7f948..3cc2378 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -100,7 +100,7 @@ typedef VOID (XTCDECL *PBL_LLIST_INITIALIZE_HEAD)(IN PLIST_ENTRY ListHead); typedef VOID (XTCDECL *PBL_LLIST_INSERT_HEAD)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry); typedef VOID (XTCDECL *PBL_LLIST_INSERT_TAIL)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry); typedef VOID (XTCDECL *PBL_LLIST_REMOVE_ENTRY)(IN PLIST_ENTRY Entry); -typedef EFI_STATUS (XTCDECL *PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *MemoryMapAddress, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine); +typedef EFI_STATUS (XTCDECL *PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *BaseAddress, IN BOOLEAN IdentityMapping, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine); typedef EFI_STATUS (XTCDECL *PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, IN ULONGLONG PhysicalAddress, IN ULONGLONG NumberOfPages); typedef EFI_STATUS (XTCDECL *PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, IN ULONGLONG PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType); typedef VOID (XTAPI *PBL_MOVE_MEMORY)(IN OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length);