PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid\r
which is used to enable recovery function from USB Drivers.\r
\r
-Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
- \r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions\r
-of the BSD License which accompanies this distribution. The\r
-full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
return NULL;\r
}\r
ZeroMem ((VOID *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE);\r
- \r
+\r
//\r
// each bit in the bit array represents USBHC_MEM_UNIT\r
// bytes of memory in the memory block.\r
//\r
ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE);\r
- \r
+\r
Block = (USBHC_MEM_BLOCK*)(UINTN)TempPtr;\r
Block->BufLen = EFI_PAGES_TO_SIZE (Pages);\r
Block->BitsLen = Block->BufLen / (USBHC_MEM_UNIT * 8);\r
- \r
+\r
PageNumber = (Block->BitsLen)/PAGESIZE +1;\r
Status = PeiServicesAllocatePages (\r
EfiBootServicesCode,\r
PageNumber,\r
&TempPtr\r
);\r
- \r
+\r
if (EFI_ERROR (Status)) {\r
return NULL;\r
}\r
- ZeroMem ((VOID *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE); \r
+ ZeroMem ((VOID *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE);\r
\r
Block->Bits = (UINT8 *)(UINTN)TempPtr;\r
\r
- \r
- Status = PeiServicesAllocatePages (\r
- EfiBootServicesCode,\r
+ Status = IoMmuAllocateBuffer (\r
+ Ehc->IoMmu,\r
Pages,\r
- &TempPtr\r
+ (VOID **) &BufHost,\r
+ &MappedAddr,\r
+ &Mapping\r
);\r
- ZeroMem ((VOID *)(UINTN)TempPtr, Pages*EFI_PAGE_SIZE);\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+ ZeroMem (BufHost, Pages*EFI_PAGE_SIZE);\r
\r
- BufHost = (VOID *)(UINTN)TempPtr;\r
- MappedAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) BufHost;\r
//\r
// Check whether the data structure used by the host controller\r
// should be restricted into the same 4G\r
/**\r
Free the memory block from the memory pool.\r
\r
+ @param Ehc The EHCI device.\r
@param Pool The memory pool to free the block from.\r
@param Block The memory block to free.\r
\r
**/\r
VOID\r
UsbHcFreeMemBlock (\r
+ IN PEI_USB2_HC_DEV *Ehc,\r
IN USBHC_MEM_POOL *Pool,\r
IN USBHC_MEM_BLOCK *Block\r
)\r
{\r
ASSERT ((Pool != NULL) && (Block != NULL));\r
+\r
+ IoMmuFreeBuffer (Ehc->IoMmu, EFI_SIZE_TO_PAGES (Block->BufLen), Block->BufHost, Block->Mapping);\r
}\r
\r
/**\r
if (Available < Units) {\r
return NULL;\r
}\r
- \r
+\r
//\r
// Mark the memory as allocated\r
//\r
return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;\r
}\r
\r
+/**\r
+ Calculate the corresponding pci bus address according to the Mem parameter.\r
+\r
+ @param Pool The memory pool of the host controller.\r
+ @param Mem The pointer to host memory.\r
+ @param Size The size of the memory region.\r
+\r
+ @return the pci memory address\r
+**/\r
+EFI_PHYSICAL_ADDRESS\r
+UsbHcGetPciAddressForHostMem (\r
+ IN USBHC_MEM_POOL *Pool,\r
+ IN VOID *Mem,\r
+ IN UINTN Size\r
+ )\r
+{\r
+ USBHC_MEM_BLOCK *Head;\r
+ USBHC_MEM_BLOCK *Block;\r
+ UINTN AllocSize;\r
+ EFI_PHYSICAL_ADDRESS PhyAddr;\r
+ UINTN Offset;\r
+\r
+ Head = Pool->Head;\r
+ AllocSize = USBHC_MEM_ROUND (Size);\r
+\r
+ if (Mem == NULL) {\r
+ return 0;\r
+ }\r
+\r
+ for (Block = Head; Block != NULL; Block = Block->Next) {\r
+ //\r
+ // scan the memory block list for the memory block that\r
+ // completely contains the allocated memory.\r
+ //\r
+ if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ ASSERT ((Block != NULL));\r
+ //\r
+ // calculate the pci memory address for host memory address.\r
+ //\r
+ Offset = (UINT8 *)Mem - Block->BufHost;\r
+ PhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->Buf + Offset);\r
+ return PhyAddr;\r
+}\r
+\r
/**\r
Insert the memory block to the pool's list of the blocks.\r
\r
{\r
UINTN Index;\r
\r
- \r
+\r
for (Index = 0; Index < Block->BitsLen; Index++) {\r
if (Block->Bits[Index] != 0) {\r
return FALSE;\r
return TRUE;\r
}\r
\r
-/**\r
- Unlink the memory block from the pool's list.\r
-\r
- @param Head The block list head of the memory's pool.\r
- @param BlockToUnlink The memory block to unlink.\r
-\r
-**/\r
-VOID\r
-UsbHcUnlinkMemBlock (\r
- IN USBHC_MEM_BLOCK *Head,\r
- IN USBHC_MEM_BLOCK *BlockToUnlink\r
- )\r
-{\r
- USBHC_MEM_BLOCK *Block;\r
-\r
- ASSERT ((Head != NULL) && (BlockToUnlink != NULL));\r
-\r
- for (Block = Head; Block != NULL; Block = Block->Next) {\r
- if (Block->Next == BlockToUnlink) {\r
- Block->Next = BlockToUnlink->Next;\r
- BlockToUnlink->Next = NULL;\r
- break;\r
- }\r
- }\r
-}\r
\r
/**\r
Initialize the memory management pool for the host controller.\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Check4G Whether the host controller requires allocated memory.\r
from one 4G address space.\r
UINTN PageNumber;\r
EFI_STATUS Status;\r
EFI_PHYSICAL_ADDRESS TempPtr;\r
- \r
+\r
PageNumber = sizeof(USBHC_MEM_POOL)/PAGESIZE +1;\r
Status = PeiServicesAllocatePages (\r
EfiBootServicesCode,\r
if (EFI_ERROR (Status)) {\r
return NULL;\r
}\r
- ZeroMem ((VOID *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE); \r
+ ZeroMem ((VOID *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE);\r
\r
- Pool = (USBHC_MEM_POOL *) ((UINTN) TempPtr); \r
+ Pool = (USBHC_MEM_POOL *) ((UINTN) TempPtr);\r
\r
Pool->Check4G = Check4G;\r
Pool->Which4G = Which4G;\r
\r
/**\r
Release the memory management pool.\r
- \r
+\r
+ @param Ehc The EHCI device.\r
@param Pool The USB memory pool to free.\r
\r
@retval EFI_DEVICE_ERROR Fail to free the memory pool.\r
**/\r
EFI_STATUS\r
UsbHcFreeMemPool (\r
+ IN PEI_USB2_HC_DEV *Ehc,\r
IN USBHC_MEM_POOL *Pool\r
)\r
{\r
\r
//\r
// Unlink all the memory blocks from the pool, then free them.\r
- // UsbHcUnlinkMemBlock can't be used to unlink and free the\r
- // first block.\r
//\r
- for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) {\r
- UsbHcFreeMemBlock (Pool, Block);\r
+ for (Block = Pool->Head->Next; Block != NULL; Block = Block->Next) {\r
+ UsbHcFreeMemBlock (Ehc, Pool, Block);\r
}\r
\r
- UsbHcFreeMemBlock (Pool, Pool->Head);\r
+ UsbHcFreeMemBlock (Ehc, Pool, Pool->Head);\r
\r
return EFI_SUCCESS;\r
}\r
/**\r
Allocate some memory from the host controller's memory pool\r
which can be used to communicate with host controller.\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Pool The host controller's memory pool.\r
@param Size Size of the memory to allocate.\r
if (NewBlock == NULL) {\r
return NULL;\r
}\r
- \r
+\r
//\r
// Add the new memory block to the pool, then allocate memory from it\r
//\r
/**\r
Free the allocated memory back to the memory pool.\r
\r
+ @param Ehc The EHCI device.\r
@param Pool The memory pool of the host controller.\r
@param Mem The memory to free.\r
@param Size The size of the memory to free.\r
**/\r
VOID\r
UsbHcFreeMem (\r
+ IN PEI_USB2_HC_DEV *Ehc,\r
IN USBHC_MEM_POOL *Pool,\r
IN VOID *Mem,\r
IN UINTN Size\r
Bit = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) % 8;\r
\r
//\r
- // reset associated bits in bit arry\r
+ // reset associated bits in bit array\r
//\r
for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) {\r
ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));\r
// Release the current memory block if it is empty and not the head\r
//\r
if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) {\r
- UsbHcFreeMemBlock (Pool, Block);\r
+ UsbHcFreeMemBlock (Ehc, Pool, Block);\r
}\r
\r
return ;\r