MdeModulePkg EhciPei: Support IoMmu

V2: Halt HC at EndOfPei.

Update the EhciPei driver to consume IOMMU_PPI to allocate DMA buffer.

If no IOMMU_PPI exists, this driver still calls PEI service to allocate
DMA buffer, with assumption that DRAM==DMA.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
Star Zeng
2017-11-15 13:35:11 +08:00
parent 2930ef9809
commit 2c656af04d
8 changed files with 551 additions and 46 deletions

View File

@@ -2,7 +2,7 @@
PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
which is used to enable recovery function from USB Drivers.
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -301,7 +301,7 @@ EhcFreeQtds (
Qtd = EFI_LIST_CONTAINER (Entry, PEI_EHC_QTD, QtdList);
RemoveEntryList (&Qtd->QtdList);
UsbHcFreeMem (Ehc->MemPool, Qtd, sizeof (PEI_EHC_QTD));
UsbHcFreeMem (Ehc, Ehc->MemPool, Qtd, sizeof (PEI_EHC_QTD));
}
}
@@ -318,13 +318,21 @@ EhcFreeUrb (
IN PEI_URB *Urb
)
{
if (Urb->RequestPhy != NULL) {
IoMmuUnmap (Ehc->IoMmu, Urb->RequestMap);
}
if (Urb->DataMap != NULL) {
IoMmuUnmap (Ehc->IoMmu, Urb->DataMap);
}
if (Urb->Qh != NULL) {
//
// Ensure that this queue head has been unlinked from the
// schedule data structures. Free all the associated QTDs
//
EhcFreeQtds (Ehc, &Urb->Qh->Qtds);
UsbHcFreeMem (Ehc->MemPool, Urb->Qh, sizeof (PEI_EHC_QH));
UsbHcFreeMem (Ehc, Ehc->MemPool, Urb->Qh, sizeof (PEI_EHC_QH));
}
}
@@ -527,13 +535,11 @@ EhcCreateUrb (
{
USB_ENDPOINT *Ep;
EFI_PHYSICAL_ADDRESS PhyAddr;
EDKII_IOMMU_OPERATION MapOp;
EFI_STATUS Status;
UINTN Len;
PEI_URB *Urb;
VOID *Map;
Map = NULL;
Urb = Ehc->Urb;
Urb->Signature = EHC_URB_SIG;
@@ -576,24 +582,40 @@ EhcCreateUrb (
//
if (Request != NULL) {
Len = sizeof (EFI_USB_DEVICE_REQUEST);
PhyAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) Request ;
if ( (Len != sizeof (EFI_USB_DEVICE_REQUEST))) {
MapOp = EdkiiIoMmuOperationBusMasterRead;
Status = IoMmuMap (Ehc->IoMmu, MapOp, Request, &Len, &PhyAddr, &Map);
if (EFI_ERROR (Status) || (Len != sizeof (EFI_USB_DEVICE_REQUEST))) {
goto ON_ERROR;
}
Urb->RequestPhy = (VOID *) ((UINTN) PhyAddr);
Urb->RequestMap = Map;
} else {
Urb->RequestPhy = NULL;
Urb->RequestMap = NULL;
}
if (Data != NULL) {
Len = DataLen;
PhyAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) Data ;
if ( (Len != DataLen)) {
if (Ep->Direction == EfiUsbDataIn) {
MapOp = EdkiiIoMmuOperationBusMasterWrite;
} else {
MapOp = EdkiiIoMmuOperationBusMasterRead;
}
Status = IoMmuMap (Ehc->IoMmu, MapOp, Data, &Len, &PhyAddr, &Map);
if (EFI_ERROR (Status) || (Len != DataLen)) {
goto ON_ERROR;
}
Urb->DataPhy = (VOID *) ((UINTN) PhyAddr);
Urb->DataMap = Map;
} else {
Urb->DataPhy = NULL;
Urb->DataMap = NULL;
}
Status = EhcCreateQtds (Ehc, Urb);