* [PATCH v3 0/6] DxeBmDmaLib (BmDmaLib class) library
@ 2017-02-09 16:40 Leo Duran
2017-02-09 16:40 ` [PATCH v3 1/6] MdeModulePkg: Add " Leo Duran
` (5 more replies)
0 siblings, 6 replies; 14+ messages in thread
From: Leo Duran @ 2017-02-09 16:40 UTC (permalink / raw)
To: edk2-devel; +Cc: Leo Duran
This series provides an abstraction layer for Bus-master DMA operations as
currently 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).
Please refer to the RFC discussion for SEV here:
http://marc.info/?l=linux-mm&m=147190814023863&w=2
This new (BmDmaLib class) library is cloned from the existing DmaLib with
an additional DmaAbove4GB (BOOLEAN) parameter for the Map and Allocate
interfaces, so that decisions can be made about the need to allocate DMA
buffers below the 4GB boundary.
NOTE: The abstraction layer is intended for Bus-master (DMA capable)
devices, and not restricted to the PCI Root-Bridge use-case. Thus the
rationale for not using EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION types.
Changes since RFC_v2:
- Include the actual DxeBmDmaLib library code that was untentionally
missing in the previous [RFC v2 1/6] submission.
- Minor cleanup on commit messages.
Leo Duran (6):
MdeModulePkg: Add DxeBmDmaLib (BmDmaLib class) library
ArmVirtPkg: Resolve BmDmaLib class for PciHostBridgeDxe driver
CorebootPayloadPkg: Resolve BmDmaLib class for PciHostBridgeDxe driver
MdeModulePkg: Resolve BmDmaLib class for PciHostBridgeDxe driver
OvmfPkg: Resolve BmDmaLib class for PciHostBridgeDxe driver
MdeModulePkg: Modify PciHostBridgeDxe to use new BmDmaLib class
library
ArmVirtPkg/ArmVirtQemu.dsc | 1 +
ArmVirtPkg/ArmVirtQemuKernel.dsc | 1 +
CorebootPayloadPkg/CorebootPayloadPkgIa32.dsc | 1 +
CorebootPayloadPkg/CorebootPayloadPkgIa32X64.dsc | 1 +
.../Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf | 1 +
.../Bus/Pci/PciHostBridgeDxe/PciRootBridge.h | 13 +-
.../Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 272 ++++------------
MdeModulePkg/Include/Library/BmDmaLib.h | 161 ++++++++++
MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.c | 351 +++++++++++++++++++++
MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf | 41 +++
MdeModulePkg/MdeModulePkg.dsc | 3 +
OvmfPkg/OvmfPkgIa32.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
OvmfPkg/OvmfPkgX64.dsc | 1 +
14 files changed, 629 insertions(+), 220 deletions(-)
create mode 100644 MdeModulePkg/Include/Library/BmDmaLib.h
create mode 100644 MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.c
create mode 100644 MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
--
1.9.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v3 1/6] MdeModulePkg: Add DxeBmDmaLib (BmDmaLib class) library
2017-02-09 16:40 [PATCH v3 0/6] DxeBmDmaLib (BmDmaLib class) library Leo Duran
@ 2017-02-09 16:40 ` Leo Duran
2017-03-01 2:39 ` Ni, Ruiyu
2017-02-09 16:40 ` [PATCH v3 2/6] ArmVirtPkg: Resolve BmDmaLib class for PciHostBridgeDxe driver Leo Duran
` (4 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Leo Duran @ 2017-02-09 16:40 UTC (permalink / raw)
To: edk2-devel; +Cc: Leo Duran, Feng Tian, Star Zeng
This patch provides an abstraction layer for Bus-master DMA operations as
currently 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 cloned from the existing DmaLib with
an additional DmaAbove4GB (BOOLEAN) parameter for the Map and Allocate
interfaces, so that decisions can be made about the need to allocate DMA
buffers below the 4GB boundary.
Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Leo Duran <leo.duran@amd.com>
---
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.<BR>
+ Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
+
+ 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.<BR>
+ Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
+
+ 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 <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BmDmaLib.h>
+
+
+#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..4ddb27d
--- /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.<BR>
+# Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
+#
+# 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/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
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 2/6] ArmVirtPkg: Resolve BmDmaLib class for PciHostBridgeDxe driver
2017-02-09 16:40 [PATCH v3 0/6] DxeBmDmaLib (BmDmaLib class) library Leo Duran
2017-02-09 16:40 ` [PATCH v3 1/6] MdeModulePkg: Add " Leo Duran
@ 2017-02-09 16:40 ` Leo Duran
2017-02-09 17:56 ` Ard Biesheuvel
2017-02-09 16:40 ` [PATCH v3 3/6] CorebootPayloadPkg: " Leo Duran
` (3 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Leo Duran @ 2017-02-09 16:40 UTC (permalink / raw)
To: edk2-devel; +Cc: Leo Duran, Laszlo Ersek, Ard Biesheuvel
This patch adds the new DxeBmDmaLib (BmDmaLib class) library, which
provides an abstraction layer for DMA operations implemented by the
PciHostBridgeDxe driver.
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Leo Duran <leo.duran@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
ArmVirtPkg/ArmVirtQemu.dsc | 1 +
ArmVirtPkg/ArmVirtQemuKernel.dsc | 1 +
2 files changed, 2 insertions(+)
diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc
index 8fe3c38..d318f82 100644
--- a/ArmVirtPkg/ArmVirtQemu.dsc
+++ b/ArmVirtPkg/ArmVirtQemu.dsc
@@ -59,6 +59,7 @@ [LibraryClasses.common]
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
NorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
+ BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc
index aa40374..721d78a 100644
--- a/ArmVirtPkg/ArmVirtQemuKernel.dsc
+++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc
@@ -58,6 +58,7 @@ [LibraryClasses.common]
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
NorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
+ BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 3/6] CorebootPayloadPkg: Resolve BmDmaLib class for PciHostBridgeDxe driver
2017-02-09 16:40 [PATCH v3 0/6] DxeBmDmaLib (BmDmaLib class) library Leo Duran
2017-02-09 16:40 ` [PATCH v3 1/6] MdeModulePkg: Add " Leo Duran
2017-02-09 16:40 ` [PATCH v3 2/6] ArmVirtPkg: Resolve BmDmaLib class for PciHostBridgeDxe driver Leo Duran
@ 2017-02-09 16:40 ` Leo Duran
2017-02-09 16:40 ` [PATCH v3 4/6] MdeModulePkg: " Leo Duran
` (2 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: Leo Duran @ 2017-02-09 16:40 UTC (permalink / raw)
To: edk2-devel; +Cc: Leo Duran, Maurice Ma, Prince Agyeman
This patch adds the new DxeBmDmaLib (BmDmaLib class) library, which
provides an abstraction layer for DMA operations implemented by the
PciHostBridgeDxe driver.
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Prince Agyeman <prince.agyeman@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Leo Duran <leo.duran@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
CorebootPayloadPkg/CorebootPayloadPkgIa32.dsc | 1 +
CorebootPayloadPkg/CorebootPayloadPkgIa32X64.dsc | 1 +
2 files changed, 2 insertions(+)
diff --git a/CorebootPayloadPkg/CorebootPayloadPkgIa32.dsc b/CorebootPayloadPkg/CorebootPayloadPkgIa32.dsc
index cdfcb75..12fcd3f 100644
--- a/CorebootPayloadPkg/CorebootPayloadPkgIa32.dsc
+++ b/CorebootPayloadPkg/CorebootPayloadPkgIa32.dsc
@@ -140,6 +140,7 @@ [LibraryClasses]
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+ BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
#
# UEFI & PI
diff --git a/CorebootPayloadPkg/CorebootPayloadPkgIa32X64.dsc b/CorebootPayloadPkg/CorebootPayloadPkgIa32X64.dsc
index 6b16af6..28e1ffa 100644
--- a/CorebootPayloadPkg/CorebootPayloadPkgIa32X64.dsc
+++ b/CorebootPayloadPkg/CorebootPayloadPkgIa32X64.dsc
@@ -140,6 +140,7 @@ [LibraryClasses]
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+ BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
#
# UEFI & PI
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 4/6] MdeModulePkg: Resolve BmDmaLib class for PciHostBridgeDxe driver
2017-02-09 16:40 [PATCH v3 0/6] DxeBmDmaLib (BmDmaLib class) library Leo Duran
` (2 preceding siblings ...)
2017-02-09 16:40 ` [PATCH v3 3/6] CorebootPayloadPkg: " Leo Duran
@ 2017-02-09 16:40 ` Leo Duran
2017-02-09 16:40 ` [PATCH v3 5/6] OvmfPkg: " Leo Duran
2017-02-09 16:40 ` [PATCH v3 6/6] MdeModulePkg: Modify PciHostBridgeDxe to use new BmDmaLib class library Leo Duran
5 siblings, 0 replies; 14+ messages in thread
From: Leo Duran @ 2017-02-09 16:40 UTC (permalink / raw)
To: edk2-devel; +Cc: Leo Duran, Feng Tian, Star Zeng
This patch adds the new DxeBmDmaLib (BmDmaLib class) library, which
provides an abstraction layer for DMA operations implemented by the
PciHostBridgeDxe driver.
Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Leo Duran <leo.duran@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
MdeModulePkg/MdeModulePkg.dsc | 1 +
1 file changed, 1 insertion(+)
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 311922e..b343c19 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -48,6 +48,7 @@ [LibraryClasses]
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf
+ BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
#
# UEFI & PI
#
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 5/6] OvmfPkg: Resolve BmDmaLib class for PciHostBridgeDxe driver
2017-02-09 16:40 [PATCH v3 0/6] DxeBmDmaLib (BmDmaLib class) library Leo Duran
` (3 preceding siblings ...)
2017-02-09 16:40 ` [PATCH v3 4/6] MdeModulePkg: " Leo Duran
@ 2017-02-09 16:40 ` Leo Duran
2017-02-09 16:40 ` [PATCH v3 6/6] MdeModulePkg: Modify PciHostBridgeDxe to use new BmDmaLib class library Leo Duran
5 siblings, 0 replies; 14+ messages in thread
From: Leo Duran @ 2017-02-09 16:40 UTC (permalink / raw)
To: edk2-devel; +Cc: Leo Duran, Jordan Justen, Laszlo Ersek
This patch adds the new DxeBmDmaLib (BmDmaLib class) library, which
provides an abstraction layer for DMA operations implemented by the
PciHostBridgeDxe driver.
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Leo Duran <leo.duran@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
OvmfPkg/OvmfPkgIa32.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
OvmfPkg/OvmfPkgX64.dsc | 1 +
3 files changed, 3 insertions(+)
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 993547d..f2fea24 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -90,6 +90,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
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 f36604e..0f1f85c 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -95,6 +95,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
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 c5bf1a6..ec43249 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -95,6 +95,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
UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 6/6] MdeModulePkg: Modify PciHostBridgeDxe to use new BmDmaLib class library
2017-02-09 16:40 [PATCH v3 0/6] DxeBmDmaLib (BmDmaLib class) library Leo Duran
` (4 preceding siblings ...)
2017-02-09 16:40 ` [PATCH v3 5/6] OvmfPkg: " Leo Duran
@ 2017-02-09 16:40 ` Leo Duran
2017-03-01 2:53 ` Ni, Ruiyu
5 siblings, 1 reply; 14+ messages in thread
From: Leo Duran @ 2017-02-09 16:40 UTC (permalink / raw)
To: edk2-devel; +Cc: Leo Duran, Feng Tian, Star Zeng
The BmDmaLib class library provides an abstraction layer for Bus-master DMA
operations as currently implemented by the PciHostBridgeDxe driver. The
intent is to allow override of the library as required by specific hardware
implementations, such as AMD's Secure Encrypted Virtualization (SEV).
Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
signed-off-by: Leo Duran <leo.duran@amd.com>
---
.../Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf | 1 +
.../Bus/Pci/PciHostBridgeDxe/PciRootBridge.h | 13 +-
.../Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 272 +++++----------------
MdeModulePkg/MdeModulePkg.dsc | 1 +
4 files changed, 67 insertions(+), 220 deletions(-)
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
index d8b0439..35bb5c4 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
@@ -42,6 +42,7 @@ [LibraryClasses]
BaseLib
PciSegmentLib
PciHostBridgeLib
+ BmDmaLib
[Protocols]
gEfiMetronomeArchProtocolGuid ## CONSUMES
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
index 13185b4..c125fcd 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
@@ -34,6 +34,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseLib.h>
#include <Library/PciSegmentLib.h>
+#include <Library/BmDmaLib.h>
#include "PciHostResource.h"
@@ -43,17 +44,6 @@ typedef enum {
PciOperation
} OPERATION_TYPE;
-#define MAP_INFO_SIGNATURE SIGNATURE_32 ('_', 'm', 'a', 'p')
-typedef struct {
- UINT32 Signature;
- LIST_ENTRY Link;
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation;
- UINTN NumberOfBytes;
- UINTN NumberOfPages;
- EFI_PHYSICAL_ADDRESS HostAddress;
- EFI_PHYSICAL_ADDRESS MappedHostAddress;
-} MAP_INFO;
-#define MAP_INFO_FROM_LINK(a) CR (a, MAP_INFO, Link, MAP_INFO_SIGNATURE)
#define PCI_ROOT_BRIDGE_SIGNATURE SIGNATURE_32 ('_', 'p', 'r', 'b')
@@ -79,7 +69,6 @@ typedef struct {
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL RootBridgeIo;
BOOLEAN ResourceSubmitted;
- LIST_ENTRY Maps;
} PCI_ROOT_BRIDGE_INSTANCE;
#define ROOT_BRIDGE_FROM_THIS(a) CR (a, PCI_ROOT_BRIDGE_INSTANCE, RootBridgeIo, PCI_ROOT_BRIDGE_SIGNATURE)
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
index 8af131b..8a74bf6 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
@@ -17,7 +17,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "PciRootBridge.h"
#include "PciHostResource.h"
-#define NO_MAPPING (VOID *) (UINTN) -1
//
// Lookup table for increment values based on transfer widths
@@ -55,6 +54,39 @@ UINT8 mOutStride[] = {
0 // EfiPciWidthFillUint64
};
+
+BM_DMA_OPERATION
+ConvertDmaOperation (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION RbOperation
+ )
+{
+ BM_DMA_OPERATION BmOperation;
+
+ switch (RbOperation) {
+ case EfiPciOperationBusMasterRead:
+ case EfiPciOperationBusMasterRead64:
+ BmOperation = DmaOperationBusMasterRead;
+ break;
+
+ case EfiPciOperationBusMasterWrite:
+ case EfiPciOperationBusMasterWrite64:
+ BmOperation = DmaOperationBusMasterWrite;
+ break;
+
+ case EfiPciOperationBusMasterCommonBuffer:
+ case EfiPciOperationBusMasterCommonBuffer64:
+ BmOperation = DmaOperationBusMasterCommonBuffer;
+ break;
+
+ default:
+ BmOperation = DmaOperationBusMasterMaximum;
+ break;
+ }
+
+ return BmOperation;
+}
+
+
/**
Construct the Pci Root Bridge instance.
@@ -168,7 +200,6 @@ CreateRootBridge (
TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
);
ASSERT (RootBridge->ConfigBuffer != NULL);
- InitializeListHead (&RootBridge->Maps);
CopyMem (&RootBridge->Bus, &Bridge->Bus, sizeof (PCI_ROOT_BRIDGE_APERTURE));
CopyMem (&RootBridge->Io, &Bridge->Io, sizeof (PCI_ROOT_BRIDGE_APERTURE));
@@ -1053,118 +1084,27 @@ RootBridgeIoMap (
OUT VOID **Mapping
)
{
- EFI_STATUS Status;
- PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
- EFI_PHYSICAL_ADDRESS PhysicalAddress;
- MAP_INFO *MapInfo;
-
- if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL ||
- Mapping == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Make sure that Operation is valid
- //
- if ((UINT32) Operation >= EfiPciOperationMaximum) {
- return EFI_INVALID_PARAMETER;
- }
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
+ BOOLEAN DmaAbove4GB;
+ BM_DMA_OPERATION BmOperation;
RootBridge = ROOT_BRIDGE_FROM_THIS (This);
-
- PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
- if ((!RootBridge->DmaAbove4G ||
- (Operation != EfiPciOperationBusMasterRead64 &&
- Operation != EfiPciOperationBusMasterWrite64 &&
- Operation != EfiPciOperationBusMasterCommonBuffer64)) &&
- ((PhysicalAddress + *NumberOfBytes) > SIZE_4GB)) {
-
- //
- // If the root bridge or the device cannot handle performing DMA above
- // 4GB but any part of the DMA transfer being mapped is above 4GB, then
- // map the DMA transfer to a buffer below 4GB.
- //
-
- if (Operation == EfiPciOperationBusMasterCommonBuffer ||
- Operation == EfiPciOperationBusMasterCommonBuffer64) {
- //
- // Common Buffer operations can not be remapped. If the common buffer
- // if above 4GB, then it is not possible to generate a mapping, so return
- // an error.
- //
- return EFI_UNSUPPORTED;
- }
-
- //
- // 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->Signature = MAP_INFO_SIGNATURE;
- MapInfo->Operation = Operation;
- MapInfo->NumberOfBytes = *NumberOfBytes;
- MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes);
- MapInfo->HostAddress = PhysicalAddress;
- MapInfo->MappedHostAddress = SIZE_4GB - 1;
-
- //
- // Allocate a buffer below 4GB to map the transfer to.
- //
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- 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 == EfiPciOperationBusMasterRead ||
- Operation == EfiPciOperationBusMasterRead64) {
- CopyMem (
- (VOID *) (UINTN) MapInfo->MappedHostAddress,
- (VOID *) (UINTN) MapInfo->HostAddress,
- MapInfo->NumberOfBytes
- );
- }
-
- InsertTailList (&RootBridge->Maps, &MapInfo->Link);
-
- //
- // The DeviceAddress is the address of the maped buffer below 4GB
- //
- *DeviceAddress = MapInfo->MappedHostAddress;
- //
- // Return a pointer to the MAP_INFO structure in Mapping
- //
- *Mapping = MapInfo;
- } else {
- //
- // If the root bridge CAN handle performing DMA above 4GB or
- // the transfer is below 4GB, so the DeviceAddress is simply the
- // HostAddress
- //
- *DeviceAddress = PhysicalAddress;
- *Mapping = NO_MAPPING;
- }
-
- return EFI_SUCCESS;
+ DmaAbove4GB = RootBridge->DmaAbove4G && (
+ Operation == EfiPciOperationBusMasterRead64 ||
+ Operation == EfiPciOperationBusMasterWrite64 ||
+ Operation == EfiPciOperationBusMasterCommonBuffer64
+ );
+
+ BmOperation = ConvertDmaOperation (Operation);
+
+ return BmDmaMap (
+ DmaAbove4GB,
+ BmOperation,
+ HostAddress,
+ NumberOfBytes,
+ DeviceAddress,
+ Mapping
+ );
}
/**
@@ -1191,58 +1131,7 @@ RootBridgeIoUnmap (
IN VOID *Mapping
)
{
- MAP_INFO *MapInfo;
- LIST_ENTRY *Link;
- PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
-
- RootBridge = ROOT_BRIDGE_FROM_THIS (This);
- //
- // 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;
- }
-
- MapInfo = NO_MAPPING;
- for (Link = GetFirstNode (&RootBridge->Maps)
- ; !IsNull (&RootBridge->Maps, Link)
- ; Link = GetNextNode (&RootBridge->Maps, Link)
- ) {
- MapInfo = MAP_INFO_FROM_LINK (Link);
- if (MapInfo == Mapping) {
- break;
- }
- }
- //
- // Mapping is not a valid value returned by Map()
- //
- if (MapInfo != Mapping) {
- return EFI_INVALID_PARAMETER;
- }
- RemoveEntryList (&MapInfo->Link);
-
- //
- // 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.
- //
- if (MapInfo->Operation == EfiPciOperationBusMasterWrite ||
- MapInfo->Operation == EfiPciOperationBusMasterWrite64) {
- 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;
+ return BmDmaUnmap (Mapping);
}
/**
@@ -1282,56 +1171,23 @@ RootBridgeIoAllocateBuffer (
IN UINT64 Attributes
)
{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS PhysicalAddress;
- PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
- EFI_ALLOCATE_TYPE AllocateType;
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
+ BOOLEAN DmaAbove4GB;
- //
- // Validate Attributes
- //
if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
return EFI_UNSUPPORTED;
}
- //
- // 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;
- }
-
RootBridge = ROOT_BRIDGE_FROM_THIS (This);
+ DmaAbove4GB = RootBridge->DmaAbove4G &&
+ (Attributes & EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE) != 0;
- AllocateType = AllocateAnyPages;
- if (!RootBridge->DmaAbove4G ||
- (Attributes & EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) {
- //
- // 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;
+ return BmDmaAllocateBuffer (
+ DmaAbove4GB,
+ MemoryType,
+ Pages,
+ HostAddress
+ );
}
/**
@@ -1356,7 +1212,7 @@ RootBridgeIoFreeBuffer (
OUT VOID *HostAddress
)
{
- return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);
+ return BmDmaFreeBuffer (Pages, HostAddress);
}
/**
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index b343c19..47aa9b9 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -83,6 +83,7 @@ [LibraryClasses]
PalLib|MdePkg/Library/BasePalLibNull/BasePalLibNull.inf
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
+ BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
#
# Misc
#
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v3 2/6] ArmVirtPkg: Resolve BmDmaLib class for PciHostBridgeDxe driver
2017-02-09 16:40 ` [PATCH v3 2/6] ArmVirtPkg: Resolve BmDmaLib class for PciHostBridgeDxe driver Leo Duran
@ 2017-02-09 17:56 ` Ard Biesheuvel
2017-02-09 19:33 ` Laszlo Ersek
0 siblings, 1 reply; 14+ messages in thread
From: Ard Biesheuvel @ 2017-02-09 17:56 UTC (permalink / raw)
To: Leo Duran; +Cc: edk2-devel@lists.01.org, Laszlo Ersek
On 9 February 2017 at 16:40, Leo Duran <leo.duran@amd.com> wrote:
> This patch adds the new DxeBmDmaLib (BmDmaLib class) library, which
> provides an abstraction layer for DMA operations implemented by the
> PciHostBridgeDxe driver.
>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Leo Duran <leo.duran@amd.com>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Laszlo already has this covered, but for redundancy (RAIM-1):
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> ArmVirtPkg/ArmVirtQemu.dsc | 1 +
> ArmVirtPkg/ArmVirtQemuKernel.dsc | 1 +
> 2 files changed, 2 insertions(+)
>
> diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc
> index 8fe3c38..d318f82 100644
> --- a/ArmVirtPkg/ArmVirtQemu.dsc
> +++ b/ArmVirtPkg/ArmVirtQemu.dsc
> @@ -59,6 +59,7 @@ [LibraryClasses.common]
> TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
> NorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
>
> + BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
> CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
> UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
> diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc
> index aa40374..721d78a 100644
> --- a/ArmVirtPkg/ArmVirtQemuKernel.dsc
> +++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc
> @@ -58,6 +58,7 @@ [LibraryClasses.common]
> TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
> NorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
>
> + BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
> CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
> UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 2/6] ArmVirtPkg: Resolve BmDmaLib class for PciHostBridgeDxe driver
2017-02-09 17:56 ` Ard Biesheuvel
@ 2017-02-09 19:33 ` Laszlo Ersek
2017-02-09 20:15 ` Ard Biesheuvel
0 siblings, 1 reply; 14+ messages in thread
From: Laszlo Ersek @ 2017-02-09 19:33 UTC (permalink / raw)
To: Ard Biesheuvel, Leo Duran; +Cc: edk2-devel@lists.01.org
On 02/09/17 18:56, Ard Biesheuvel wrote:
> On 9 February 2017 at 16:40, Leo Duran <leo.duran@amd.com> wrote:
>> This patch adds the new DxeBmDmaLib (BmDmaLib class) library, which
>> provides an abstraction layer for DMA operations implemented by the
>> PciHostBridgeDxe driver.
>>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Leo Duran <leo.duran@amd.com>
>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>
> Laszlo already has this covered, but for redundancy (RAIM-1):
^^^^^^
I see what you did there. It's funny on three separate levels -- the pun
as a whole, the letter "I" per se, and level "1" too.
I'm impressed! :)
Laszlo
>
> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>
>> ---
>> ArmVirtPkg/ArmVirtQemu.dsc | 1 +
>> ArmVirtPkg/ArmVirtQemuKernel.dsc | 1 +
>> 2 files changed, 2 insertions(+)
>>
>> diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc
>> index 8fe3c38..d318f82 100644
>> --- a/ArmVirtPkg/ArmVirtQemu.dsc
>> +++ b/ArmVirtPkg/ArmVirtQemu.dsc
>> @@ -59,6 +59,7 @@ [LibraryClasses.common]
>> TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
>> NorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
>>
>> + BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
>> CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
>> UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
>> BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
>> diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc
>> index aa40374..721d78a 100644
>> --- a/ArmVirtPkg/ArmVirtQemuKernel.dsc
>> +++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc
>> @@ -58,6 +58,7 @@ [LibraryClasses.common]
>> TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
>> NorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
>>
>> + BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
>> CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
>> UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
>> BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
>> --
>> 1.9.1
>>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 2/6] ArmVirtPkg: Resolve BmDmaLib class for PciHostBridgeDxe driver
2017-02-09 19:33 ` Laszlo Ersek
@ 2017-02-09 20:15 ` Ard Biesheuvel
0 siblings, 0 replies; 14+ messages in thread
From: Ard Biesheuvel @ 2017-02-09 20:15 UTC (permalink / raw)
To: Laszlo Ersek; +Cc: Leo Duran, edk2-devel@lists.01.org
On 9 February 2017 at 19:33, Laszlo Ersek <lersek@redhat.com> wrote:
> On 02/09/17 18:56, Ard Biesheuvel wrote:
>> On 9 February 2017 at 16:40, Leo Duran <leo.duran@amd.com> wrote:
>>> This patch adds the new DxeBmDmaLib (BmDmaLib class) library, which
>>> provides an abstraction layer for DMA operations implemented by the
>>> PciHostBridgeDxe driver.
>>>
>>> Cc: Laszlo Ersek <lersek@redhat.com>
>>> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>> Contributed-under: TianoCore Contribution Agreement 1.0
>>> Signed-off-by: Leo Duran <leo.duran@amd.com>
>>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>>
>> Laszlo already has this covered, but for redundancy (RAIM-1):
> ^^^^^^
>
> I see what you did there. It's funny on three separate levels -- the pun
> as a whole, the letter "I" per se, and level "1" too.
>
:-)
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 1/6] MdeModulePkg: Add DxeBmDmaLib (BmDmaLib class) library
2017-02-09 16:40 ` [PATCH v3 1/6] MdeModulePkg: Add " Leo Duran
@ 2017-03-01 2:39 ` Ni, Ruiyu
2017-03-01 2:48 ` Tian, Feng
0 siblings, 1 reply; 14+ messages in thread
From: Ni, Ruiyu @ 2017-03-01 2:39 UTC (permalink / raw)
To: Leo Duran, edk2-devel@ml01.01.org; +Cc: Tian, Feng, Zeng, Star
I suggest to align to BS->FreePages() prototype. Other parts of this patch are good to me.
BmDmaFreeBuffer (,
IN VOID *HostAddress
IN UINTN Pages
Thanks/Ray
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Leo Duran
> Sent: Friday, February 10, 2017 12:40 AM
> To: edk2-devel@ml01.01.org
> Cc: Tian, Feng <feng.tian@intel.com>; Leo Duran <leo.duran@amd.com>;
> Zeng, Star <star.zeng@intel.com>
> Subject: [edk2] [PATCH v3 1/6] MdeModulePkg: Add DxeBmDmaLib
> (BmDmaLib class) library
>
> This patch provides an abstraction layer for Bus-master DMA operations as
> currently 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 cloned from the existing DmaLib with an
> additional DmaAbove4GB (BOOLEAN) parameter for the Map and Allocate
> interfaces, so that decisions can be made about the need to allocate DMA
> buffers below the 4GB boundary.
>
> Cc: Feng Tian <feng.tian@intel.com>
> Cc: Star Zeng <star.zeng@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Leo Duran <leo.duran@amd.com>
> ---
> 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.<BR>
> + Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
> +
> + 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.<BR>
> + Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
> +
> + 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 <PiDxe.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DxeServicesTableLib.h> #include
> +<Library/MemoryAllocationLib.h> #include
> +<Library/UefiBootServicesTableLib.h>
> +#include <Library/BmDmaLib.h>
> +
> +
> +#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..4ddb27d
> --- /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.<BR> #
> +Copyright (c) 2017, AMD Inc. All rights reserved.<BR> # # 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/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/UefiMemoryAlloca
> tionProfileLib.inf
>
> MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllo
> cationLib.inf
> --
> 1.9.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 1/6] MdeModulePkg: Add DxeBmDmaLib (BmDmaLib class) library
2017-03-01 2:39 ` Ni, Ruiyu
@ 2017-03-01 2:48 ` Tian, Feng
2017-03-01 2:54 ` Ni, Ruiyu
0 siblings, 1 reply; 14+ messages in thread
From: Tian, Feng @ 2017-03-01 2:48 UTC (permalink / raw)
To: Ni, Ruiyu, Leo Duran, edk2-devel@ml01.01.org; +Cc: Zeng, Star, Tian, Feng
A minor comment:
> + LIBRARY_CLASS = BmDmaLib|DXE_DRIVER
Shouldn't this lib support UEFI driver?
Thanks
Feng
-----Original Message-----
From: Ni, Ruiyu
Sent: Wednesday, March 1, 2017 10:39 AM
To: Leo Duran <leo.duran@amd.com>; edk2-devel@ml01.01.org
Cc: Tian, Feng <feng.tian@intel.com>; Zeng, Star <star.zeng@intel.com>
Subject: RE: [edk2] [PATCH v3 1/6] MdeModulePkg: Add DxeBmDmaLib (BmDmaLib class) library
I suggest to align to BS->FreePages() prototype. Other parts of this patch are good to me.
BmDmaFreeBuffer (,
IN VOID *HostAddress
IN UINTN Pages
Thanks/Ray
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Leo Duran
> Sent: Friday, February 10, 2017 12:40 AM
> To: edk2-devel@ml01.01.org
> Cc: Tian, Feng <feng.tian@intel.com>; Leo Duran <leo.duran@amd.com>;
> Zeng, Star <star.zeng@intel.com>
> Subject: [edk2] [PATCH v3 1/6] MdeModulePkg: Add DxeBmDmaLib (BmDmaLib
> class) library
>
> This patch provides an abstraction layer for Bus-master DMA operations
> as currently 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 cloned from the existing DmaLib
> with an additional DmaAbove4GB (BOOLEAN) parameter for the Map and
> Allocate interfaces, so that decisions can be made about the need to
> allocate DMA buffers below the 4GB boundary.
>
> Cc: Feng Tian <feng.tian@intel.com>
> Cc: Star Zeng <star.zeng@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Leo Duran <leo.duran@amd.com>
> ---
> 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.<BR>
> + Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
> +
> + 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.<BR>
> + Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
> +
> + 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 <PiDxe.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DxeServicesTableLib.h> #include
> +<Library/MemoryAllocationLib.h> #include
> +<Library/UefiBootServicesTableLib.h>
> +#include <Library/BmDmaLib.h>
> +
> +
> +#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..4ddb27d
> --- /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.<BR> #
> +Copyright (c) 2017, AMD Inc. All rights reserved.<BR> # # 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/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/UefiMemoryAlloca
> tionProfileLib.inf
>
> MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllo
> cationLib.inf
> --
> 1.9.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 6/6] MdeModulePkg: Modify PciHostBridgeDxe to use new BmDmaLib class library
2017-02-09 16:40 ` [PATCH v3 6/6] MdeModulePkg: Modify PciHostBridgeDxe to use new BmDmaLib class library Leo Duran
@ 2017-03-01 2:53 ` Ni, Ruiyu
0 siblings, 0 replies; 14+ messages in thread
From: Ni, Ruiyu @ 2017-03-01 2:53 UTC (permalink / raw)
To: Leo Duran, edk2-devel@ml01.01.org; +Cc: Tian, Feng, Zeng, Star
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
Thanks/Ray
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Leo Duran
> Sent: Friday, February 10, 2017 12:40 AM
> To: edk2-devel@ml01.01.org
> Cc: Tian, Feng <feng.tian@intel.com>; Leo Duran <leo.duran@amd.com>;
> Zeng, Star <star.zeng@intel.com>
> Subject: [edk2] [PATCH v3 6/6] MdeModulePkg: Modify PciHostBridgeDxe to
> use new BmDmaLib class library
>
> The BmDmaLib class library provides an abstraction layer for Bus-master DMA
> operations as currently implemented by the PciHostBridgeDxe driver. The
> intent is to allow override of the library as required by specific hardware
> implementations, such as AMD's Secure Encrypted Virtualization (SEV).
>
> Cc: Feng Tian <feng.tian@intel.com>
> Cc: Star Zeng <star.zeng@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> signed-off-by: Leo Duran <leo.duran@amd.com>
> ---
> .../Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf | 1 +
> .../Bus/Pci/PciHostBridgeDxe/PciRootBridge.h | 13 +-
> .../Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 272 +++++----------------
> MdeModulePkg/MdeModulePkg.dsc | 1 +
> 4 files changed, 67 insertions(+), 220 deletions(-)
>
> diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> index d8b0439..35bb5c4 100644
> --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> @@ -42,6 +42,7 @@ [LibraryClasses]
> BaseLib
> PciSegmentLib
> PciHostBridgeLib
> + BmDmaLib
>
> [Protocols]
> gEfiMetronomeArchProtocolGuid ## CONSUMES
> diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
> b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
> index 13185b4..c125fcd 100644
> --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
> +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h
> @@ -34,6 +34,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> KIND, EITHER EXPRESS OR IMPLIED.
> #include <Library/UefiBootServicesTableLib.h>
> #include <Library/BaseLib.h>
> #include <Library/PciSegmentLib.h>
> +#include <Library/BmDmaLib.h>
> #include "PciHostResource.h"
>
>
> @@ -43,17 +44,6 @@ typedef enum {
> PciOperation
> } OPERATION_TYPE;
>
> -#define MAP_INFO_SIGNATURE SIGNATURE_32 ('_', 'm', 'a', 'p') -typedef
> struct {
> - UINT32 Signature;
> - LIST_ENTRY Link;
> - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation;
> - UINTN NumberOfBytes;
> - UINTN NumberOfPages;
> - EFI_PHYSICAL_ADDRESS HostAddress;
> - EFI_PHYSICAL_ADDRESS MappedHostAddress;
> -} MAP_INFO;
> -#define MAP_INFO_FROM_LINK(a) CR (a, MAP_INFO, Link,
> MAP_INFO_SIGNATURE)
>
> #define PCI_ROOT_BRIDGE_SIGNATURE SIGNATURE_32 ('_', 'p', 'r', 'b')
>
> @@ -79,7 +69,6 @@ typedef struct {
> EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL RootBridgeIo;
>
> BOOLEAN ResourceSubmitted;
> - LIST_ENTRY Maps;
> } PCI_ROOT_BRIDGE_INSTANCE;
>
> #define ROOT_BRIDGE_FROM_THIS(a) CR (a, PCI_ROOT_BRIDGE_INSTANCE,
> RootBridgeIo, PCI_ROOT_BRIDGE_SIGNATURE) diff --git
> a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
> b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
> index 8af131b..8a74bf6 100644
> --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
> +++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
> @@ -17,7 +17,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY
> KIND, EITHER EXPRESS OR IMPLIED.
> #include "PciRootBridge.h"
> #include "PciHostResource.h"
>
> -#define NO_MAPPING (VOID *) (UINTN) -1
>
> //
> // Lookup table for increment values based on transfer widths @@ -55,6
> +54,39 @@ UINT8 mOutStride[] = {
> 0 // EfiPciWidthFillUint64
> };
>
> +
> +BM_DMA_OPERATION
> +ConvertDmaOperation (
> + IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION RbOperation
> + )
> +{
> + BM_DMA_OPERATION BmOperation;
> +
> + switch (RbOperation) {
> + case EfiPciOperationBusMasterRead:
> + case EfiPciOperationBusMasterRead64:
> + BmOperation = DmaOperationBusMasterRead;
> + break;
> +
> + case EfiPciOperationBusMasterWrite:
> + case EfiPciOperationBusMasterWrite64:
> + BmOperation = DmaOperationBusMasterWrite;
> + break;
> +
> + case EfiPciOperationBusMasterCommonBuffer:
> + case EfiPciOperationBusMasterCommonBuffer64:
> + BmOperation = DmaOperationBusMasterCommonBuffer;
> + break;
> +
> + default:
> + BmOperation = DmaOperationBusMasterMaximum;
> + break;
> + }
> +
> + return BmOperation;
> +}
> +
> +
> /**
> Construct the Pci Root Bridge instance.
>
> @@ -168,7 +200,6 @@ CreateRootBridge (
> TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof
> (EFI_ACPI_END_TAG_DESCRIPTOR)
> );
> ASSERT (RootBridge->ConfigBuffer != NULL);
> - InitializeListHead (&RootBridge->Maps);
>
> CopyMem (&RootBridge->Bus, &Bridge->Bus, sizeof
> (PCI_ROOT_BRIDGE_APERTURE));
> CopyMem (&RootBridge->Io, &Bridge->Io, sizeof
> (PCI_ROOT_BRIDGE_APERTURE)); @@ -1053,118 +1084,27 @@
> RootBridgeIoMap (
> OUT VOID **Mapping
> )
> {
> - EFI_STATUS Status;
> - PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
> - EFI_PHYSICAL_ADDRESS PhysicalAddress;
> - MAP_INFO *MapInfo;
> -
> - if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress ==
> NULL ||
> - Mapping == NULL) {
> - return EFI_INVALID_PARAMETER;
> - }
> -
> - //
> - // Make sure that Operation is valid
> - //
> - if ((UINT32) Operation >= EfiPciOperationMaximum) {
> - return EFI_INVALID_PARAMETER;
> - }
> + PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
> + BOOLEAN DmaAbove4GB;
> + BM_DMA_OPERATION BmOperation;
>
> RootBridge = ROOT_BRIDGE_FROM_THIS (This);
> -
> - PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
> - if ((!RootBridge->DmaAbove4G ||
> - (Operation != EfiPciOperationBusMasterRead64 &&
> - Operation != EfiPciOperationBusMasterWrite64 &&
> - Operation != EfiPciOperationBusMasterCommonBuffer64)) &&
> - ((PhysicalAddress + *NumberOfBytes) > SIZE_4GB)) {
> -
> - //
> - // If the root bridge or the device cannot handle performing DMA above
> - // 4GB but any part of the DMA transfer being mapped is above 4GB, then
> - // map the DMA transfer to a buffer below 4GB.
> - //
> -
> - if (Operation == EfiPciOperationBusMasterCommonBuffer ||
> - Operation == EfiPciOperationBusMasterCommonBuffer64) {
> - //
> - // Common Buffer operations can not be remapped. If the common
> buffer
> - // if above 4GB, then it is not possible to generate a mapping, so return
> - // an error.
> - //
> - return EFI_UNSUPPORTED;
> - }
> -
> - //
> - // 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->Signature = MAP_INFO_SIGNATURE;
> - MapInfo->Operation = Operation;
> - MapInfo->NumberOfBytes = *NumberOfBytes;
> - MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (MapInfo-
> >NumberOfBytes);
> - MapInfo->HostAddress = PhysicalAddress;
> - MapInfo->MappedHostAddress = SIZE_4GB - 1;
> -
> - //
> - // Allocate a buffer below 4GB to map the transfer to.
> - //
> - Status = gBS->AllocatePages (
> - AllocateMaxAddress,
> - 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 == EfiPciOperationBusMasterRead ||
> - Operation == EfiPciOperationBusMasterRead64) {
> - CopyMem (
> - (VOID *) (UINTN) MapInfo->MappedHostAddress,
> - (VOID *) (UINTN) MapInfo->HostAddress,
> - MapInfo->NumberOfBytes
> - );
> - }
> -
> - InsertTailList (&RootBridge->Maps, &MapInfo->Link);
> -
> - //
> - // The DeviceAddress is the address of the maped buffer below 4GB
> - //
> - *DeviceAddress = MapInfo->MappedHostAddress;
> - //
> - // Return a pointer to the MAP_INFO structure in Mapping
> - //
> - *Mapping = MapInfo;
> - } else {
> - //
> - // If the root bridge CAN handle performing DMA above 4GB or
> - // the transfer is below 4GB, so the DeviceAddress is simply the
> - // HostAddress
> - //
> - *DeviceAddress = PhysicalAddress;
> - *Mapping = NO_MAPPING;
> - }
> -
> - return EFI_SUCCESS;
> + DmaAbove4GB = RootBridge->DmaAbove4G && (
> + Operation == EfiPciOperationBusMasterRead64 ||
> + Operation == EfiPciOperationBusMasterWrite64 ||
> + Operation == EfiPciOperationBusMasterCommonBuffer64
> + );
> +
> + BmOperation = ConvertDmaOperation (Operation);
> +
> + return BmDmaMap (
> + DmaAbove4GB,
> + BmOperation,
> + HostAddress,
> + NumberOfBytes,
> + DeviceAddress,
> + Mapping
> + );
> }
>
> /**
> @@ -1191,58 +1131,7 @@ RootBridgeIoUnmap (
> IN VOID *Mapping
> )
> {
> - MAP_INFO *MapInfo;
> - LIST_ENTRY *Link;
> - PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
> -
> - RootBridge = ROOT_BRIDGE_FROM_THIS (This);
> - //
> - // 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;
> - }
> -
> - MapInfo = NO_MAPPING;
> - for (Link = GetFirstNode (&RootBridge->Maps)
> - ; !IsNull (&RootBridge->Maps, Link)
> - ; Link = GetNextNode (&RootBridge->Maps, Link)
> - ) {
> - MapInfo = MAP_INFO_FROM_LINK (Link);
> - if (MapInfo == Mapping) {
> - break;
> - }
> - }
> - //
> - // Mapping is not a valid value returned by Map()
> - //
> - if (MapInfo != Mapping) {
> - return EFI_INVALID_PARAMETER;
> - }
> - RemoveEntryList (&MapInfo->Link);
> -
> - //
> - // 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.
> - //
> - if (MapInfo->Operation == EfiPciOperationBusMasterWrite ||
> - MapInfo->Operation == EfiPciOperationBusMasterWrite64) {
> - 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;
> + return BmDmaUnmap (Mapping);
> }
>
> /**
> @@ -1282,56 +1171,23 @@ RootBridgeIoAllocateBuffer (
> IN UINT64 Attributes
> )
> {
> - EFI_STATUS Status;
> - EFI_PHYSICAL_ADDRESS PhysicalAddress;
> - PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
> - EFI_ALLOCATE_TYPE AllocateType;
> + PCI_ROOT_BRIDGE_INSTANCE *RootBridge;
> + BOOLEAN DmaAbove4GB;
>
> - //
> - // Validate Attributes
> - //
> if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) !=
> 0) {
> return EFI_UNSUPPORTED;
> }
>
> - //
> - // 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;
> - }
> -
> RootBridge = ROOT_BRIDGE_FROM_THIS (This);
> + DmaAbove4GB = RootBridge->DmaAbove4G &&
> + (Attributes & EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE)
> + != 0;
>
> - AllocateType = AllocateAnyPages;
> - if (!RootBridge->DmaAbove4G ||
> - (Attributes & EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE) == 0) {
> - //
> - // 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;
> + return BmDmaAllocateBuffer (
> + DmaAbove4GB,
> + MemoryType,
> + Pages,
> + HostAddress
> + );
> }
>
> /**
> @@ -1356,7 +1212,7 @@ RootBridgeIoFreeBuffer (
> OUT VOID *HostAddress
> )
> {
> - return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress,
> Pages);
> + return BmDmaFreeBuffer (Pages, HostAddress);
> }
>
> /**
> diff --git a/MdeModulePkg/MdeModulePkg.dsc
> b/MdeModulePkg/MdeModulePkg.dsc index b343c19..47aa9b9 100644
> --- a/MdeModulePkg/MdeModulePkg.dsc
> +++ b/MdeModulePkg/MdeModulePkg.dsc
> @@ -83,6 +83,7 @@ [LibraryClasses]
> PalLib|MdePkg/Library/BasePalLibNull/BasePalLibNull.inf
>
> CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/Custo
> mizedDisplayLib.inf
>
> FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBuffer
> BltLib.inf
> + BmDmaLib|MdeModulePkg/Library/DxeBmDmaLib/DxeBmDmaLib.inf
> #
> # Misc
> #
> --
> 1.9.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 1/6] MdeModulePkg: Add DxeBmDmaLib (BmDmaLib class) library
2017-03-01 2:48 ` Tian, Feng
@ 2017-03-01 2:54 ` Ni, Ruiyu
0 siblings, 0 replies; 14+ messages in thread
From: Ni, Ruiyu @ 2017-03-01 2:54 UTC (permalink / raw)
To: Tian, Feng, Leo Duran, edk2-devel@ml01.01.org; +Cc: Zeng, Star
I didn't notice this change. But I think only supporting DXE_DRIVER is better.
UEFI driver should use the PCI_IO interface to do DMA buffer manipulation.
Thanks/Ray
> -----Original Message-----
> From: Tian, Feng
> Sent: Wednesday, March 1, 2017 10:48 AM
> To: Ni, Ruiyu <ruiyu.ni@intel.com>; Leo Duran <leo.duran@amd.com>; edk2-
> devel@ml01.01.org
> Cc: Zeng, Star <star.zeng@intel.com>; Tian, Feng <feng.tian@intel.com>
> Subject: RE: [edk2] [PATCH v3 1/6] MdeModulePkg: Add DxeBmDmaLib
> (BmDmaLib class) library
>
> A minor comment:
>
> > + LIBRARY_CLASS = BmDmaLib|DXE_DRIVER
>
> Shouldn't this lib support UEFI driver?
>
> Thanks
> Feng
>
> -----Original Message-----
> From: Ni, Ruiyu
> Sent: Wednesday, March 1, 2017 10:39 AM
> To: Leo Duran <leo.duran@amd.com>; edk2-devel@ml01.01.org
> Cc: Tian, Feng <feng.tian@intel.com>; Zeng, Star <star.zeng@intel.com>
> Subject: RE: [edk2] [PATCH v3 1/6] MdeModulePkg: Add DxeBmDmaLib
> (BmDmaLib class) library
>
> I suggest to align to BS->FreePages() prototype. Other parts of this patch are
> good to me.
>
> BmDmaFreeBuffer (,
> IN VOID *HostAddress
> IN UINTN Pages
>
> Thanks/Ray
>
> > -----Original Message-----
> > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > Leo Duran
> > Sent: Friday, February 10, 2017 12:40 AM
> > To: edk2-devel@ml01.01.org
> > Cc: Tian, Feng <feng.tian@intel.com>; Leo Duran <leo.duran@amd.com>;
> > Zeng, Star <star.zeng@intel.com>
> > Subject: [edk2] [PATCH v3 1/6] MdeModulePkg: Add DxeBmDmaLib
> (BmDmaLib
> > class) library
> >
> > This patch provides an abstraction layer for Bus-master DMA operations
> > as currently 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 cloned from the existing DmaLib
> > with an additional DmaAbove4GB (BOOLEAN) parameter for the Map and
> > Allocate interfaces, so that decisions can be made about the need to
> > allocate DMA buffers below the 4GB boundary.
> >
> > Cc: Feng Tian <feng.tian@intel.com>
> > Cc: Star Zeng <star.zeng@intel.com>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Leo Duran <leo.duran@amd.com>
> > ---
> > 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.<BR>
> > + Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
> > +
> > + 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.<BR>
> > + Copyright (c) 2017, AMD Inc. All rights reserved.<BR>
> > +
> > + 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 <PiDxe.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/DxeServicesTableLib.h> #include
> > +<Library/MemoryAllocationLib.h> #include
> > +<Library/UefiBootServicesTableLib.h>
> > +#include <Library/BmDmaLib.h>
> > +
> > +
> > +#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..4ddb27d
> > --- /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.<BR> #
> > +Copyright (c) 2017, AMD Inc. All rights reserved.<BR> # # 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/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/UefiMemoryAlloca
> > tionProfileLib.inf
> >
> >
> MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllo
> > cationLib.inf
> > --
> > 1.9.1
> >
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2017-03-01 2:54 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-02-09 16:40 [PATCH v3 0/6] DxeBmDmaLib (BmDmaLib class) library Leo Duran
2017-02-09 16:40 ` [PATCH v3 1/6] MdeModulePkg: Add " Leo Duran
2017-03-01 2:39 ` Ni, Ruiyu
2017-03-01 2:48 ` Tian, Feng
2017-03-01 2:54 ` Ni, Ruiyu
2017-02-09 16:40 ` [PATCH v3 2/6] ArmVirtPkg: Resolve BmDmaLib class for PciHostBridgeDxe driver Leo Duran
2017-02-09 17:56 ` Ard Biesheuvel
2017-02-09 19:33 ` Laszlo Ersek
2017-02-09 20:15 ` Ard Biesheuvel
2017-02-09 16:40 ` [PATCH v3 3/6] CorebootPayloadPkg: " Leo Duran
2017-02-09 16:40 ` [PATCH v3 4/6] MdeModulePkg: " Leo Duran
2017-02-09 16:40 ` [PATCH v3 5/6] OvmfPkg: " Leo Duran
2017-02-09 16:40 ` [PATCH v3 6/6] MdeModulePkg: Modify PciHostBridgeDxe to use new BmDmaLib class library Leo Duran
2017-03-01 2:53 ` Ni, Ruiyu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox