]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c
MdeModulePkg/XhciPei: Support IoMmu.
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciPei / XhciSched.c
index 3dd2b8909787180ec94bc19af05c382a838d7ca1..e5aee4918b6336a9597fb1a13de5356c2ad8788c 100644 (file)
@@ -200,6 +200,8 @@ XhcPeiFreeUrb (
     return;\r
   }\r
 \r
+  IoMmuUnmap (Urb->DataMap);\r
+\r
   FreePool (Urb);\r
 }\r
 \r
@@ -227,6 +229,10 @@ XhcPeiCreateTransferTrb (
   UINTN                         TotalLen;\r
   UINTN                         Len;\r
   UINTN                         TrbNum;\r
+  EDKII_IOMMU_OPERATION         MapOp;\r
+  EFI_PHYSICAL_ADDRESS          PhyAddr;\r
+  VOID                          *Map;\r
+  EFI_STATUS                    Status;\r
 \r
   SlotId = XhcPeiBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr);\r
   if (SlotId == 0) {\r
@@ -249,7 +255,27 @@ XhcPeiCreateTransferTrb (
     EPType  = (UINT8) ((DEVICE_CONTEXT_64 *)OutputContext)->EP[Dci-1].EPType;\r
   }\r
 \r
-  Urb->DataPhy = Urb->Data;\r
+  //\r
+  // No need to remap.\r
+  //\r
+  if ((Urb->Data != NULL) && (Urb->DataMap == NULL)) {\r
+    if (((UINT8) (Urb->Ep.Direction)) == EfiUsbDataIn) {\r
+      MapOp = EdkiiIoMmuOperationBusMasterWrite;\r
+    } else {\r
+      MapOp = EdkiiIoMmuOperationBusMasterRead;\r
+    }\r
+\r
+    Len = Urb->DataLen;\r
+    Status = IoMmuMap (MapOp, Urb->Data, &Len, &PhyAddr, &Map);\r
+\r
+    if (EFI_ERROR (Status) || (Len != Urb->DataLen)) {\r
+      DEBUG ((DEBUG_ERROR, "XhcCreateTransferTrb: Fail to map Urb->Data.\n"));\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    Urb->DataPhy  = (VOID *) ((UINTN) PhyAddr);\r
+    Urb->DataMap  = Map;\r
+  }\r
 \r
   //\r
   // Construct the TRB\r
@@ -2812,6 +2838,7 @@ XhcPeiInitSched (
   UINT64                *ScratchEntry;\r
   EFI_PHYSICAL_ADDRESS  ScratchEntryPhy;\r
   UINT32                Index;\r
+  UINTN                 *ScratchEntryMap;\r
   EFI_STATUS            Status;\r
 \r
   //\r
@@ -2847,6 +2874,13 @@ XhcPeiInitSched (
   Xhc->MaxScratchpadBufs = MaxScratchpadBufs;\r
   ASSERT (MaxScratchpadBufs <= 1023);\r
   if (MaxScratchpadBufs != 0) {\r
+    //\r
+    // Allocate the buffer to record the Mapping for each scratch buffer in order to Unmap them\r
+    //\r
+    ScratchEntryMap = AllocateZeroPool (sizeof (UINTN) * MaxScratchpadBufs);\r
+    ASSERT (ScratchEntryMap != NULL);\r
+    Xhc->ScratchEntryMap = ScratchEntryMap;\r
+\r
     //\r
     // Allocate the buffer to record the host address for each entry\r
     //\r
@@ -2859,7 +2893,8 @@ XhcPeiInitSched (
                EFI_SIZE_TO_PAGES (MaxScratchpadBufs * sizeof (UINT64)),\r
                Xhc->PageSize,\r
                (VOID **) &ScratchBuf,\r
-               &ScratchPhy\r
+               &ScratchPhy,\r
+               &Xhc->ScratchMap\r
                );\r
     ASSERT_EFI_ERROR (Status);\r
 \r
@@ -2875,7 +2910,8 @@ XhcPeiInitSched (
                  EFI_SIZE_TO_PAGES (Xhc->PageSize),\r
                  Xhc->PageSize,\r
                  (VOID **) &ScratchEntry[Index],\r
-                 &ScratchEntryPhy\r
+                 &ScratchEntryPhy,\r
+                 (VOID **) &ScratchEntryMap[Index]\r
                  );\r
       ASSERT_EFI_ERROR (Status);\r
       ZeroMem ((VOID *) (UINTN) ScratchEntry[Index], Xhc->PageSize);\r
@@ -2967,12 +3003,13 @@ XhcPeiFreeSched (
       //\r
       // Free Scratchpad Buffers\r
       //\r
-      UsbHcFreeAlignedPages ((VOID*) (UINTN) ScratchEntry[Index], EFI_SIZE_TO_PAGES (Xhc->PageSize));\r
+      UsbHcFreeAlignedPages ((VOID*) (UINTN) ScratchEntry[Index], EFI_SIZE_TO_PAGES (Xhc->PageSize), (VOID *) Xhc->ScratchEntryMap[Index]);\r
     }\r
     //\r
     // Free Scratchpad Buffer Array\r
     //\r
-    UsbHcFreeAlignedPages (Xhc->ScratchBuf, EFI_SIZE_TO_PAGES (Xhc->MaxScratchpadBufs * sizeof (UINT64)));\r
+    UsbHcFreeAlignedPages (Xhc->ScratchBuf, EFI_SIZE_TO_PAGES (Xhc->MaxScratchpadBufs * sizeof (UINT64)), Xhc->ScratchMap);\r
+    FreePool (Xhc->ScratchEntryMap);\r
     FreePool (Xhc->ScratchEntry);\r
   }\r
 \r