IntelSiliconPkg IntelVTdPmrPei: Install IOMMU PPI for pre-memory phase
authorStar Zeng <star.zeng@intel.com>
Tue, 6 Feb 2018 10:36:19 +0000 (18:36 +0800)
committerStar Zeng <star.zeng@intel.com>
Wed, 7 Feb 2018 10:28:12 +0000 (18:28 +0800)
Install IOMMU PPI for pre-memory phase and return
EFI_NOT_AVAILABLE_YET to indicate that DMA protection has been enabled,
but DMA buffer are not available to be allocated yet.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c

index 87708cf..c6a1ccd 100644 (file)
@@ -112,6 +112,8 @@ typedef struct {
   @retval EFI_UNSUPPORTED        The IOMMU does not support the memory range specified by Mapping.\r
   @retval EFI_OUT_OF_RESOURCES   There are not enough resources available to modify the IOMMU access.\r
   @retval EFI_DEVICE_ERROR       The IOMMU device reported an error while attempting the operation.\r
+  @retval EFI_NOT_AVAILABLE_YET  DMA protection has been enabled, but DMA buffer are\r
+                                 not available to be allocated yet.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -122,6 +124,16 @@ PeiIoMmuSetAttribute (
   IN UINT64                IoMmuAccess\r
   )\r
 {\r
+  VOID                        *Hob;\r
+  DMA_BUFFER_INFO             *DmaBufferInfo;\r
+\r
+  Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);\r
+  DmaBufferInfo = GET_GUID_HOB_DATA(Hob);\r
+\r
+  if (DmaBufferInfo->DmaBufferCurrentTop == 0) {\r
+    return EFI_NOT_AVAILABLE_YET;\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -143,6 +155,8 @@ PeiIoMmuSetAttribute (
   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.\r
   @retval EFI_DEVICE_ERROR      The system hardware could not map the requested address.\r
+  @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are\r
+                                not available to be allocated yet.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -164,6 +178,14 @@ PeiIoMmuMap (
   Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);\r
   DmaBufferInfo = GET_GUID_HOB_DATA(Hob);\r
 \r
+  DEBUG ((DEBUG_VERBOSE, "PeiIoMmuMap - HostAddress - 0x%x, NumberOfBytes - %x\n", HostAddress, *NumberOfBytes));\r
+  DEBUG ((DEBUG_VERBOSE, "  DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop));\r
+  DEBUG ((DEBUG_VERBOSE, "  DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom));\r
+\r
+  if (DmaBufferInfo->DmaBufferCurrentTop == 0) {\r
+    return EFI_NOT_AVAILABLE_YET;\r
+  }\r
+\r
   if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||\r
       Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {\r
     *DeviceAddress = (UINTN)HostAddress;\r
@@ -171,10 +193,6 @@ PeiIoMmuMap (
     return EFI_SUCCESS;\r
   }\r
 \r
-  DEBUG ((DEBUG_VERBOSE, "PeiIoMmuMap - HostAddress - 0x%x, NumberOfBytes - %x\n", HostAddress, *NumberOfBytes));\r
-  DEBUG ((DEBUG_VERBOSE, "  DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop));\r
-  DEBUG ((DEBUG_VERBOSE, "  DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom));\r
-\r
   Length = *NumberOfBytes + sizeof(MAP_INFO);\r
   if (Length > DmaBufferInfo->DmaBufferCurrentTop - DmaBufferInfo->DmaBufferCurrentBottom) {\r
     DEBUG ((DEBUG_ERROR, "PeiIoMmuMap - OUT_OF_RESOURCE\n"));\r
@@ -220,6 +238,9 @@ PeiIoMmuMap (
   @retval EFI_SUCCESS           The range was unmapped.\r
   @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().\r
   @retval EFI_DEVICE_ERROR      The data was not committed to the target system memory.\r
+  @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are\r
+                                not available to be allocated yet.\r
+\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
@@ -236,14 +257,18 @@ PeiIoMmuUnmap (
   Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);\r
   DmaBufferInfo = GET_GUID_HOB_DATA(Hob);\r
 \r
-  if (Mapping == NULL) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
   DEBUG ((DEBUG_VERBOSE, "PeiIoMmuUnmap - Mapping - %x\n", Mapping));\r
   DEBUG ((DEBUG_VERBOSE, "  DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop));\r
   DEBUG ((DEBUG_VERBOSE, "  DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom));\r
 \r
+  if (DmaBufferInfo->DmaBufferCurrentTop == 0) {\r
+    return EFI_NOT_AVAILABLE_YET;\r
+  }\r
+\r
+  if (Mapping == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   MapInfo = Mapping;\r
   ASSERT (MapInfo->Signature == MAP_INFO_SIGNATURE);\r
   DEBUG ((DEBUG_VERBOSE, "  Op(%x):DeviceAddress - %x, NumberOfBytes - %x\n", MapInfo->Operation, (UINTN)MapInfo->DeviceAddress, MapInfo->NumberOfBytes));\r
@@ -287,6 +312,8 @@ PeiIoMmuUnmap (
                                 MEMORY_WRITE_COMBINE, MEMORY_CACHED and DUAL_ADDRESS_CYCLE.\r
   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
   @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.\r
+  @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are\r
+                                not available to be allocated yet.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -310,6 +337,10 @@ PeiIoMmuAllocateBuffer (
   DEBUG ((DEBUG_VERBOSE, "  DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop));\r
   DEBUG ((DEBUG_VERBOSE, "  DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom));\r
 \r
+  if (DmaBufferInfo->DmaBufferCurrentTop == 0) {\r
+    return EFI_NOT_AVAILABLE_YET;\r
+  }\r
+\r
   Length = EFI_PAGES_TO_SIZE(Pages);\r
   if (Length > DmaBufferInfo->DmaBufferCurrentTop - DmaBufferInfo->DmaBufferCurrentBottom) {\r
     DEBUG ((DEBUG_ERROR, "PeiIoMmuAllocateBuffer - OUT_OF_RESOURCE\n"));\r
@@ -333,6 +364,8 @@ PeiIoMmuAllocateBuffer (
   @retval EFI_SUCCESS           The requested memory pages were freed.\r
   @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages\r
                                 was not allocated with AllocateBuffer().\r
+  @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are\r
+                                not available to be allocated yet.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -354,6 +387,10 @@ PeiIoMmuFreeBuffer (
   DEBUG ((DEBUG_VERBOSE, "  DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop));\r
   DEBUG ((DEBUG_VERBOSE, "  DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom));\r
 \r
+  if (DmaBufferInfo->DmaBufferCurrentTop == 0) {\r
+    return EFI_NOT_AVAILABLE_YET;\r
+  }\r
+\r
   Length = EFI_PAGES_TO_SIZE(Pages);\r
   if ((UINTN)HostAddress == DmaBufferInfo->DmaBufferCurrentTop) {\r
     DmaBufferInfo->DmaBufferCurrentTop += Length;\r
@@ -400,6 +437,8 @@ InitDmaProtection (
   UINT64                      HighTop;\r
   DMA_BUFFER_INFO             *DmaBufferInfo;\r
   VOID                        *Hob;\r
+  EFI_PEI_PPI_DESCRIPTOR      *OldDescriptor;\r
+  EDKII_IOMMU_PPI             *OldIoMmuPpi;\r
 \r
   Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);\r
   DmaBufferInfo = GET_GUID_HOB_DATA(Hob);\r
@@ -427,10 +466,20 @@ InitDmaProtection (
   DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo->DmaBufferBase;\r
 \r
   //\r
-  // Install PPI.\r
+  // (Re)Install PPI.\r
   //\r
-  Status = PeiServicesInstallPpi (&mIoMmuPpiList);\r
-  ASSERT_EFI_ERROR(Status);\r
+  Status = PeiServicesLocatePpi (\r
+             &gEdkiiIoMmuPpiGuid,\r
+             0,\r
+             &OldDescriptor,\r
+             (VOID **) &OldIoMmuPpi\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = PeiServicesReInstallPpi (OldDescriptor, &mIoMmuPpiList);\r
+  } else {\r
+    Status = PeiServicesInstallPpi (&mIoMmuPpiList);\r
+  }\r
+  ASSERT_EFI_ERROR (Status);\r
 \r
   LowBottom = 0;\r
   LowTop = DmaBufferInfo->DmaBufferBase;\r
@@ -668,6 +717,12 @@ VTdInfoNotify (
     //\r
     InitVTdInfo ();\r
     InitVTdPmrForAll ();\r
+\r
+    //\r
+    // Install PPI.\r
+    //\r
+    Status = PeiServicesInstallPpi (&mIoMmuPpiList);\r
+    ASSERT_EFI_ERROR(Status);\r
   } else {\r
     //\r
     // If the memory is initialized,\r