diff --git a/xtldr/CMakeLists.txt b/xtldr/CMakeLists.txt index b83193a..7116b7f 100644 --- a/xtldr/CMakeLists.txt +++ b/xtldr/CMakeLists.txt @@ -14,6 +14,7 @@ list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/blproto.c ${XTLDR_SOURCE_DIR}/console.c ${XTLDR_SOURCE_DIR}/efiutil.c + ${XTLDR_SOURCE_DIR}/memory.c ${XTLDR_SOURCE_DIR}/string.c ${XTLDR_SOURCE_DIR}/system.c ${XTLDR_SOURCE_DIR}/volume.c diff --git a/xtldr/efiutil.c b/xtldr/efiutil.c index 9a8067f..a25f84c 100644 --- a/xtldr/efiutil.c +++ b/xtldr/efiutil.c @@ -162,84 +162,6 @@ BlDbgPrint(IN PUINT16 Format, } } -/** - * This routine allocates one or more 4KB pages. - * - * @param Pages - * The number of contiguous 4KB pages to allocate. - * - * @param Memory - * The pointer to a physical address. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -EFI_STATUS -BlEfiMemoryAllocatePages(IN UINT64 Pages, - OUT PEFI_PHYSICAL_ADDRESS Memory) -{ - return EfiSystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, Pages, Memory); -} - -/** - * This routine allocates a pool memory. - * - * @param Size - * The number of bytes to allocate from the pool. - * - * @param Memory - * The pointer to a physical address. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -EFI_STATUS -BlEfiMemoryAllocatePool(IN UINT_PTR Size, - OUT PVOID *Memory) -{ - /* Allocate pool */ - return EfiSystemTable->BootServices->AllocatePool(EfiLoaderData, Size, Memory); -} - -/** - * This routine frees memory pages. - * - * @param Pages - * The number of contiguous 4 KB pages to free. - * - * @param Memory - * The base physical address of the pages to be freed. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -EFI_STATUS -BlEfiMemoryFreePages(IN UINT64 Pages, - IN EFI_PHYSICAL_ADDRESS Memory) -{ - return EfiSystemTable->BootServices->FreePages(Memory, Pages); -} - -/** - * Returns pool memory to the system. - * - * @param Memory - * The pointer to the buffer to free. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -EFI_STATUS -BlEfiMemoryFreePool(IN PVOID Memory) -{ - /* Free pool */ - return EfiSystemTable->BootServices->FreePool(Memory); -} - /** * This routine formats the input string and prints it out to the stdout and serial console. * diff --git a/xtldr/includes/xtbl.h b/xtldr/includes/xtbl.h index 4c7e38e..5783076 100644 --- a/xtldr/includes/xtbl.h +++ b/xtldr/includes/xtbl.h @@ -85,6 +85,12 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, IN CONST PWCHAR FileSystemPath, OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath); +EFI_STATUS +BlGetMemoryMap(OUT PEFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT PUINT_PTR MapKey, + OUT PUINT_PTR DescriptorSize, + OUT PUINT_PTR DescriptorCount); + EFI_STATUS BlGetVolumeDevicePath(IN PUCHAR SystemPath, OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, diff --git a/xtldr/memory.c b/xtldr/memory.c new file mode 100644 index 0000000..40a3bf2 --- /dev/null +++ b/xtldr/memory.c @@ -0,0 +1,162 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtldr/memory.c + * DESCRIPTION: EFI memory management + * DEVELOPERS: Rafal Kupiec + */ + +#include + +/** + * This routine allocates one or more 4KB pages. + * + * @param Pages + * The number of contiguous 4KB pages to allocate. + * + * @param Memory + * The pointer to a physical address. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +EFI_STATUS +BlEfiMemoryAllocatePages(IN UINT64 Pages, + OUT PEFI_PHYSICAL_ADDRESS Memory) +{ + return EfiSystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, Pages, Memory); +} + +/** + * This routine allocates a pool memory. + * + * @param Size + * The number of bytes to allocate from the pool. + * + * @param Memory + * The pointer to a physical address. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +EFI_STATUS +BlEfiMemoryAllocatePool(IN UINT_PTR Size, + OUT PVOID *Memory) +{ + /* Allocate pool */ + return EfiSystemTable->BootServices->AllocatePool(EfiLoaderData, Size, Memory); +} + +/** + * This routine frees memory pages. + * + * @param Pages + * The number of contiguous 4 KB pages to free. + * + * @param Memory + * The base physical address of the pages to be freed. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +EFI_STATUS +BlEfiMemoryFreePages(IN UINT64 Pages, + IN EFI_PHYSICAL_ADDRESS Memory) +{ + return EfiSystemTable->BootServices->FreePages(Memory, Pages); +} + +/** + * Returns pool memory to the system. + * + * @param Memory + * The pointer to the buffer to free. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +EFI_STATUS +BlEfiMemoryFreePool(IN PVOID Memory) +{ + /* Free pool */ + return EfiSystemTable->BootServices->FreePool(Memory); +} + +/** + * Returns the memory descriptors which define a memory map of all the physical memory ranges reserved by the UEFI. + * + * @param MemoryMap + * Supplies a pointer to the buffer where memory map will be written. + * + * @param MapKey + * Supplies a pointer where the firmware stores the map key. + * + * @param DescriptorSize + * Supplies a pointer where the size of EFI_MEMORY_DESCRIPTOR will be stored. + * + * @param DescriptorCount + * Supplies a pointer where number of written descriptors will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +EFI_STATUS +BlGetMemoryMap(OUT PEFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT PUINT_PTR MapKey, + OUT PUINT_PTR DescriptorSize, + OUT PUINT_PTR DescriptorCount) +{ + PEFI_MEMORY_DESCRIPTOR LocalMemoryMap = NULL; + UINT_PTR MemoryMapSize = 0, LocalMapKey, LocalDescriptorSize; + UINT32 DescriptorVersion; + EFI_STATUS Status; + + /* Get memory map */ + do + { + /* Attempt do get EFI memory map */ + Status = EfiSystemTable->BootServices->GetMemoryMap(&MemoryMapSize, LocalMemoryMap, &LocalMapKey, + &LocalDescriptorSize, &DescriptorVersion); + if(Status == STATUS_EFI_SUCCESS) + { + /* Go further if succeeded */ + break; + } + else if(Status != STATUS_EFI_BUFFER_TOO_SMALL) + { + /* Some error occurred */ + if(MemoryMap) + { + /* Free allocated memory */ + BlEfiMemoryFreePool(MemoryMap); + } + return Status; + } + + /* Allocate the desired amount of memory */ + MemoryMapSize += 2 * LocalDescriptorSize; + BlEfiMemoryAllocatePool(MemoryMapSize, (PVOID *)&LocalMemoryMap); + } + while(Status == STATUS_EFI_BUFFER_TOO_SMALL); + + /* Make sure memory map is set */ + if(LocalMemoryMap == NULL) + { + /* Something went wrong */ + return STATUS_EFI_INVALID_PARAMETER; + } + + /* Store memory map details */ + *MemoryMap = LocalMemoryMap; + *MapKey = LocalMapKey; + *DescriptorSize = LocalDescriptorSize; + *DescriptorCount = MemoryMapSize / LocalDescriptorSize; + + /* Return success */ + return STATUS_EFI_SUCCESS; +}