From nobody Sat Nov 2 10:28:14 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zoho.com; dkim=fail spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1493138182459827.2172004631722; Tue, 25 Apr 2017 09:36:22 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 256BF2193CF44; Tue, 25 Apr 2017 09:36:16 -0700 (PDT) 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) 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) X-Original-To: edk2-devel@lists.01.org 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) From: Brijesh Singh To: edk2-devel@lists.01.org, lersek@redhat.com, jordan.l.justen@intel.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: [edk2] [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: , Cc: thomas.lendacky@amd.com, brijesh.singh@amd.com, ard.biesheuvel@linaro.org, liming.gao@intel.com, leo.duran@amd.com, jiewen.yao@intel.com, star.zeng@intel.com MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" 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/UefiHiiServic= esLib.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/UefiBootManag= erLib.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/UefiHiiServic= esLib.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/UefiBootManag= erLib.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/UefiHiiServic= esLib.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/UefiBootManag= erLib.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 B= SD 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 IM= PLIED. +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D DxeBmDmaLib + FILE_GUID =3D daa403e0-071d-44ef-95cf-7f2472e4a4d5 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D 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/B= mDmaLib.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 BS= D License + which accompanies this distribution. The full text of the license may b= e 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 IMP= LIED. + + 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 pro= cessor 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 m= emory. + + Operation is relative to the DMA bus master. + + @param DmaAbove4GB Indicates capability of DMA operations abo= ve 4GB. + @param Operation Indicates if the bus master is going to re= ad or write to system memory. + @param HostAddress The system memory address to map to the DM= A controller. + @param NumberOfBytes On input the number of bytes to map. On ou= tput the number of bytes + that were mapped. + @param DeviceAddress The resulting map address for the bus mast= er 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 Numb= erOfBytes. + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a comm= on 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 requ= ested 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 s= ystem memory. + +**/ +EFI_STATUS +EFIAPI +BmDmaUnmap ( + IN VOID *Mapping + ); + + +/** + Allocates pages that are suitable for a BmDmaMap() of type DmaOperationB= usMasterCommonBuffer. + + @param DmaAbove4GB Indicates capability of DMA operations abo= ve 4GB. + @param MemoryType The type of memory to allocate: EfiBootSer= vicesData 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 allo= cated 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/Dx= eBmDmaLib/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 BS= D License + which accompanies this distribution. The full text of the license may b= e 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 IMP= LIED. + + 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 =3D AllocatePool (sizeof (MAP_INFO)); + if (MapInfo =3D=3D NULL) { + *NumberOfBytes =3D 0; + return EFI_OUT_OF_RESOURCES; + } + + // + // Initialize the MAP_INFO structure + // + MapInfo->Operation =3D Operation; + MapInfo->NumberOfBytes =3D *NumberOfBytes; + MapInfo->NumberOfPages =3D EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes); + MapInfo->HostAddress =3D HostAddress; + + if (ForceBelow4GB) { + // + // Limit allocations to memory below 4GB + // + AllocateType =3D AllocateMaxAddress; + MapInfo->MappedHostAddress =3D SIZE_4GB - 1; + } else { + AllocateType =3D AllocateAnyPages; + } + + // + // Allocate DMA bounce buffer + // + Status =3D gBS->AllocatePages ( + AllocateType, + EfiBootServicesData, + MapInfo->NumberOfPages, + &MapInfo->MappedHostAddress + ); + + if (EFI_ERROR (Status)) { + FreePool (MapInfo); + *NumberOfBytes =3D 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 =3D=3D DmaOperationBusMasterRead) { + CopyMem ( + (VOID *) (UINTN) MapInfo->MappedHostAddress, + (VOID *) (UINTN) MapInfo->HostAddress, + MapInfo->NumberOfBytes + ); + } + + // + // The DeviceAddress is the address of the mapped buffer + // + *DeviceAddress =3D MapInfo->MappedHostAddress; + + // + // Return a pointer to the MAP_INFO structure in Mapping + // + *Mapping =3D MapInfo; + + return EFI_SUCCESS; +} + + +/** + Provides the DMA controller-specific addresses needed to access system m= emory. + + Operation is relative to the DMA bus master. + + @param DmaAbove4GB Indicates capability of DMA operations abo= ve 4GB. + @param Operation Indicates if the bus master is going to re= ad or write to system memory. + @param HostAddress The system memory address to map to the DM= A controller. + @param NumberOfBytes On input the number of bytes to map. On ou= tput the number of bytes + that were mapped. + @param DeviceAddress The resulting map address for the bus mast= er 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 Numb= erOfBytes. + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a comm= on 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 requ= ested 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 =3D=3D NULL || NumberOfBytes =3D=3D NULL || DeviceAddres= s =3D=3D NULL || + Mapping =3D=3D NULL || (UINT32) Operation >=3D DmaOperationBusMaster= Maximum) { + return EFI_INVALID_PARAMETER; + } + + PhysicalAddress =3D (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress; + if (DmaAbove4GB || (PhysicalAddress + *NumberOfBytes) <=3D SIZE_4GB) { + // + // If we CAN handle DMA above 4GB or the transfer is below 4GB, + // the DeviceAddress is simply the HostAddress + // + *DeviceAddress =3D PhysicalAddress; + *Mapping =3D 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 =3D=3D 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 s= ystem memory. + +**/ +EFI_STATUS +EFIAPI +BmDmaUnmap ( + IN VOID *Mapping + ) +{ + MAP_INFO *MapInfo; + + // + // Check for invalid inputs + // + if (Mapping =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // See if the Map() operation associated with this Unmap() required a ma= pping + // buffer. If a mapping buffer was not required, then this function simp= ly + // returns EFI_SUCCESS. + // + if (Mapping =3D=3D 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 =3D (MAP_INFO *)Mapping; + if (MapInfo->Operation =3D=3D 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 DmaOperationB= usMasterCommonBuffer. + + @param DmaAbove4GB Indicates capability of DMA operations abo= ve 4GB. + @param MemoryType The type of memory to allocate: EfiBootSer= vicesData 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 =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // The only valid memory types are EfiBootServicesData and + // EfiRuntimeServicesData + // + if (MemoryType !=3D EfiBootServicesData && + MemoryType !=3D EfiRuntimeServicesData) { + return EFI_INVALID_PARAMETER; + } + + if (DmaAbove4GB) { + AllocateType =3D AllocateAnyPages; + } else { + // + // Limit allocations to memory below 4GB + // + AllocateType =3D AllocateMaxAddress; + PhysicalAddress =3D (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1); + } + Status =3D gBS->AllocatePages ( + AllocateType, + MemoryType, + Pages, + &PhysicalAddress + ); + if (!EFI_ERROR (Status)) { + *HostAddress =3D (VOID *) (UINTN) PhysicalAddress; + } + + return Status; +} + + +/** + Frees memory that was allocated with BmDmaAllocateBuffer(). + + @param HostAddress The base system memory address of the allo= cated 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= ); +} + --=20 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel