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 - 2016, 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
@@ -79,16 +79,18 @@ UsbHcAllocMemBlock (
Block->Bits = (UINT8 *)(UINTN)TempPtr;
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
Status = IoMmuAllocateBuffer (
Ehc->IoMmu,
Pages,
&TempPtr
(VOID **) &BufHost,
&MappedAddr,
&Mapping
);
ZeroMem ((VOID *)(UINTN)TempPtr, Pages*EFI_PAGE_SIZE);
if (EFI_ERROR (Status)) {
return NULL;
}
ZeroMem (BufHost, Pages*EFI_PAGE_SIZE);
BufHost = (VOID *)(UINTN)TempPtr;
MappedAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) BufHost;
//
// Check whether the data structure used by the host controller
// should be restricted into the same 4G
@@ -109,17 +111,21 @@ UsbHcAllocMemBlock (
/**
Free the memory block from the memory pool.
@param Ehc The EHCI device.
@param Pool The memory pool to free the block from.
@param Block The memory block to free.
**/
VOID
UsbHcFreeMemBlock (
IN PEI_USB2_HC_DEV *Ehc,
IN USBHC_MEM_POOL *Pool,
IN USBHC_MEM_BLOCK *Block
)
{
ASSERT ((Pool != NULL) && (Block != NULL));
IoMmuFreeBuffer (Ehc->IoMmu, EFI_SIZE_TO_PAGES (Block->BufLen), Block->BufHost, Block->Mapping);
}
/**
@@ -195,6 +201,54 @@ UsbHcAllocMemFromBlock (
return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;
}
/**
Calculate the corresponding pci bus address according to the Mem parameter.
@param Pool The memory pool of the host controller.
@param Mem The pointer to host memory.
@param Size The size of the memory region.
@return the pci memory address
**/
EFI_PHYSICAL_ADDRESS
UsbHcGetPciAddressForHostMem (
IN USBHC_MEM_POOL *Pool,
IN VOID *Mem,
IN UINTN Size
)
{
USBHC_MEM_BLOCK *Head;
USBHC_MEM_BLOCK *Block;
UINTN AllocSize;
EFI_PHYSICAL_ADDRESS PhyAddr;
UINTN Offset;
Head = Pool->Head;
AllocSize = USBHC_MEM_ROUND (Size);
if (Mem == NULL) {
return 0;
}
for (Block = Head; Block != NULL; Block = Block->Next) {
//
// scan the memory block list for the memory block that
// completely contains the allocated memory.
//
if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) {
break;
}
}
ASSERT ((Block != NULL));
//
// calculate the pci memory address for host memory address.
//
Offset = (UINT8 *)Mem - Block->BufHost;
PhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->Buf + Offset);
return PhyAddr;
}
/**
Insert the memory block to the pool's list of the blocks.
@@ -316,7 +370,8 @@ UsbHcInitMemPool (
/**
Release the memory management pool.
@param Ehc The EHCI device.
@param Pool The USB memory pool to free.
@retval EFI_DEVICE_ERROR Fail to free the memory pool.
@@ -325,6 +380,7 @@ UsbHcInitMemPool (
**/
EFI_STATUS
UsbHcFreeMemPool (
IN PEI_USB2_HC_DEV *Ehc,
IN USBHC_MEM_POOL *Pool
)
{
@@ -337,11 +393,11 @@ UsbHcFreeMemPool (
// UsbHcUnlinkMemBlock can't be used to unlink and free the
// first block.
//
for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) {
UsbHcFreeMemBlock (Pool, Block);
for (Block = Pool->Head->Next; Block != NULL; Block = Block->Next) {
UsbHcFreeMemBlock (Ehc, Pool, Block);
}
UsbHcFreeMemBlock (Pool, Pool->Head);
UsbHcFreeMemBlock (Ehc, Pool, Pool->Head);
return EFI_SUCCESS;
}
@@ -425,6 +481,7 @@ UsbHcAllocateMem (
/**
Free the allocated memory back to the memory pool.
@param Ehc The EHCI device.
@param Pool The memory pool of the host controller.
@param Mem The memory to free.
@param Size The size of the memory to free.
@@ -432,6 +489,7 @@ UsbHcAllocateMem (
**/
VOID
UsbHcFreeMem (
IN PEI_USB2_HC_DEV *Ehc,
IN USBHC_MEM_POOL *Pool,
IN VOID *Mem,
IN UINTN Size
@@ -486,7 +544,7 @@ UsbHcFreeMem (
// Release the current memory block if it is empty and not the head
//
if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) {
UsbHcFreeMemBlock (Pool, Block);
UsbHcFreeMemBlock (Ehc, Pool, Block);
}
return ;