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>
@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_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
IN UINT64 IoMmuAccess\r
)\r
{\r
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
return EFI_SUCCESS;\r
}\r
\r
@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_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
Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);\r
DmaBufferInfo = GET_GUID_HOB_DATA(Hob);\r
\r
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
if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||\r
Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {\r
*DeviceAddress = (UINTN)HostAddress;\r
return EFI_SUCCESS;\r
}\r
\r
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
Length = *NumberOfBytes + sizeof(MAP_INFO);\r
if (Length > DmaBufferInfo->DmaBufferCurrentTop - DmaBufferInfo->DmaBufferCurrentBottom) {\r
DEBUG ((DEBUG_ERROR, "PeiIoMmuMap - OUT_OF_RESOURCE\n"));\r
@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_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
**/\r
EFI_STATUS\r
EFIAPI\r
Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);\r
DmaBufferInfo = GET_GUID_HOB_DATA(Hob);\r
\r
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
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
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
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
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
DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop));\r
DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom));\r
\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
Length = EFI_PAGES_TO_SIZE(Pages);\r
if (Length > DmaBufferInfo->DmaBufferCurrentTop - DmaBufferInfo->DmaBufferCurrentBottom) {\r
DEBUG ((DEBUG_ERROR, "PeiIoMmuAllocateBuffer - OUT_OF_RESOURCE\n"));\r
Length = EFI_PAGES_TO_SIZE(Pages);\r
if (Length > DmaBufferInfo->DmaBufferCurrentTop - DmaBufferInfo->DmaBufferCurrentBottom) {\r
DEBUG ((DEBUG_ERROR, "PeiIoMmuAllocateBuffer - OUT_OF_RESOURCE\n"));\r
@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_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
DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop));\r
DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom));\r
\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
Length = EFI_PAGES_TO_SIZE(Pages);\r
if ((UINTN)HostAddress == DmaBufferInfo->DmaBufferCurrentTop) {\r
DmaBufferInfo->DmaBufferCurrentTop += Length;\r
Length = EFI_PAGES_TO_SIZE(Pages);\r
if ((UINTN)HostAddress == DmaBufferInfo->DmaBufferCurrentTop) {\r
DmaBufferInfo->DmaBufferCurrentTop += Length;\r
UINT64 HighTop;\r
DMA_BUFFER_INFO *DmaBufferInfo;\r
VOID *Hob;\r
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
\r
Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);\r
DmaBufferInfo = GET_GUID_HOB_DATA(Hob);\r
DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo->DmaBufferBase;\r
\r
//\r
DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo->DmaBufferBase;\r
\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
\r
LowBottom = 0;\r
LowTop = DmaBufferInfo->DmaBufferBase;\r
//\r
InitVTdInfo ();\r
InitVTdPmrForAll ();\r
//\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
} else {\r
//\r
// If the memory is initialized,\r