From 93fa2aed676e0324cede3902e0e79ba6293d47e3 Mon Sep 17 00:00:00 2001 From: belliash Date: Tue, 6 Dec 2022 23:32:31 +0100 Subject: [PATCH] Implement BlMapVirtualMemory() routine for recursive mapping --- sdk/xtdk/amd64/mmtypes.h | 36 ++++++++ sdk/xtdk/i686/mmtypes.h | 36 ++++++++ sdk/xtdk/xtkmapi.h | 3 + xtldr/CMakeLists.txt | 1 + xtldr/amd64/memory.c | 177 +++++++++++++++++++++++++++++++++++++++ xtldr/i686/memory.c | 42 ++++++++++ xtldr/includes/xtbl.h | 7 ++ 7 files changed, 302 insertions(+) create mode 100644 sdk/xtdk/amd64/mmtypes.h create mode 100644 sdk/xtdk/i686/mmtypes.h create mode 100644 xtldr/amd64/memory.c create mode 100644 xtldr/i686/memory.c diff --git a/sdk/xtdk/amd64/mmtypes.h b/sdk/xtdk/amd64/mmtypes.h new file mode 100644 index 0000000..683bbd0 --- /dev/null +++ b/sdk/xtdk/amd64/mmtypes.h @@ -0,0 +1,36 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: sdk/xtdk/amd64/mmtypes.h + * DESCRIPTION: Memory management data structures for AMD64 architecture + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTDK_AMD64_MMTYPES_H +#define __XTDK_AMD64_MMTYPES_H + +#include "xtcommon.h" + + +/* Page Table entry structure definition */ +typedef struct _HARDWARE_PTE +{ + ULONGLONG Valid:1; + ULONGLONG Write:1; + ULONGLONG Owner:1; + ULONGLONG WriteThrough:1; + ULONGLONG CacheDisable:1; + ULONGLONG Accessed:1; + ULONGLONG Dirty:1; + ULONGLONG LargePage:1; + ULONGLONG Global:1; + ULONGLONG CopyOnWrite:1; + ULONGLONG Prototype:1; + ULONGLONG Reserved0:1; + ULONGLONG PageFrameNumber:28; + ULONGLONG Reserved1:12; + ULONGLONG SoftwareWsIndex:11; + ULONGLONG NoExecute:1; +} HARDWARE_PTE, *PHARDWARE_PTE; + +#endif /* __XTDK_AMD64_MMTYPES_H */ diff --git a/sdk/xtdk/i686/mmtypes.h b/sdk/xtdk/i686/mmtypes.h new file mode 100644 index 0000000..7c939c8 --- /dev/null +++ b/sdk/xtdk/i686/mmtypes.h @@ -0,0 +1,36 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: sdk/xtdk/i686/mmtypes.h + * DESCRIPTION: Memory management data structures for i686 architecture + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTDK_I686_MMTYPES_H +#define __XTDK_I686_MMTYPES_H + +#include "xtcommon.h" + + +/* Page Table entry with PAE support structure definition */ +typedef struct _HARDWARE_PTE +{ + ULONGLONG Valid:1; + ULONGLONG Write:1; + ULONGLONG Owner:1; + ULONGLONG WriteThrough:1; + ULONGLONG CacheDisable:1; + ULONGLONG Accessed:1; + ULONGLONG Dirty:1; + ULONGLONG LargePage:1; + ULONGLONG Global:1; + ULONGLONG CopyOnWrite:1; + ULONGLONG Prototype:1; + ULONGLONG Reserved0:1; + ULONGLONG PageFrameNumber:28; + ULONGLONG Reserved1:12; + ULONGLONG SoftwareWsIndex:11; + ULONGLONG NoExecute:1; +} HARDWARE_PTE, *PHARDWARE_PTE; + +#endif /* __XTDK_I686_MMTYPES_H */ diff --git a/sdk/xtdk/xtkmapi.h b/sdk/xtdk/xtkmapi.h index 9778c48..f3c52b8 100644 --- a/sdk/xtdk/xtkmapi.h +++ b/sdk/xtdk/xtkmapi.h @@ -29,6 +29,9 @@ #include "ldrtypes.h" #include "hltypes.h" +/* Architecture-specific low level data types headers */ +#include ARCH_HEADER(mmtypes.h) + /* XT routines */ #include "hlfuncs.h" #include "rtlfuncs.h" diff --git a/xtldr/CMakeLists.txt b/xtldr/CMakeLists.txt index 7116b7f..5aecb7b 100644 --- a/xtldr/CMakeLists.txt +++ b/xtldr/CMakeLists.txt @@ -11,6 +11,7 @@ include_directories( # Specify list of source code files list(APPEND XTLDR_SOURCE + ${XTLDR_SOURCE_DIR}/${ARCH}/memory.c ${XTLDR_SOURCE_DIR}/blproto.c ${XTLDR_SOURCE_DIR}/console.c ${XTLDR_SOURCE_DIR}/efiutil.c diff --git a/xtldr/amd64/memory.c b/xtldr/amd64/memory.c new file mode 100644 index 0000000..f0c4dab --- /dev/null +++ b/xtldr/amd64/memory.c @@ -0,0 +1,177 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/amd64/memory.c + * DESCRIPTION: EFI memory management for AMD64 target + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * This routine does the actual virtual memory mapping. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param VirtualAddress + * Supplies a virtual address of the mapping. + * + * @param PhysicalAddress + * Supplies a physical address of the mapping. + * + * @param NumberOfPages + * Supplies a number of the pages of the mapping. + * + * @param PtePointer + * Supplies a pointer to an array of pointers to page table entries. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +EFI_STATUS +BlMapVirtualMemory(IN PLIST_ENTRY MemoryMappings, + IN UINT_PTR VirtualAddress, + IN UINT_PTR PhysicalAddress, + IN UINT NumberOfPages, + IN OUT PHARDWARE_PTE *PtePointer) +{ + PHARDWARE_PTE PageDirectoryPointTable, PageDirectory, PageTable; + UINT Pml4Index, PdpIndex, PdIndex, PtIndex; + EFI_PHYSICAL_ADDRESS Address; + UINT_PTR PageFrameNumber; + EFI_STATUS Status; + UINT64 Pointer; + + /* Set the PFN */ + PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT; + + /* Do the recursive mapping */ + while(NumberOfPages > 0) + { + /* Calculate indices from a virtual address */ + Pml4Index = (VirtualAddress >> 39) & 0x1FF; + PdpIndex = (VirtualAddress >> 30) & 0x1FF; + PdIndex = (VirtualAddress >> 21) & 0x1FF; + PtIndex = (VirtualAddress >> 12) & 0x1FF; + + /* Validate Page Map Level 4 (PML4) */ + if(!(*PtePointer)[Pml4Index].Valid) + { + /* Allocate pages for the PDPT */ + Status = BlEfiMemoryAllocatePages(1, &Address); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory allocation failure */ + return Status; + } + + /* Add new memory mapping */ + Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); + if(Status != STATUS_EFI_SUCCESS) { + /* Memory mapping failed */ + return Status; + } + + /* Zero memory */ + RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE); + + /* Set paging entry setting */ + (*PtePointer)[Pml4Index].PageFrameNumber = Address / EFI_PAGE_SIZE; + (*PtePointer)[Pml4Index].Valid = 1; + (*PtePointer)[Pml4Index].Write = 1; + PageDirectoryPointTable = (PHARDWARE_PTE)(UINT_PTR)Address; + } + else + { + /* Find Page Directory Point Table (PDPT) */ + Pointer = (*PtePointer)[Pml4Index].PageFrameNumber; + Pointer <<= EFI_PAGE_SHIFT; + PageDirectoryPointTable = (PHARDWARE_PTE)(UINT_PTR)Pointer; + } + + /* Validate Page Directory Point Table (PDPT)*/ + if(!PageDirectoryPointTable[PdpIndex].Valid) + { + /* Allocate pages for the PD */ + Status = BlEfiMemoryAllocatePages(1, &Address); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory allocation failure */ + return Status; + } + + /* Add new memory mapping */ + Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory mapping failed */ + return Status; + } + + /* Zero memory */ + RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE); + + /* Set paging entry setting */ + PageDirectoryPointTable[PdpIndex].PageFrameNumber = Address / EFI_PAGE_SIZE; + PageDirectoryPointTable[PdpIndex].Valid = 1; + PageDirectoryPointTable[PdpIndex].Write = 1; + PageDirectory = (PHARDWARE_PTE)(UINT_PTR)Address; + } + else + { + /* Find Page Directory (PD) */ + Pointer = PageDirectoryPointTable[PdpIndex].PageFrameNumber; + Pointer <<= EFI_PAGE_SHIFT; + PageDirectory = (PHARDWARE_PTE)(UINT_PTR)Pointer; + } + + /* Validate Page Directory (PD)*/ + if(!PageDirectory[PdIndex].Valid) + { + /* Allocate pages for the PT */ + Status = BlEfiMemoryAllocatePages(1, &Address); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory allocation failure */ + return Status; + } + + /* Add new memory mapping */ + Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); + if (Status != STATUS_EFI_SUCCESS) { + /* Memory mapping failed */ + return Status; + } + + /* Zero memory */ + RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE); + + /* Set paging entry setting */ + PageDirectory[PdIndex].PageFrameNumber = Address / EFI_PAGE_SIZE; + PageDirectory[PdIndex].Valid = 1; + PageDirectory[PdIndex].Write = 1; + PageTable = (PHARDWARE_PTE)(UINT_PTR)Address; + } + else + { + /* Find Page Table (PT) */ + Pointer = PageDirectory[PdIndex].PageFrameNumber; + Pointer <<= EFI_PAGE_SHIFT; + PageTable = (PHARDWARE_PTE)(UINT_PTR)Pointer; + } + + /* Set paging entry setting */ + PageTable[PtIndex].PageFrameNumber = PageFrameNumber; + PageTable[PtIndex].Valid = 1; + PageTable[PtIndex].Write = 1; + + /* Take next virtual address and PFN */ + VirtualAddress += EFI_PAGE_SIZE; + PageFrameNumber++; + + /* Decrease number of pages left */ + NumberOfPages--; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} diff --git a/xtldr/i686/memory.c b/xtldr/i686/memory.c new file mode 100644 index 0000000..5ed6a1b --- /dev/null +++ b/xtldr/i686/memory.c @@ -0,0 +1,42 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/i686/memory.c + * DESCRIPTION: EFI memory management for i686 target + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * This routine does the actual virtual memory mapping. + * + * @param MemoryMappings + * Supplies a pointer to linked list containing all memory mappings. + * + * @param VirtualAddress + * Supplies a virtual address of the mapping. + * + * @param PhysicalAddress + * Supplies a physical address of the mapping. + * + * @param NumberOfPages + * Supplies a number of the pages of the mapping. + * + * @param PtePointer + * Supplies a pointer to an array of pointers to page table entries. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +EFI_STATUS +BlMapVirtualMemory(IN PLIST_ENTRY MemoryMappings, + IN UINT_PTR VirtualAddress, + IN UINT_PTR PhysicalAddress, + IN UINT NumberOfPages, + IN OUT PHARDWARE_PTE *PtePointer) +{ + return STATUS_EFI_SUCCESS; +} diff --git a/xtldr/includes/xtbl.h b/xtldr/includes/xtbl.h index 01c1e91..832f954 100644 --- a/xtldr/includes/xtbl.h +++ b/xtldr/includes/xtbl.h @@ -111,6 +111,13 @@ BlInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings, EFI_STATUS BlLoadEfiModules(); +EFI_STATUS +BlMapVirtualMemory(IN PLIST_ENTRY MemoryMappings, + IN UINT_PTR VirtualAddress, + IN UINT_PTR PhysicalAddress, + IN UINT NumberOfPages, + IN OUT PHARDWARE_PTE *PtePointer); + EFI_STATUS BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle,