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....@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Star Zeng <star.z...@intel.com>
---
 .../Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c    | 77 ++++++++++++++++++----
 1 file changed, 66 insertions(+), 11 deletions(-)

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

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to