]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyPci.c
IntelFramdworkModulePkg/LegacyBios: Add IoMmu Support.
[mirror_edk2.git] / IntelFrameworkModulePkg / Csm / LegacyBiosDxe / LegacyPci.c
index c4c77ec344a0399b957b559bc5d43035f6c1c052..8ffdf0c1ff9551ad06f0bc8070b3d26243d3b442 100644 (file)
@@ -41,7 +41,7 @@ BOOLEAN                             mIgnoreBbsUpdateFlag;
 BOOLEAN                             mVgaInstallationInProgress  = FALSE;\r
 UINT32                              mRomCount                   = 0x00;\r
 ROM_INSTANCE_ENTRY                  mRomEntry[ROM_MAX_ENTRIES];\r
-\r
+EDKII_IOMMU_PROTOCOL                *mIoMmu;\r
 \r
 /**\r
   Query shadowed legacy ROM parameters registered by RomShadow() previously.\r
@@ -2696,6 +2696,61 @@ Done:
   return Status;\r
 }\r
 \r
+/**\r
+  Let IOMMU grant DMA access for the PCI device.\r
+\r
+  @param  PciHandle             The EFI handle for the PCI device.\r
+  @param  HostAddress           The system memory address to map to the PCI controller.\r
+  @param  NumberOfBytes         The number of bytes to map.\r
+\r
+  @retval EFI_SUCCESS  The DMA access is granted.\r
+**/\r
+EFI_STATUS\r
+IoMmuGrantAccess (\r
+  IN  EFI_HANDLE                        PciHandle,\r
+  IN  EFI_PHYSICAL_ADDRESS              HostAddress,\r
+  IN  UINTN                             NumberOfBytes\r
+  )\r
+{\r
+  EFI_PHYSICAL_ADDRESS            DeviceAddress;\r
+  VOID                            *Mapping;\r
+  EFI_STATUS                      Status;\r
+\r
+  if (PciHandle == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
+  if (mIoMmu == NULL) {\r
+    gBS->LocateProtocol (&gEdkiiIoMmuProtocolGuid, NULL, (VOID **)&mIoMmu);\r
+  }\r
+  if (mIoMmu != NULL) {\r
+    Status = mIoMmu->Map (\r
+                       mIoMmu,\r
+                       EdkiiIoMmuOperationBusMasterCommonBuffer,\r
+                       (VOID *)(UINTN)HostAddress,\r
+                       &NumberOfBytes,\r
+                       &DeviceAddress,\r
+                       &Mapping\r
+                       );\r
+    if (EFI_ERROR(Status)) {\r
+      DEBUG ((DEBUG_ERROR, "LegacyPci - IoMmuMap - %r\n", Status));\r
+    } else {\r
+      ASSERT (DeviceAddress == HostAddress);\r
+      Status = mIoMmu->SetAttribute (\r
+                         mIoMmu,\r
+                         PciHandle,\r
+                         Mapping,\r
+                         EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE\r
+                         );\r
+      if (EFI_ERROR(Status)) {\r
+        DEBUG ((DEBUG_ERROR, "LegacyPci - IoMmuSetAttribute - %r\n", Status));\r
+      }\r
+    }\r
+  }\r
+  return Status;\r
+}\r
+\r
 /**\r
   Load a legacy PC-AT OPROM on the PciHandle device. Return information\r
   about how many disks were added by the OPROM and the shadow address and\r
@@ -2978,6 +3033,21 @@ LegacyBiosInstallPciRom (
       RuntimeImageLength = Pcir->MaxRuntimeImageLength * 512;\r
     }\r
   }\r
+\r
+  //\r
+  // Grant access for below 1M\r
+  // BDA/EBDA/LowPMM and scratch memory for OPROM.\r
+  //\r
+  IoMmuGrantAccess (PciHandle, 0, SIZE_1MB);\r
+  //\r
+  // Grant access for HiPmm\r
+  //\r
+  IoMmuGrantAccess (\r
+    PciHandle,\r
+    Private->IntThunk->EfiToLegacy16InitTable.HiPmmMemory,\r
+    Private->IntThunk->EfiToLegacy16InitTable.HiPmmMemorySizeInBytes\r
+    );\r
+\r
   //\r
   // Shadow and initialize the OpROM.\r
   //\r