+/**\r
+ This function handles S3 resume task at the end of PEI\r
+\r
+ @param[in] PeiServices Pointer to PEI Services Table.\r
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that\r
+ caused this function to execute.\r
+ @param[in] Ppi Pointer to the PPI data associated with this function.\r
+\r
+ @retval EFI_STATUS Always return EFI_SUCCESS\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+S3EndOfPeiNotify(\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
+ IN VOID *Ppi\r
+ )\r
+{\r
+ VOID *Hob;\r
+ VTD_INFO *VTdInfo;\r
+ UINT64 EngineMask;\r
+\r
+ DEBUG((DEBUG_INFO, "VTdPmr S3EndOfPeiNotify\n"));\r
+\r
+ if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT1) == 0) {\r
+ Hob = GetFirstGuidHob (&mVTdInfoGuid);\r
+ if (Hob == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ VTdInfo = GET_GUID_HOB_DATA(Hob);\r
+\r
+ EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;\r
+ DisableDmaProtection (VTdInfo, EngineMask);\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc = {\r
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+ &gEfiEndOfPeiSignalPpiGuid,\r
+ S3EndOfPeiNotify\r
+};\r
+\r
+/**\r
+ This function handles VTd engine setup\r
+\r
+ @param[in] PeiServices Pointer to PEI Services Table.\r
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that\r
+ caused this function to execute.\r
+ @param[in] Ppi Pointer to the PPI data associated with this function.\r
+\r
+ @retval EFI_STATUS Always return EFI_SUCCESS\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+VTdInfoNotify (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
+ IN VOID *Ppi\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VOID *MemoryDiscovered;\r
+ UINT64 EnabledEngineMask;\r
+ VOID *Hob;\r
+ VTD_INFO *VTdInfo;\r
+ BOOLEAN MemoryInitialized;\r
+\r
+ DEBUG ((DEBUG_INFO, "VTdInfoNotify\n"));\r
+\r
+ //\r
+ // Check if memory is initialized.\r
+ //\r
+ MemoryInitialized = FALSE;\r
+ Status = PeiServicesLocatePpi (\r
+ &gEfiPeiMemoryDiscoveredPpiGuid,\r
+ 0,\r
+ NULL,\r
+ &MemoryDiscovered\r
+ );\r
+ if (!EFI_ERROR(Status)) {\r
+ MemoryInitialized = TRUE;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "MemoryInitialized - %x\n", MemoryInitialized));\r
+\r
+ if (!MemoryInitialized) {\r
+ //\r
+ // If the memory is not initialized,\r
+ // Protect all system memory\r
+ //\r
+ InitVTdInfo ();\r
+ InitVTdPmrForAll ();\r
+ } else {\r
+ //\r
+ // If the memory is initialized,\r
+ // Allocate DMA buffer and protect rest system memory\r
+ //\r
+\r
+ //\r
+ // NOTE: We need reinit VTdInfo because previous information might be overriden.\r
+ //\r
+ InitVTdInfo ();\r
+\r
+ Hob = GetFirstGuidHob (&mVTdInfoGuid);\r
+ VTdInfo = GET_GUID_HOB_DATA(Hob);\r
+\r
+ //\r
+ // NOTE: We need check if PMR is enabled or not.\r
+ //\r
+ EnabledEngineMask = GetDmaProtectionEnabledEngineMask (VTdInfo, VTdInfo->EngineMask);\r
+ if (EnabledEngineMask != 0) {\r
+ EnableVTdTranslationProtection (VTdInfo, EnabledEngineMask);\r
+ DisableDmaProtection (VTdInfo, EnabledEngineMask);\r
+ }\r
+ InitVTdPmrForDma ();\r
+ if (EnabledEngineMask != 0) {\r
+ DisableVTdTranslationProtection (VTdInfo, EnabledEngineMask);\r
+ }\r
+\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_PEI_NOTIFY_DESCRIPTOR mVTdInfoNotifyDesc = {\r
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+ &gEdkiiVTdInfoPpiGuid,\r
+ VTdInfoNotify\r
+};\r
+\r
+/**\r
+ Initializes the Intel VTd PMR PEIM.\r
+\r
+ @param FileHandle Handle of the file being invoked.\r
+ @param PeiServices Describes the list of possible PEI Services.\r
+\r
+ @retval EFI_SUCCESS Usb bot driver is successfully initialized.\r
+ @retval EFI_OUT_OF_RESOURCES Can't initialize the driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IntelVTdPmrInitialize (\r
+ IN EFI_PEI_FILE_HANDLE FileHandle,\r
+ IN CONST EFI_PEI_SERVICES **PeiServices\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_BOOT_MODE BootMode;\r
+ DMA_BUFFER_INFO *DmaBufferInfo;\r
+\r
+ DEBUG ((DEBUG_INFO, "IntelVTdPmrInitialize\n"));\r
+\r
+ if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT0) == 0) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ DmaBufferInfo = BuildGuidHob (&mDmaBufferInfoGuid, sizeof(DMA_BUFFER_INFO));\r
+ ASSERT(DmaBufferInfo != NULL);\r
+ if (DmaBufferInfo == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ ZeroMem (DmaBufferInfo, sizeof(DMA_BUFFER_INFO));\r
+\r
+ PeiServicesGetBootMode (&BootMode);\r
+\r
+ if (BootMode == BOOT_ON_S3_RESUME) {\r
+ DmaBufferInfo->DmaBufferSize = TOTAL_DMA_BUFFER_SIZE_S3;\r
+ } else {\r
+ DmaBufferInfo->DmaBufferSize = TOTAL_DMA_BUFFER_SIZE;\r
+ }\r
+\r
+ Status = PeiServicesNotifyPpi (&mVTdInfoNotifyDesc);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Register EndOfPei Notify for S3\r
+ //\r
+ if (BootMode == BOOT_ON_S3_RESUME) {\r
+ Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r