From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-oi0-x241.google.com (mail-oi0-x241.google.com [IPv6:2607:f8b0:4003:c06::241]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id D6EDB2193CF66 for ; Tue, 25 Apr 2017 09:36:14 -0700 (PDT) Received: by mail-oi0-x241.google.com with SMTP id m34so28207627oik.2 for ; Tue, 25 Apr 2017 09:36:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=KwRyTw0nv4O2O7XWys+fz5Mfu4v03fptsq+8EGGcGgI=; b=VgKfpvnP0u44wzvTAmBP1vhNqOUsMIVl7i65rY6L4nshjr0BTttjkp2lV+bxxa15Ya b3uoDKF2d1TboaNu5/QoRg7g1t+LFPxcXofZrKi+QVZcW3Bw0utQLm8V66BF6XFCDGyD 4oCTnz2GYqNU/A9f/sCzByRZGbuntsHUxxJ08hC1mFTIuLIpEy77JejDP4ZbALb4eC3I qelzlTqwgQW3nbBIaO799FPZxhbP+MxWNYWfwhMNDwqq43FR0We9G7jIvp7Ydd7UoAED WH0RX2Xg6q5l9enbOBSkhHXwNcA6ygH8IgEpzfIH62/GxRn74W55F33qZx1WdvLsrb+n Cv7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=KwRyTw0nv4O2O7XWys+fz5Mfu4v03fptsq+8EGGcGgI=; b=kmUEHe6U5soKmwv5LiN9rFQ2nZqBHHGSgjKJajCat5qxoVcojOoglzItHJNiEF/fuw rw9ef6rYvUzl9QbSQa65iPfUDk6hYm3ph39VxHZStGrV79ZTIsWlUr6KTPeyYO9moe/o mMXO4yDxQo38aFu20RHvW8HDpetxypRJi1LwAdzKB0sXlet0AynlnPne0sZDgMqvM/oW FgsNUHyfugOvY9ELHYoRxJHMWIewwQOyAfLmkHtVsSMwlOcp1hybfv6meQK1MQHYKhed 4ySJU4TRuuP3M/LdFLcfP/veh3sDVm0fb5TgwTVq2dNSDn8U8xl+HdHZo4yI4s58fIkV g1pA== X-Gm-Message-State: AN3rC/7hizkjZ9Ny84tW0j4fXUIegvSw9Nt4uubACawijVlXPZbQBVr9 nz75BWK4m/L+tNhQUAU= X-Received: by 10.202.175.133 with SMTP id y127mr17528834oie.97.1493138173646; Tue, 25 Apr 2017 09:36:13 -0700 (PDT) Received: from brijesh-build-machine.amd.com ([165.204.77.1]) by smtp.gmail.com with ESMTPSA id j17sm9666356ota.24.2017.04.25.09.36.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 25 Apr 2017 09:36:12 -0700 (PDT) From: Brijesh Singh To: edk2-devel@lists.01.org, lersek@redhat.com, jordan.l.justen@intel.com Cc: jiewen.yao@intel.com, leo.duran@amd.com, star.zeng@intel.com, liming.gao@intel.com, ard.biesheuvel@linaro.org, brijesh.singh@amd.com, William.Tambe@amd.com, thomas.lendacky@amd.com Date: Tue, 25 Apr 2017 12:34:15 -0400 Message-Id: <1493138064-7816-7-git-send-email-brijesh.ksingh@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1493138064-7816-1-git-send-email-brijesh.ksingh@gmail.com> References: <1493138064-7816-1-git-send-email-brijesh.ksingh@gmail.com> Subject: [RFC v3 06/15] OvmfPkg/DxeBmDmaLib: Import DxeBmDmaLib package X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 25 Apr 2017 16:36:15 -0000 From: Brijesh Singh Import DxeBmDmaLib package in OvmfPkg, we need to modify the package to include SEV support. The BmDmaLib is proposed by Leo Duran https://lists.01.org/pipermail/edk2-devel/2017-March/008109.html NOTE: This patch is still under discussion and have not been accepted upstream. Signed-off-by: Brijesh Singh --- OvmfPkg/OvmfPkgIa32.dsc | 2 +- OvmfPkg/OvmfPkgIa32X64.dsc | 2 +- OvmfPkg/OvmfPkgX64.dsc | 2 +- OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf | 41 +++ OvmfPkg/Include/Library/BmDmaLib.h | 161 +++++++++ OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c | 351 ++++++++++++++++++++ 6 files changed, 556 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 04e7e0fe948f..0475e10e484a 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -91,7 +91,7 @@ [LibraryClasses] UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf - BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf + BmDmaLib|OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 882dc8daacc8..408ab37e4a88 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -96,7 +96,7 @@ [LibraryClasses] UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf - BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf + BmDmaLib|OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 3cfd09a3f260..dd3674a5d6dc 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -96,7 +96,7 @@ [LibraryClasses] UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf - BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf + BmDmaLib|OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf diff --git a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf new file mode 100644 index 000000000000..4ddb27d578bc --- /dev/null +++ b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf @@ -0,0 +1,41 @@ +## @file +# +# DMA abstraction library APIs. Based on PCI IO protocol DMA abstractions. +# +# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+# Copyright (c) 2017, AMD Inc. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeBmDmaLib + FILE_GUID = daa403e0-071d-44ef-95cf-7f2472e4a4d5 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = BmDmaLib|DXE_DRIVER + +[Sources.common] + DxeBmDmaLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DxeServicesTableLib + MemoryAllocationLib + UefiBootServicesTableLib + + diff --git a/OvmfPkg/Include/Library/BmDmaLib.h b/OvmfPkg/Include/Library/BmDmaLib.h new file mode 100644 index 000000000000..070340c9cca8 --- /dev/null +++ b/OvmfPkg/Include/Library/BmDmaLib.h @@ -0,0 +1,161 @@ +/** @file + DMA abstraction library APIs. Based on PCI IO protocol DMA abstractions. + + Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+ Copyright (c) 2017, AMD Inc. All rights reserved.
+ + DMA Bus Master Read Operation: + Call BmDmaMap() for DmaOperationBusMasterRead. + Program the DMA Bus Master with the DeviceAddress returned by BmDmaMap(). + Start the DMA Bus Master. + Wait for DMA Bus Master to complete the read operation. + Call BmDmaUnmap(). + + DMA Bus Master Write Operation: + Call BmDmaMap() for DmaOperationBusMasterWrite. + Program the DMA Bus Master with the DeviceAddress returned by BmDmaMap(). + Start the DMA Bus Master. + Wait for DMA Bus Master to complete the write operation. + Call BmDmaUnmap(). + + DMA Bus Master Common Buffer Operation: + Call BmDmaAllocateBuffer() to allocate a common buffer. + Call BmDmaMap() for DmaOperationBusMasterCommonBuffer. + Program the DMA Bus Master with the DeviceAddress returned by BmDmaMap(). + The common buffer can now be accessed equally by the processor and the DMA bus master. + Call BmDmaUnmap(). + Call BmDmaFreeBuffer(). + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Derived from: + EmbeddedPkg/Include/Library/DmaLib.h + +**/ + +#ifndef __BM_DMA_LIB_H__ +#define __BM_DMA_LIB_H__ + + +typedef enum { + /// + /// A read operation from system memory by a bus master. + /// + DmaOperationBusMasterRead, + /// + /// A write operation from system memory by a bus master. + /// + DmaOperationBusMasterWrite, + /// + /// Provides both read and write access to system memory by both the processor and a + /// bus master. The buffer is coherent from both the processor's and the bus master's point of view. + /// + DmaOperationBusMasterCommonBuffer, + DmaOperationBusMasterMaximum +} BM_DMA_OPERATION; + + +/** + Provides the DMA controller-specific addresses needed to access system memory. + + Operation is relative to the DMA bus master. + + @param DmaAbove4GB Indicates capability of DMA operations above 4GB. + @param Operation Indicates if the bus master is going to read or write to system memory. + @param HostAddress The system memory address to map to the DMA controller. + @param NumberOfBytes On input the number of bytes to map. On output the number of bytes + that were mapped. + @param DeviceAddress The resulting map address for the bus master controller to use to + access the hosts HostAddress. + @param Mapping A resulting value to pass to BmDmaUnmap(). + + @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. + +**/ +EFI_STATUS +EFIAPI +BmDmaMap ( + IN BOOLEAN DmaAbove4GB, + IN BM_DMA_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ); + + +/** + Completes the DmaOperationBusMasterRead/Write/CommonBuffer operation + and releases any corresponding resources. + + @param Mapping The mapping value returned from BmDmaMap(). + + @retval EFI_SUCCESS The range was unmapped. + @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. + +**/ +EFI_STATUS +EFIAPI +BmDmaUnmap ( + IN VOID *Mapping + ); + + +/** + Allocates pages that are suitable for a BmDmaMap() of type DmaOperationBusMasterCommonBuffer. + + @param DmaAbove4GB Indicates capability of DMA operations above 4GB. + @param MemoryType The type of memory to allocate: EfiBootServicesData or + EfiRuntimeServicesData. + @param Pages The number of pages to allocate. + @param HostAddress A pointer to store the base system memory address of the + allocated range. + + @retval EFI_SUCCESS The requested memory pages were allocated. + @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are + MEMORY_WRITE_COMBINE and MEMORY_CACHED. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + +**/ +EFI_STATUS +EFIAPI +BmDmaAllocateBuffer ( + IN BOOLEAN DmaAbove4GB, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress + ); + + +/** + Frees memory that was allocated with BmDmaAllocateBuffer(). + + @param HostAddress The base system memory address of the allocated range. + @param Pages The number of pages to free. + + @retval EFI_SUCCESS The requested memory pages were freed. + @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages + was not allocated with BmDmaAllocateBuffer(). + +**/ +EFI_STATUS +EFIAPI +BmDmaFreeBuffer ( + IN VOID *HostAddress, + IN UINTN Pages + ); + + +#endif + diff --git a/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c new file mode 100644 index 000000000000..4a6a704f9aa5 --- /dev/null +++ b/OvmfPkg/Library/DxeBmDmaLib/DxeBmDmaLib.c @@ -0,0 +1,351 @@ +/** @file + DMA abstraction library APIs. Based on PCI IO protocol DMA abstractions. + + Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+ Copyright (c) 2017, AMD Inc. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + Derived from: + MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define FORCE_BELOW_4GB_TRUE TRUE +#define FORCE_BELOW_4GB_FALSE FALSE +#define NO_MAPPING (VOID *) (UINTN) -1 + + +typedef struct { + BM_DMA_OPERATION Operation; + UINTN NumberOfBytes; + UINTN NumberOfPages; + EFI_PHYSICAL_ADDRESS HostAddress; + EFI_PHYSICAL_ADDRESS MappedHostAddress; +} MAP_INFO; + + +EFI_STATUS +AllocateBounceBuffer ( + IN BOOLEAN ForceBelow4GB, + IN BM_DMA_OPERATION Operation, + IN EFI_PHYSICAL_ADDRESS HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ) +{ + EFI_STATUS Status; + MAP_INFO *MapInfo; + EFI_ALLOCATE_TYPE AllocateType; + + // + // Allocate a MAP_INFO structure to remember the mapping when Unmap() is + // called later. + // + MapInfo = AllocatePool (sizeof (MAP_INFO)); + if (MapInfo == NULL) { + *NumberOfBytes = 0; + return EFI_OUT_OF_RESOURCES; + } + + // + // Initialize the MAP_INFO structure + // + MapInfo->Operation = Operation; + MapInfo->NumberOfBytes = *NumberOfBytes; + MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes); + MapInfo->HostAddress = HostAddress; + + if (ForceBelow4GB) { + // + // Limit allocations to memory below 4GB + // + AllocateType = AllocateMaxAddress; + MapInfo->MappedHostAddress = SIZE_4GB - 1; + } else { + AllocateType = AllocateAnyPages; + } + + // + // Allocate DMA bounce buffer + // + Status = gBS->AllocatePages ( + AllocateType, + EfiBootServicesData, + MapInfo->NumberOfPages, + &MapInfo->MappedHostAddress + ); + + if (EFI_ERROR (Status)) { + FreePool (MapInfo); + *NumberOfBytes = 0; + return Status; + } + + // + // If this is a read operation from the Bus Master's point of view, + // then copy the contents of the real buffer into the mapped buffer + // so the Bus Master can read the contents of the real buffer. + // + if (Operation == DmaOperationBusMasterRead) { + CopyMem ( + (VOID *) (UINTN) MapInfo->MappedHostAddress, + (VOID *) (UINTN) MapInfo->HostAddress, + MapInfo->NumberOfBytes + ); + } + + // + // The DeviceAddress is the address of the mapped buffer + // + *DeviceAddress = MapInfo->MappedHostAddress; + + // + // Return a pointer to the MAP_INFO structure in Mapping + // + *Mapping = MapInfo; + + return EFI_SUCCESS; +} + + +/** + Provides the DMA controller-specific addresses needed to access system memory. + + Operation is relative to the DMA bus master. + + @param DmaAbove4GB Indicates capability of DMA operations above 4GB. + @param Operation Indicates if the bus master is going to read or write to system memory. + @param HostAddress The system memory address to map to the DMA controller. + @param NumberOfBytes On input the number of bytes to map. On output the number of bytes + that were mapped. + @param DeviceAddress The resulting map address for the bus master controller to use to + access the hosts HostAddress. + @param Mapping A resulting value to pass to BmDmaUnmap(). + + @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. + +**/ +EFI_STATUS +EFIAPI +BmDmaMap ( + IN BOOLEAN DmaAbove4GB, + IN BM_DMA_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ) +{ + EFI_PHYSICAL_ADDRESS PhysicalAddress; + + // + // Check for invalid inputs + // + if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || + Mapping == NULL || (UINT32) Operation >= DmaOperationBusMasterMaximum) { + return EFI_INVALID_PARAMETER; + } + + PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress; + if (DmaAbove4GB || (PhysicalAddress + *NumberOfBytes) <= SIZE_4GB) { + // + // If we CAN handle DMA above 4GB or the transfer is below 4GB, + // the DeviceAddress is simply the HostAddress + // + *DeviceAddress = PhysicalAddress; + *Mapping = NO_MAPPING; + + return EFI_SUCCESS; + } + + // + // If we cannot handle DMA above 4GB and any part of the DMA transfer + // being is above 4GB, then map the DMA transfer to a buffer below 4GB. + // + if (Operation == DmaOperationBusMasterCommonBuffer) { + // + // Common Buffer operations cannot be remapped, so return an error. + // + return EFI_UNSUPPORTED; + } + + return AllocateBounceBuffer ( + FORCE_BELOW_4GB_TRUE, + Operation, + PhysicalAddress, + NumberOfBytes, + DeviceAddress, + Mapping + ); +} + + +/** + Completes the DmaOperationBusMasterRead/Write/CommonBuffer operation + and releases any corresponding resources. + + @param Mapping The mapping value returned from BmDmaMap(). + + @retval EFI_SUCCESS The range was unmapped. + @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. + +**/ +EFI_STATUS +EFIAPI +BmDmaUnmap ( + IN VOID *Mapping + ) +{ + MAP_INFO *MapInfo; + + // + // Check for invalid inputs + // + if (Mapping == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // See if the Map() operation associated with this Unmap() required a mapping + // buffer. If a mapping buffer was not required, then this function simply + // returns EFI_SUCCESS. + // + if (Mapping == NO_MAPPING) { + return EFI_SUCCESS; + } + + // + // If this is a write operation from the Bus Master's point of view, + // then copy the contents of the mapped buffer into the real buffer + // so the processor can read the contents of the real buffer. + // + MapInfo = (MAP_INFO *)Mapping; + if (MapInfo->Operation == DmaOperationBusMasterWrite) { + CopyMem ( + (VOID *) (UINTN) MapInfo->HostAddress, + (VOID *) (UINTN) MapInfo->MappedHostAddress, + MapInfo->NumberOfBytes + ); + } + + // + // Free the mapped buffer and the MAP_INFO structure. + // + gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages); + FreePool (Mapping); + return EFI_SUCCESS; +} + + +/** + Allocates pages that are suitable for a BmDmaMap() of type DmaOperationBusMasterCommonBuffer. + + @param DmaAbove4GB Indicates capability of DMA operations above 4GB. + @param MemoryType The type of memory to allocate: EfiBootServicesData or + EfiRuntimeServicesData. + @param Pages The number of pages to allocate. + @param HostAddress A pointer to store the base system memory address of the + allocated range. + + @retval EFI_SUCCESS The requested memory pages were allocated. + @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are + MEMORY_WRITE_COMBINE and MEMORY_CACHED. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + +**/ +EFI_STATUS +EFIAPI +BmDmaAllocateBuffer ( + IN BOOLEAN DmaAbove4GB, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS PhysicalAddress; + EFI_ALLOCATE_TYPE AllocateType; + + // + // Check for invalid inputs + // + if (HostAddress == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // The only valid memory types are EfiBootServicesData and + // EfiRuntimeServicesData + // + if (MemoryType != EfiBootServicesData && + MemoryType != EfiRuntimeServicesData) { + return EFI_INVALID_PARAMETER; + } + + if (DmaAbove4GB) { + AllocateType = AllocateAnyPages; + } else { + // + // Limit allocations to memory below 4GB + // + AllocateType = AllocateMaxAddress; + PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1); + } + Status = gBS->AllocatePages ( + AllocateType, + MemoryType, + Pages, + &PhysicalAddress + ); + if (!EFI_ERROR (Status)) { + *HostAddress = (VOID *) (UINTN) PhysicalAddress; + } + + return Status; +} + + +/** + Frees memory that was allocated with BmDmaAllocateBuffer(). + + @param HostAddress The base system memory address of the allocated range. + @param Pages The number of pages to free. + + @retval EFI_SUCCESS The requested memory pages were freed. + @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages + was not allocated with BmDmaAllocateBuffer(). + +**/ +EFI_STATUS +EFIAPI +BmDmaFreeBuffer ( + IN VOID *HostAddress, + IN UINTN Pages + ) +{ + return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages); +} + -- 2.7.4