From: Leo Duran <leo.duran@amd.com>
To: <edk2-devel@lists.01.org>
Cc: <brijesh.singh@amd.com>, <lersek@redhat.com>,
<jordan.l.justen@intel.com>, <feng.tian@intel.com>,
<star.zeng@intel.com>, <maurice.ma@intel.com>,
<prince.agyeman@intel.com>, <ard.biesheuvel@linaro.org>,
Leo Duran <leo.duran@amd.com>
Subject: [RFC 6/6] MdeModulePkg: Modify PciHostBridgeDxe to use new BmDmaLib library.
Date: Mon, 9 Jan 2017 18:17:01 -0600 [thread overview]
Message-ID: <1484007421-15462-7-git-send-email-leo.duran@amd.com> (raw)
In-Reply-To: <1484007421-15462-1-git-send-email-leo.duran@amd.com>
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
next prev parent reply other threads:[~2017-01-10 0:17 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-10 0:16 [RFC 0/6] DxeBmDmaLib Leo Duran
2017-01-10 0:16 ` [RFC 1/6] MdeModulePkg: Add DxeBmDmaLib library Leo Duran
2017-01-10 0:47 ` Andrew Fish
2017-01-10 5:51 ` Duran, Leo
2017-01-10 0:16 ` [RFC 2/6] ArmVirtPkg: Modify .DSC files that include PciHostBridgeDxe driver Leo Duran
2017-01-10 0:16 ` [RFC 3/6] CorebootPayloadPkg: " Leo Duran
2017-01-10 3:56 ` Ma, Maurice
2017-01-10 0:16 ` [RFC 4/6] MdeModulePkg: " Leo Duran
2017-01-10 0:17 ` [RFC 5/6] OvmfPkg: " Leo Duran
2017-01-10 0:17 ` Leo Duran [this message]
2017-01-12 5:43 ` [RFC 0/6] DxeBmDmaLib Ni, Ruiyu
2017-01-12 15:55 ` Duran, Leo
2017-01-12 9:51 ` Laszlo Ersek
2017-01-12 16:04 ` Duran, Leo
2017-01-12 16:44 ` Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1484007421-15462-7-git-send-email-leo.duran@amd.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox