* [PATCH] IntelSiliconPkg/VTd: Add iommu 5 level paging support
@ 2020-11-11 4:53 Sheng Wei
0 siblings, 0 replies; only message in thread
From: Sheng Wei @ 2020-11-11 4:53 UTC (permalink / raw)
To: devel; +Cc: Ray Ni, Rangasai V Chaganty, Jiewen Yao, Jenny Huang
Support iommu 5 level paging for translation table.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3067
Signed-off-by: Sheng Wei <w.sheng@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jenny Huang <jenny.huang@intel.com>
---
.../Feature/VTd/IntelVTdDxe/DmaProtection.c | 4 +-
.../Feature/VTd/IntelVTdDxe/DmaProtection.h | 19 +-
.../Feature/VTd/IntelVTdDxe/TranslationTable.c | 286 +++++++++++++++------
.../Feature/VTd/IntelVTdDxe/TranslationTableEx.c | 34 ++-
.../Feature/VTd/IntelVTdDxe/VtdReg.c | 10 +-
Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec | 3 +
6 files changed, 256 insertions(+), 100 deletions(-)
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
index 9b6135ef..628565ee 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
@@ -523,10 +523,10 @@ SetupVtd (
for (Index = 0; Index < mVtdUnitNumber; Index++) {
DEBUG ((DEBUG_INFO,"VTD Unit %d (Segment: %04x)\n", Index, mVtdUnitInformation[Index].Segment));
if (mVtdUnitInformation[Index].ExtRootEntryTable != NULL) {
- DumpDmarExtContextEntryTable (mVtdUnitInformation[Index].ExtRootEntryTable);
+ DumpDmarExtContextEntryTable (mVtdUnitInformation[Index].ExtRootEntryTable, mVtdUnitInformation[Index].Is5LevelPaging);
}
if (mVtdUnitInformation[Index].RootEntryTable != NULL) {
- DumpDmarContextEntryTable (mVtdUnitInformation[Index].RootEntryTable);
+ DumpDmarContextEntryTable (mVtdUnitInformation[Index].RootEntryTable, mVtdUnitInformation[Index].Is5LevelPaging);
}
}
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
index a3331db8..f641cea0 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
@@ -77,6 +77,7 @@ typedef struct {
BOOLEAN HasDirtyContext;
BOOLEAN HasDirtyPages;
PCI_DEVICE_INFORMATION PciDeviceInfo;
+ BOOLEAN Is5LevelPaging;
} VTD_UNIT_INFORMATION;
//
@@ -375,31 +376,37 @@ ParseDmarAcpiTableRmrr (
/**
Dump DMAR context entry table.
- @param[in] RootEntry DMAR root entry.
+ @param[in] RootEntry DMAR root entry.
+ @param[in] Is5LevelPaging If it is the 5 level paging.
**/
VOID
DumpDmarContextEntryTable (
- IN VTD_ROOT_ENTRY *RootEntry
+ IN VTD_ROOT_ENTRY *RootEntry,
+ IN BOOLEAN Is5LevelPaging
);
/**
Dump DMAR extended context entry table.
- @param[in] ExtRootEntry DMAR extended root entry.
+ @param[in] ExtRootEntry DMAR extended root entry.
+ @param[in] Is5LevelPaging If it is the 5 level paging.
**/
VOID
DumpDmarExtContextEntryTable (
- IN VTD_EXT_ROOT_ENTRY *ExtRootEntry
+ IN VTD_EXT_ROOT_ENTRY *ExtRootEntry,
+ IN BOOLEAN Is5LevelPaging
);
/**
Dump DMAR second level paging entry.
- @param[in] SecondLevelPagingEntry The second level paging entry.
+ @param[in] SecondLevelPagingEntry The second level paging entry.
+ @param[in] Is5LevelPaging If it is the 5 level paging.
**/
VOID
DumpSecondLevelPagingEntry (
- IN VOID *SecondLevelPagingEntry
+ IN VOID *SecondLevelPagingEntry,
+ IN BOOLEAN Is5LevelPaging
);
/**
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.c
index 201d663d..01197ecb 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.c
@@ -128,11 +128,31 @@ CreateContextEntry (
DEBUG ((DEBUG_INFO,"Source: S%04x B%02x D%02x F%02x\n", mVtdUnitInformation[VtdIndex].Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
- if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) == 0) {
- DEBUG((DEBUG_ERROR, "!!!! 4-level page-table is not supported on VTD %d !!!!\n", VtdIndex));
+ mVtdUnitInformation[VtdIndex].Is5LevelPaging = FALSE;
+ if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT3) != 0) {
+ if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT3) != 0) {
+ DEBUG((DEBUG_ERROR, "Force to use 4-level page-table on VTD %d\n", Index));
+ ContextEntry->Bits.AddressWidth = 0x2;
+ } if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT4) != 0) {
+ DEBUG((DEBUG_ERROR, "Force to use 5-level page-table on VTD %d\n", Index));
+ ContextEntry->Bits.AddressWidth = 0x3;
+ } else {
+ if (mAcpiDmarTable->HostAddressWidth > 48) {
+ DEBUG((DEBUG_ERROR, "Using 5-level page-table on VTD %d\n", Index));
+ ContextEntry->Bits.AddressWidth = 0x3;
+ mVtdUnitInformation[VtdIndex].Is5LevelPaging = TRUE;
+ } else {
+ DEBUG((DEBUG_ERROR, "Using 4-level page-table on VTD %d\n", Index));
+ ContextEntry->Bits.AddressWidth = 0x2;
+ }
+ }
+ } else if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) != 0) {
+ DEBUG((DEBUG_ERROR, "Using 4-level page-table on VTD %d\n", Index));
+ ContextEntry->Bits.AddressWidth = 0x2;
+ } else {
+ DEBUG((DEBUG_ERROR, "!!!! Page-table type is not supported on VTD %d !!!!\n", VtdIndex));
return EFI_UNSUPPORTED;
}
- ContextEntry->Bits.AddressWidth = 0x2;
}
FlushPageTableMemory (VtdIndex, (UINTN)mVtdUnitInformation[VtdIndex].RootEntryTable, EFI_PAGES_TO_SIZE(EntryTablePages));
@@ -148,6 +168,7 @@ CreateContextEntry (
@param[in] MemoryBase The base of the memory.
@param[in] MemoryLimit The limit of the memory.
@param[in] IoMmuAccess The IOMMU access.
+ @param[in] Is5LevelPaging If it is the 5 level paging.
@return The second level paging entry.
**/
@@ -157,16 +178,23 @@ CreateSecondLevelPagingEntryTable (
IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry,
IN UINT64 MemoryBase,
IN UINT64 MemoryLimit,
- IN UINT64 IoMmuAccess
+ IN UINT64 IoMmuAccess,
+ IN BOOLEAN Is5LevelPaging
)
{
+ UINTN Index5;
UINTN Index4;
UINTN Index3;
UINTN Index2;
+ UINTN Lvl5Start;
+ UINTN Lvl5End;
+ UINTN Lvl4PagesStart;
+ UINTN Lvl4PagesEnd;
UINTN Lvl4Start;
UINTN Lvl4End;
UINTN Lvl3Start;
UINTN Lvl3End;
+ VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl5PtEntry;
VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl4PtEntry;
VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl3PtEntry;
VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl2PtEntry;
@@ -184,7 +212,7 @@ CreateSecondLevelPagingEntryTable (
if (SecondLevelPagingEntry == NULL) {
SecondLevelPagingEntry = AllocateZeroPages (1);
if (SecondLevelPagingEntry == NULL) {
- DEBUG ((DEBUG_ERROR,"Could not Alloc LVL4 PT. \n"));
+ DEBUG ((DEBUG_ERROR,"Could not Alloc LVL4 or LVL5 PT. \n"));
return NULL;
}
FlushPageTableMemory (VtdIndex, (UINTN)SecondLevelPagingEntry, EFI_PAGES_TO_SIZE(1));
@@ -197,66 +225,109 @@ CreateSecondLevelPagingEntryTable (
return SecondLevelPagingEntry;
}
- Lvl4Start = RShiftU64 (BaseAddress, 39) & 0x1FF;
- Lvl4End = RShiftU64 (EndAddress - 1, 39) & 0x1FF;
+ if (Is5LevelPaging) {
+ Lvl5Start = RShiftU64 (BaseAddress, 48) & 0x1FF;
+ Lvl5End = RShiftU64 (EndAddress - 1, 48) & 0x1FF;
+ DEBUG ((DEBUG_INFO," Lvl5Start - 0x%x, Lvl5End - 0x%x\n", Lvl5Start, Lvl5End));
- DEBUG ((DEBUG_INFO," Lvl4Start - 0x%x, Lvl4End - 0x%x\n", Lvl4Start, Lvl4End));
+ Lvl4Start = RShiftU64 (BaseAddress, 39) & 0x1FF;
+ Lvl4End = RShiftU64 (EndAddress - 1, 39) & 0x1FF;
- Lvl4PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)SecondLevelPagingEntry;
- for (Index4 = Lvl4Start; Index4 <= Lvl4End; Index4++) {
- if (Lvl4PtEntry[Index4].Uint64 == 0) {
- Lvl4PtEntry[Index4].Uint64 = (UINT64)(UINTN)AllocateZeroPages (1);
- if (Lvl4PtEntry[Index4].Uint64 == 0) {
- DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL4 PAGE FAIL (0x%x)!!!!!!\n", Index4));
- ASSERT(FALSE);
- return NULL;
- }
- FlushPageTableMemory (VtdIndex, (UINTN)Lvl4PtEntry[Index4].Uint64, SIZE_4KB);
- SetSecondLevelPagingEntryAttribute (&Lvl4PtEntry[Index4], EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE);
- }
+ Lvl4PagesStart = (Lvl5Start<<9) | Lvl4Start;
+ Lvl4PagesEnd = (Lvl5End<<9) | Lvl4End;
+ DEBUG ((DEBUG_INFO," Lvl4PagesStart - 0x%x, Lvl4PagesEnd - 0x%x\n", Lvl4PagesStart, Lvl4PagesEnd));
- Lvl3Start = RShiftU64 (BaseAddress, 30) & 0x1FF;
- if (ALIGN_VALUE_LOW(BaseAddress + SIZE_1GB, SIZE_1GB) <= EndAddress) {
- Lvl3End = SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY) - 1;
- } else {
- Lvl3End = RShiftU64 (EndAddress - 1, 30) & 0x1FF;
+ Lvl5PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)SecondLevelPagingEntry;
+ } else {
+ Lvl5Start = RShiftU64 (BaseAddress, 48) & 0x1FF;
+ Lvl5End = Lvl5Start;
+
+ Lvl4Start = RShiftU64 (BaseAddress, 39) & 0x1FF;
+ Lvl4End = RShiftU64 (EndAddress - 1, 39) & 0x1FF;
+ DEBUG ((DEBUG_INFO," Lvl4Start - 0x%x, Lvl4End - 0x%x\n", Lvl4Start, Lvl4End));
+
+ Lvl4PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)SecondLevelPagingEntry;
+ }
+
+ for (Index5 = Lvl5Start; Index5 <= Lvl5End; Index5++) {
+ if (Is5LevelPaging) {
+ if (Lvl5PtEntry[Index5].Uint64 == 0) {
+ Lvl5PtEntry[Index5].Uint64 = (UINT64)(UINTN)AllocateZeroPages (1);
+ if (Lvl5PtEntry[Index5].Uint64 == 0) {
+ DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL4 PAGE FAIL (0x%x)!!!!!!\n", Index5));
+ ASSERT(FALSE);
+ return NULL;
+ }
+ FlushPageTableMemory (VtdIndex, (UINTN)Lvl5PtEntry[Index5].Uint64, SIZE_4KB);
+ SetSecondLevelPagingEntryAttribute (&Lvl5PtEntry[Index5], EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE);
+ }
+ Lvl4Start = Lvl4PagesStart & 0x1FF;
+ if (((Index5+1)<<9) > Lvl4PagesEnd) {
+ Lvl4End = SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY) - 1;;
+ Lvl4PagesStart = (Index5+1)<<9;
+ } else {
+ Lvl4End = Lvl4PagesEnd & 0x1FF;
+ }
+ DEBUG ((DEBUG_INFO," Lvl5(0x%x): Lvl4Start - 0x%x, Lvl4End - 0x%x\n", Index5, Lvl4Start, Lvl4End));
+ Lvl4PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(Lvl5PtEntry[Index5].Bits.AddressLo, Lvl5PtEntry[Index5].Bits.AddressHi);
}
- DEBUG ((DEBUG_INFO," Lvl4(0x%x): Lvl3Start - 0x%x, Lvl3End - 0x%x\n", Index4, Lvl3Start, Lvl3End));
- Lvl3PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(Lvl4PtEntry[Index4].Bits.AddressLo, Lvl4PtEntry[Index4].Bits.AddressHi);
- for (Index3 = Lvl3Start; Index3 <= Lvl3End; Index3++) {
- if (Lvl3PtEntry[Index3].Uint64 == 0) {
- Lvl3PtEntry[Index3].Uint64 = (UINT64)(UINTN)AllocateZeroPages (1);
- if (Lvl3PtEntry[Index3].Uint64 == 0) {
- DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL3 PAGE FAIL (0x%x, 0x%x)!!!!!!\n", Index4, Index3));
+ for (Index4 = Lvl4Start; Index4 <= Lvl4End; Index4++) {
+ if (Lvl4PtEntry[Index4].Uint64 == 0) {
+ Lvl4PtEntry[Index4].Uint64 = (UINT64)(UINTN)AllocateZeroPages (1);
+ if (Lvl4PtEntry[Index4].Uint64 == 0) {
+ DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL4 PAGE FAIL (0x%x)!!!!!!\n", Index4));
ASSERT(FALSE);
return NULL;
}
- FlushPageTableMemory (VtdIndex, (UINTN)Lvl3PtEntry[Index3].Uint64, SIZE_4KB);
- SetSecondLevelPagingEntryAttribute (&Lvl3PtEntry[Index3], EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE);
+ FlushPageTableMemory (VtdIndex, (UINTN)Lvl4PtEntry[Index4].Uint64, SIZE_4KB);
+ SetSecondLevelPagingEntryAttribute (&Lvl4PtEntry[Index4], EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE);
}
- Lvl2PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, Lvl3PtEntry[Index3].Bits.AddressHi);
- for (Index2 = 0; Index2 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index2++) {
- Lvl2PtEntry[Index2].Uint64 = BaseAddress;
- SetSecondLevelPagingEntryAttribute (&Lvl2PtEntry[Index2], IoMmuAccess);
- Lvl2PtEntry[Index2].Bits.PageSize = 1;
- BaseAddress += SIZE_2MB;
+ Lvl3Start = RShiftU64 (BaseAddress, 30) & 0x1FF;
+ if (ALIGN_VALUE_LOW(BaseAddress + SIZE_1GB, SIZE_1GB) <= EndAddress) {
+ Lvl3End = SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY) - 1;
+ } else {
+ Lvl3End = RShiftU64 (EndAddress - 1, 30) & 0x1FF;
+ }
+ DEBUG ((DEBUG_INFO," Lvl4(0x%x): Lvl3Start - 0x%x, Lvl3End - 0x%x\n", Index4, Lvl3Start, Lvl3End));
+
+ Lvl3PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(Lvl4PtEntry[Index4].Bits.AddressLo, Lvl4PtEntry[Index4].Bits.AddressHi);
+ for (Index3 = Lvl3Start; Index3 <= Lvl3End; Index3++) {
+ if (Lvl3PtEntry[Index3].Uint64 == 0) {
+ Lvl3PtEntry[Index3].Uint64 = (UINT64)(UINTN)AllocateZeroPages (1);
+ if (Lvl3PtEntry[Index3].Uint64 == 0) {
+ DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL3 PAGE FAIL (0x%x, 0x%x)!!!!!!\n", Index4, Index3));
+ ASSERT(FALSE);
+ return NULL;
+ }
+ FlushPageTableMemory (VtdIndex, (UINTN)Lvl3PtEntry[Index3].Uint64, SIZE_4KB);
+ SetSecondLevelPagingEntryAttribute (&Lvl3PtEntry[Index3], EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE);
+ }
+
+ Lvl2PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, Lvl3PtEntry[Index3].Bits.AddressHi);
+ for (Index2 = 0; Index2 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index2++) {
+ Lvl2PtEntry[Index2].Uint64 = BaseAddress;
+ SetSecondLevelPagingEntryAttribute (&Lvl2PtEntry[Index2], IoMmuAccess);
+ Lvl2PtEntry[Index2].Bits.PageSize = 1;
+ BaseAddress += SIZE_2MB;
+ if (BaseAddress >= MemoryLimit) {
+ break;
+ }
+ }
+ FlushPageTableMemory (VtdIndex, (UINTN)Lvl2PtEntry, SIZE_4KB);
if (BaseAddress >= MemoryLimit) {
break;
}
}
- FlushPageTableMemory (VtdIndex, (UINTN)Lvl2PtEntry, SIZE_4KB);
+ FlushPageTableMemory (VtdIndex, (UINTN)&Lvl3PtEntry[Lvl3Start], (UINTN)&Lvl3PtEntry[Lvl3End + 1] - (UINTN)&Lvl3PtEntry[Lvl3Start]);
if (BaseAddress >= MemoryLimit) {
break;
}
}
- FlushPageTableMemory (VtdIndex, (UINTN)&Lvl3PtEntry[Lvl3Start], (UINTN)&Lvl3PtEntry[Lvl3End + 1] - (UINTN)&Lvl3PtEntry[Lvl3Start]);
- if (BaseAddress >= MemoryLimit) {
- break;
- }
+ FlushPageTableMemory (VtdIndex, (UINTN)&Lvl4PtEntry[Lvl4Start], (UINTN)&Lvl4PtEntry[Lvl4End + 1] - (UINTN)&Lvl4PtEntry[Lvl4Start]);
}
- FlushPageTableMemory (VtdIndex, (UINTN)&Lvl4PtEntry[Lvl4Start], (UINTN)&Lvl4PtEntry[Lvl4End + 1] - (UINTN)&Lvl4PtEntry[Lvl4Start]);
+ FlushPageTableMemory (VtdIndex, (UINTN)&Lvl5PtEntry[Lvl5Start], (UINTN)&Lvl5PtEntry[Lvl5End + 1] - (UINTN)&Lvl5PtEntry[Lvl5Start]);
return SecondLevelPagingEntry;
}
@@ -266,26 +337,28 @@ CreateSecondLevelPagingEntryTable (
@param[in] VtdIndex The index of the VTd engine.
@param[in] IoMmuAccess The IOMMU access.
+ @param[in] Is5LevelPaging If it is the 5 level paging.
@return The second level paging entry.
**/
VTD_SECOND_LEVEL_PAGING_ENTRY *
CreateSecondLevelPagingEntry (
IN UINTN VtdIndex,
- IN UINT64 IoMmuAccess
+ IN UINT64 IoMmuAccess,
+ IN BOOLEAN Is5LevelPaging
)
{
VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
SecondLevelPagingEntry = NULL;
- SecondLevelPagingEntry = CreateSecondLevelPagingEntryTable (VtdIndex, SecondLevelPagingEntry, 0, mBelow4GMemoryLimit, IoMmuAccess);
+ SecondLevelPagingEntry = CreateSecondLevelPagingEntryTable (VtdIndex, SecondLevelPagingEntry, 0, mBelow4GMemoryLimit, IoMmuAccess, Is5LevelPaging);
if (SecondLevelPagingEntry == NULL) {
return NULL;
}
if (mAbove4GMemoryLimit != 0) {
ASSERT (mAbove4GMemoryLimit > BASE_4GB);
- SecondLevelPagingEntry = CreateSecondLevelPagingEntryTable (VtdIndex, SecondLevelPagingEntry, SIZE_4GB, mAbove4GMemoryLimit, IoMmuAccess);
+ SecondLevelPagingEntry = CreateSecondLevelPagingEntryTable (VtdIndex, SecondLevelPagingEntry, SIZE_4GB, mAbove4GMemoryLimit, IoMmuAccess, Is5LevelPaging);
if (SecondLevelPagingEntry == NULL) {
return NULL;
}
@@ -326,11 +399,13 @@ SetupTranslationTable (
/**
Dump DMAR context entry table.
- @param[in] RootEntry DMAR root entry.
+ @param[in] RootEntry DMAR root entry.
+ @param[in] Is5LevelPaging If it is the 5 level paging.
**/
VOID
DumpDmarContextEntryTable (
- IN VTD_ROOT_ENTRY *RootEntry
+ IN VTD_ROOT_ENTRY *RootEntry,
+ IN BOOLEAN Is5LevelPaging
)
{
UINTN Index;
@@ -359,7 +434,7 @@ DumpDmarContextEntryTable (
if (ContextEntry[Index2].Bits.Present == 0) {
continue;
}
- DumpSecondLevelPagingEntry ((VOID *)(UINTN)VTD_64BITS_ADDRESS(ContextEntry[Index2].Bits.SecondLevelPageTranslationPointerLo, ContextEntry[Index2].Bits.SecondLevelPageTranslationPointerHi));
+ DumpSecondLevelPagingEntry ((VOID *)(UINTN)VTD_64BITS_ADDRESS(ContextEntry[Index2].Bits.SecondLevelPageTranslationPointerLo, ContextEntry[Index2].Bits.SecondLevelPageTranslationPointerHi), Is5LevelPaging);
}
}
DEBUG ((DEBUG_INFO,"=========================\n"));
@@ -368,17 +443,22 @@ DumpDmarContextEntryTable (
/**
Dump DMAR second level paging entry.
- @param[in] SecondLevelPagingEntry The second level paging entry.
+ @param[in] SecondLevelPagingEntry The second level paging entry.
+ @param[in] Is5LevelPaging If it is the 5 level paging.
**/
VOID
DumpSecondLevelPagingEntry (
- IN VOID *SecondLevelPagingEntry
+ IN VOID *SecondLevelPagingEntry,
+ IN BOOLEAN Is5LevelPaging
)
{
+ UINTN Index5;
UINTN Index4;
UINTN Index3;
UINTN Index2;
UINTN Index1;
+ UINTN Lvl5IndexEnd;
+ VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl5PtEntry;
VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl4PtEntry;
VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl3PtEntry;
VTD_SECOND_LEVEL_PAGING_ENTRY *Lvl2PtEntry;
@@ -386,38 +466,53 @@ DumpSecondLevelPagingEntry (
DEBUG ((DEBUG_VERBOSE,"================\n"));
DEBUG ((DEBUG_VERBOSE,"DMAR Second Level Page Table:\n"));
+ DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry Base - 0x%x, Is5LevelPaging - %d\n", SecondLevelPagingEntry, Is5LevelPaging));
- DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry Base - 0x%x\n", SecondLevelPagingEntry));
+ Lvl5IndexEnd = Is5LevelPaging ? SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY) : 1;
Lvl4PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)SecondLevelPagingEntry;
- for (Index4 = 0; Index4 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index4++) {
- if (Lvl4PtEntry[Index4].Uint64 != 0) {
- DEBUG ((DEBUG_VERBOSE," Lvl4Pt Entry(0x%03x) - 0x%016lx\n", Index4, Lvl4PtEntry[Index4].Uint64));
- }
- if (Lvl4PtEntry[Index4].Uint64 == 0) {
- continue;
- }
- Lvl3PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(Lvl4PtEntry[Index4].Bits.AddressLo, Lvl4PtEntry[Index4].Bits.AddressHi);
- for (Index3 = 0; Index3 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index3++) {
- if (Lvl3PtEntry[Index3].Uint64 != 0) {
- DEBUG ((DEBUG_VERBOSE," Lvl3Pt Entry(0x%03x) - 0x%016lx\n", Index3, Lvl3PtEntry[Index3].Uint64));
+ Lvl5PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)SecondLevelPagingEntry;
+
+ for (Index5 = 0; Index5 < Lvl5IndexEnd; Index5++) {
+ if (Is5LevelPaging) {
+ if (Lvl5PtEntry[Index5].Uint64 != 0) {
+ DEBUG ((DEBUG_VERBOSE," Lvl5Pt Entry(0x%03x) - 0x%016lx\n", Index5, Lvl5PtEntry[Index5].Uint64));
}
- if (Lvl3PtEntry[Index3].Uint64 == 0) {
+ if (Lvl5PtEntry[Index5].Uint64 == 0) {
continue;
}
+ Lvl4PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(Lvl5PtEntry[Index5].Bits.AddressLo, Lvl5PtEntry[Index5].Bits.AddressHi);
+ }
- Lvl2PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, Lvl3PtEntry[Index3].Bits.AddressHi);
- for (Index2 = 0; Index2 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index2++) {
- if (Lvl2PtEntry[Index2].Uint64 != 0) {
- DEBUG ((DEBUG_VERBOSE," Lvl2Pt Entry(0x%03x) - 0x%016lx\n", Index2, Lvl2PtEntry[Index2].Uint64));
+ for (Index4 = 0; Index4 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index4++) {
+ if (Lvl4PtEntry[Index4].Uint64 != 0) {
+ DEBUG ((DEBUG_VERBOSE," Lvl4Pt Entry(0x%03x) - 0x%016lx\n", Index4, Lvl4PtEntry[Index4].Uint64));
+ }
+ if (Lvl4PtEntry[Index4].Uint64 == 0) {
+ continue;
+ }
+ Lvl3PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(Lvl4PtEntry[Index4].Bits.AddressLo, Lvl4PtEntry[Index4].Bits.AddressHi);
+ for (Index3 = 0; Index3 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index3++) {
+ if (Lvl3PtEntry[Index3].Uint64 != 0) {
+ DEBUG ((DEBUG_VERBOSE," Lvl3Pt Entry(0x%03x) - 0x%016lx\n", Index3, Lvl3PtEntry[Index3].Uint64));
}
- if (Lvl2PtEntry[Index2].Uint64 == 0) {
+ if (Lvl3PtEntry[Index3].Uint64 == 0) {
continue;
}
- if (Lvl2PtEntry[Index2].Bits.PageSize == 0) {
- Lvl1PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(Lvl2PtEntry[Index2].Bits.AddressLo, Lvl2PtEntry[Index2].Bits.AddressHi);
- for (Index1 = 0; Index1 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index1++) {
- if (Lvl1PtEntry[Index1].Uint64 != 0) {
- DEBUG ((DEBUG_VERBOSE," Lvl1Pt Entry(0x%03x) - 0x%016lx\n", Index1, Lvl1PtEntry[Index1].Uint64));
+
+ Lvl2PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(Lvl3PtEntry[Index3].Bits.AddressLo, Lvl3PtEntry[Index3].Bits.AddressHi);
+ for (Index2 = 0; Index2 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index2++) {
+ if (Lvl2PtEntry[Index2].Uint64 != 0) {
+ DEBUG ((DEBUG_VERBOSE," Lvl2Pt Entry(0x%03x) - 0x%016lx\n", Index2, Lvl2PtEntry[Index2].Uint64));
+ }
+ if (Lvl2PtEntry[Index2].Uint64 == 0) {
+ continue;
+ }
+ if (Lvl2PtEntry[Index2].Bits.PageSize == 0) {
+ Lvl1PtEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(Lvl2PtEntry[Index2].Bits.AddressLo, Lvl2PtEntry[Index2].Bits.AddressHi);
+ for (Index1 = 0; Index1 < SIZE_4KB/sizeof(VTD_SECOND_LEVEL_PAGING_ENTRY); Index1++) {
+ if (Lvl1PtEntry[Index1].Uint64 != 0) {
+ DEBUG ((DEBUG_VERBOSE," Lvl1Pt Entry(0x%03x) - 0x%016lx\n", Index1, Lvl1PtEntry[Index1].Uint64));
+ }
}
}
}
@@ -510,6 +605,7 @@ PageAttributeToLength (
@param[in] VtdIndex The index used to identify a VTd engine.
@param[in] SecondLevelPagingEntry The second level paging entry in VTd table for the device.
@param[in] Address The address to be checked.
+ @param[in] Is5LevelPaging If it is the 5 level paging.
@param[out] PageAttributes The page attribute of the page entry.
@return The page entry.
@@ -519,6 +615,7 @@ GetSecondLevelPageTableEntry (
IN UINTN VtdIndex,
IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry,
IN PHYSICAL_ADDRESS Address,
+ IN BOOLEAN Is5LevelPaging,
OUT PAGE_ATTRIBUTE *PageAttribute
)
{
@@ -526,17 +623,38 @@ GetSecondLevelPageTableEntry (
UINTN Index2;
UINTN Index3;
UINTN Index4;
+ UINTN Index5;
UINT64 *L1PageTable;
UINT64 *L2PageTable;
UINT64 *L3PageTable;
UINT64 *L4PageTable;
+ UINT64 *L5PageTable;
+ Index5 = ((UINTN)RShiftU64 (Address, 48)) & PAGING_VTD_INDEX_MASK;
Index4 = ((UINTN)RShiftU64 (Address, 39)) & PAGING_VTD_INDEX_MASK;
Index3 = ((UINTN)Address >> 30) & PAGING_VTD_INDEX_MASK;
Index2 = ((UINTN)Address >> 21) & PAGING_VTD_INDEX_MASK;
Index1 = ((UINTN)Address >> 12) & PAGING_VTD_INDEX_MASK;
- L4PageTable = (UINT64 *)SecondLevelPagingEntry;
+ if (Is5LevelPaging) {
+ L5PageTable = (UINT64 *)SecondLevelPagingEntry;
+ if (L5PageTable[Index5] == 0) {
+ L5PageTable[Index5] = (UINT64)(UINTN)AllocateZeroPages (1);
+ if (L5PageTable[Index5] == 0) {
+ DEBUG ((DEBUG_ERROR,"!!!!!! ALLOCATE LVL5 PAGE FAIL (0x%x)!!!!!!\n", Index4));
+ ASSERT(FALSE);
+ *PageAttribute = PageNone;
+ return NULL;
+ }
+ FlushPageTableMemory (VtdIndex, (UINTN)L5PageTable[Index5], SIZE_4KB);
+ SetSecondLevelPagingEntryAttribute ((VTD_SECOND_LEVEL_PAGING_ENTRY *)&L5PageTable[Index5], EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE);
+ FlushPageTableMemory (VtdIndex, (UINTN)&L5PageTable[Index5], sizeof(L5PageTable[Index5]));
+ }
+ L4PageTable = (UINT64 *)(UINTN)(L5PageTable[Index5] & PAGING_4K_ADDRESS_MASK_64);
+ } else {
+ L4PageTable = (UINT64 *)SecondLevelPagingEntry;
+ }
+
if (L4PageTable[Index4] == 0) {
L4PageTable[Index4] = (UINT64)(UINTN)AllocateZeroPages (1);
if (L4PageTable[Index4] == 0) {
@@ -785,7 +903,7 @@ SetSecondLevelPagingAttribute (
}
while (Length != 0) {
- PageEntry = GetSecondLevelPageTableEntry (VtdIndex, SecondLevelPagingEntry, BaseAddress, &PageAttribute);
+ PageEntry = GetSecondLevelPageTableEntry (VtdIndex, SecondLevelPagingEntry, BaseAddress, mVtdUnitInformation[VtdIndex].Is5LevelPaging, &PageAttribute);
if (PageEntry == NULL) {
DEBUG ((DEBUG_ERROR, "PageEntry - NULL\n"));
return RETURN_UNSUPPORTED;
@@ -913,7 +1031,7 @@ SetAccessAttribute (
if (ExtContextEntry != NULL) {
if (ExtContextEntry->Bits.Present == 0) {
- SecondLevelPagingEntry = CreateSecondLevelPagingEntry (VtdIndex, 0);
+ SecondLevelPagingEntry = CreateSecondLevelPagingEntry (VtdIndex, 0, mVtdUnitInformation[VtdIndex].Is5LevelPaging);
DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry - 0x%x (S%04x B%02x D%02x F%02x) New\n", SecondLevelPagingEntry, Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
Pt = (UINT64)RShiftU64 ((UINT64)(UINTN)SecondLevelPagingEntry, 12);
@@ -922,7 +1040,7 @@ SetAccessAttribute (
ExtContextEntry->Bits.DomainIdentifier = DomainIdentifier;
ExtContextEntry->Bits.Present = 1;
FlushPageTableMemory (VtdIndex, (UINTN)ExtContextEntry, sizeof(*ExtContextEntry));
- DumpDmarExtContextEntryTable (mVtdUnitInformation[VtdIndex].ExtRootEntryTable);
+ DumpDmarExtContextEntryTable (mVtdUnitInformation[VtdIndex].ExtRootEntryTable, mVtdUnitInformation[VtdIndex].Is5LevelPaging);
mVtdUnitInformation[VtdIndex].HasDirtyContext = TRUE;
} else {
SecondLevelPagingEntry = (VOID *)(UINTN)VTD_64BITS_ADDRESS(ExtContextEntry->Bits.SecondLevelPageTranslationPointerLo, ExtContextEntry->Bits.SecondLevelPageTranslationPointerHi);
@@ -930,7 +1048,7 @@ SetAccessAttribute (
}
} else if (ContextEntry != NULL) {
if (ContextEntry->Bits.Present == 0) {
- SecondLevelPagingEntry = CreateSecondLevelPagingEntry (VtdIndex, 0);
+ SecondLevelPagingEntry = CreateSecondLevelPagingEntry (VtdIndex, 0, mVtdUnitInformation[VtdIndex].Is5LevelPaging);
DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry - 0x%x (S%04x B%02x D%02x F%02x) New\n", SecondLevelPagingEntry, Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
Pt = (UINT64)RShiftU64 ((UINT64)(UINTN)SecondLevelPagingEntry, 12);
@@ -939,7 +1057,7 @@ SetAccessAttribute (
ContextEntry->Bits.DomainIdentifier = DomainIdentifier;
ContextEntry->Bits.Present = 1;
FlushPageTableMemory (VtdIndex, (UINTN)ContextEntry, sizeof(*ContextEntry));
- DumpDmarContextEntryTable (mVtdUnitInformation[VtdIndex].RootEntryTable);
+ DumpDmarContextEntryTable (mVtdUnitInformation[VtdIndex].RootEntryTable, mVtdUnitInformation[VtdIndex].Is5LevelPaging);
mVtdUnitInformation[VtdIndex].HasDirtyContext = TRUE;
} else {
SecondLevelPagingEntry = (VOID *)(UINTN)VTD_64BITS_ADDRESS(ContextEntry->Bits.SecondLevelPageTranslationPointerLo, ContextEntry->Bits.SecondLevelPageTranslationPointerHi);
@@ -1000,7 +1118,7 @@ AlwaysEnablePageAttribute (
if (mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry == 0) {
DEBUG((DEBUG_INFO, "CreateSecondLevelPagingEntry - %d\n", VtdIndex));
- mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry = CreateSecondLevelPagingEntry (VtdIndex, EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE);
+ mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry = CreateSecondLevelPagingEntry (VtdIndex, EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE, mVtdUnitInformation[VtdIndex].Is5LevelPaging);
}
SecondLevelPagingEntry = mVtdUnitInformation[VtdIndex].FixedSecondLevelPagingEntry;
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableEx.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableEx.c
index 0ed9e3ca..7412d0c9 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableEx.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTableEx.c
@@ -78,11 +78,31 @@ CreateExtContextEntry (
DEBUG ((DEBUG_INFO,"DOMAIN: S%04x, B%02x D%02x F%02x\n", mVtdUnitInformation[VtdIndex].Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
- if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) == 0) {
- DEBUG((DEBUG_ERROR, "!!!! 4-level page-table is not supported on VTD %d !!!!\n", VtdIndex));
+ mVtdUnitInformation[VtdIndex].Is5LevelPaging = FALSE;
+ if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT3) != 0) {
+ if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT3) != 0) {
+ DEBUG((DEBUG_ERROR, "Force to use 4-level page-table on VTD %d\n", Index));
+ ExtContextEntry->Bits.AddressWidth = 0x2;
+ } if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT4) != 0) {
+ DEBUG((DEBUG_ERROR, "Force to use 5-level page-table on VTD %d\n", Index));
+ ExtContextEntry->Bits.AddressWidth = 0x3;
+ } else {
+ if (mAcpiDmarTable->HostAddressWidth > 48) {
+ DEBUG((DEBUG_ERROR, "Using 5-level page-table on VTD %d\n", Index));
+ ExtContextEntry->Bits.AddressWidth = 0x3;
+ mVtdUnitInformation[VtdIndex].Is5LevelPaging = TRUE;
+ } else {
+ DEBUG((DEBUG_ERROR, "Using 4-level page-table on VTD %d\n", Index));
+ ExtContextEntry->Bits.AddressWidth = 0x2;
+ }
+ }
+ } else if ((mVtdUnitInformation[VtdIndex].CapReg.Bits.SAGAW & BIT2) != 0) {
+ DEBUG((DEBUG_ERROR, "Using 4-level page-table on VTD %d\n", Index));
+ ExtContextEntry->Bits.AddressWidth = 0x2;
+ } else {
+ DEBUG((DEBUG_ERROR, "!!!! Page-table type is not supported on VTD %d !!!!\n", VtdIndex));
return EFI_UNSUPPORTED;
}
- ExtContextEntry->Bits.AddressWidth = 0x2;
}
FlushPageTableMemory (VtdIndex, (UINTN)mVtdUnitInformation[VtdIndex].ExtRootEntryTable, EFI_PAGES_TO_SIZE(EntryTablePages));
@@ -93,11 +113,13 @@ CreateExtContextEntry (
/**
Dump DMAR extended context entry table.
- @param[in] ExtRootEntry DMAR extended root entry.
+ @param[in] ExtRootEntry DMAR extended root entry.
+ @param[in] Is5LevelPaging If it is the 5 level paging.
**/
VOID
DumpDmarExtContextEntryTable (
- IN VTD_EXT_ROOT_ENTRY *ExtRootEntry
+ IN VTD_EXT_ROOT_ENTRY *ExtRootEntry,
+ IN BOOLEAN Is5LevelPaging
)
{
UINTN Index;
@@ -127,7 +149,7 @@ DumpDmarExtContextEntryTable (
if (ExtContextEntry[Index2].Bits.Present == 0) {
continue;
}
- DumpSecondLevelPagingEntry ((VOID *)(UINTN)VTD_64BITS_ADDRESS(ExtContextEntry[Index2].Bits.SecondLevelPageTranslationPointerLo, ExtContextEntry[Index2].Bits.SecondLevelPageTranslationPointerHi));
+ DumpSecondLevelPagingEntry ((VOID *)(UINTN)VTD_64BITS_ADDRESS(ExtContextEntry[Index2].Bits.SecondLevelPageTranslationPointerLo, ExtContextEntry[Index2].Bits.SecondLevelPageTranslationPointerHi), Is5LevelPaging);
}
if (ExtRootEntry[Index].Bits.UpperPresent == 0) {
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
index 699639ba..686d235f 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
@@ -174,8 +174,14 @@ PrepareVtdConfig (
if ((mVtdUnitInformation[Index].CapReg.Bits.SLLPS & BIT0) == 0) {
DEBUG((DEBUG_WARN, "!!!! 2MB super page is not supported on VTD %d !!!!\n", Index));
}
- if ((mVtdUnitInformation[Index].CapReg.Bits.SAGAW & BIT2) == 0) {
- DEBUG((DEBUG_ERROR, "!!!! 4-level page-table is not supported on VTD %d !!!!\n", Index));
+ if ((mVtdUnitInformation[Index].CapReg.Bits.SAGAW & BIT3) != 0) {
+ DEBUG((DEBUG_INFO, "Support 5-level page-table on VTD %d\n", Index));
+ }
+ if ((mVtdUnitInformation[Index].CapReg.Bits.SAGAW & BIT2) != 0) {
+ DEBUG((DEBUG_INFO, "Support 4-level page-table on VTD %d\n", Index));
+ }
+ if ((mVtdUnitInformation[Index].CapReg.Bits.SAGAW & (BIT3 | BIT2)) == 0) {
+ DEBUG((DEBUG_ERROR, "!!!! Page-table type 0x%X is not supported on VTD %d !!!!\n", Index, mVtdUnitInformation[Index].CapReg.Bits.SAGAW));
return ;
}
diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
index 284820af..8f1edfe2 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -95,6 +95,9 @@
# BIT0: Enable IOMMU during boot (If DMAR table is installed in DXE. If VTD_INFO_PPI is installed in PEI.)
# BIT1: Enable IOMMU when transfer control to OS (ExitBootService in normal boot. EndOfPEI in S3)
# BIT2: Force no IOMMU access attribute request recording before DMAR table is installed.
+ # BIT3: Force to use 4 level paging.
+ # BIT4: If iommu support 5 level paging, force to use 5 level paging.
+ # (If both BIT3 and BIT4 are set, force to use 4 level paging.)
# @Prompt The policy for VTd driver behavior.
gIntelSiliconPkgTokenSpaceGuid.PcdVTdPolicyPropertyMask|1|UINT8|0x00000002
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2020-11-11 4:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-11-11 4:53 [PATCH] IntelSiliconPkg/VTd: Add iommu 5 level paging support Sheng Wei
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox