]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c
MdeModulePkg/PciBus: Add IOMMU support.
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciIo.c
index f72598d3ae680fa05ea400ae2922ed56d287ea89..3b3b53abced5493ad2abd7d4c74f1f3d037ac972 100644 (file)
@@ -14,6 +14,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "PciBus.h"\r
 \r
+extern EDKII_IOMMU_PROTOCOL                          *mIoMmuProtocol;\r
+\r
 //\r
 // Pci Io Protocol Interface\r
 //\r
@@ -965,8 +967,10 @@ PciIoMap (
   OUT    VOID                           **Mapping\r
   )\r
 {\r
-  EFI_STATUS    Status;\r
-  PCI_IO_DEVICE *PciIoDevice;\r
+  EFI_STATUS                                 Status;\r
+  PCI_IO_DEVICE                              *PciIoDevice;\r
+  UINT64                                     IoMmuAttribute;\r
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION  RootBridgeIoOperation;\r
 \r
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
 \r
@@ -978,13 +982,14 @@ PciIoMap (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  RootBridgeIoOperation = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION)Operation;\r
   if ((PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) != 0) {\r
-    Operation = (EFI_PCI_IO_PROTOCOL_OPERATION) (Operation + EfiPciOperationBusMasterRead64);\r
+    RootBridgeIoOperation = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION)(Operation + EfiPciOperationBusMasterRead64);\r
   }\r
 \r
   Status = PciIoDevice->PciRootBridgeIo->Map (\r
                                           PciIoDevice->PciRootBridgeIo,\r
-                                          (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,\r
+                                          RootBridgeIoOperation,\r
                                           HostAddress,\r
                                           NumberOfBytes,\r
                                           DeviceAddress,\r
@@ -999,6 +1004,31 @@ PciIoMap (
       );\r
   }\r
 \r
+  if (mIoMmuProtocol != NULL) {\r
+    if (!EFI_ERROR (Status)) {\r
+      switch (Operation) {\r
+      case EfiPciIoOperationBusMasterRead:\r
+        IoMmuAttribute = EDKII_IOMMU_ACCESS_READ;\r
+        break;\r
+      case EfiPciIoOperationBusMasterWrite:\r
+        IoMmuAttribute = EDKII_IOMMU_ACCESS_WRITE;\r
+        break;\r
+      case EfiPciIoOperationBusMasterCommonBuffer:\r
+        IoMmuAttribute = EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE;\r
+        break;\r
+      default:\r
+        ASSERT(FALSE);\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+      mIoMmuProtocol->SetAttribute (\r
+                        mIoMmuProtocol,\r
+                        PciIoDevice->Handle,\r
+                        *Mapping,\r
+                        IoMmuAttribute\r
+                        );\r
+    }\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
@@ -1024,6 +1054,15 @@ PciIoUnmap (
 \r
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);\r
 \r
+  if (mIoMmuProtocol != NULL) {\r
+    mIoMmuProtocol->SetAttribute (\r
+                      mIoMmuProtocol,\r
+                      PciIoDevice->Handle,\r
+                      Mapping,\r
+                      0\r
+                      );\r
+  }\r
+\r
   Status = PciIoDevice->PciRootBridgeIo->Unmap (\r
                                           PciIoDevice->PciRootBridgeIo,\r
                                           Mapping\r