summaryrefslogtreecommitdiff
path: root/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c
diff options
context:
space:
mode:
Diffstat (limited to 'IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c')
-rw-r--r--IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c130
1 files changed, 111 insertions, 19 deletions
diff --git a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c
index 6179dfe..000a81b 100644
--- a/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c
+++ b/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmr.c
@@ -22,17 +22,17 @@
#include "IntelVTdPmrPei.h"
-extern VTD_INFO *mVTdInfo;
-
/**
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 = mVTdInfo->HostAddressWidth;
MmioWrite64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG, 0xFFFFFFFFFFFFFFFF);
Data64 = MmioRead64 (VtdUnitBaseAddress + R_PMEN_HIGH_BASE_REG);
@@ -73,12 +72,14 @@ 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 (
+ IN VTD_INFO *VTdInfo,
IN UINT64 EngineMask
)
{
@@ -87,11 +88,11 @@ GetLowMemoryAlignment (
UINT32 FinalAlignment;
FinalAlignment = 0;
- for (Index = 0; Index < mVTdInfo->VTdEngineCount; Index++) {
+ for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
if ((EngineMask & LShiftU64(1, Index)) == 0) {
continue;
}
- Alignment = GetPlmrAlignment ((UINTN)mVTdInfo->VTdEngineAddress[Index]);
+ Alignment = GetPlmrAlignment (VTdInfo->HostAddressWidth, (UINTN)VTdInfo->VTdEngineAddress[Index]);
if (FinalAlignment < Alignment) {
FinalAlignment = Alignment;
}
@@ -102,12 +103,14 @@ 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 (
+ IN VTD_INFO *VTdInfo,
IN UINT64 EngineMask
)
{
@@ -116,11 +119,11 @@ GetHighMemoryAlignment (
UINT64 FinalAlignment;
FinalAlignment = 0;
- for (Index = 0; Index < mVTdInfo->VTdEngineCount; Index++) {
+ for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
if ((EngineMask & LShiftU64(1, Index)) == 0) {
continue;
}
- Alignment = GetPhmrAlignment ((UINTN)mVTdInfo->VTdEngineAddress[Index]);
+ Alignment = GetPhmrAlignment (VTdInfo->HostAddressWidth, (UINTN)VTdInfo->VTdEngineAddress[Index]);
if (FinalAlignment < Alignment) {
FinalAlignment = Alignment;
}
@@ -144,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 {
@@ -157,6 +167,8 @@ EnablePmr (
} while((Reg32 & BIT0) == 0);
}
+ DEBUG ((DEBUG_INFO, "EnablePmr - Done\n"));
+
return EFI_SUCCESS;
}
@@ -182,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 {
@@ -195,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.
@@ -206,6 +224,7 @@ DisablePmr (
**/
EFI_STATUS
SetPmrRegion (
+ IN UINT8 HostAddressWidth,
IN UINTN VtdUnitBaseAddress,
IN UINT32 LowMemoryBase,
IN UINT32 LowMemoryLength,
@@ -225,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)) ||
@@ -247,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;
}
@@ -256,6 +277,7 @@ 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.
@@ -267,6 +289,7 @@ SetPmrRegion (
**/
EFI_STATUS
SetDmaProtectedRange (
+ IN VTD_INFO *VTdInfo,
IN UINT64 EngineMask,
IN UINT32 LowMemoryBase,
IN UINT32 LowMemoryLength,
@@ -279,13 +302,14 @@ SetDmaProtectedRange (
DEBUG ((DEBUG_INFO, "SetDmaProtectedRange(0x%lx) - [0x%x, 0x%x] [0x%lx, 0x%lx]\n", EngineMask, LowMemoryBase, LowMemoryLength, HighMemoryBase, HighMemoryLength));
- for (Index = 0; Index < mVTdInfo->VTdEngineCount; Index++) {
+ for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
if ((EngineMask & LShiftU64(1, Index)) == 0) {
continue;
}
- DisablePmr ((UINTN)mVTdInfo->VTdEngineAddress[Index]);
+ DisablePmr ((UINTN)VTdInfo->VTdEngineAddress[Index]);
Status = SetPmrRegion (
- (UINTN)mVTdInfo->VTdEngineAddress[Index],
+ VTdInfo->HostAddressWidth,
+ (UINTN)VTdInfo->VTdEngineAddress[Index],
LowMemoryBase,
LowMemoryLength,
HighMemoryBase,
@@ -294,7 +318,7 @@ SetDmaProtectedRange (
if (EFI_ERROR(Status)) {
return Status;
}
- Status = EnablePmr ((UINTN)mVTdInfo->VTdEngineAddress[Index]);
+ Status = EnablePmr ((UINTN)VTdInfo->VTdEngineAddress[Index]);
if (EFI_ERROR(Status)) {
return Status;
}
@@ -306,25 +330,29 @@ SetDmaProtectedRange (
/**
Diable DMA protection.
+ @param VTdInfo The VTd engine context information.
@param EngineMask The mask of the VTd engine to be accessed.
- @retval DMA protection is disabled.
+ @retval EFI_SUCCESS DMA protection is disabled.
**/
EFI_STATUS
DisableDmaProtection (
+ 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 < VTdInfo->VTdEngineCount; Index++) {
+ DEBUG ((DEBUG_INFO, "Disabling...%d\n", Index));
- for (Index = 0; Index < mVTdInfo->VTdEngineCount; Index++) {
if ((EngineMask & LShiftU64(1, Index)) == 0) {
continue;
}
- Status = DisablePmr ((UINTN)mVTdInfo->VTdEngineAddress[Index]);
+ Status = DisablePmr ((UINTN)VTdInfo->VTdEngineAddress[Index]);
if (EFI_ERROR(Status)) {
return Status;
}
@@ -332,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;
+}