IntelFramdworkModulePkg/LegacyBios: Add IoMmu Support.
authorJiewen Yao <jiewen.yao@intel.com>
Mon, 4 Sep 2017 01:28:26 +0000 (09:28 +0800)
committerJiewen Yao <jiewen.yao@intel.com>
Wed, 6 Sep 2017 04:11:16 +0000 (12:11 +0800)
If IOMMU is enabled, the legacy BIOS need allow the legacy memory
access by the legacy device.
The legacy memory is below 1M memory and HighPmm memory.

Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosInterface.h
IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyPci.c

index 4ca412a..48473a0 100644 (file)
   gEfiLegacyBiosProtocolGuid                    ## PRODUCES\r
   gEfiSerialIoProtocolGuid                      ## CONSUMES\r
   gEfiSioProtocolGuid                           ## CONSUMES\r
+  gEdkiiIoMmuProtocolGuid                       ## CONSUMES\r
 \r
 [Pcd]\r
   gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLegacyBiosCacheLegacyRegion  ## CONSUMES\r
index 069646b..fe9dd74 100644 (file)
@@ -47,6 +47,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/PciRootBridgeIo.h>\r
 #include <Protocol/SerialIo.h>\r
 #include <Protocol/SuperIo.h>\r
+#include <Protocol/IoMmu.h>\r
 \r
 #include <Library/BaseLib.h>\r
 #include <Library/DebugLib.h>\r
index c4c77ec..8ffdf0c 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