From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-in5.apple.com (mail-out5.apple.com [17.151.62.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 3319481935 for ; Mon, 9 Jan 2017 16:47:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; d=apple.com; s=mailout2048s; c=relaxed/simple; q=dns/txt; i=@apple.com; t=1484009232; h=From:Sender:Reply-To:Subject:Date:Message-id:To:Cc:MIME-version:Content-type: Content-transfer-encoding:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-reply-to:References:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=B2yGzsuD/eqEmODjWtH61uLg9MGgICfQVIkFDWr96GA=; b=w1YpX4gNKhdPjQnr5tWo5nfYs5gN4zxLJ1UhizPADh5Qah4JyquoVf9zYQMzjtpl SbAlEdY8a+5HH0dUAR/QMfzj10AMjDn+a4FmfJ4OJBFU8oNJUyBiItpKKnGYHQR+ +g27DMzfFAJtReKSSp4qVuATHUNDdcivswz5YlwXWO+z1chsVENTHlJ0N9mxJQpF vlNJhUPeLYrQmcgJeeN9UZTt977l/mQ7N0C2BEGloW8VI1Srm8aFgL0iuLJDmZ5J Vr2sY1KmXSUgRjDC1rH1mNmJAQG2vrsYy4SLHLW49UldynaFrogOSJCHd1m20/mr Cbxh07bnH4EYx9O9dpceIA==; Received: from relay6.apple.com (relay6.apple.com [17.128.113.90]) by mail-in5.apple.com (Apple Secure Mail Relay) with SMTP id A3.77.12965.01F24785; Mon, 9 Jan 2017 16:47:12 -0800 (PST) X-AuditID: 11973e13-f2dff700000032a5-fd-58742f102289 Received: from nwk-mmpp-sz07.apple.com (nwk-mmpp-sz07.apple.com [17.128.115.240]) by relay6.apple.com (Apple SCV relay) with SMTP id 8E.07.23613.01F24785; Mon, 9 Jan 2017 16:47:12 -0800 (PST) MIME-version: 1.0 Received: from [17.114.152.206] (unknown [17.114.152.206]) by nwk-mmpp-sz07.apple.com (Oracle Communications Messaging Server 8.0.1.1.0 64bit (built Jun 15 2016)) with ESMTPSA id <0OJJ00937GUONA80@nwk-mmpp-sz07.apple.com>; Mon, 09 Jan 2017 16:47:12 -0800 (PST) Sender: afish@apple.com From: Andrew Fish In-reply-to: <1484007421-15462-2-git-send-email-leo.duran@amd.com> Date: Mon, 09 Jan 2017 16:47:11 -0800 Cc: edk2-devel , "Tian, Feng" , brijesh.singh@amd.com, Ard Biesheuvel , Jordan Justen , "Agyeman, Prince" , lersek@redhat.com, star.zeng@intel.com Message-id: <24BD7DF0-C741-4DE7-965E-46451968F574@apple.com> References: <1484007421-15462-1-git-send-email-leo.duran@amd.com> <1484007421-15462-2-git-send-email-leo.duran@amd.com> To: Leo Duran X-Mailer: Apple Mail (2.3226) X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrLLMWRmVeSWpSXmKPExsUi2FAYpSugXxJh0Pzb0OL/h92MFjM39TFa 7Dl0lNli0m52ix3X+lksup+fZLdYdmwHi0Xr52VMFvt6rR04PVov/WXzWLznJZPHnWt72Dy6 Z/9j8Xi/7ypbAGsUl01Kak5mWWqRvl0CV8a6VVuYC9ZuZayY9+0JawPjx2bGLkZODgkBE4k/ K1ezdDFycQgJ7GWUuHl6IRNM4tD8+WwQiUOMEp+X/mQFSfAKCEr8mHwPqIODg1lAXuLgeVmQ MLOAlsT3R61Qg3qYJBqvrWcHSQgLiEu8O7OJGcJ2lljVcADMZhNQllgx/wNYDaeAk8T11XfA FrMIqEpM2tzMDjKIWWAGk8S+z41sEIttJI6/vwdmCwlUSiw/2g7WICKgKPFn20YmkIMkBGQl Zv/yAumVEPjPJvFp0k7GCYzCs5DcPQvh7llI7l7AyLyKUSg3MTNHNzPPVC+xoCAnVS85P3cT Iyh+ptsJ72A8vcrqEKMAB6MSD2/EhOIIIdbEsuLK3EOM0hwsSuK8uXIlEUIC6YklqdmpqQWp RfFFpTmpxYcYmTg4pRoYY83/zM6Mnu7k67w3RdZZ32rz/WfrVzm1pO97q9Nvtabce+1ZVadC f8kns6unuOhmmGn6vXzfqp6uIb0248l+wSnpPEf4p3+62Pyhtsrcw6Bm41q5qC2ne3/VbDCY 0MvsODdjbfO2R/8C8x6W35966TYzq+TNnhNRIYcck15sSTDlVbq3sMxIiaU4I9FQi7moOBEA 7XUTtoACAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrCIsWRmVeSWpSXmKPExsUi2FD8QVdAvyTCYGG3ssX/D7sZLWZu6mO0 2HPoKLPFpN3sFjuu9bNYdD8/yW6x7NgOFovWz8uYLPb1WjtwerRe+svmsXjPSyaPO9f2sHl0 z/7H4vF+31W2ANYoLpuU1JzMstQifbsErox1q7YwF6zdylgx79sT1gbGj82MXYycHBICJhKH 5s9ng7DFJC7cWw9kc3EICRxilPi89CcrSIJXQFDix+R7LF2MHBzMAvISB8/LgoSZBbQkvj9q ZYGo72GSaLy2nh0kISwgLvHuzCZmCNtZYlXDATCbTUBZYsX8D2A1nAJOEtdX32ECsVkEVCUm bW5mBxnELDCDSWLf50Y2iMU2Esff3wOzhQQqJZYfbQdrEBFQlPizbSMTyEESArISs395TWAU nIXk1FkIp85CcuoCRuZVjAJFqTmJlWZ6iQUFOal6yfm5mxjBcVAYtYOxYbnVIUYBDkYlHt6E 6cURQqyJZcWVucCw4GBWEuFdqV0SIcSbklhZlVqUH19UmpNafIgxGej+icxSosn5wBjNK4k3 NDExMDE2NjM2NjcxJ01YSZzXXzInQkggPbEkNTs1tSC1CGYLEwenVAMjx4cmtWV7C/WebV+s EHAqMUpy++3lIU/3vjj175bvtnU7Z7876s9xpPjs1BOflL+edojqvy7weKtFXM2hH68WZM5S 1Fn48tTrZ6VFS//ILfe3KhJxOefYJp4ZFLTsn/r+CYKx/KUtC1tm9SuvPbvjSUxCYFDJMvbu Fwfm8ollsEpxu9jdufXASomlOCPRUIu5qDgRAJn9lo/HAgAA Subject: Re: [RFC 1/6] MdeModulePkg: Add DxeBmDmaLib library X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 Jan 2017 00:47:13 -0000 Content-transfer-encoding: 7BIT Content-type: text/plain; CHARSET=US-ASCII > On Jan 9, 2017, at 4:16 PM, Leo Duran wrote: > > This patch provides an abstraction layer for DMA operations implemented > by the PciHostBridgeDxe driver. The intent is to then allow override of > this library as may be required by specific hardware implementations, > such as AMD's Secure Encrypted Virtualization (SEV). > > This new (BmDmaLib class) library is modeled after the existing DmaLib > plus an extra DmaAbove4GB (BOOLEAN) parameter in the Map and Allocate > interfaces, so that decisions can be made about the need to allocate DMA > buffers below the 4GB boundary. > Leo, Sorry to jump in late, and maybe this is a phase 2 kind of thing, but should we support a generic IOMMU architecture via this library? I'm not really familiar with AMD's SEV, but in general an IO MMU can restrict a DMA buffer to a specific PCI device, and block other PCI devices from having access to that buffer. That would seem to imply it would be good to have the option of passing the PCI device via these library APIs or I guess we could add an Ex version of the APIs that include the PCI device? You could always implement the Ex versions of the API by ignoring the PCI device (if you don't care about per device IOMMU pertection) and calling the non-Ex version. To be honest it is kind of hard to fully implement an IOMMU with the current UEFI spec as is, but I thought it be worth asking the question? Thanks, Andrew Fish > Cc: Feng Tian > Cc: Star Zeng > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Leo Duran > --- > MdeModulePkg/Include/Library/BmDmaLib.h | 161 +++++++++++ > MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.c | 351 +++++++++++++++++++++++ > MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf | 41 +++ > MdeModulePkg/MdeModulePkg.dsc | 1 + > 4 files changed, 554 insertions(+) > create mode 100644 MdeModulePkg/Include/Library/BmDmaLib.h > create mode 100644 MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.c > create mode 100644 MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf > > diff --git a/MdeModulePkg/Include/Library/BmDmaLib.h b/MdeModulePkg/Include/Library/BmDmaLib.h > new file mode 100644 > index 0000000..2c0e50f > --- /dev/null > +++ b/MdeModulePkg/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 Pages The number of pages to free. > + @param HostAddress The base system memory address of the allocated range. > + > + @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 UINTN Pages, > + IN VOID *HostAddress > + ); > + > + > +#endif > + > diff --git a/MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.c b/MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.c > new file mode 100644 > index 0000000..824b51f > --- /dev/null > +++ b/MdeModulePkg/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 ( > + Operation, > + FORCE_BELOW_4GB_TRUE, > + 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 Pages The number of pages to free. > + @param HostAddress The base system memory address of the allocated range. > + > + @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 UINTN Pages, > + IN VOID *HostAddress > + ) > +{ > + return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages); > +} > + > diff --git a/MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf b/MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf > new file mode 100644 > index 0000000..06bb8b1 > --- /dev/null > +++ b/MdeModulePkg/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 > + > +[Sources.common] > + DxeBmDmaLib.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > + DebugLib > + DxeServicesTableLib > + MemoryAllocationLib > + UefiBootServicesTableLib > + > + > diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc > index 5996fe5..311922e 100644 > --- a/MdeModulePkg/MdeModulePkg.dsc > +++ b/MdeModulePkg/MdeModulePkg.dsc > @@ -275,6 +275,7 @@ [Components] > MdeModulePkg/Core/Pei/PeiMain.inf > MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf > > + MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf > MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf > MdeModulePkg/Library/UefiMemoryAllocationProfileLib/UefiMemoryAllocationProfileLib.inf > MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf > -- > 1.9.1 > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel