MdeModulePkg/EhciDxe: enable 64-bit PCI DMA

PCI controller drivers must set the EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
attribute if the controller supports 64-bit DMA addressing.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Feng Tian <feng.tian@Intel.com>
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
index 4e9e05f..c7a6a40 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
@@ -89,7 +89,7 @@
 

   *MaxSpeed       = EFI_USB_SPEED_HIGH;

   *PortNumber     = (UINT8) (Ehc->HcStructParams & HCSP_NPORTS);

-  *Is64BitCapable = (UINT8) (Ehc->HcCapParams & HCCP_64BIT);

+  *Is64BitCapable = (UINT8) Ehc->Support64BitDma;

 

   DEBUG ((EFI_D_INFO, "EhcGetCapability: %d ports, 64 bit %d\n", *PortNumber, *Is64BitCapable));

 

@@ -1877,6 +1877,26 @@
     goto CLOSE_PCIIO;

   }

 

+  //

+  // Enable 64-bit DMA support in the PCI layer if this controller

+  // supports it.

+  //

+  if (EHC_BIT_IS_SET (Ehc->HcCapParams, HCCP_64BIT)) {

+    Status = PciIo->Attributes (

+                      PciIo,

+                      EfiPciIoAttributeOperationEnable,

+                      EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE,

+                      NULL

+                      );

+    if (!EFI_ERROR (Status)) {

+      Ehc->Support64BitDma = TRUE;

+    } else {

+      DEBUG ((EFI_D_WARN,

+        "%a: failed to enable 64-bit DMA on 64-bit capable controller @ %p (%r)\n",

+        __FUNCTION__, Controller, Status));

+    }

+  }

+

   Status = gBS->InstallProtocolInterface (

                   &Controller,

                   &gEfiUsb2HcProtocolGuid,

diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h
index 7177658..be81bde 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h
@@ -173,6 +173,8 @@
   UINT16                    DebugPortOffset; // The offset of debug port mmio register

   UINT8                     DebugPortBarNum; // The bar number of debug port mmio register

   UINT8                     DebugPortNum;    // The port number of usb debug port

+

+  BOOLEAN                   Support64BitDma; // Whether 64 bit DMA may be used with this device

 };

 

 

diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
index 5594e66..036c00b 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
@@ -178,7 +178,7 @@
   //

   Ehc->MemPool = UsbHcInitMemPool (

                    PciIo,

-                   EHC_BIT_IS_SET (Ehc->HcCapParams, HCCP_64BIT),

+                   Ehc->Support64BitDma,

                    EHC_HIGH_32BIT (PhyAddr)

                    );