X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=IntelSiliconPkg%2FFeature%2FVTd%2FIntelVTdPmrPei%2FIntelVTdPmrPei.c;h=240a6d281737b84922276443c32c0bae88cc1665;hp=d118b7ef26471d27fa62f5d1e98352db1538d232;hb=a1e7cd0b020ac024015095068b02e03a68edd96c;hpb=db5c75863d17e9fc1e5b7081a7ec62dee8c6f177 diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c index d118b7ef26..240a6d2817 100644 --- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.c @@ -23,17 +23,29 @@ #include #include #include -#include +#include +#include +#include #include "IntelVTdPmrPei.h" #define TOTAL_DMA_BUFFER_SIZE SIZE_4MB +#define TOTAL_DMA_BUFFER_SIZE_S3 SIZE_1MB -EDKII_VTD_INFO_PPI *mVTdInfoPpi; -UINTN mDmaBufferBase; -UINTN mDmaBufferSize = TOTAL_DMA_BUFFER_SIZE; -UINTN mDmaBufferCurrentTop; -UINTN mDmaBufferCurrentBottom; +EFI_GUID mVTdInfoGuid = { + 0x222f5e30, 0x5cd, 0x49c6, { 0x8a, 0xc, 0x36, 0xd6, 0x58, 0x41, 0xe0, 0x82 } +}; + +EFI_GUID mDmaBufferInfoGuid = { + 0x7b624ec7, 0xfb67, 0x4f9c, { 0xb6, 0xb0, 0x4d, 0xfa, 0x9c, 0x88, 0x20, 0x39 } +}; + +typedef struct { + UINTN DmaBufferBase; + UINTN DmaBufferSize; + UINTN DmaBufferCurrentTop; + UINTN DmaBufferCurrentBottom; +} DMA_BUFFER_INFO; #define MAP_INFO_SIGNATURE SIGNATURE_32 ('D', 'M', 'A', 'P') typedef struct { @@ -48,15 +60,19 @@ typedef struct { PEI Memory Layout: + +------------------+ <=============== PHMR.Limit (Top of memory) + | Mem Resource | + | | + +------------------+ <------- EfiMemoryTop | PEI allocated | - =========== +==================+ + =========== +==================+ <=============== PHMR.Base ^ | Commom Buf | | | -------------- | DMA Buffer | * DMA FREE * | | | -------------- | V | Read/Write Buf | - =========== +==================+ + =========== +==================+ <=============== PLMR.Limit | PEI allocated | | -------------- | <------- EfiFreeMemoryTop | * PEI FREE * | @@ -70,9 +86,11 @@ typedef struct { | Mem Alloc Hob | +------------------+ + | | + | Mem Resource | + +------------------+ <=============== PLMR.Base (0) **/ - /** Set IOMMU attribute for a system memory. @@ -138,8 +156,13 @@ PeiIoMmuMap ( OUT VOID **Mapping ) { - MAP_INFO *MapInfo; - UINTN Length; + MAP_INFO *MapInfo; + UINTN Length; + VOID *Hob; + DMA_BUFFER_INFO *DmaBufferInfo; + + Hob = GetFirstGuidHob (&mDmaBufferInfoGuid); + DmaBufferInfo = GET_GUID_HOB_DATA(Hob); if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer || Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) { @@ -149,18 +172,18 @@ PeiIoMmuMap ( } DEBUG ((DEBUG_VERBOSE, "PeiIoMmuMap - HostAddress - 0x%x, NumberOfBytes - %x\n", HostAddress, *NumberOfBytes)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom)); + DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop)); + DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom)); Length = *NumberOfBytes + sizeof(MAP_INFO); - if (Length > mDmaBufferCurrentTop - mDmaBufferCurrentBottom) { + if (Length > DmaBufferInfo->DmaBufferCurrentTop - DmaBufferInfo->DmaBufferCurrentBottom) { DEBUG ((DEBUG_ERROR, "PeiIoMmuMap - OUT_OF_RESOURCE\n")); ASSERT (FALSE); return EFI_OUT_OF_RESOURCES; } - *DeviceAddress = mDmaBufferCurrentBottom; - mDmaBufferCurrentBottom += Length; + *DeviceAddress = DmaBufferInfo->DmaBufferCurrentBottom; + DmaBufferInfo->DmaBufferCurrentBottom += Length; MapInfo = (VOID *)(UINTN)(*DeviceAddress + *NumberOfBytes); MapInfo->Signature = MAP_INFO_SIGNATURE; @@ -205,16 +228,21 @@ PeiIoMmuUnmap ( IN VOID *Mapping ) { - MAP_INFO *MapInfo; - UINTN Length; + MAP_INFO *MapInfo; + UINTN Length; + VOID *Hob; + DMA_BUFFER_INFO *DmaBufferInfo; + + 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, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom)); + DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop)); + DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom)); MapInfo = Mapping; ASSERT (MapInfo->Signature == MAP_INFO_SIGNATURE); @@ -235,8 +263,8 @@ PeiIoMmuUnmap ( } Length = MapInfo->NumberOfBytes + sizeof(MAP_INFO); - if (mDmaBufferCurrentBottom == MapInfo->DeviceAddress + Length) { - mDmaBufferCurrentBottom -= Length; + if (DmaBufferInfo->DmaBufferCurrentBottom == MapInfo->DeviceAddress + Length) { + DmaBufferInfo->DmaBufferCurrentBottom -= Length; } return EFI_SUCCESS; @@ -271,20 +299,25 @@ PeiIoMmuAllocateBuffer ( IN UINT64 Attributes ) { - UINTN Length; + UINTN Length; + VOID *Hob; + DMA_BUFFER_INFO *DmaBufferInfo; + + Hob = GetFirstGuidHob (&mDmaBufferInfoGuid); + DmaBufferInfo = GET_GUID_HOB_DATA(Hob); DEBUG ((DEBUG_VERBOSE, "PeiIoMmuAllocateBuffer - page - %x\n", Pages)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom)); + DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop)); + DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom)); Length = EFI_PAGES_TO_SIZE(Pages); - if (Length > mDmaBufferCurrentTop - mDmaBufferCurrentBottom) { + if (Length > DmaBufferInfo->DmaBufferCurrentTop - DmaBufferInfo->DmaBufferCurrentBottom) { DEBUG ((DEBUG_ERROR, "PeiIoMmuAllocateBuffer - OUT_OF_RESOURCE\n")); ASSERT (FALSE); return EFI_OUT_OF_RESOURCES; } - *HostAddress = (VOID *)(UINTN)(mDmaBufferCurrentTop - Length); - mDmaBufferCurrentTop -= Length; + *HostAddress = (VOID *)(UINTN)(DmaBufferInfo->DmaBufferCurrentTop - Length); + DmaBufferInfo->DmaBufferCurrentTop -= Length; DEBUG ((DEBUG_VERBOSE, "PeiIoMmuAllocateBuffer - allocate - %x\n", *HostAddress)); return EFI_SUCCESS; @@ -310,15 +343,20 @@ PeiIoMmuFreeBuffer ( IN VOID *HostAddress ) { - UINTN Length; + UINTN Length; + VOID *Hob; + DMA_BUFFER_INFO *DmaBufferInfo; + + Hob = GetFirstGuidHob (&mDmaBufferInfoGuid); + DmaBufferInfo = GET_GUID_HOB_DATA(Hob); DEBUG ((DEBUG_VERBOSE, "PeiIoMmuFreeBuffer - page - %x, HostAddr - %x\n", Pages, HostAddress)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentTop - %x\n", mDmaBufferCurrentTop)); - DEBUG ((DEBUG_VERBOSE, " mDmaBufferCurrentBottom - %x\n", mDmaBufferCurrentBottom)); + DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentTop - %x\n", DmaBufferInfo->DmaBufferCurrentTop)); + DEBUG ((DEBUG_VERBOSE, " DmaBufferCurrentBottom - %x\n", DmaBufferInfo->DmaBufferCurrentBottom)); Length = EFI_PAGES_TO_SIZE(Pages); - if ((UINTN)HostAddress == mDmaBufferCurrentTop) { - mDmaBufferCurrentTop += Length; + if ((UINTN)HostAddress == DmaBufferInfo->DmaBufferCurrentTop) { + DmaBufferInfo->DmaBufferCurrentTop += Length; } return EFI_SUCCESS; @@ -457,20 +495,21 @@ DumpPhitHob ( /** Get the highest memory. - @param HobList the HOB list. - @return the highest memory. **/ UINT64 GetTopMemory ( - IN VOID *HobList + VOID ) { + VOID *HobList; EFI_PEI_HOB_POINTERS Hob; EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; UINT64 TopMemory; UINT64 ResourceTop; + HobList = GetHobList (); + TopMemory = 0; for (Hob.Raw = HobList; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { @@ -494,6 +533,7 @@ GetTopMemory ( /** Initialize DMA protection. + @param VTdInfo The VTd engine context information. @param DmaBufferSize the DMA buffer size @param DmaBufferBase the DMA buffer base @@ -502,8 +542,9 @@ GetTopMemory ( **/ EFI_STATUS InitDmaProtection ( - IN UINTN DmaBufferSize, - OUT UINTN *DmaBufferBase + IN VTD_INFO *VTdInfo, + IN UINTN DmaBufferSize, + OUT UINTN *DmaBufferBase ) { EFI_STATUS Status; @@ -525,8 +566,8 @@ InitDmaProtection ( ASSERT (PhitHob->EfiMemoryBottom < PhitHob->EfiMemoryTop); - LowMemoryAlignment = GetLowMemoryAlignment (); - HighMemoryAlignment = GetHighMemoryAlignment (); + LowMemoryAlignment = GetLowMemoryAlignment (VTdInfo, VTdInfo->EngineMask); + HighMemoryAlignment = GetHighMemoryAlignment (VTdInfo, VTdInfo->EngineMask); if (LowMemoryAlignment < HighMemoryAlignment) { MemoryAlignment = (UINTN)HighMemoryAlignment; } else { @@ -534,6 +575,7 @@ InitDmaProtection ( } ASSERT (DmaBufferSize == ALIGN_VALUE(DmaBufferSize, MemoryAlignment)); *DmaBufferBase = (UINTN)AllocateAlignedPages (EFI_SIZE_TO_PAGES(DmaBufferSize), MemoryAlignment); + ASSERT (*DmaBufferBase != 0); if (*DmaBufferBase == 0) { DEBUG ((DEBUG_INFO, " InitDmaProtection : OutOfResource\n")); return EFI_OUT_OF_RESOURCES; @@ -542,14 +584,16 @@ InitDmaProtection ( LowBottom = 0; LowTop = *DmaBufferBase; HighBottom = *DmaBufferBase + DmaBufferSize; - HighTop = GetTopMemory (HobList); + HighTop = GetTopMemory (); Status = SetDmaProtectedRange ( - (UINT32)LowBottom, - (UINT32)(LowTop - LowBottom), - HighBottom, - HighTop - HighBottom - ); + VTdInfo, + VTdInfo->EngineMask, + (UINT32)LowBottom, + (UINT32)(LowTop - LowBottom), + HighBottom, + HighTop - HighBottom + ); if (EFI_ERROR(Status)) { FreePages ((VOID *)*DmaBufferBase, EFI_SIZE_TO_PAGES(DmaBufferSize)); @@ -559,50 +603,136 @@ InitDmaProtection ( } /** - Initializes the Intel VTd PMR PEIM. - - @param FileHandle Handle of the file being invoked. - @param PeiServices Describes the list of possible PEI Services. + Initializes the Intel VTd Info. @retval EFI_SUCCESS Usb bot driver is successfully initialized. @retval EFI_OUT_OF_RESOURCES Can't initialize the driver. **/ EFI_STATUS -EFIAPI -IntelVTdPmrInitialize ( - IN EFI_PEI_FILE_HANDLE FileHandle, - IN CONST EFI_PEI_SERVICES **PeiServices +InitVTdInfo ( + VOID ) { EFI_STATUS Status; - - if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT0) == 0) { - return EFI_UNSUPPORTED; - } + EFI_ACPI_DMAR_HEADER *AcpiDmarTable; + VOID *Hob; Status = PeiServicesLocatePpi ( &gEdkiiVTdInfoPpiGuid, 0, NULL, - (VOID **)&mVTdInfoPpi + (VOID **)&AcpiDmarTable ); ASSERT_EFI_ERROR(Status); + DumpAcpiDMAR (AcpiDmarTable); + + // + // Clear old VTdInfo Hob. + // + Hob = GetFirstGuidHob (&mVTdInfoGuid); + if (Hob != NULL) { + ZeroMem (&((EFI_HOB_GUID_TYPE *)Hob)->Name, sizeof(EFI_GUID)); + } + + // + // Get DMAR information to local VTdInfo + // + Status = ParseDmarAcpiTableDrhd (AcpiDmarTable); + if (EFI_ERROR(Status)) { + return Status; + } + + // + // NOTE: Do not parse RMRR here, because RMRR may cause PMR programming. + // + + return EFI_SUCCESS; +} + +/** + Initializes the Intel VTd PMR for all memory. + + @retval EFI_SUCCESS Usb bot driver is successfully initialized. + @retval EFI_OUT_OF_RESOURCES Can't initialize the driver. + +**/ +EFI_STATUS +InitVTdPmrForAll ( + VOID + ) +{ + EFI_STATUS Status; + VOID *Hob; + VTD_INFO *VTdInfo; + UINTN LowBottom; + UINTN LowTop; + UINTN HighBottom; + UINT64 HighTop; + + Hob = GetFirstGuidHob (&mVTdInfoGuid); + VTdInfo = GET_GUID_HOB_DATA(Hob); + + LowBottom = 0; + LowTop = 0; + HighBottom = 0; + HighTop = LShiftU64 (1, VTdInfo->HostAddressWidth); + + Status = SetDmaProtectedRange ( + VTdInfo, + VTdInfo->EngineMask, + (UINT32)LowBottom, + (UINT32)(LowTop - LowBottom), + HighBottom, + HighTop - HighBottom + ); + + return Status; +} + +/** + Initializes the Intel VTd PMR for DMA buffer. + + @retval EFI_SUCCESS Usb bot driver is successfully initialized. + @retval EFI_OUT_OF_RESOURCES Can't initialize the driver. + +**/ +EFI_STATUS +InitVTdPmrForDma ( + VOID + ) +{ + EFI_STATUS Status; + VOID *Hob; + VTD_INFO *VTdInfo; + DMA_BUFFER_INFO *DmaBufferInfo; + + Hob = GetFirstGuidHob (&mVTdInfoGuid); + VTdInfo = GET_GUID_HOB_DATA(Hob); + + // + // If there is RMRR memory, parse it here. + // + ParseDmarAcpiTableRmrr (VTdInfo); + + Hob = GetFirstGuidHob (&mDmaBufferInfoGuid); + DmaBufferInfo = GET_GUID_HOB_DATA(Hob); + + DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", DmaBufferInfo->DmaBufferSize)); // // Find a pre-memory in resource hob as DMA buffer // Mark PEI memory to be DMA protected. // - Status = InitDmaProtection (mDmaBufferSize, &mDmaBufferBase); + Status = InitDmaProtection (VTdInfo, DmaBufferInfo->DmaBufferSize, &DmaBufferInfo->DmaBufferBase); if (EFI_ERROR(Status)) { return Status; } - DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n", mDmaBufferBase)); - DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", mDmaBufferSize)); + DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n", DmaBufferInfo->DmaBufferBase)); - mDmaBufferCurrentTop = mDmaBufferBase + mDmaBufferSize; - mDmaBufferCurrentBottom = mDmaBufferBase; + DmaBufferInfo->DmaBufferCurrentTop = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize; + DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo->DmaBufferBase; // // Install PPI. @@ -613,3 +743,190 @@ IntelVTdPmrInitialize ( return Status; } +/** + This function handles S3 resume task at the end of PEI + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +S3EndOfPeiNotify( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + VOID *Hob; + VTD_INFO *VTdInfo; + UINT64 EngineMask; + + DEBUG((DEBUG_INFO, "VTdPmr S3EndOfPeiNotify\n")); + + if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT1) == 0) { + Hob = GetFirstGuidHob (&mVTdInfoGuid); + if (Hob == NULL) { + return EFI_SUCCESS; + } + VTdInfo = GET_GUID_HOB_DATA(Hob); + + EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1; + DisableDmaProtection (VTdInfo, EngineMask); + } + return EFI_SUCCESS; +} + +EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + S3EndOfPeiNotify +}; + +/** + This function handles VTd engine setup + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +VTdInfoNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + EFI_STATUS Status; + VOID *MemoryDiscovered; + UINT64 EnabledEngineMask; + VOID *Hob; + VTD_INFO *VTdInfo; + BOOLEAN MemoryInitialized; + + DEBUG ((DEBUG_INFO, "VTdInfoNotify\n")); + + // + // Check if memory is initialized. + // + MemoryInitialized = FALSE; + Status = PeiServicesLocatePpi ( + &gEfiPeiMemoryDiscoveredPpiGuid, + 0, + NULL, + &MemoryDiscovered + ); + if (!EFI_ERROR(Status)) { + MemoryInitialized = TRUE; + } + + DEBUG ((DEBUG_INFO, "MemoryInitialized - %x\n", MemoryInitialized)); + + if (!MemoryInitialized) { + // + // If the memory is not initialized, + // Protect all system memory + // + InitVTdInfo (); + InitVTdPmrForAll (); + } else { + // + // If the memory is initialized, + // Allocate DMA buffer and protect rest system memory + // + + // + // NOTE: We need reinit VTdInfo because previous information might be overriden. + // + InitVTdInfo (); + + Hob = GetFirstGuidHob (&mVTdInfoGuid); + VTdInfo = GET_GUID_HOB_DATA(Hob); + + // + // NOTE: We need check if PMR is enabled or not. + // + EnabledEngineMask = GetDmaProtectionEnabledEngineMask (VTdInfo, VTdInfo->EngineMask); + if (EnabledEngineMask != 0) { + EnableVTdTranslationProtection (VTdInfo, EnabledEngineMask); + DisableDmaProtection (VTdInfo, EnabledEngineMask); + } + InitVTdPmrForDma (); + if (EnabledEngineMask != 0) { + DisableVTdTranslationProtection (VTdInfo, EnabledEngineMask); + } + + } + + return EFI_SUCCESS; +} + +EFI_PEI_NOTIFY_DESCRIPTOR mVTdInfoNotifyDesc = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEdkiiVTdInfoPpiGuid, + VTdInfoNotify +}; + +/** + Initializes the Intel VTd PMR PEIM. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS Usb bot driver is successfully initialized. + @retval EFI_OUT_OF_RESOURCES Can't initialize the driver. + +**/ +EFI_STATUS +EFIAPI +IntelVTdPmrInitialize ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + DMA_BUFFER_INFO *DmaBufferInfo; + + DEBUG ((DEBUG_INFO, "IntelVTdPmrInitialize\n")); + + if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT0) == 0) { + return EFI_UNSUPPORTED; + } + + DmaBufferInfo = BuildGuidHob (&mDmaBufferInfoGuid, sizeof(DMA_BUFFER_INFO)); + ASSERT(DmaBufferInfo != NULL); + if (DmaBufferInfo == NULL) { + return EFI_OUT_OF_RESOURCES; + } + ZeroMem (DmaBufferInfo, sizeof(DMA_BUFFER_INFO)); + + PeiServicesGetBootMode (&BootMode); + + if (BootMode == BOOT_ON_S3_RESUME) { + DmaBufferInfo->DmaBufferSize = TOTAL_DMA_BUFFER_SIZE_S3; + } else { + DmaBufferInfo->DmaBufferSize = TOTAL_DMA_BUFFER_SIZE; + } + + Status = PeiServicesNotifyPpi (&mVTdInfoNotifyDesc); + ASSERT_EFI_ERROR (Status); + + // + // Register EndOfPei Notify for S3 + // + if (BootMode == BOOT_ON_S3_RESUME) { + Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc); + ASSERT_EFI_ERROR (Status); + } + + return EFI_SUCCESS; +} +