X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=IntelSiliconPkg%2FFeature%2FVTd%2FIntelVTdPmrPei%2FIntelVTdPmr.c;h=000a81ba187940926f2448addf471eefb4d9a3f5;hp=ef08e2991f0abfe69ff381784dc2ea6a5c968fdd;hb=a1e7cd0b020ac024015095068b02e03a68edd96c;hpb=db5c75863d17e9fc1e5b7081a7ec62dee8c6f177 diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c index ef08e2991f..000a81ba18 100644 --- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c +++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c @@ -18,21 +18,21 @@ #include #include #include -#include +#include #include "IntelVTdPmrPei.h" -extern EDKII_VTD_INFO_PPI *mVTdInfoPpi; - /** Get protected low memory alignment. + @param HostAddressWidth The host address width. @param VtdUnitBaseAddress The base address of the VTd engine. @return protected low memory alignment. **/ UINT32 GetPlmrAlignment ( + IN UINT8 HostAddressWidth, IN UINTN VtdUnitBaseAddress ) { @@ -48,19 +48,18 @@ GetPlmrAlignment ( /** Get protected high memory alignment. + @param HostAddressWidth The host address width. @param VtdUnitBaseAddress The base address of the VTd engine. @return protected high memory alignment. **/ UINT64 GetPhmrAlignment ( + IN UINT8 HostAddressWidth, IN UINTN VtdUnitBaseAddress ) { UINT64 Data64; - UINT8 HostAddressWidth; - - HostAddressWidth = mVTdInfoPpi->HostAddressWidth; MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, 0xFFFFFFFFFFFFFFFF); Data64 = MmioRead64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG); @@ -73,11 +72,15 @@ GetPhmrAlignment ( /** Get protected low memory alignment. + @param VTdInfo The VTd engine context information. + @param EngineMask The mask of the VTd engine to be accessed. + @return protected low memory alignment. **/ UINT32 GetLowMemoryAlignment ( - VOID + IN VTD_INFO *VTdInfo, + IN UINT64 EngineMask ) { UINTN Index; @@ -85,8 +88,11 @@ GetLowMemoryAlignment ( UINT32 FinalAlignment; FinalAlignment = 0; - for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { - Alignment = GetPlmrAlignment ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); + for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) { + if ((EngineMask & LShiftU64(1, Index)) == 0) { + continue; + } + Alignment = GetPlmrAlignment (VTdInfo->HostAddressWidth, (UINTN)VTdInfo->VTdEngineAddress[Index]); if (FinalAlignment < Alignment) { FinalAlignment = Alignment; } @@ -97,11 +103,15 @@ GetLowMemoryAlignment ( /** Get protected high memory alignment. + @param VTdInfo The VTd engine context information. + @param EngineMask The mask of the VTd engine to be accessed. + @return protected high memory alignment. **/ UINT64 GetHighMemoryAlignment ( - VOID + IN VTD_INFO *VTdInfo, + IN UINT64 EngineMask ) { UINTN Index; @@ -109,8 +119,11 @@ GetHighMemoryAlignment ( UINT64 FinalAlignment; FinalAlignment = 0; - for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { - Alignment = GetPhmrAlignment ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); + for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) { + if ((EngineMask & LShiftU64(1, Index)) == 0) { + continue; + } + Alignment = GetPhmrAlignment (VTdInfo->HostAddressWidth, (UINTN)VTdInfo->VTdEngineAddress[Index]); if (FinalAlignment < Alignment) { FinalAlignment = Alignment; } @@ -134,12 +147,19 @@ EnablePmr ( UINT32 Reg32; VTD_CAP_REG CapReg; + DEBUG ((DEBUG_INFO, "EnablePmr - %x\n", VtdUnitBaseAddress)); + CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG); if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) { return EFI_UNSUPPORTED; } Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG); + if (Reg32 == 0xFFFFFFFF) { + DEBUG ((DEBUG_ERROR, "R_PMEN_ENABLE_REG - 0x%x\n", Reg32)); + ASSERT(FALSE); + } + if ((Reg32 & BIT0) == 0) { MmioWrite32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG, BIT31); do { @@ -147,6 +167,8 @@ EnablePmr ( } while((Reg32 & BIT0) == 0); } + DEBUG ((DEBUG_INFO, "EnablePmr - Done\n")); + return EFI_SUCCESS; } @@ -172,6 +194,11 @@ DisablePmr ( } Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG); + if (Reg32 == 0xFFFFFFFF) { + DEBUG ((DEBUG_ERROR, "R_PMEN_ENABLE_REG - 0x%x\n", Reg32)); + ASSERT(FALSE); + } + if ((Reg32 & BIT0) != 0) { MmioWrite32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG, 0x0); do { @@ -185,6 +212,7 @@ DisablePmr ( /** Set PMR region in the VTd engine. + @param HostAddressWidth The host address width. @param VtdUnitBaseAddress The base address of the VTd engine. @param LowMemoryBase The protected low memory region base. @param LowMemoryLength The protected low memory region length. @@ -196,6 +224,7 @@ DisablePmr ( **/ EFI_STATUS SetPmrRegion ( + IN UINT8 HostAddressWidth, IN UINTN VtdUnitBaseAddress, IN UINT32 LowMemoryBase, IN UINT32 LowMemoryLength, @@ -215,9 +244,9 @@ SetPmrRegion ( return EFI_UNSUPPORTED; } - PlmrAlignment = GetPlmrAlignment (VtdUnitBaseAddress); + PlmrAlignment = GetPlmrAlignment (HostAddressWidth, VtdUnitBaseAddress); DEBUG ((DEBUG_INFO, "PlmrAlignment - 0x%x\n", PlmrAlignment)); - PhmrAlignment = GetPhmrAlignment (VtdUnitBaseAddress); + PhmrAlignment = GetPhmrAlignment (HostAddressWidth, VtdUnitBaseAddress); DEBUG ((DEBUG_INFO, "PhmrAlignment - 0x%lx\n", PhmrAlignment)); if ((LowMemoryBase != ALIGN_VALUE(LowMemoryBase, PlmrAlignment)) || @@ -237,8 +266,10 @@ SetPmrRegion ( MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_BASE_REG, LowMemoryBase); MmioWrite32 (VtdUnitBaseAddress + R_PMEN_LOW_LIMITE_REG, LowMemoryBase + LowMemoryLength - 1); + DEBUG ((DEBUG_INFO, "PLMR set done\n")); MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, HighMemoryBase); MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_LIMITE_REG, HighMemoryBase + HighMemoryLength - 1); + DEBUG ((DEBUG_INFO, "PHMR set done\n")); return EFI_SUCCESS; } @@ -246,6 +277,8 @@ SetPmrRegion ( /** Set DMA protected region. + @param VTdInfo The VTd engine context information. + @param EngineMask The mask of the VTd engine to be accessed. @param LowMemoryBase The protected low memory region base. @param LowMemoryLength The protected low memory region length. @param HighMemoryBase The protected high memory region base. @@ -256,6 +289,8 @@ SetPmrRegion ( **/ EFI_STATUS SetDmaProtectedRange ( + IN VTD_INFO *VTdInfo, + IN UINT64 EngineMask, IN UINT32 LowMemoryBase, IN UINT32 LowMemoryLength, IN UINT64 HighMemoryBase, @@ -265,12 +300,16 @@ SetDmaProtectedRange ( UINTN Index; EFI_STATUS Status; - DEBUG ((DEBUG_INFO, "SetDmaProtectedRange - [0x%x, 0x%x] [0x%lx, 0x%lx]\n", LowMemoryBase, LowMemoryLength, HighMemoryBase, HighMemoryLength)); + DEBUG ((DEBUG_INFO, "SetDmaProtectedRange(0x%lx) - [0x%x, 0x%x] [0x%lx, 0x%lx]\n", EngineMask, LowMemoryBase, LowMemoryLength, HighMemoryBase, HighMemoryLength)); - for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { - DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); + for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) { + if ((EngineMask & LShiftU64(1, Index)) == 0) { + continue; + } + DisablePmr ((UINTN)VTdInfo->VTdEngineAddress[Index]); Status = SetPmrRegion ( - (UINTN)mVTdInfoPpi->VTdEngineAddress[Index], + VTdInfo->HostAddressWidth, + (UINTN)VTdInfo->VTdEngineAddress[Index], LowMemoryBase, LowMemoryLength, HighMemoryBase, @@ -279,7 +318,7 @@ SetDmaProtectedRange ( if (EFI_ERROR(Status)) { return Status; } - Status = EnablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); + Status = EnablePmr ((UINTN)VTdInfo->VTdEngineAddress[Index]); if (EFI_ERROR(Status)) { return Status; } @@ -291,20 +330,29 @@ SetDmaProtectedRange ( /** Diable DMA protection. - @retval DMA protection is disabled. + @param VTdInfo The VTd engine context information. + @param EngineMask The mask of the VTd engine to be accessed. + + @retval EFI_SUCCESS DMA protection is disabled. **/ EFI_STATUS DisableDmaProtection ( - VOID + IN VTD_INFO *VTdInfo, + IN UINT64 EngineMask ) { UINTN Index; EFI_STATUS Status; - DEBUG ((DEBUG_INFO, "DisableDmaProtection\n")); + DEBUG ((DEBUG_INFO, "DisableDmaProtection - 0x%lx\n", EngineMask)); - for (Index = 0; Index < mVTdInfoPpi->VTdEngineCount; Index++) { - Status = DisablePmr ((UINTN)mVTdInfoPpi->VTdEngineAddress[Index]); + for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) { + DEBUG ((DEBUG_INFO, "Disabling...%d\n", Index)); + + if ((EngineMask & LShiftU64(1, Index)) == 0) { + continue; + } + Status = DisablePmr ((UINTN)VTdInfo->VTdEngineAddress[Index]); if (EFI_ERROR(Status)) { return Status; } @@ -312,3 +360,67 @@ DisableDmaProtection ( return EFI_SUCCESS; } + +/** + Return if the PMR is enabled. + + @param VtdUnitBaseAddress The base address of the VTd engine. + + @retval TRUE PMR is enabled. + @retval FALSE PMR is disabled or unsupported. +**/ +BOOLEAN +IsPmrEnabled ( + IN UINTN VtdUnitBaseAddress + ) +{ + UINT32 Reg32; + VTD_CAP_REG CapReg; + + CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG); + if (CapReg.Bits.PLMR == 0 || CapReg.Bits.PHMR == 0) { + return FALSE; + } + + Reg32 = MmioRead32 (VtdUnitBaseAddress + R_PMEN_ENABLE_REG); + if ((Reg32 & BIT0) == 0) { + return FALSE; + } + + return TRUE; +} + +/** + Return the mask of the VTd engine which is enabled. + + @param VTdInfo The VTd engine context information. + @param EngineMask The mask of the VTd engine to be accessed. + + @return the mask of the VTd engine which is enabled. +**/ +UINT64 +GetDmaProtectionEnabledEngineMask ( + IN VTD_INFO *VTdInfo, + IN UINT64 EngineMask + ) +{ + UINTN Index; + BOOLEAN Result; + UINT64 EnabledEngineMask; + + DEBUG ((DEBUG_INFO, "GetDmaProtectionEnabledEngineMask - 0x%lx\n", EngineMask)); + + EnabledEngineMask = 0; + for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) { + if ((EngineMask & LShiftU64(1, Index)) == 0) { + continue; + } + Result = IsPmrEnabled ((UINTN)VTdInfo->VTdEngineAddress[Index]); + if (Result) { + EnabledEngineMask |= LShiftU64(1, Index); + } + } + + DEBUG ((DEBUG_INFO, "EnabledEngineMask - 0x%lx\n", EnabledEngineMask)); + return EnabledEngineMask; +}