+\r
+/**\r
+ Return if the PMR is enabled.\r
+\r
+ @param VtdUnitBaseAddress The base address of the VTd engine.\r
+\r
+ @retval TRUE PMR is enabled.\r
+ @retval FALSE PMR is disabled or unsupported.\r
+**/\r
+BOOLEAN\r
+IsPmrEnabled (\r
+ IN UINTN VtdUnitBaseAddress\r
+ )\r
+{\r
+ UINT32 Reg32;\r
+ VTD_CAP_REG CapReg;\r
+\r
+ CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG);\r
+ if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) {\r
+ return FALSE;\r
+ }\r
+\r
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG);\r
+ if ((Reg32 & BIT0) == 0) {\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+ Return the mask of the VTd engine which is enabled.\r
+\r
+ @param VTdInfo The VTd engine context information.\r
+ @param EngineMask The mask of the VTd engine to be accessed.\r
+\r
+ @return the mask of the VTd engine which is enabled.\r
+**/\r
+UINT64\r
+GetDmaProtectionEnabledEngineMask (\r
+ IN VTD_INFO *VTdInfo,\r
+ IN UINT64 EngineMask\r
+ )\r
+{\r
+ UINTN Index;\r
+ BOOLEAN Result;\r
+ UINT64 EnabledEngineMask;\r
+\r
+ DEBUG ((DEBUG_INFO, "GetDmaProtectionEnabledEngineMask - 0x%lx\n", EngineMask));\r
+\r
+ EnabledEngineMask = 0;\r
+ for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {\r
+ if ((EngineMask & LShiftU64(1, Index)) == 0) {\r
+ continue;\r
+ }\r
+ Result = IsPmrEnabled ((UINTN)VTdInfo->VTdEngineAddress[Index]);\r
+ if (Result) {\r
+ EnabledEngineMask |= LShiftU64(1, Index);\r
+ }\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "EnabledEngineMask - 0x%lx\n", EnabledEngineMask));\r
+ return EnabledEngineMask;\r
+}\r