]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/EhciPei/UsbHcMem.c
MdeModulePkg EhciPei: Support IoMmu
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / EhciPei / UsbHcMem.c
index 5f9f5f0718f391ecf6f691c2369166217b523d67..a0419bd857229992804a817c21f6107c2842a6ac 100644 (file)
@@ -2,7 +2,7 @@
 PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid\r
 which is used to enable recovery function from USB Drivers.\r
 \r
-Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2010 - 2017, 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
@@ -79,16 +79,18 @@ UsbHcAllocMemBlock (
 \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
@@ -109,17 +111,21 @@ UsbHcAllocMemBlock (
 /**\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
@@ -195,6 +201,54 @@ UsbHcAllocMemFromBlock (
   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
@@ -316,7 +370,8 @@ UsbHcInitMemPool (
 \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
@@ -325,6 +380,7 @@ UsbHcInitMemPool (
 **/\r
 EFI_STATUS\r
 UsbHcFreeMemPool (\r
+  IN PEI_USB2_HC_DEV      *Ehc,\r
   IN USBHC_MEM_POOL       *Pool\r
   )\r
 {\r
@@ -337,11 +393,11 @@ UsbHcFreeMemPool (
   // 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
@@ -425,6 +481,7 @@ UsbHcAllocateMem (
 /**\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
@@ -432,6 +489,7 @@ UsbHcAllocateMem (
 **/\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
@@ -486,7 +544,7 @@ UsbHcFreeMem (
   // 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