* [PATCH v3 0/4] There are 4 patches for VTd drivers
@ 2021-12-14 5:35 Sheng Wei
2021-12-14 5:35 ` [PATCH v3 1/4] IntelSiliconPkg/VTd: Fix typos Sheng Wei
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Sheng Wei @ 2021-12-14 5:35 UTC (permalink / raw)
To: devel; +Cc: Ray Ni, Rangasai V Chaganty, Jenny Huang, Robert Kowalewski
[PATCH 1/4] IntelSiliconPkg/VTd: Fix typos
[PATCH 2/4] IntelSiliconPkg/VTd: Update VTd register structs
[PATCH 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode
[PATCH 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once.
Patch v2 update:
Fix build error in [PATCH 2/4] and [PATCH 4/4]
Patch v3 update:
Refine code for PEI 64 bit build compatible.
Change the condition for using Register-based Invalidation.
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Jenny Huang <jenny.huang@intel.com>
Cc: Robert Kowalewski <robert.kowalewski@intel.com>
Signed-off-by: Sheng Wei <w.sheng@intel.com>
Sheng Wei (4):
IntelSiliconPkg/VTd: Fix typos
IntelSiliconPkg/VTd: Update VTd register structs
IntelSiliconPkg/VTd: Support VTd Abort DMA Mode
IntelSiliconPkg/VTd: Only generate PEI DMA buffer once.
.../Feature/VTd/IntelVTdDmarPei/DmarTable.c | 405 +++++-----------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c | 429 ++++++++---------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c | 507 ++++++++++++---------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h | 127 ++++--
.../Feature/VTd/IntelVTdDmarPei/TranslationTable.c | 224 +++++----
.../Feature/VTd/IntelVTdDxe/DmarAcpiTable.c | 12 +-
.../Feature/VTd/IntelVTdDxe/TranslationTable.c | 22 +-
.../Feature/VTd/IntelVTdDxe/VtdReg.c | 6 +-
.../Feature/VTd/IntelVTdPmrPei/DmarTable.c | 6 +-
.../IntelSiliconPkg/Include/IndustryStandard/Vtd.h | 34 +-
10 files changed, 846 insertions(+), 926 deletions(-)
--
2.16.2.windows.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/4] IntelSiliconPkg/VTd: Fix typos
2021-12-14 5:35 [PATCH v3 0/4] There are 4 patches for VTd drivers Sheng Wei
@ 2021-12-14 5:35 ` Sheng Wei
2021-12-14 5:35 ` [PATCH v3 2/4] IntelSiliconPkg/VTd: Update VTd register structs Sheng Wei
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Sheng Wei @ 2021-12-14 5:35 UTC (permalink / raw)
To: devel; +Cc: Ray Ni, Rangasai V Chaganty, Jenny Huang, Robert Kowalewski
It is DRHD(DMA Remapping Hardware Unit Definition).
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3622
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Jenny Huang <jenny.huang@intel.com>
Cc: Robert Kowalewski <robert.kowalewski@intel.com>
Signed-off-by: Sheng Wei <w.sheng@intel.com>
---
.../IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c | 12 ++++++------
.../IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c | 12 ++++++------
.../IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/DmarTable.c | 6 +++---
3 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
index 2154690d..e9c99d0a 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
@@ -539,14 +539,14 @@ RegisterPciDevice (
}
/**
- Process DMAR DHRD table.
+ Process DMAR DRHD table.
@param[in] VTdUnitInfo The VTd engine unit information.
@param[in] DmarDrhd The DRHD table.
**/
VOID
-ProcessDhrd (
+ProcessDrhd (
IN VTD_UNIT_INFO *VTdUnitInfo,
IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
)
@@ -581,10 +581,10 @@ ProcessDhrd (
if ((DmarDrhd->Flags & EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL) != 0) {
VTdUnitInfo->PciDeviceInfo.IncludeAllFlag = TRUE;
- DEBUG ((DEBUG_INFO," ProcessDhrd: with INCLUDE ALL\n"));
+ DEBUG ((DEBUG_INFO," ProcessDrhd: with INCLUDE ALL\n"));
} else {
VTdUnitInfo->PciDeviceInfo.IncludeAllFlag = FALSE;
- DEBUG ((DEBUG_INFO," ProcessDhrd: without INCLUDE ALL\n"));
+ DEBUG ((DEBUG_INFO," ProcessDrhd: without INCLUDE ALL\n"));
}
VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber = 0;
@@ -600,7 +600,7 @@ ProcessDhrd (
return;
}
- DEBUG ((DEBUG_INFO," ProcessDhrd: "));
+ DEBUG ((DEBUG_INFO," ProcessDrhd: "));
switch (DmarDevScopeEntry->Type) {
case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
DEBUG ((DEBUG_INFO,"PCI Endpoint"));
@@ -708,7 +708,7 @@ ParseDmarAcpiTableDrhd (
switch (DmarHeader->Type) {
case EFI_ACPI_DMAR_TYPE_DRHD:
ASSERT (VtdIndex < VtdUnitNumber);
- ProcessDhrd (&VTdInfo->VtdUnitInfo[VtdIndex], (EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader);
+ ProcessDrhd (&VTdInfo->VtdUnitInfo[VtdIndex], (EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader);
VtdIndex++;
break;
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c
index 1ee290b7..75fbd53e 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c
@@ -662,7 +662,7 @@ GetPciBusDeviceFunction (
}
/**
- Process DMAR DHRD table.
+ Process DMAR DRHD table.
@param[in] VtdIndex The index of VTd engine.
@param[in] DmarDrhd The DRHD table.
@@ -670,7 +670,7 @@ GetPciBusDeviceFunction (
@retval EFI_SUCCESS The DRHD table is processed.
**/
EFI_STATUS
-ProcessDhrd (
+ProcessDrhd (
IN UINTN VtdIndex,
IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
)
@@ -690,7 +690,7 @@ ProcessDhrd (
if ((DmarDrhd->Flags & EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL) != 0) {
mVtdUnitInformation[VtdIndex].PciDeviceInfo.IncludeAllFlag = TRUE;
- DEBUG ((DEBUG_INFO," ProcessDhrd: with INCLUDE ALL\n"));
+ DEBUG ((DEBUG_INFO," ProcessDrhd: with INCLUDE ALL\n"));
Status = ScanAllPciBus((VOID *)VtdIndex, DmarDrhd->SegmentNumber, ScanBusCallbackRegisterPciDevice);
if (EFI_ERROR (Status)) {
@@ -698,7 +698,7 @@ ProcessDhrd (
}
} else {
mVtdUnitInformation[VtdIndex].PciDeviceInfo.IncludeAllFlag = FALSE;
- DEBUG ((DEBUG_INFO," ProcessDhrd: without INCLUDE ALL\n"));
+ DEBUG ((DEBUG_INFO," ProcessDrhd: without INCLUDE ALL\n"));
}
DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((UINTN)(DmarDrhd + 1));
@@ -709,7 +709,7 @@ ProcessDhrd (
return Status;
}
- DEBUG ((DEBUG_INFO," ProcessDhrd: "));
+ DEBUG ((DEBUG_INFO," ProcessDrhd: "));
switch (DmarDevScopeEntry->Type) {
case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
DEBUG ((DEBUG_INFO,"PCI Endpoint"));
@@ -877,7 +877,7 @@ ParseDmarAcpiTableDrhd (
switch (DmarHeader->Type) {
case EFI_ACPI_DMAR_TYPE_DRHD:
ASSERT (VtdIndex < mVtdUnitNumber);
- Status = ProcessDhrd (VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader);
+ Status = ProcessDrhd (VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader);
if (EFI_ERROR (Status)) {
return Status;
}
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/DmarTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/DmarTable.c
index d920d136..1bb74f40 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/DmarTable.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/DmarTable.c
@@ -356,14 +356,14 @@ GetVtdEngineNumber (
}
/**
- Process DMAR DHRD table.
+ Process DMAR DRHD table.
@param[in] VTdInfo The VTd engine context information.
@param[in] VtdIndex The index of VTd engine.
@param[in] DmarDrhd The DRHD table.
**/
VOID
-ProcessDhrd (
+ProcessDrhd (
IN VTD_INFO *VTdInfo,
IN UINTN VtdIndex,
IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
@@ -415,7 +415,7 @@ ParseDmarAcpiTableDrhd (
switch (DmarHeader->Type) {
case EFI_ACPI_DMAR_TYPE_DRHD:
ASSERT (VtdIndex < VtdUnitNumber);
- ProcessDhrd (VTdInfo, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader);
+ ProcessDrhd (VTdInfo, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader);
VtdIndex++;
break;
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v3 2/4] IntelSiliconPkg/VTd: Update VTd register structs
2021-12-14 5:35 [PATCH v3 0/4] There are 4 patches for VTd drivers Sheng Wei
2021-12-14 5:35 ` [PATCH v3 1/4] IntelSiliconPkg/VTd: Fix typos Sheng Wei
@ 2021-12-14 5:35 ` Sheng Wei
2021-12-14 5:35 ` [PATCH v3 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode Sheng Wei
2021-12-14 5:35 ` [PATCH v3 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once Sheng Wei
3 siblings, 0 replies; 5+ messages in thread
From: Sheng Wei @ 2021-12-14 5:35 UTC (permalink / raw)
To: devel; +Cc: Ray Ni, Rangasai V Chaganty, Jenny Huang, Robert Kowalewski
Update VTd register structs accroding to VTd spec ver 3.3
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3765
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Jenny Huang <jenny.huang@intel.com>
Cc: Robert Kowalewski <robert.kowalewski@intel.com>
Signed-off-by: Sheng Wei <w.sheng@intel.com>
---
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c | 3 +-
.../Feature/VTd/IntelVTdDmarPei/TranslationTable.c | 23 +++++++++++----
.../Feature/VTd/IntelVTdDxe/TranslationTable.c | 22 ++++++++++++--
.../Feature/VTd/IntelVTdDxe/VtdReg.c | 6 ++--
.../IntelSiliconPkg/Include/IndustryStandard/Vtd.h | 34 +++++++++++++++++-----
5 files changed, 67 insertions(+), 21 deletions(-)
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c
index c3a939c9..87ce9716 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c
@@ -631,10 +631,8 @@ DumpVtdECapRegs (
DEBUG ((DEBUG_INFO, " SC - 0x%x\n", ECapReg->Bits.SC));
DEBUG ((DEBUG_INFO, " IRO - 0x%x\n", ECapReg->Bits.IRO));
DEBUG ((DEBUG_INFO, " MHMV - 0x%x\n", ECapReg->Bits.MHMV));
- DEBUG ((DEBUG_INFO, " ECS - 0x%x\n", ECapReg->Bits.ECS));
DEBUG ((DEBUG_INFO, " MTS - 0x%x\n", ECapReg->Bits.MTS));
DEBUG ((DEBUG_INFO, " NEST - 0x%x\n", ECapReg->Bits.NEST));
- DEBUG ((DEBUG_INFO, " DIS - 0x%x\n", ECapReg->Bits.DIS));
DEBUG ((DEBUG_INFO, " PASID - 0x%x\n", ECapReg->Bits.PASID));
DEBUG ((DEBUG_INFO, " PRS - 0x%x\n", ECapReg->Bits.PRS));
DEBUG ((DEBUG_INFO, " ERS - 0x%x\n", ECapReg->Bits.ERS));
@@ -642,6 +640,7 @@ DumpVtdECapRegs (
DEBUG ((DEBUG_INFO, " NWFS - 0x%x\n", ECapReg->Bits.NWFS));
DEBUG ((DEBUG_INFO, " EAFS - 0x%x\n", ECapReg->Bits.EAFS));
DEBUG ((DEBUG_INFO, " PSS - 0x%x\n", ECapReg->Bits.PSS));
+ DEBUG ((DEBUG_INFO, " ADMS - 0x%x\n", ECapReg->Bits.ADMS));
}
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTable.c
index 6676b2a9..a309d566 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTable.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTable.c
@@ -884,13 +884,26 @@ SetupTranslationTable (
return Status;
}
- if (VtdUnitInfo->ECapReg.Bits.ECS) {
- DEBUG ((DEBUG_INFO, "CreateExtContextEntry - %d\n", Index));
- Status = CreateExtContextEntry (VtdUnitInfo);
+ if (VtdUnitInfo->ECapReg.Bits.SMTS) {
+ if (VtdUnitInfo->ECapReg.Bits.DEP_24) {
+ DEBUG ((DEBUG_ERROR,"ECapReg.bit24 is not zero\n"));
+ ASSERT(FALSE);
+ Status = EFI_UNSUPPORTED;
+ } else {
+ Status = CreateExtContextEntry (VtdUnitInfo);
+ }
} else {
- DEBUG ((DEBUG_INFO, "CreateContextEntry - %d\n", Index));
- Status = CreateContextEntry (VtdUnitInfo);
+ if (VtdUnitInfo->ECapReg.Bits.DEP_24) {
+ //
+ // To compatible with pervious VTd engine
+ // It was ECS(Extended Context Support) bit.
+ //
+ Status = CreateExtContextEntry (VtdUnitInfo);
+ } else {
+ Status = CreateContextEntry (VtdUnitInfo);
+ }
}
+
if (EFI_ERROR (Status)) {
return Status;
}
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.c
index ca5f65a8..48e38d56 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTable.c
@@ -382,11 +382,27 @@ SetupTranslationTable (
for (Index = 0; Index < mVtdUnitNumber; Index++) {
DEBUG((DEBUG_INFO, "CreateContextEntry - %d\n", Index));
- if (mVtdUnitInformation[Index].ECapReg.Bits.ECS) {
- Status = CreateExtContextEntry (Index);
+
+ if (mVtdUnitInformation[Index].ECapReg.Bits.SMTS) {
+ if (mVtdUnitInformation[Index].ECapReg.Bits.DEP_24) {
+ DEBUG ((DEBUG_ERROR,"ECapReg.bit24 is not zero\n"));
+ ASSERT(FALSE);
+ Status = EFI_UNSUPPORTED;
+ } else {
+ Status = CreateExtContextEntry (Index);
+ }
} else {
- Status = CreateContextEntry (Index);
+ if (mVtdUnitInformation[Index].ECapReg.Bits.DEP_24) {
+ //
+ // To compatible with pervious VTd engine
+ // It was ECS(Extended Context Support) bit.
+ //
+ Status = CreateExtContextEntry (Index);
+ } else {
+ Status = CreateContextEntry (Index);
+ }
}
+
if (EFI_ERROR (Status)) {
return Status;
}
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
index 1ce9c1c0..105911a9 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
@@ -698,10 +698,8 @@ DumpVtdECapRegs (
DEBUG((DEBUG_INFO, " SC - 0x%x\n", ECapReg->Bits.SC));
DEBUG((DEBUG_INFO, " IRO - 0x%x\n", ECapReg->Bits.IRO));
DEBUG((DEBUG_INFO, " MHMV - 0x%x\n", ECapReg->Bits.MHMV));
- DEBUG((DEBUG_INFO, " ECS - 0x%x\n", ECapReg->Bits.ECS));
DEBUG((DEBUG_INFO, " MTS - 0x%x\n", ECapReg->Bits.MTS));
DEBUG((DEBUG_INFO, " NEST - 0x%x\n", ECapReg->Bits.NEST));
- DEBUG((DEBUG_INFO, " DIS - 0x%x\n", ECapReg->Bits.DIS));
DEBUG((DEBUG_INFO, " PASID - 0x%x\n", ECapReg->Bits.PASID));
DEBUG((DEBUG_INFO, " PRS - 0x%x\n", ECapReg->Bits.PRS));
DEBUG((DEBUG_INFO, " ERS - 0x%x\n", ECapReg->Bits.ERS));
@@ -709,6 +707,8 @@ DumpVtdECapRegs (
DEBUG((DEBUG_INFO, " NWFS - 0x%x\n", ECapReg->Bits.NWFS));
DEBUG((DEBUG_INFO, " EAFS - 0x%x\n", ECapReg->Bits.EAFS));
DEBUG((DEBUG_INFO, " PSS - 0x%x\n", ECapReg->Bits.PSS));
+ DEBUG((DEBUG_INFO, " SMTS - 0x%x\n", ECapReg->Bits.SMTS));
+ DEBUG((DEBUG_INFO, " ADMS - 0x%x\n", ECapReg->Bits.ADMS));
}
/**
@@ -771,7 +771,7 @@ DumpVtdRegs (
DEBUG((DEBUG_INFO, " Fault Info - 0x%016lx\n", VTD_64BITS_ADDRESS(FrcdReg.Bits.FILo, FrcdReg.Bits.FIHi)));
SourceId.Uint16 = (UINT16)FrcdReg.Bits.SID;
DEBUG((DEBUG_INFO, " Source - B%02x D%02x F%02x\n", SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
- DEBUG((DEBUG_INFO, " Type - %x (%a)\n", FrcdReg.Bits.T, FrcdReg.Bits.T ? "read" : "write"));
+ DEBUG((DEBUG_INFO, " Type - 0x%02x\n", (FrcdReg.Bits.T1 << 1) | FrcdReg.Bits.T2));
DEBUG((DEBUG_INFO, " Reason - %x (Refer to VTd Spec, Appendix A)\n", FrcdReg.Bits.FR));
}
}
diff --git a/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/Vtd.h b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/Vtd.h
index a759ca10..32fbdd02 100644
--- a/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/Vtd.h
+++ b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/Vtd.h
@@ -216,6 +216,7 @@ typedef union {
#define B_GSTS_REG_RTPS BIT30
#define B_GSTS_REG_TE BIT31
#define R_RTADDR_REG 0x20
+#define V_RTADDR_REG_TTM_ADM (BIT11|BIT10)
#define R_CCMD_REG 0x28
#define B_CCMD_REG_CIRG_MASK (BIT62|BIT61)
#define V_CCMD_REG_CIRG_GLOBAL BIT61
@@ -334,7 +335,10 @@ typedef union {
UINT8 FL1GP:1; // First Level 1-GByte Page Support
UINT8 Rsvd_57:2;
UINT8 PI:1; // Posted Interrupts Support
- UINT8 Rsvd_60:4;
+ UINT8 FL5LP:1; // First Level 5-level Paging Support
+ UINT8 Rsvd_61:1;
+ UINT8 ESIRTPS:1; // Enhanced Set Interrupt Remap Table Pointer Support
+ UINT8 ESRTPS:1; // Enhanced Set Root Table Pointer Support
} Bits;
UINT64 Uint64;
} VTD_CAP_REG;
@@ -346,7 +350,7 @@ typedef union {
UINT8 DT:1; // Device-TLB support
UINT8 IR:1; // Interrupt Remapping support
UINT8 EIM:1; // Extended Interrupt Mode
- UINT8 Rsvd_5:1;
+ UINT8 DEP_5:1;
UINT8 PT:1; // Pass Through
UINT8 SC:1; // Snoop Control
@@ -354,11 +358,11 @@ typedef union {
UINT16 Rsvd_18:2;
UINT16 MHMV:4; // Maximum Handle Mask Value
- UINT8 ECS:1; // Extended Context Support
+ UINT8 DEP_24:1;
UINT8 MTS:1; // Memory Type Support
UINT8 NEST:1; // Nested Translation Support
- UINT8 DIS:1; // Deferred Invalidate Support
- UINT8 PASID:1; // Process Address Space ID Support
+ UINT8 Rsvd_27:1;
+ UINT8 DEP_28:1;
UINT8 PRS:1; // Page Request Support
UINT8 ERS:1; // Execute Request Support
UINT8 SRS:1; // Supervisor Request Support
@@ -367,7 +371,20 @@ typedef union {
UINT32 NWFS:1; // No Write Flag Support
UINT32 EAFS:1; // Extended Accessed Flag Support
UINT32 PSS:5; // PASID Size Supported
- UINT32 Rsvd_40:24;
+ UINT32 PASID:1; // Process Address Space ID Support
+ UINT32 DIT:1; // Device-TLB Invalidation Throttle
+ UINT32 PDS:1; // Page-request Drain Support
+ UINT32 SMTS:1; // Scalable Mode Translation Support
+ UINT32 VCS:1; // Virtual Command Support
+ UINT32 SLADS:1; // Second-Level Accessed Dirty Support
+ UINT32 SLTS:1; // Second-level Translation Support
+ UINT32 FLTS:1; // First-level Translation Support
+ UINT32 SMPWCS:1; // Scalable-Mode Page-walk Coherency Support
+ UINT32 RPS:1; // RID-PASID Support
+ UINT32 Rsvd_50:2;
+ UINT32 ADMS:1; // Abort DMA Mode Support
+ UINT32 RPRIVS:1; // RID_PRIV Support
+ UINT32 Rsvd_54:10;
} Bits;
UINT64 Uint64;
} VTD_ECAP_REG;
@@ -379,7 +396,8 @@ typedef union {
UINT32 FIHi:32; // FaultInfo
UINT32 SID:16; // Source Identifier
- UINT32 Rsvd_80:13;
+ UINT32 Rsvd_80:12;
+ UINT32 T2:1; // Type bit2 (0: Write/Read, 1: Page/AtomicOp)
UINT32 PRIV:1; // Privilege Mode Requested
UINT32 EXE:1; // Execute Permission Requested
UINT32 PP:1; // PASID Present
@@ -387,7 +405,7 @@ typedef union {
UINT32 FR:8; // Fault Reason
UINT32 PV:20; // PASID Value
UINT32 AT:2; // Address Type
- UINT32 T:1; // Type (0: Write, 1: Read)
+ UINT32 T1:1; // Type bit1 (0: Write/Page, 1: Read/AtomicOp)
UINT32 F:1; // Fault
} Bits;
UINT64 Uint64[2];
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v3 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode
2021-12-14 5:35 [PATCH v3 0/4] There are 4 patches for VTd drivers Sheng Wei
2021-12-14 5:35 ` [PATCH v3 1/4] IntelSiliconPkg/VTd: Fix typos Sheng Wei
2021-12-14 5:35 ` [PATCH v3 2/4] IntelSiliconPkg/VTd: Update VTd register structs Sheng Wei
@ 2021-12-14 5:35 ` Sheng Wei
2021-12-14 5:35 ` [PATCH v3 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once Sheng Wei
3 siblings, 0 replies; 5+ messages in thread
From: Sheng Wei @ 2021-12-14 5:35 UTC (permalink / raw)
To: devel; +Cc: Ray Ni, Rangasai V Chaganty, Jenny Huang, Robert Kowalewski
If VTd ECAP_REG.ADMS bit is set, abort DMA mode is supported.
When VTd Abort DMA Mode is enabled, hardware will abort all DMA
operations without the need to set up a root-table with each
entry marked as not-present.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3766
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Jenny Huang <jenny.huang@intel.com>
Cc: Robert Kowalewski <robert.kowalewski@intel.com>
Signed-off-by: Sheng Wei <w.sheng@intel.com>
---
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c | 43 +++++++++++++---------
1 file changed, 26 insertions(+), 17 deletions(-)
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c
index 87ce9716..63397a1a 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c
@@ -384,7 +384,7 @@ InvalidateIOTLB (
Enable DMAR translation inpre-mem phase.
@param[in] VtdUnitBaseAddress The base address of the VTd engine.
- @param[in] RootEntryTable The address of the VTd RootEntryTable.
+ @param[in] RtaddrRegValue The value of RTADDR_REG.
@retval EFI_SUCCESS DMAR translation is enabled.
@retval EFI_DEVICE_ERROR DMAR translation is not enabled.
@@ -392,15 +392,15 @@ InvalidateIOTLB (
EFI_STATUS
EnableDmarPreMem (
IN UINTN VtdUnitBaseAddress,
- IN UINTN RootEntryTable
+ IN UINTN RtaddrRegValue
)
{
UINT32 Reg32;
DEBUG ((DEBUG_INFO, ">>>>>>EnableDmarPreMem() for engine [%x] \n", VtdUnitBaseAddress));
- DEBUG ((DEBUG_INFO, "RootEntryTable 0x%x \n", RootEntryTable));
- MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64) (UINTN) RootEntryTable);
+ DEBUG ((DEBUG_INFO, "RTADDR_REG : 0x%x \n", RtaddrRegValue));
+ MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64) RtaddrRegValue);
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_SRTP);
@@ -662,18 +662,6 @@ EnableVTdTranslationProtectionAll (
DEBUG ((DEBUG_INFO, "EnableVTdTranslationProtectionAll - 0x%lx\n", EngineMask));
- Status = PeiServicesLocatePpi (
- &gEdkiiVTdNullRootEntryTableGuid,
- 0,
- NULL,
- (VOID **)&RootEntryTable
- );
- if (EFI_ERROR(Status)) {
- DEBUG ((DEBUG_ERROR, "Locate Null Root Entry Table Ppi Failed : %r\n", Status));
- ASSERT (FALSE);
- return;
- }
-
for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
if ((EngineMask & LShiftU64(1, Index)) == 0) {
continue;
@@ -686,7 +674,28 @@ EnableVTdTranslationProtectionAll (
VTdInfo->VtdUnitInfo[Index].ECapReg.Uint64 = MmioRead64 (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress + R_ECAP_REG);
DumpVtdECapRegs (&VTdInfo->VtdUnitInfo[Index].ECapReg);
- EnableDmarPreMem (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress, (UINTN) *RootEntryTable);
+ if (VTdInfo->VtdUnitInfo[Index].ECapReg.Bits.ADMS == 1) {
+ //
+ // Use Abort DMA Mode
+ //
+ Status = EnableDmarPreMem (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress, V_RTADDR_REG_TTM_ADM);
+ } else {
+ //
+ // Use Null Root Entry Table
+ //
+ Status = PeiServicesLocatePpi (
+ &gEdkiiVTdNullRootEntryTableGuid,
+ 0,
+ NULL,
+ (VOID **)&RootEntryTable
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, "Locate Null Root Entry Table Ppi Failed : %r\n", Status));
+ ASSERT (FALSE);
+ return;
+ }
+ EnableDmarPreMem (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress, (UINTN) *RootEntryTable);
+ }
}
return;
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v3 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once.
2021-12-14 5:35 [PATCH v3 0/4] There are 4 patches for VTd drivers Sheng Wei
` (2 preceding siblings ...)
2021-12-14 5:35 ` [PATCH v3 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode Sheng Wei
@ 2021-12-14 5:35 ` Sheng Wei
3 siblings, 0 replies; 5+ messages in thread
From: Sheng Wei @ 2021-12-14 5:35 UTC (permalink / raw)
To: devel; +Cc: Ray Ni, Rangasai V Chaganty, Jenny Huang, Robert Kowalewski
VTdInfoNotify may be called manay times, PEI DMA buffer should be
generated only once.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3667
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
Cc: Jenny Huang <jenny.huang@intel.com>
Cc: Robert Kowalewski <robert.kowalewski@intel.com>
Signed-off-by: Sheng Wei <w.sheng@intel.com>
---
.../Feature/VTd/IntelVTdDmarPei/DmarTable.c | 405 +++++-----------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c | 433 ++++++++----------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c | 507 ++++++++++++---------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h | 127 ++++--
.../Feature/VTd/IntelVTdDmarPei/TranslationTable.c | 201 ++++----
5 files changed, 769 insertions(+), 904 deletions(-)
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
index e9c99d0a..31792189 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
@@ -1,6 +1,7 @@
/** @file
- Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
+
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -413,142 +414,53 @@ GetPciBusDeviceFunction (
}
/**
- Return the index of PCI data.
-
- @param[in] VTdUnitInfo The VTd engine unit information.
- @param[in] Segment The Segment used to identify a VTd engine.
- @param[in] SourceId The SourceId used to identify a VTd engine and table entry.
-
- @return The index of the PCI data.
- @retval (UINTN)-1 The PCI data is not found.
-**/
-UINTN
-GetPciDataIndex (
- IN VTD_UNIT_INFO *VTdUnitInfo,
- IN UINT16 Segment,
- IN VTD_SOURCE_ID SourceId
- )
-{
- UINTN Index;
- VTD_SOURCE_ID *PciSourceId;
- PEI_PCI_DEVICE_DATA *PciDeviceDataBase;
-
- if (Segment != VTdUnitInfo->Segment) {
- return (UINTN)-1;
- }
-
- for (Index = 0; Index < VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber; Index++) {
- PciDeviceDataBase = (PEI_PCI_DEVICE_DATA*) (UINTN) VTdUnitInfo->PciDeviceInfo.PciDeviceData;
- PciSourceId = &PciDeviceDataBase[Index].PciSourceId;
- if ((PciSourceId->Bits.Bus == SourceId.Bits.Bus) &&
- (PciSourceId->Bits.Device == SourceId.Bits.Device) &&
- (PciSourceId->Bits.Function == SourceId.Bits.Function) ) {
- return Index;
- }
- }
-
- return (UINTN)-1;
-}
-
-
-/**
- Register PCI device to VTd engine.
+ Parse DMAR DRHD table.
- @param[in] VTdUnitInfo The VTd engine unit information.
- @param[in] Segment The segment of the source.
- @param[in] SourceId The SourceId of the source.
- @param[in] DeviceType The DMAR device scope type.
- @param[in] CheckExist TRUE: ERROR will be returned if the PCI device is already registered.
- FALSE: SUCCESS will be returned if the PCI device is registered.
+ @param[in] AcpiDmarTable DMAR ACPI table
+ @param[in] Callback Callback function for handle DRHD
+ @param[in] Context Callback function Context
- @retval EFI_SUCCESS The PCI device is registered.
- @retval EFI_OUT_OF_RESOURCES No enough resource to register a new PCI device.
- @retval EFI_ALREADY_STARTED The device is already registered.
+ @return EFI_SUCCESS The DMAR DRHD table is parsed.
**/
EFI_STATUS
-RegisterPciDevice (
- IN VTD_UNIT_INFO *VTdUnitInfo,
- IN UINT16 Segment,
- IN VTD_SOURCE_ID SourceId,
- IN UINT8 DeviceType,
- IN BOOLEAN CheckExist
+ParseDmarAcpiTableDrhd (
+ IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable,
+ IN PROCESS_DRHD_CALLBACK_FUNC Callback,
+ IN VOID *Context
)
{
- PEI_PCI_DEVICE_INFORMATION *PciDeviceInfo;
- VTD_SOURCE_ID *PciSourceId;
- UINTN PciDataIndex;
- UINTN PciDeviceDataSize;
- PEI_PCI_DEVICE_DATA *NewPciDeviceData;
- PEI_PCI_DEVICE_DATA *PciDeviceDataBase;
-
- PciDeviceInfo = &VTdUnitInfo->PciDeviceInfo;
-
- PciDataIndex = GetPciDataIndex (VTdUnitInfo, Segment, SourceId);
- if (PciDataIndex == (UINTN)-1) {
- //
- // Register new
- //
-
- if (PciDeviceInfo->PciDeviceDataNumber >= PciDeviceInfo->PciDeviceDataMaxNumber) {
- //
- // Reallocate
- //
- PciDeviceDataSize = sizeof(*NewPciDeviceData) * (PciDeviceInfo->PciDeviceDataMaxNumber + MAX_VTD_PCI_DATA_NUMBER);
- DEBUG ((DEBUG_INFO, "New PciDeviceDataSize:%d Page:%d\n", PciDeviceDataSize, EFI_SIZE_TO_PAGES (PciDeviceDataSize)));
- NewPciDeviceData = AllocateZeroPages (EFI_SIZE_TO_PAGES(PciDeviceDataSize));
- if (NewPciDeviceData == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- PciDeviceInfo->PciDeviceDataMaxNumber += MAX_VTD_PCI_DATA_NUMBER;
- if (PciDeviceInfo->PciDeviceData != 0) {
- CopyMem (NewPciDeviceData, (VOID *) (UINTN) PciDeviceInfo->PciDeviceData, sizeof (*NewPciDeviceData) * PciDeviceInfo->PciDeviceDataNumber);
- FreePages((VOID *) (UINTN) PciDeviceInfo->PciDeviceData, PciDeviceInfo->PciDeviceDataPageSize);
- }
- PciDeviceInfo->PciDeviceData = (UINT32) (UINTN) NewPciDeviceData;
- PciDeviceInfo->PciDeviceDataPageSize = (UINT32) EFI_SIZE_TO_PAGES (PciDeviceDataSize);
- }
-
- ASSERT (PciDeviceInfo->PciDeviceDataNumber < PciDeviceInfo->PciDeviceDataMaxNumber);
-
- PciDeviceDataBase = (PEI_PCI_DEVICE_DATA *) (UINTN) PciDeviceInfo->PciDeviceData;
- PciSourceId = &PciDeviceDataBase[PciDeviceInfo->PciDeviceDataNumber].PciSourceId;
- PciSourceId->Bits.Bus = SourceId.Bits.Bus;
- PciSourceId->Bits.Device = SourceId.Bits.Device;
- PciSourceId->Bits.Function = SourceId.Bits.Function;
-
- DEBUG ((DEBUG_INFO, " RegisterPciDevice: PCI S%04x B%02x D%02x F%02x", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
-
- PciDeviceDataBase[PciDeviceInfo->PciDeviceDataNumber].DeviceType = DeviceType;
-
- if ((DeviceType != EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) &&
- (DeviceType != EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE)) {
- DEBUG ((DEBUG_INFO, " (*)"));
- }
- DEBUG ((DEBUG_INFO, "\n"));
+ EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
+ UINT32 VtdIndex;
- PciDeviceInfo->PciDeviceDataNumber++;
- } else {
- if (CheckExist) {
- DEBUG ((DEBUG_INFO, " RegisterPciDevice: PCI S%04x B%02x D%02x F%02x already registered\n", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
- return EFI_ALREADY_STARTED;
+ VtdIndex = 0;
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) (AcpiDmarTable + 1));
+ while ((UINTN) DmarHeader < (UINTN) AcpiDmarTable + AcpiDmarTable->Header.Length) {
+ switch (DmarHeader->Type) {
+ case EFI_ACPI_DMAR_TYPE_DRHD:
+ Callback (Context, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader);
+ VtdIndex++;
+ break;
+ default:
+ break;
}
+ DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) DmarHeader + DmarHeader->Length);
}
return EFI_SUCCESS;
}
/**
- Process DMAR DRHD table.
+ Parse DMAR RMRR table to get device number.
+
+ @param[in] DmarRmrr The RMRR table.
- @param[in] VTdUnitInfo The VTd engine unit information.
- @param[in] DmarDrhd The DRHD table.
+ @return the device number
**/
-VOID
-ProcessDrhd (
- IN VTD_UNIT_INFO *VTdUnitInfo,
- IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
+UINTN
+ProcessRmrrGetDeviceNumber (
+ IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr
)
{
EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry;
@@ -556,189 +468,83 @@ ProcessDrhd (
UINT8 Device;
UINT8 Function;
EFI_STATUS Status;
- VTD_SOURCE_ID SourceId;
-
- DEBUG ((DEBUG_INFO," VTD BaseAddress - 0x%016lx\n", DmarDrhd->RegisterBaseAddress));
- VTdUnitInfo->VtdUnitBaseAddress = (UINT32) DmarDrhd->RegisterBaseAddress;
-
- VTdUnitInfo->EnableQueuedInvalidation = 0;
-
- DEBUG ((DEBUG_INFO," VTD Segment - %d\n", DmarDrhd->SegmentNumber));
- VTdUnitInfo->Segment = DmarDrhd->SegmentNumber;
-
- VTdUnitInfo->FixedSecondLevelPagingEntry = 0;
- VTdUnitInfo->RmrrSecondLevelPagingEntry = 0;
- VTdUnitInfo->RootEntryTable = 0;
- VTdUnitInfo->ExtRootEntryTable = 0;
- VTdUnitInfo->RootEntryTablePageSize = 0;
- VTdUnitInfo->ExtRootEntryTablePageSize = 0;
-
- VTdUnitInfo->PciDeviceInfo.IncludeAllFlag = 0;
- VTdUnitInfo->PciDeviceInfo.PciDeviceDataMaxNumber = 0;
- VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber = 0;
- VTdUnitInfo->PciDeviceInfo.PciDeviceDataPageSize = 0;
- VTdUnitInfo->PciDeviceInfo.PciDeviceData = 0;
-
- if ((DmarDrhd->Flags & EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL) != 0) {
- VTdUnitInfo->PciDeviceInfo.IncludeAllFlag = TRUE;
- DEBUG ((DEBUG_INFO," ProcessDrhd: with INCLUDE ALL\n"));
- } else {
- VTdUnitInfo->PciDeviceInfo.IncludeAllFlag = FALSE;
- DEBUG ((DEBUG_INFO," ProcessDrhd: without INCLUDE ALL\n"));
- }
+ UINTN DeviceNumber;
- VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber = 0;
- VTdUnitInfo->PciDeviceInfo.PciDeviceDataMaxNumber = 0;
- VTdUnitInfo->PciDeviceInfo.PciDeviceDataPageSize = 0;
- VTdUnitInfo->PciDeviceInfo.PciDeviceData = 0;
+ DEBUG ((DEBUG_INFO," PEI RMRR (Base 0x%016lx, Limit 0x%016lx)\n", DmarRmrr->ReservedMemoryRegionBaseAddress, DmarRmrr->ReservedMemoryRegionLimitAddress));
- DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN) (DmarDrhd + 1));
- while ((UINTN)DmarDevScopeEntry < (UINTN) DmarDrhd + DmarDrhd->Header.Length) {
+ DeviceNumber = 0;
- Status = GetPciBusDeviceFunction (DmarDrhd->SegmentNumber, DmarDevScopeEntry, &Bus, &Device, &Function);
- if (EFI_ERROR (Status)) {
- return;
- }
+ if ((DmarRmrr->ReservedMemoryRegionBaseAddress == 0) ||
+ (DmarRmrr->ReservedMemoryRegionLimitAddress == 0)) {
+ return DeviceNumber;
+ }
- DEBUG ((DEBUG_INFO," ProcessDrhd: "));
- switch (DmarDevScopeEntry->Type) {
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
- DEBUG ((DEBUG_INFO,"PCI Endpoint"));
- break;
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:
- DEBUG ((DEBUG_INFO,"PCI-PCI bridge"));
- break;
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC:
- DEBUG ((DEBUG_INFO,"IOAPIC"));
- break;
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET:
- DEBUG ((DEBUG_INFO,"MSI Capable HPET"));
- break;
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE:
- DEBUG ((DEBUG_INFO,"ACPI Namespace Device"));
- break;
+ DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN) (DmarRmrr + 1));
+ while ((UINTN) DmarDevScopeEntry < (UINTN) DmarRmrr + DmarRmrr->Header.Length) {
+ if (DmarDevScopeEntry->Type != EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) {
+ DEBUG ((DEBUG_INFO,"RMRR DevScopeEntryType is not endpoint, type[0x%x] \n", DmarDevScopeEntry->Type));
+ return DeviceNumber;
}
- DEBUG ((DEBUG_INFO," S%04x B%02x D%02x F%02x\n", DmarDrhd->SegmentNumber, Bus, Device, Function));
-
- SourceId.Bits.Bus = Bus;
- SourceId.Bits.Device = Device;
- SourceId.Bits.Function = Function;
- Status = RegisterPciDevice (VTdUnitInfo, DmarDrhd->SegmentNumber, SourceId, DmarDevScopeEntry->Type, TRUE);
+ Status = GetPciBusDeviceFunction (DmarRmrr->SegmentNumber, DmarDevScopeEntry, &Bus, &Device, &Function);
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR,"RegisterPciDevice Failed !\n"));
+ continue;
}
- DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN) DmarDevScopeEntry + DmarDevScopeEntry->Length);
- }
-}
-
-/**
- Dump the PCI device information managed by this VTd engine.
-
- @param[in] VTdInfo The VTd engine context information.
- @param[in] VtdIndex The index of VTd engine.
-
-**/
-VOID
-DumpPciDeviceInfo (
- IN VTD_INFO *VTdInfo,
- IN UINTN VtdIndex
- )
-{
- UINTN Index;
- PEI_PCI_DEVICE_DATA *PciDeviceDataBase;
-
- DEBUG ((DEBUG_INFO,"PCI Device Information (Number 0x%x, IncludeAll - %d):\n",
- VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.PciDeviceDataNumber,
- VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.IncludeAllFlag
- ));
+ DEBUG ((DEBUG_INFO,"RMRR S%04x B%02x D%02x F%02x\n", DmarRmrr->SegmentNumber, Bus, Device, Function));
- PciDeviceDataBase = (PEI_PCI_DEVICE_DATA *) (UINTN) VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.PciDeviceData;
+ DeviceNumber++;
- for (Index = 0; Index < VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; Index++) {
- DEBUG ((DEBUG_INFO," S%04x B%02x D%02x F%02x\n",
- VTdInfo->VtdUnitInfo[VtdIndex].Segment,
- PciDeviceDataBase[Index].PciSourceId.Bits.Bus,
- PciDeviceDataBase[Index].PciSourceId.Bits.Device,
- PciDeviceDataBase[Index].PciSourceId.Bits.Function
- ));
+ DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN) DmarDevScopeEntry + DmarDevScopeEntry->Length);
}
+
+ return DeviceNumber;
}
/**
- Parse DMAR DRHD table.
+ Get VTd DMAR RMRR device number.
@param[in] AcpiDmarTable DMAR ACPI table
- @return EFI_SUCCESS The DMAR DRHD table is parsed.
-
+ @return the device number
**/
-EFI_STATUS
-ParseDmarAcpiTableDrhd (
- IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
+UINTN
+GetVtdRmrrDeviceNumber (
+ IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
)
{
- EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
- UINTN VtdUnitNumber;
- UINTN VtdIndex;
- VTD_INFO *VTdInfo;
-
- VtdUnitNumber = GetVtdEngineNumber (AcpiDmarTable);
- if (VtdUnitNumber == 0) {
- return EFI_UNSUPPORTED;
- }
+ UINTN DeviceNumber;
+ EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
- VTdInfo = BuildGuidHob (&mVTdInfoGuid, sizeof (VTD_INFO) + (VtdUnitNumber - 1) * sizeof (VTD_UNIT_INFO));
- ASSERT(VTdInfo != NULL);
- if (VTdInfo == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Initialize the engine mask to all.
- //
- VTdInfo->AcpiDmarTable = (UINT32) (UINTN) AcpiDmarTable;
- VTdInfo->HostAddressWidth = AcpiDmarTable->HostAddressWidth;
- VTdInfo->VTdEngineCount = (UINT32) VtdUnitNumber;
+ DeviceNumber = 0;
- VtdIndex = 0;
DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) (AcpiDmarTable + 1));
while ((UINTN) DmarHeader < (UINTN) AcpiDmarTable + AcpiDmarTable->Header.Length) {
switch (DmarHeader->Type) {
- case EFI_ACPI_DMAR_TYPE_DRHD:
- ASSERT (VtdIndex < VtdUnitNumber);
- ProcessDrhd (&VTdInfo->VtdUnitInfo[VtdIndex], (EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader);
- VtdIndex++;
-
+ case EFI_ACPI_DMAR_TYPE_RMRR:
+ DeviceNumber += ProcessRmrrGetDeviceNumber ((EFI_ACPI_DMAR_RMRR_HEADER *) DmarHeader);
break;
-
default:
break;
}
DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) DmarHeader + DmarHeader->Length);
}
- ASSERT (VtdIndex == VtdUnitNumber);
-
- for (VtdIndex = 0; VtdIndex < VtdUnitNumber; VtdIndex++) {
- DumpPciDeviceInfo (VTdInfo, VtdIndex);
- }
-
- return EFI_SUCCESS;
+ return DeviceNumber;
}
-
/**
- Process DMAR RMRR table.
+ Parse RMRR table.
- @param[in] VTdInfo The VTd engine context information.
- @param[in] DmarRmrr The RMRR table.
+ @param[in] DmarRmrr RMRR table
+ @param[out] RmrrInfo The VTd RMRR information.
+
+ @return EFI_SUCCESS The DMAR DRHD table is parsed.
**/
VOID
ProcessRmrr (
- IN VTD_INFO *VTdInfo,
- IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr
+ IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr,
+ OUT VTD_RMRR_INFO *RmrrInfo
)
{
EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry;
@@ -746,7 +552,7 @@ ProcessRmrr (
UINT8 Device;
UINT8 Function;
EFI_STATUS Status;
- VTD_SOURCE_ID SourceId;
+ UINTN DeviceIndex;
DEBUG ((DEBUG_INFO," PEI RMRR (Base 0x%016lx, Limit 0x%016lx)\n", DmarRmrr->ReservedMemoryRegionBaseAddress, DmarRmrr->ReservedMemoryRegionLimitAddress));
@@ -755,6 +561,11 @@ ProcessRmrr (
return ;
}
+ RmrrInfo->SegmentNumber = DmarRmrr->SegmentNumber;
+ RmrrInfo->ReservedMemoryRegionBaseAddress = DmarRmrr->ReservedMemoryRegionBaseAddress;
+ RmrrInfo->ReservedMemoryRegionLimitAddress = DmarRmrr->ReservedMemoryRegionLimitAddress;
+ DeviceIndex = 0;
+
DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN) (DmarRmrr + 1));
while ((UINTN) DmarDevScopeEntry < (UINTN) DmarRmrr + DmarRmrr->Header.Length) {
if (DmarDevScopeEntry->Type != EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) {
@@ -766,50 +577,39 @@ ProcessRmrr (
if (EFI_ERROR (Status)) {
continue;
}
+ ASSERT (DeviceIndex < RmrrInfo->DeviceNumber);
DEBUG ((DEBUG_INFO,"RMRR S%04x B%02x D%02x F%02x\n", DmarRmrr->SegmentNumber, Bus, Device, Function));
- SourceId.Bits.Bus = Bus;
- SourceId.Bits.Device = Device;
- SourceId.Bits.Function = Function;
-
- Status = EnableRmrrPageAttribute (
- VTdInfo,
- DmarRmrr->SegmentNumber,
- SourceId,
- DmarRmrr->ReservedMemoryRegionBaseAddress,
- DmarRmrr->ReservedMemoryRegionLimitAddress,
- EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "EnableRmrrPageAttribute : %r\n", Status));
- }
+ RmrrInfo->SourceId[DeviceIndex].Bits.Bus = Bus;
+ RmrrInfo->SourceId[DeviceIndex].Bits.Device = Device;
+ RmrrInfo->SourceId[DeviceIndex].Bits.Function = Function;
+ DeviceIndex++;
DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN) DmarDevScopeEntry + DmarDevScopeEntry->Length);
}
}
/**
- Parse DMAR DRHD table.
+ Parse DMAR RMRR table.
- @param[in] VTdInfo The VTd engine context information.
+ @param[in] AcpiDmarTable DMAR ACPI table
+ @param[out] RmrrInfo The VTd RMRR information.
**/
VOID
-ParseDmarAcpiTableRmrr (
- IN VTD_INFO *VTdInfo
+ParseRmrrDmarAcpiTable (
+ IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable,
+ OUT VTD_RMRR_INFO *RmrrInfo
)
{
- EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
- AcpiDmarTable = (EFI_ACPI_DMAR_HEADER *) (UINTN) VTdInfo->AcpiDmarTable;
-
DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) (AcpiDmarTable + 1));
while ((UINTN) DmarHeader < (UINTN) AcpiDmarTable + AcpiDmarTable->Header.Length) {
switch (DmarHeader->Type) {
case EFI_ACPI_DMAR_TYPE_RMRR:
- ProcessRmrr (VTdInfo, (EFI_ACPI_DMAR_RMRR_HEADER *) DmarHeader);
+ ProcessRmrr ((EFI_ACPI_DMAR_RMRR_HEADER *) DmarHeader, RmrrInfo);
break;
default:
break;
@@ -818,3 +618,36 @@ ParseDmarAcpiTableRmrr (
}
}
+/**
+ Get RMRR Info from ACPI DMAR Table.
+
+ @param[in] AcpiDmarTable DMAR ACPI table
+
+ @return the VTd engine number.
+**/
+VTD_RMRR_INFO *
+GetVtdRmrrInfo (
+ IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
+ )
+{
+ UINTN DeviceNumber;
+ VTD_RMRR_INFO *RmrrInfo;
+ UINTN InfoSize;
+
+ RmrrInfo = NULL;
+ DeviceNumber = GetVtdRmrrDeviceNumber (AcpiDmarTable);
+
+ if (DeviceNumber > 0) {
+ InfoSize = sizeof (VTD_RMRR_INFO) - sizeof (VTD_SOURCE_ID) + sizeof (VTD_SOURCE_ID) * DeviceNumber;
+ RmrrInfo = (VTD_RMRR_INFO *) AllocateZeroPages (EFI_SIZE_TO_PAGES (InfoSize));
+ if (RmrrInfo == NULL) {
+ DEBUG ((DEBUG_ERROR, "GetVtdRmrrInfo - OUT_OF_RESOURCE\n"));
+ ASSERT (FALSE);
+ return NULL;
+ }
+
+ RmrrInfo->DeviceNumber = DeviceNumber;
+ ParseRmrrDmarAcpiTable (AcpiDmarTable, RmrrInfo);
+ }
+ return RmrrInfo;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c
index 63397a1a..b51b38a0 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -79,77 +79,73 @@ PerpareCacheInvalidationInterface (
IN VTD_UNIT_INFO *VTdUnitInfo
)
{
- UINT16 QueueSize;
+ UINT16 QiDescLength;
UINT64 Reg64;
UINT32 Reg32;
VTD_ECAP_REG ECapReg;
+ UINTN VtdUnitBaseAddress;
+ VtdUnitBaseAddress = VTdUnitInfo->VtdUnitBaseAddress;
- if (VTdUnitInfo->VerReg.Bits.Major <= 6) {
+ if (VTdUnitInfo->VerReg.Bits.Major <= 5) {
VTdUnitInfo->EnableQueuedInvalidation = 0;
- DEBUG ((DEBUG_INFO, "Use Register-based Invalidation Interface for engine [0x%x]\n", VTdUnitInfo->VtdUnitBaseAddress));
+ DEBUG ((DEBUG_INFO, "Use Register-based Invalidation Interface for engine [0x%x]\n", VtdUnitBaseAddress));
return EFI_SUCCESS;
}
- ECapReg.Uint64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_ECAP_REG);
+ ECapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_ECAP_REG);
if (ECapReg.Bits.QI == 0) {
- DEBUG ((DEBUG_ERROR, "Hardware does not support queued invalidations interface for engine [0x%x]\n", VTdUnitInfo->VtdUnitBaseAddress));
+ DEBUG ((DEBUG_ERROR, "Hardware does not support queued invalidations interface for engine [0x%x]\n", VtdUnitBaseAddress));
return EFI_UNSUPPORTED;
}
VTdUnitInfo->EnableQueuedInvalidation = 1;
- DEBUG ((DEBUG_INFO, "Use Queued Invalidation Interface for engine [0x%x]\n", VTdUnitInfo->VtdUnitBaseAddress));
+ DEBUG ((DEBUG_INFO, "Use Queued Invalidation Interface for engine [0x%x]\n", VtdUnitBaseAddress));
- Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
if ((Reg32 & B_GSTS_REG_QIES) != 0) {
DEBUG ((DEBUG_INFO,"Queued Invalidation Interface was enabled.\n"));
Reg32 &= (~B_GSTS_REG_QIES);
- MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg32);
+ MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32);
do {
- Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
} while ((Reg32 & B_GSTS_REG_QIES) != 0);
- MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQA_REG, 0);
-
- if (VTdUnitInfo->QiDesc != NULL) {
- FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * VTdUnitInfo->QiDescLength));
- VTdUnitInfo->QiDesc = NULL;
- VTdUnitInfo->QiDescLength = 0;
- }
+ MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, 0);
}
//
// Initialize the Invalidation Queue Tail Register to zero.
//
- MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQT_REG, 0);
+ MmioWrite64 (VtdUnitBaseAddress + R_IQT_REG, 0);
//
// Setup the IQ address, size and descriptor width through the Invalidation Queue Address Register
//
- QueueSize = 0;
- VTdUnitInfo->QiDescLength = 1 << (QueueSize + 8);
- VTdUnitInfo->QiDesc = (QI_DESC *) AllocatePages (EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * VTdUnitInfo->QiDescLength));
-
if (VTdUnitInfo->QiDesc == NULL) {
- VTdUnitInfo->QiDescLength = 0;
- DEBUG ((DEBUG_ERROR,"Could not Alloc Invalidation Queue Buffer.\n"));
- return EFI_OUT_OF_RESOURCES;
+ VTdUnitInfo->QueueSize = 0;
+ QiDescLength = 1 << (VTdUnitInfo->QueueSize + 8);
+ VTdUnitInfo->QiDesc = (QI_DESC *) AllocatePages (EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * QiDescLength));
+ if (VTdUnitInfo->QiDesc == NULL) {
+ DEBUG ((DEBUG_ERROR,"Could not Alloc Invalidation Queue Buffer.\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
}
- DEBUG ((DEBUG_INFO, "Invalidation Queue Length : %d\n", VTdUnitInfo->QiDescLength));
- Reg64 = (UINT64)(UINTN)VTdUnitInfo->QiDesc;
- Reg64 |= QueueSize;
- MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQA_REG, Reg64);
+ DEBUG ((DEBUG_INFO, "Invalidation Queue Length : %d\n", QiDescLength));
+ Reg64 = (UINT64) (UINTN) VTdUnitInfo->QiDesc;
+ Reg64 |= VTdUnitInfo->QueueSize;
+ MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, Reg64);
//
// Enable the queued invalidation interface through the Global Command Register.
// When enabled, hardware sets the QIES field in the Global Status Register.
//
- Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
Reg32 |= B_GMCD_REG_QIE;
- MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg32);
+ MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32);
DEBUG ((DEBUG_INFO, "Enable Queued Invalidation Interface. GCMD_REG = 0x%x\n", Reg32));
do {
- Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
} while ((Reg32 & B_GSTS_REG_QIES) == 0);
VTdUnitInfo->QiFreeHead = 0;
@@ -167,21 +163,23 @@ DisableQueuedInvalidationInterface (
IN VTD_UNIT_INFO *VTdUnitInfo
)
{
- UINT32 Reg32;
+ UINT32 Reg32;
+ UINT16 QiDescLength;
if (VTdUnitInfo->EnableQueuedInvalidation != 0) {
- Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);
+ Reg32 = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);
Reg32 &= (~B_GMCD_REG_QIE);
- MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg32);
+ MmioWrite32 (VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg32);
DEBUG ((DEBUG_INFO, "Disable Queued Invalidation Interface. GCMD_REG = 0x%x\n", Reg32));
do {
- Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);
+ Reg32 = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);
} while ((Reg32 & B_GSTS_REG_QIES) != 0);
if (VTdUnitInfo->QiDesc != NULL) {
- FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * VTdUnitInfo->QiDescLength));
+ QiDescLength = 1 << (VTdUnitInfo->QueueSize + 8);
+ FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * QiDescLength));
VTdUnitInfo->QiDesc = NULL;
- VTdUnitInfo->QiDescLength = 0;
+ VTdUnitInfo->QueueSize = 0;
}
VTdUnitInfo->EnableQueuedInvalidation = 0;
@@ -203,26 +201,11 @@ QueuedInvalidationCheckFault (
{
UINT32 FaultReg;
- FaultReg = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG);
-
- if (FaultReg & B_FSTS_REG_IQE) {
- DEBUG((DEBUG_ERROR, "Detect Invalidation Queue Error [0x%08x]\n", FaultReg));
- FaultReg |= B_FSTS_REG_IQE;
- MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG, FaultReg);
- return RETURN_DEVICE_ERROR;
- }
-
- if (FaultReg & B_FSTS_REG_ITE) {
- DEBUG((DEBUG_ERROR, "Detect Invalidation Time-out Error [0x%08x]\n", FaultReg));
- FaultReg |= B_FSTS_REG_ITE;
- MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG, FaultReg);
- return RETURN_DEVICE_ERROR;
- }
-
- if (FaultReg & B_FSTS_REG_ICE) {
- DEBUG((DEBUG_ERROR, "Detect Invalidation Completion Error [0x%08x]\n", FaultReg));
- FaultReg |= B_FSTS_REG_ICE;
- MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG, FaultReg);
+ FaultReg = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG);
+ if (FaultReg & (B_FSTS_REG_IQE | B_FSTS_REG_ITE | B_FSTS_REG_ICE)) {
+ DEBUG((DEBUG_ERROR, "Detect Queue Invalidation Error [0x%08x]\n", FaultReg));
+ FaultReg |= (B_FSTS_REG_IQE | B_FSTS_REG_ITE | B_FSTS_REG_ICE);
+ MmioWrite32 (VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG, FaultReg);
return RETURN_DEVICE_ERROR;
}
@@ -256,7 +239,7 @@ SubmitQueuedInvalidationDescriptor (
return EFI_INVALID_PARAMETER;
}
- QiDescLength = VTdUnitInfo->QiDescLength;
+ QiDescLength = 1 << (VTdUnitInfo->QueueSize + 8);
BaseDesc = VTdUnitInfo->QiDesc;
DEBUG((DEBUG_INFO, "[0x%x] Submit QI Descriptor [0x%08x, 0x%08x]\n", VTdUnitInfo->VtdUnitBaseAddress, Desc->Low, Desc->High));
@@ -268,12 +251,12 @@ SubmitQueuedInvalidationDescriptor (
DEBUG((DEBUG_INFO,"QI Free Head=0x%x\n", VTdUnitInfo->QiFreeHead));
VTdUnitInfo->QiFreeHead = (VTdUnitInfo->QiFreeHead + 1) % QiDescLength;
- Reg64Iqh = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQH_REG);
+ Reg64Iqh = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_IQH_REG);
//
// Update the HW tail register indicating the presence of new descriptors.
//
Reg64Iqt = VTdUnitInfo->QiFreeHead << DMAR_IQ_SHIFT;
- MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQT_REG, Reg64Iqt);
+ MmioWrite64 (VTdUnitInfo->VtdUnitBaseAddress + R_IQT_REG, Reg64Iqt);
Status = EFI_SUCCESS;
do {
@@ -283,7 +266,7 @@ SubmitQueuedInvalidationDescriptor (
break;
}
- Reg64Iqh = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQH_REG);
+ Reg64Iqh = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_IQH_REG);
} while (Reg64Iqt != Reg64Iqh);
DEBUG((DEBUG_ERROR,"SubmitQueuedInvalidationDescriptor end\n"));
@@ -307,18 +290,18 @@ InvalidateContextCache (
//
// Register-based Invalidation
//
- Reg64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_CCMD_REG);
+ Reg64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_CCMD_REG);
if ((Reg64 & B_CCMD_REG_ICC) != 0) {
- DEBUG ((DEBUG_ERROR,"ERROR: InvalidateContextCache: B_CCMD_REG_ICC is set for VTD(%x)\n", (UINTN)VTdUnitInfo->VtdUnitBaseAddress));
+ DEBUG ((DEBUG_ERROR,"ERROR: InvalidateContextCache: B_CCMD_REG_ICC is set for VTD(%x)\n", VTdUnitInfo->VtdUnitBaseAddress));
return EFI_DEVICE_ERROR;
}
Reg64 &= ((~B_CCMD_REG_ICC) & (~B_CCMD_REG_CIRG_MASK));
Reg64 |= (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_GLOBAL);
- MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_CCMD_REG, Reg64);
+ MmioWrite64 (VTdUnitInfo->VtdUnitBaseAddress + R_CCMD_REG, Reg64);
do {
- Reg64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_CCMD_REG);
+ Reg64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_CCMD_REG);
} while ((Reg64 & B_CCMD_REG_ICC) != 0);
} else {
//
@@ -351,26 +334,26 @@ InvalidateIOTLB (
//
// Register-based Invalidation
//
- ECapReg.Uint64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_ECAP_REG);
+ ECapReg.Uint64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_ECAP_REG);
- Reg64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
+ Reg64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
if ((Reg64 & B_IOTLB_REG_IVT) != 0) {
- DEBUG ((DEBUG_ERROR, "ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is set for VTD(%x)\n", (UINTN)VTdUnitInfo->VtdUnitBaseAddress));
+ DEBUG ((DEBUG_ERROR, "ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is set for VTD(%x)\n", VTdUnitInfo->VtdUnitBaseAddress));
return EFI_DEVICE_ERROR;
}
Reg64 &= ((~B_IOTLB_REG_IVT) & (~B_IOTLB_REG_IIRG_MASK));
Reg64 |= (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_GLOBAL);
- MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + (ECapReg.Bits.IRO * 16) + R_IOTLB_REG, Reg64);
+ MmioWrite64 (VTdUnitInfo->VtdUnitBaseAddress + (ECapReg.Bits.IRO * 16) + R_IOTLB_REG, Reg64);
do {
- Reg64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
+ Reg64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + (ECapReg.Bits.IRO * 16) + R_IOTLB_REG);
} while ((Reg64 & B_IOTLB_REG_IVT) != 0);
} else {
//
// Queued Invalidation
//
- ECapReg.Uint64 = MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_ECAP_REG);
+ ECapReg.Uint64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_ECAP_REG);
QiDesc.Low = QI_IOTLB_DID(0) | QI_IOTLB_DR(CAP_READ_DRAIN(ECapReg.Uint64)) | QI_IOTLB_DW(CAP_WRITE_DRAIN(ECapReg.Uint64)) | QI_IOTLB_GRAN(1) | QI_IOTLB_TYPE;
QiDesc.High = QI_IOTLB_ADDR(0) | QI_IOTLB_IH(0) | QI_IOTLB_AM(0);
@@ -392,14 +375,14 @@ InvalidateIOTLB (
EFI_STATUS
EnableDmarPreMem (
IN UINTN VtdUnitBaseAddress,
- IN UINTN RtaddrRegValue
+ IN UINT64 RtaddrRegValue
)
{
UINT32 Reg32;
DEBUG ((DEBUG_INFO, ">>>>>>EnableDmarPreMem() for engine [%x] \n", VtdUnitBaseAddress));
- DEBUG ((DEBUG_INFO, "RTADDR_REG : 0x%x \n", RtaddrRegValue));
+ DEBUG ((DEBUG_INFO, "RTADDR_REG : 0x%016lx \n", RtaddrRegValue));
MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64) RtaddrRegValue);
Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
@@ -452,30 +435,33 @@ EnableDmar (
)
{
UINT32 Reg32;
+ UINTN VtdUnitBaseAddress;
- DEBUG ((DEBUG_INFO, ">>>>>>EnableDmar() for engine [%x] \n", VTdUnitInfo->VtdUnitBaseAddress));
+ VtdUnitBaseAddress = VTdUnitInfo->VtdUnitBaseAddress;
+
+ DEBUG ((DEBUG_INFO, ">>>>>>EnableDmar() for engine [%x] \n", VtdUnitBaseAddress));
DEBUG ((DEBUG_INFO, "RootEntryTable 0x%x \n", RootEntryTable));
- MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_RTADDR_REG, (UINT64) (UINTN) RootEntryTable);
+ MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64) RootEntryTable);
- Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);
- MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_SRTP);
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
+ MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_SRTP);
DEBUG ((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n"));
do {
- Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
} while((Reg32 & B_GSTS_REG_RTPS) == 0);
DEBUG ((DEBUG_INFO, "EnableDmar: R_GSTS_REG = 0x%x \n", Reg32));
//
// Init DMAr Fault Event and Data registers
//
- Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FEDATA_REG);
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_FEDATA_REG);
//
// Write Buffer Flush before invalidation
//
- FlushWriteBuffer ((UINTN)VTdUnitInfo->VtdUnitBaseAddress);
+ FlushWriteBuffer (VtdUnitBaseAddress);
//
// Invalidate the context cache
@@ -490,11 +476,11 @@ EnableDmar (
//
// Enable VTd
//
- Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);
- MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_TE);
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
+ MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_TE);
DEBUG ((DEBUG_INFO, "EnableDmar: Waiting B_GSTS_REG_TE ...\n"));
do {
- Reg32 = MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);
+ Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);
} while ((Reg32 & B_GSTS_REG_TE) == 0);
DEBUG ((DEBUG_INFO, "VTD () enabled!<<<<<<\n"));
@@ -566,139 +552,52 @@ DisableDmar (
}
/**
- Dump VTd version registers.
+ Enable VTd translation table protection for block DMA
- @param[in] VerReg The version register.
-**/
-VOID
-DumpVtdVerRegs (
- IN VTD_VER_REG *VerReg
- )
-{
- DEBUG ((DEBUG_INFO, " VerReg:\n", VerReg->Uint32));
- DEBUG ((DEBUG_INFO, " Major - 0x%x\n", VerReg->Bits.Major));
- DEBUG ((DEBUG_INFO, " Minor - 0x%x\n", VerReg->Bits.Minor));
-}
-
-/**
- Dump VTd capability registers.
-
- @param[in] CapReg The capability register.
-**/
-VOID
-DumpVtdCapRegs (
- IN VTD_CAP_REG *CapReg
- )
-{
- DEBUG ((DEBUG_INFO, " CapReg:\n", CapReg->Uint64));
- DEBUG ((DEBUG_INFO, " ND - 0x%x\n", CapReg->Bits.ND));
- DEBUG ((DEBUG_INFO, " AFL - 0x%x\n", CapReg->Bits.AFL));
- DEBUG ((DEBUG_INFO, " RWBF - 0x%x\n", CapReg->Bits.RWBF));
- DEBUG ((DEBUG_INFO, " PLMR - 0x%x\n", CapReg->Bits.PLMR));
- DEBUG ((DEBUG_INFO, " PHMR - 0x%x\n", CapReg->Bits.PHMR));
- DEBUG ((DEBUG_INFO, " CM - 0x%x\n", CapReg->Bits.CM));
- DEBUG ((DEBUG_INFO, " SAGAW - 0x%x\n", CapReg->Bits.SAGAW));
- DEBUG ((DEBUG_INFO, " MGAW - 0x%x\n", CapReg->Bits.MGAW));
- DEBUG ((DEBUG_INFO, " ZLR - 0x%x\n", CapReg->Bits.ZLR));
- DEBUG ((DEBUG_INFO, " FRO - 0x%x\n", CapReg->Bits.FRO));
- DEBUG ((DEBUG_INFO, " SLLPS - 0x%x\n", CapReg->Bits.SLLPS));
- DEBUG ((DEBUG_INFO, " PSI - 0x%x\n", CapReg->Bits.PSI));
- DEBUG ((DEBUG_INFO, " NFR - 0x%x\n", CapReg->Bits.NFR));
- DEBUG ((DEBUG_INFO, " MAMV - 0x%x\n", CapReg->Bits.MAMV));
- DEBUG ((DEBUG_INFO, " DWD - 0x%x\n", CapReg->Bits.DWD));
- DEBUG ((DEBUG_INFO, " DRD - 0x%x\n", CapReg->Bits.DRD));
- DEBUG ((DEBUG_INFO, " FL1GP - 0x%x\n", CapReg->Bits.FL1GP));
- DEBUG ((DEBUG_INFO, " PI - 0x%x\n", CapReg->Bits.PI));
-}
+ @param[in] VtdUnitBaseAddress The base address of the VTd engine.
-/**
- Dump VTd extended capability registers.
-
- @param[in] ECapReg The extended capability register.
+ @retval EFI_SUCCESS DMAR translation is enabled.
+ @retval EFI_DEVICE_ERROR DMAR translation is not enabled.
**/
-VOID
-DumpVtdECapRegs (
- IN VTD_ECAP_REG *ECapReg
- )
-{
- DEBUG ((DEBUG_INFO, " ECapReg:\n", ECapReg->Uint64));
- DEBUG ((DEBUG_INFO, " C - 0x%x\n", ECapReg->Bits.C));
- DEBUG ((DEBUG_INFO, " QI - 0x%x\n", ECapReg->Bits.QI));
- DEBUG ((DEBUG_INFO, " DT - 0x%x\n", ECapReg->Bits.DT));
- DEBUG ((DEBUG_INFO, " IR - 0x%x\n", ECapReg->Bits.IR));
- DEBUG ((DEBUG_INFO, " EIM - 0x%x\n", ECapReg->Bits.EIM));
- DEBUG ((DEBUG_INFO, " PT - 0x%x\n", ECapReg->Bits.PT));
- DEBUG ((DEBUG_INFO, " SC - 0x%x\n", ECapReg->Bits.SC));
- DEBUG ((DEBUG_INFO, " IRO - 0x%x\n", ECapReg->Bits.IRO));
- DEBUG ((DEBUG_INFO, " MHMV - 0x%x\n", ECapReg->Bits.MHMV));
- DEBUG ((DEBUG_INFO, " MTS - 0x%x\n", ECapReg->Bits.MTS));
- DEBUG ((DEBUG_INFO, " NEST - 0x%x\n", ECapReg->Bits.NEST));
- DEBUG ((DEBUG_INFO, " PASID - 0x%x\n", ECapReg->Bits.PASID));
- DEBUG ((DEBUG_INFO, " PRS - 0x%x\n", ECapReg->Bits.PRS));
- DEBUG ((DEBUG_INFO, " ERS - 0x%x\n", ECapReg->Bits.ERS));
- DEBUG ((DEBUG_INFO, " SRS - 0x%x\n", ECapReg->Bits.SRS));
- DEBUG ((DEBUG_INFO, " NWFS - 0x%x\n", ECapReg->Bits.NWFS));
- DEBUG ((DEBUG_INFO, " EAFS - 0x%x\n", ECapReg->Bits.EAFS));
- DEBUG ((DEBUG_INFO, " PSS - 0x%x\n", ECapReg->Bits.PSS));
- DEBUG ((DEBUG_INFO, " ADMS - 0x%x\n", ECapReg->Bits.ADMS));
-}
-
-
-/**
- Enable VTd translation table protection for all.
-
- @param[in] VTdInfo The VTd engine context information.
- @param[in] EngineMask The mask of the VTd engine to be accessed.
-**/
-VOID
-EnableVTdTranslationProtectionAll (
- IN VTD_INFO *VTdInfo,
- IN UINT64 EngineMask
+EFI_STATUS
+EnableVTdTranslationProtectionBlockDma (
+ IN UINTN VtdUnitBaseAddress
)
{
- EFI_STATUS Status;
- EDKII_VTD_NULL_ROOT_ENTRY_TABLE_PPI *RootEntryTable;
- UINTN Index;
+ EFI_STATUS Status;
+ VTD_ECAP_REG ECapReg;
+ EDKII_VTD_NULL_ROOT_ENTRY_TABLE_PPI *RootEntryTable;
- DEBUG ((DEBUG_INFO, "EnableVTdTranslationProtectionAll - 0x%lx\n", EngineMask));
+ DEBUG ((DEBUG_INFO, "EnableVTdTranslationProtectionBlockDma - 0x%08x\n", VtdUnitBaseAddress));
- for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
- if ((EngineMask & LShiftU64(1, Index)) == 0) {
- continue;
- }
+ ECapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_ECAP_REG);
+ DEBUG ((DEBUG_INFO, "ECapReg : 0%016lx\n", ECapReg.Uint64));
- VTdInfo->VtdUnitInfo[Index].VerReg.Uint32 = MmioRead32 (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress + R_VER_REG);
- DumpVtdVerRegs (&VTdInfo->VtdUnitInfo[Index].VerReg);
- VTdInfo->VtdUnitInfo[Index].CapReg.Uint64 = MmioRead64 (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress + R_CAP_REG);
- DumpVtdCapRegs (&VTdInfo->VtdUnitInfo[Index].CapReg);
- VTdInfo->VtdUnitInfo[Index].ECapReg.Uint64 = MmioRead64 (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress + R_ECAP_REG);
- DumpVtdECapRegs (&VTdInfo->VtdUnitInfo[Index].ECapReg);
-
- if (VTdInfo->VtdUnitInfo[Index].ECapReg.Bits.ADMS == 1) {
- //
- // Use Abort DMA Mode
- //
- Status = EnableDmarPreMem (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress, V_RTADDR_REG_TTM_ADM);
- } else {
- //
- // Use Null Root Entry Table
- //
- Status = PeiServicesLocatePpi (
- &gEdkiiVTdNullRootEntryTableGuid,
- 0,
- NULL,
- (VOID **)&RootEntryTable
- );
- if (EFI_ERROR(Status)) {
- DEBUG ((DEBUG_ERROR, "Locate Null Root Entry Table Ppi Failed : %r\n", Status));
- ASSERT (FALSE);
- return;
- }
- EnableDmarPreMem (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress, (UINTN) *RootEntryTable);
+ if (ECapReg.Bits.ADMS == 1) {
+ //
+ // Use Abort DMA Mode
+ //
+ DEBUG ((DEBUG_INFO, "Enable abort DMA mode.\n"));
+ Status = EnableDmarPreMem (VtdUnitBaseAddress, V_RTADDR_REG_TTM_ADM);
+ } else {
+ //
+ // Use Null Root Entry Table
+ //
+ Status = PeiServicesLocatePpi (
+ &gEdkiiVTdNullRootEntryTableGuid,
+ 0,
+ NULL,
+ (VOID **)&RootEntryTable
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, "Locate Null Root Entry Table Ppi Failed : %r\n", Status));
+ ASSERT (FALSE);
+ return EFI_DEVICE_ERROR;
}
+ Status = EnableDmarPreMem (VtdUnitBaseAddress, (UINT64) (*RootEntryTable));
}
- return;
+ return Status;
}
/**
@@ -715,18 +614,25 @@ EnableVTdTranslationProtection (
)
{
EFI_STATUS Status;
- UINTN VtdIndex;
+ UINTN Index;
+ VTD_UNIT_INFO *VtdUnitInfo;
- for (VtdIndex = 0; VtdIndex < VTdInfo->VTdEngineCount; VtdIndex++) {
- if (VTdInfo->VtdUnitInfo[VtdIndex].ExtRootEntryTable != 0) {
- DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) ExtRootEntryTable 0x%x\n", VtdIndex, VTdInfo->VtdUnitInfo[VtdIndex].ExtRootEntryTable));
- Status = EnableDmar (&VTdInfo->VtdUnitInfo[VtdIndex], VTdInfo->VtdUnitInfo[VtdIndex].ExtRootEntryTable);
+ for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
+ VtdUnitInfo = &VTdInfo->VtdUnitInfo[Index];
+ if (VtdUnitInfo->Done) {
+ DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) was enabled\n", Index));
+ continue;
+ }
+
+ if (VtdUnitInfo->ExtRootEntryTable != 0) {
+ DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) ExtRootEntryTable 0x%x\n", Index, VtdUnitInfo->ExtRootEntryTable));
+ Status = EnableDmar (VtdUnitInfo, VtdUnitInfo->ExtRootEntryTable);
} else {
- DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) RootEntryTable 0x%x\n", VtdIndex, VTdInfo->VtdUnitInfo[VtdIndex].RootEntryTable));
- Status = EnableDmar (&VTdInfo->VtdUnitInfo[VtdIndex], VTdInfo->VtdUnitInfo[VtdIndex].RootEntryTable);
+ DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) RootEntryTable 0x%x\n", Index, VtdUnitInfo->RootEntryTable));
+ Status = EnableDmar (VtdUnitInfo, VtdUnitInfo->RootEntryTable);
}
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "EnableVtdDmar (%d) Failed !\n", VtdIndex));
+ DEBUG ((DEBUG_ERROR, "EnableVtdDmar (%d) Failed !\n", Index));
return Status;
}
}
@@ -737,23 +643,22 @@ EnableVTdTranslationProtection (
Disable VTd translation table protection.
@param[in] VTdInfo The VTd engine context information.
- @param[in] EngineMask The mask of the VTd engine to be accessed.
**/
VOID
DisableVTdTranslationProtection (
- IN VTD_INFO *VTdInfo,
- IN UINT64 EngineMask
+ IN VTD_INFO *VTdInfo
)
{
UINTN Index;
- DEBUG ((DEBUG_INFO, "DisableVTdTranslationProtection - 0x%lx\n", EngineMask));
+ if (VTdInfo == NULL) {
+ return;
+ }
+
+ DEBUG ((DEBUG_INFO, "DisableVTdTranslationProtection - %d Vtd Engine\n", VTdInfo->VTdEngineCount));
for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
- if ((EngineMask & LShiftU64(1, Index)) == 0) {
- continue;
- }
- DisableDmar ((UINTN) VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress);
+ DisableDmar (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress);
DisableQueuedInvalidationInterface(&VTdInfo->VtdUnitInfo[Index]);
}
@@ -786,6 +691,36 @@ PrepareVtdCacheInvalidationConfig (
return EFI_SUCCESS;
}
+/**
+
+**/
+EFI_STATUS
+VtdCheckUsing5LevelPaging (
+ IN UINT8 HostAddressWidth,
+ IN VTD_UNIT_INFO *VtdUnitInfo,
+ OUT BOOLEAN *Is5LevelPaging
+ )
+{
+ DEBUG((DEBUG_INFO, " CapReg SAGAW bits : 0x%02x\n", VtdUnitInfo->CapReg.Bits.SAGAW));
+
+ *Is5LevelPaging = FALSE;
+ if ((VtdUnitInfo->CapReg.Bits.SAGAW & BIT3) != 0) {
+ *Is5LevelPaging = TRUE;
+ if ((HostAddressWidth <= 48) &&
+ ((VtdUnitInfo->CapReg.Bits.SAGAW & BIT2) != 0)) {
+ *Is5LevelPaging = FALSE;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ if ((VtdUnitInfo->CapReg.Bits.SAGAW & (BIT3 | BIT2)) == 0) {
+ return EFI_UNSUPPORTED;
+ }
+ DEBUG((DEBUG_INFO, " Using %d Level Paging\n", *Is5LevelPaging ? 5 : 4));
+ return EFI_SUCCESS;
+}
+
+
/**
Prepare VTD configuration.
@@ -798,43 +733,37 @@ PrepareVtdConfig (
IN VTD_INFO *VTdInfo
)
{
+ EFI_STATUS Status;
UINTN Index;
- UINTN DomainNumber;
+ VTD_UNIT_INFO *VtdUnitInfo;
+ UINTN VtdUnitBaseAddress;
for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
- DEBUG ((DEBUG_ERROR, "Dump VTd Capability (%d)\n", Index));
- VTdInfo->VtdUnitInfo[Index].VerReg.Uint32 = MmioRead32 (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress + R_VER_REG);
- DumpVtdVerRegs (&VTdInfo->VtdUnitInfo[Index].VerReg);
- VTdInfo->VtdUnitInfo[Index].CapReg.Uint64 = MmioRead64 (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress + R_CAP_REG);
- DumpVtdCapRegs (&VTdInfo->VtdUnitInfo[Index].CapReg);
- VTdInfo->VtdUnitInfo[Index].ECapReg.Uint64 = MmioRead64 (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress + R_ECAP_REG);
- DumpVtdECapRegs (&VTdInfo->VtdUnitInfo[Index].ECapReg);
-
- VTdInfo->VtdUnitInfo[Index].Is5LevelPaging = FALSE;
- if ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & BIT2) != 0) {
- DEBUG ((DEBUG_INFO, "Support 4-level page-table on VTD %d\n", Index));
- }
- if ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & BIT3) != 0) {
- DEBUG((DEBUG_INFO, "Support 5-level page-table on VTD %d\n", Index));
- VTdInfo->VtdUnitInfo[Index].Is5LevelPaging = TRUE;
-
- if ((VTdInfo->HostAddressWidth <= 48) &&
- ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & BIT2) != 0)) {
- DEBUG ((DEBUG_INFO, "Rollback to 4-level page-table on VTD %d\n", Index));
- VTdInfo->VtdUnitInfo[Index].Is5LevelPaging = FALSE;
- }
+ VtdUnitInfo = &VTdInfo->VtdUnitInfo[Index];
+ if (VtdUnitInfo->Done) {
+ continue;
}
- if ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & (BIT3 | BIT2)) == 0) {
- DEBUG ((DEBUG_ERROR, "!!!! Page-table type 0x%X is not supported on VTD %d !!!!\n", Index, VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW));
- return EFI_UNSUPPORTED;
+ VtdUnitBaseAddress = VtdUnitInfo->VtdUnitBaseAddress;
+ DEBUG((DEBUG_INFO, "VTd Engine: 0x%08X\n", VtdUnitBaseAddress));
+
+ VtdUnitInfo->VerReg.Uint32 = MmioRead32 (VtdUnitBaseAddress + R_VER_REG);
+ VtdUnitInfo->CapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_CAP_REG);
+ VtdUnitInfo->ECapReg.Uint64 = MmioRead64 (VtdUnitBaseAddress + R_ECAP_REG);
+ DEBUG((DEBUG_INFO, " VerReg : 0x%08X\n", VtdUnitInfo->VerReg.Uint32));
+ DEBUG((DEBUG_INFO, " CapReg : 0x%016lX\n", VtdUnitInfo->CapReg.Uint64));
+ DEBUG((DEBUG_INFO, " ECapReg : 0x%016lX\n", VtdUnitInfo->ECapReg.Uint64));
+
+ Status = VtdCheckUsing5LevelPaging (VTdInfo->HostAddressWidth, VtdUnitInfo, &(VtdUnitInfo->Is5LevelPaging));
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "!!!! Page-table type 0x%X is not supported!!!!\n", VtdUnitInfo->CapReg.Bits.SAGAW));
+ return Status;
}
- DomainNumber = (UINTN)1 << (UINT8) ((UINTN) VTdInfo->VtdUnitInfo[Index].CapReg.Bits.ND * 2 + 4);
- if (VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataNumber >= DomainNumber) {
- DEBUG ((DEBUG_ERROR, "!!!! Pci device Number(0x%x) >= DomainNumber(0x%x) !!!!\n", VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataNumber, DomainNumber));
- return EFI_UNSUPPORTED;
+ Status = PerpareCacheInvalidationInterface(VtdUnitInfo);
+ if (EFI_ERROR (Status)) {
+ return Status;
}
}
+
return EFI_SUCCESS;
}
-
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c
index a8f7bfee..3d38cbee 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -50,20 +50,20 @@ typedef struct {
the device driver need use SetAttribute() to update the IOMMU
attribute to request DMA access (read and/or write).
- @param[in] This The PPI instance pointer.
- @param[in] DeviceHandle The device who initiates the DMA access request.
- @param[in] Mapping The mapping value returned from Map().
- @param[in] IoMmuAccess The IOMMU access.
-
- @retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by DeviceAddress and Length.
- @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
- @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
- @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
- @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by Mapping.
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
- @retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.
- @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
- not available to be allocated yet.
+ @param[in] This The PPI instance pointer.
+ @param[in] DeviceHandle The device who initiates the DMA access request.
+ @param[in] Mapping The mapping value returned from Map().
+ @param[in] IoMmuAccess The IOMMU access.
+
+ @retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by DeviceAddress and Length.
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
+ @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.
+ @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.
+ @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by Mapping.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.
+ @retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.
+ @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
+ not available to be allocated yet.
**/
EFI_STATUS
EFIAPI
@@ -93,22 +93,22 @@ PeiIoMmuSetAttribute (
Provides the controller-specific addresses required to access system memory from a
DMA bus master.
- @param This The PPI instance pointer.
- @param Operation Indicates if the bus master is going to read or write to system memory.
- @param HostAddress The system memory address to map to the PCI controller.
- @param NumberOfBytes On input the number of bytes to map. On output the number of bytes
- that were mapped.
- @param DeviceAddress The resulting map address for the bus master PCI controller to use to
- access the hosts HostAddress.
- @param Mapping A resulting value to pass to Unmap().
-
- @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
- @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
- @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
- @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
- not available to be allocated yet.
+ @param [in] This The PPI instance pointer.
+ @param [in] Operation Indicates if the bus master is going to read or write to system memory.
+ @param [in] HostAddress The system memory address to map to the PCI controller.
+ @param [in] [out] NumberOfBytes On input the number of bytes to map. On output the number of bytes
+ that were mapped.
+ @param [out] DeviceAddress The resulting map address for the bus master PCI controller to use to
+ access the hosts HostAddress.
+ @param [out] Mapping A resulting value to pass to Unmap().
+
+ @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
+ @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
+ @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
+ not available to be allocated yet.
**/
EFI_STATUS
EFIAPI
@@ -140,7 +140,7 @@ PeiIoMmuMap (
if (Operation == EdkiiIoMmuOperationBusMasterCommonBuffer ||
Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) {
- *DeviceAddress = (UINTN)HostAddress;
+ *DeviceAddress = (UINTN) HostAddress;
*Mapping = NULL;
return EFI_SUCCESS;
}
@@ -184,14 +184,14 @@ PeiIoMmuMap (
/**
Completes the Map() operation and releases any corresponding resources.
- @param This The PPI instance pointer.
- @param Mapping The mapping value returned from Map().
+ @param [in] This The PPI instance pointer.
+ @param [in] Mapping The mapping value returned from Map().
- @retval EFI_SUCCESS The range was unmapped.
- @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
- @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
- @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
- not available to be allocated yet.
+ @retval EFI_SUCCESS The range was unmapped.
+ @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
+ @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
+ not available to be allocated yet.
**/
EFI_STATUS
EFIAPI
@@ -250,21 +250,21 @@ PeiIoMmuUnmap (
Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
OperationBusMasterCommonBuffer64 mapping.
- @param This The PPI instance pointer.
- @param MemoryType The type of memory to allocate, EfiBootServicesData or
- EfiRuntimeServicesData.
- @param Pages The number of pages to allocate.
- @param HostAddress A pointer to store the base system memory address of the
- allocated range.
- @param Attributes The requested bit mask of attributes for the allocated range.
-
- @retval EFI_SUCCESS The requested memory pages were allocated.
- @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
- MEMORY_WRITE_COMBINE, MEMORY_CACHED and DUAL_ADDRESS_CYCLE.
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
- @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
- @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
- not available to be allocated yet.
+ @param [in] This The PPI instance pointer.
+ @param [in] MemoryType The type of memory to allocate, EfiBootServicesData or
+ EfiRuntimeServicesData.
+ @param [in] Pages The number of pages to allocate.
+ @param [in] [out] HostAddress A pointer to store the base system memory address of the
+ allocated range.
+ @param [in] Attributes The requested bit mask of attributes for the allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were allocated.
+ @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
+ MEMORY_WRITE_COMBINE, MEMORY_CACHED and DUAL_ADDRESS_CYCLE.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+ @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
+ not available to be allocated yet.
**/
EFI_STATUS
EFIAPI
@@ -307,15 +307,15 @@ PeiIoMmuAllocateBuffer (
/**
Frees memory that was allocated with AllocateBuffer().
- @param This The PPI instance pointer.
- @param Pages The number of pages to free.
- @param HostAddress The base system memory address of the allocated range.
+ @param [in] This The PPI instance pointer.
+ @param [in] Pages The number of pages to free.
+ @param [in] HostAddress The base system memory address of the allocated range.
- @retval EFI_SUCCESS The requested memory pages were freed.
- @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
- was not allocated with AllocateBuffer().
- @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
- not available to be allocated yet.
+ @retval EFI_SUCCESS The requested memory pages were freed.
+ @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
+ was not allocated with AllocateBuffer().
+ @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA buffer are
+ not available to be allocated yet.
**/
EFI_STATUS
EFIAPI
@@ -364,52 +364,147 @@ CONST EFI_PEI_PPI_DESCRIPTOR mIoMmuPpiList = {
};
/**
- Release the momery in the Intel VTd Info
+ Get ACPI DMAT Table from EdkiiVTdInfo PPI
- @param[in] VTdInfo The VTd engine context information.
+ @retval Address ACPI DMAT Table address
+ @retval NULL Failed to get ACPI DMAT Table
**/
-VOID
-ReleaseVTdInfo (
- IN VTD_INFO *VTdInfo
+EFI_ACPI_DMAR_HEADER * GetAcpiDmarTable (
+ VOID
)
{
- UINTN Index;
+ EFI_STATUS Status;
+ EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
- for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
- DEBUG ((DEBUG_INFO, "Release momery in VTdInfo[%d]\n", Index));
+ //
+ // Get the DMAR table
+ //
+ Status = PeiServicesLocatePpi (
+ &gEdkiiVTdInfoPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&AcpiDmarTable
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to get ACPI DMAR Table : %r\n", Status));
+ AcpiDmarTable = NULL;
+ } else {
+ DumpAcpiDMAR (AcpiDmarTable);
+ }
- if (VTdInfo->VtdUnitInfo[Index].FixedSecondLevelPagingEntry) {
- FreePages ((VOID *) (UINTN) VTdInfo->VtdUnitInfo[Index].FixedSecondLevelPagingEntry, 1);
- VTdInfo->VtdUnitInfo[Index].FixedSecondLevelPagingEntry = 0;
- }
+ return AcpiDmarTable;
+}
- if (VTdInfo->VtdUnitInfo[Index].RmrrSecondLevelPagingEntry) {
- FreePages ((VOID *) (UINTN) VTdInfo->VtdUnitInfo[Index].RmrrSecondLevelPagingEntry, 1);
- VTdInfo->VtdUnitInfo[Index].RmrrSecondLevelPagingEntry = 0;
- }
+/**
+ Get the VTd engine context information hob.
- if (VTdInfo->VtdUnitInfo[Index].RootEntryTable) {
- FreePages ((VOID *) (UINTN) VTdInfo->VtdUnitInfo[Index].RootEntryTable, VTdInfo->VtdUnitInfo[Index].RootEntryTablePageSize);
- VTdInfo->VtdUnitInfo[Index].RootEntryTable = 0;
- }
+ @retval The VTd engine context information.
- if (VTdInfo->VtdUnitInfo[Index].ExtRootEntryTable) {
- FreePages ((VOID *) (UINTN) VTdInfo->VtdUnitInfo[Index].ExtRootEntryTable, VTdInfo->VtdUnitInfo[Index].ExtRootEntryTablePageSize);
- VTdInfo->VtdUnitInfo[Index].RootEntryTable = 0;
+**/
+VTD_INFO *
+GetVTdInfoHob (
+ VOID
+ )
+{
+ VOID *Hob;
+ VTD_INFO *VTdInfo;
+
+ Hob = GetFirstGuidHob (&mVTdInfoGuid);
+ if (Hob == NULL) {
+ VTdInfo = BuildGuidHob (&mVTdInfoGuid, sizeof (VTD_INFO));
+ if (VTdInfo != NULL) {
+ ZeroMem (VTdInfo, sizeof (VTD_INFO));
}
+ } else {
+ VTdInfo = GET_GUID_HOB_DATA(Hob);
+ }
+ return VTdInfo;
+}
+
+/**
+ Callback function of parse DMAR DRHD table in pre-memory phase.
- if (VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceData) {
- FreePages ((VOID *) (UINTN) VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceData, VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataPageSize);
- VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataPageSize = 0;
- VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceData = 0;
- VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataNumber = 0;
- VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataMaxNumber = 0;
+ @param [in] [out] Context Callback function context.
+ @param [in] VTdIndex The VTd engine index.
+ @param [in] DmarDrhd The DRHD table.
+
+**/
+VOID
+ProcessDhrdPreMemory (
+ IN OUT VOID *Context,
+ IN UINT32 VTdIndex,
+ IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
+ )
+{
+ DEBUG ((DEBUG_INFO,"VTD (%d) BaseAddress - 0x%016lx\n", VTdIndex, DmarDrhd->RegisterBaseAddress));
+
+ EnableVTdTranslationProtectionBlockDma ((UINTN) DmarDrhd->RegisterBaseAddress);
+}
+
+
+/**
+ Compare 2 RMRR contexts are same or not.
+
+ @param[in] Destin Destiny RMRR Info
+ @param[in] Source Source RMRR Info
+
+ @retval Same or not same
+
+**/
+BOOLEAN
+CompareVTdRmrrInfo (
+ IN VTD_RMRR_INFO *Destin,
+ IN VTD_RMRR_INFO *Source
+ )
+{
+ UINTN InfoSize;
+
+ if ((Destin == NULL) && (Source == NULL)) {
+ return TRUE;
+ }
+
+ if ((Destin != NULL) && (Source != NULL)) {
+ if (Destin->DeviceNumber == Source->DeviceNumber) {
+ InfoSize = sizeof (VTD_RMRR_INFO) - sizeof (VTD_SOURCE_ID) + sizeof (VTD_SOURCE_ID) * Destin->DeviceNumber;
+ if (CompareMem (Destin, Source, InfoSize) == 0) {
+ return TRUE;
+ }
}
}
+ return FALSE;
+}
+
+/**
+ Callback function of parse DMAR DRHD table in post memory phase.
+
+ @param [in] [out] Context Callback function context.
+ @param [in] VTdIndex The VTd engine index.
+ @param [in] DmarDrhd The DRHD table.
+
+**/
+VOID
+ProcessDrhdPostMemory (
+ IN OUT VOID *Context,
+ IN UINT32 VTdIndex,
+ IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
+ )
+{
+ VTD_UNIT_INFO *VtdUnitInfo;
+
+ VtdUnitInfo = (VTD_UNIT_INFO *) Context;
+ VtdUnitInfo += VTdIndex;
+
+ VtdUnitInfo->Done = FALSE;
+ VtdUnitInfo->VtdUnitBaseAddress = (UINTN) DmarDrhd->RegisterBaseAddress;
+ VtdUnitInfo->Segment = DmarDrhd->SegmentNumber;
+ VtdUnitInfo->Flags = DmarDrhd->Flags;
+
+ DEBUG ((DEBUG_INFO,"VTD (%d) BaseAddress - 0x%016lx\n", VTdIndex, DmarDrhd->RegisterBaseAddress));
+ DEBUG ((DEBUG_INFO," Segment - %d, Flags - 0x%x\n", DmarDrhd->SegmentNumber, DmarDrhd->Flags));
}
/**
- Initializes the Intel VTd Info.
+ Initializes the Intel VTd Info in post memory phase.
@retval EFI_SUCCESS Usb bot driver is successfully initialized.
@retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
@@ -419,89 +514,96 @@ InitVTdInfo (
VOID
)
{
- EFI_STATUS Status;
EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
- VOID *Hob;
+ VTD_RMRR_INFO *RmrrInfo;
+ BOOLEAN RmrrInfoEqual;
VTD_INFO *VTdInfo;
- UINT64 EngineMask;
-
- Status = PeiServicesLocatePpi (
- &gEdkiiVTdInfoPpiGuid,
- 0,
- NULL,
- (VOID **)&AcpiDmarTable
- );
- ASSERT_EFI_ERROR (Status);
+ VTD_UNIT_INFO *VtdUnitInfo;
+ UINTN VtdUnitNumber;
+ EFI_STATUS Status;
+ UINTN i;
+ UINTN j;
- DumpAcpiDMAR (AcpiDmarTable);
+ VTdInfo = GetVTdInfoHob ();
+ ASSERT (VTdInfo != NULL);
- //
- // Clear old VTdInfo Hob.
- //
- Hob = GetFirstGuidHob (&mVTdInfoGuid);
- if (Hob != NULL) {
- DEBUG ((DEBUG_INFO, " Find Hob : mVTdInfoGuid - 0x%x\n", Hob));
+ AcpiDmarTable = GetAcpiDmarTable ();
+ ASSERT (AcpiDmarTable != NULL);
- VTdInfo = GET_GUID_HOB_DATA(Hob);
- EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;
- EnableVTdTranslationProtectionAll (VTdInfo, EngineMask);
-
- ReleaseVTdInfo (VTdInfo);
- VTdInfo->VTdEngineCount = 0;
+ VtdUnitNumber = GetVtdEngineNumber (AcpiDmarTable);
+ if (VtdUnitNumber == 0) {
+ return EFI_UNSUPPORTED;
+ }
+ RmrrInfo = GetVtdRmrrInfo (AcpiDmarTable);
+ RmrrInfoEqual = CompareVTdRmrrInfo (VTdInfo->VtdRmrrInfo, RmrrInfo);
- ZeroMem (&((EFI_HOB_GUID_TYPE *) Hob)->Name, sizeof (EFI_GUID));
+ VtdUnitInfo = AllocateZeroPages (EFI_SIZE_TO_PAGES (sizeof (VTD_UNIT_INFO) * VtdUnitNumber));
+ if (VtdUnitInfo == NULL) {
+ DEBUG ((DEBUG_ERROR, "InitVTdInfo - OUT_OF_RESOURCE\n"));
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
}
- //
- // Get DMAR information to local VTdInfo
- //
- Status = ParseDmarAcpiTableDrhd (AcpiDmarTable);
- if (EFI_ERROR(Status)) {
- DEBUG ((DEBUG_ERROR, " ParseDmarAcpiTableDrhd : %r\n", Status));
+ Status = ParseDmarAcpiTableDrhd (AcpiDmarTable, ProcessDrhdPostMemory, VtdUnitInfo);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
return Status;
}
//
- // NOTE: Do not parse RMRR here, because RMRR may cause DMAR programming.
+ // Check Host Address Width
//
+ if ((AcpiDmarTable->HostAddressWidth == VTdInfo->HostAddressWidth) && RmrrInfoEqual) {
+ for (i = 0; i < VtdUnitNumber; i++) {
+ //
+ // Scan each new Vtd Unit
+ //
+ for (j = 0; j < VTdInfo->VTdEngineCount; j++) {
+ //
+ // Compare the new Vtd Unit with each exist VTd Unit
+ //
+ if (VtdUnitInfo[i].VtdUnitBaseAddress == VTdInfo->VtdUnitInfo[j].VtdUnitBaseAddress) {
+ DEBUG ((DEBUG_INFO,"Find VTD [0x%08x] Exist\n", VtdUnitInfo[i].VtdUnitBaseAddress));
+ CopyMem (&VtdUnitInfo[i], &VTdInfo->VtdUnitInfo[j], sizeof (VTD_UNIT_INFO));
+ VtdUnitInfo[i].Done = TRUE;
+
+ break;
+ }
+ }
+ }
+ }
+ VTdInfo->AcpiDmarTable = AcpiDmarTable;
+ VTdInfo->HostAddressWidth = AcpiDmarTable->HostAddressWidth;
+ VTdInfo->VTdEngineCount = VtdUnitNumber;
+ VTdInfo->VtdUnitInfo = VtdUnitInfo;
+ VTdInfo->VtdRmrrInfo = RmrrInfo;
return EFI_SUCCESS;
}
/**
- Initializes the Intel VTd DMAR for all memory.
+ Initializes the Intel VTd DMAR for block all DMA.
@retval EFI_SUCCESS Driver is successfully initialized.
@retval RETURN_NOT_READY Fail to get VTdInfo Hob .
**/
EFI_STATUS
-InitVTdDmarForAll (
+InitVTdDmarBlockAll (
VOID
)
{
- VOID *Hob;
- VTD_INFO *VTdInfo;
- UINT64 EngineMask;
- EFI_STATUS Status;
-
- Hob = GetFirstGuidHob (&mVTdInfoGuid);
- if (Hob == NULL) {
- DEBUG ((DEBUG_ERROR, "Fail to get VTdInfo Hob.\n"));
- return RETURN_NOT_READY;
- }
- VTdInfo = GET_GUID_HOB_DATA (Hob);
- EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;
-
- DEBUG ((DEBUG_INFO, "PrepareVtdConfig\n"));
- Status = PrepareVtdConfig (VTdInfo);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
+ EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
- EnableVTdTranslationProtectionAll (VTdInfo, EngineMask);
+ //
+ // Get the DMAR table
+ //
+ AcpiDmarTable = GetAcpiDmarTable ();
+ ASSERT (AcpiDmarTable != NULL);
- return EFI_SUCCESS;
+ //
+ // Parse the DMAR table and block all DMA
+ //
+ return ParseDmarAcpiTableDrhd (AcpiDmarTable, ProcessDhrdPreMemory, NULL);
}
/**
@@ -524,8 +626,8 @@ InitDmaBuffer(
DEBUG ((DEBUG_INFO, "InitDmaBuffer :\n"));
Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
+ ASSERT(Hob != NULL);
DmaBufferInfo = GET_GUID_HOB_DATA (Hob);
- VtdPmrHobPtr = GetFirstGuidHob (&gVtdPmrInfoDataHobGuid);
/**
When gVtdPmrInfoDataHobGuid exists, it means:
@@ -535,7 +637,7 @@ InitDmaBuffer(
4. Protection regions will be conveyed through VTD_PMR_INFO_HOB
When gVtdPmrInfoDataHobGuid dosen't exist, it means:
- 1. IntelVTdDmar driver will calcuate the PMR memory alignment
+ 1. IntelVTdDmarPei driver will calcuate the protected memory alignment
2. Dma buffer is reserved by AllocateAlignedPages()
**/
@@ -545,33 +647,40 @@ InitDmaBuffer(
return EFI_INVALID_PARAMETER;
}
- if (VtdPmrHobPtr == NULL) {
- //
- // Allocate memory for DMA buffer
- //
- DmaBufferInfo->DmaBufferBase = (UINT64) (UINTN) AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) DmaBufferInfo->DmaBufferSize), 0);
- if (DmaBufferInfo->DmaBufferBase == 0) {
- DEBUG ((DEBUG_ERROR, " InitDmaBuffer : OutOfResource\n"));
- return EFI_OUT_OF_RESOURCES;
+ if (DmaBufferInfo->DmaBufferBase == 0) {
+ VtdPmrHobPtr = GetFirstGuidHob (&gVtdPmrInfoDataHobGuid);
+ if (VtdPmrHobPtr != NULL) {
+ //
+ // Get the protected memory ranges information from the VTd PMR hob
+ //
+ VtdPmrHob = GET_GUID_HOB_DATA (VtdPmrHobPtr);
+
+ if ((VtdPmrHob->ProtectedHighBase - VtdPmrHob->ProtectedLowLimit) < DmaBufferInfo->DmaBufferSize) {
+ DEBUG ((DEBUG_ERROR, " DmaBufferSize not enough\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+ DmaBufferInfo->DmaBufferBase = VtdPmrHob->ProtectedLowLimit;
+ } else {
+ //
+ // Allocate memory for DMA buffer
+ //
+ DmaBufferInfo->DmaBufferBase = (UINTN) AllocateAlignedPages (EFI_SIZE_TO_PAGES (DmaBufferInfo->DmaBufferSize), 0);
+ if (DmaBufferInfo->DmaBufferBase == 0) {
+ DEBUG ((DEBUG_ERROR, " InitDmaBuffer : OutOfResource\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ DEBUG ((DEBUG_INFO, "Alloc DMA buffer success.\n"));
}
- DmaBufferInfo->DmaBufferLimit = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
- DEBUG ((DEBUG_INFO, "Alloc DMA buffer success.\n"));
- } else {
- //
- // Get the PMR ranges information for the VTd PMR hob
- //
- VtdPmrHob = GET_GUID_HOB_DATA (VtdPmrHobPtr);
- DmaBufferInfo->DmaBufferBase = VtdPmrHob->ProtectedLowLimit;
- DmaBufferInfo->DmaBufferLimit = VtdPmrHob->ProtectedHighBase;
+
+ DmaBufferInfo->DmaBufferCurrentTop = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
+ DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo->DmaBufferBase;
+
+ DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", DmaBufferInfo->DmaBufferSize));
+ DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n", DmaBufferInfo->DmaBufferBase));
}
- DmaBufferInfo->DmaBufferCurrentTop = DmaBufferInfo->DmaBufferBase + DmaBufferInfo->DmaBufferSize;
- DmaBufferInfo->DmaBufferCurrentBottom = DmaBufferInfo->DmaBufferBase;
- DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%lx\n", DmaBufferInfo->DmaBufferSize));
- DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%lx\n", DmaBufferInfo->DmaBufferBase));
- DEBUG ((DEBUG_INFO, " DmaBufferLimit : 0x%lx\n", DmaBufferInfo->DmaBufferLimit));
- DEBUG ((DEBUG_INFO, " DmaBufferCurrentTop : 0x%lx\n", DmaBufferInfo->DmaBufferCurrentTop));
- DEBUG ((DEBUG_INFO, " DmaBufferCurrentBottom : 0x%lx\n", DmaBufferInfo->DmaBufferCurrentBottom));
+ DEBUG ((DEBUG_INFO, " DmaBufferCurrentTop : 0x%x\n", DmaBufferInfo->DmaBufferCurrentTop));
+ DEBUG ((DEBUG_INFO, " DmaBufferCurrentBottom : 0x%x\n", DmaBufferInfo->DmaBufferCurrentBottom));
return EFI_SUCCESS;
}
@@ -588,14 +697,14 @@ InitVTdDmarForDma (
VOID
)
{
- VOID *Hob;
VTD_INFO *VTdInfo;
+
EFI_STATUS Status;
EFI_PEI_PPI_DESCRIPTOR *OldDescriptor;
EDKII_IOMMU_PPI *OldIoMmuPpi;
- Hob = GetFirstGuidHob (&mVTdInfoGuid);
- VTdInfo = GET_GUID_HOB_DATA (Hob);
+ VTdInfo = GetVTdInfoHob ();
+ ASSERT (VTdInfo != NULL);
DEBUG ((DEBUG_INFO, "PrepareVtdConfig\n"));
Status = PrepareVtdConfig (VTdInfo);
@@ -604,13 +713,6 @@ InitVTdDmarForDma (
return Status;
}
- DEBUG ((DEBUG_INFO, "PrepareVtdCacheInvalidationConfig\n"));
- Status = PrepareVtdCacheInvalidationConfig (VTdInfo);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
-
// create root entry table
DEBUG ((DEBUG_INFO, "SetupTranslationTable\n"));
Status = SetupTranslationTable (VTdInfo);
@@ -620,8 +722,11 @@ InitVTdDmarForDma (
}
// If there is RMRR memory, parse it here.
- DEBUG ((DEBUG_INFO, "PeiParseDmarAcpiTableRmrr\n"));
- ParseDmarAcpiTableRmrr (VTdInfo);
+ Status = SetupRmrr (VTdInfo);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
DEBUG ((DEBUG_INFO, "EnableVtdDmar\n"));
Status = EnableVTdTranslationProtection(VTdInfo);
@@ -668,21 +773,10 @@ S3EndOfPeiNotify(
IN VOID *Ppi
)
{
- VOID *Hob;
- VTD_INFO *VTdInfo;
- UINT64 EngineMask;
-
DEBUG((DEBUG_INFO, "VTd DMAR PEI S3EndOfPeiNotify\n"));
if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT1) == 0) {
- Hob = GetFirstGuidHob (&mVTdInfoGuid);
- if (Hob == NULL) {
- return EFI_SUCCESS;
- }
- VTdInfo = GET_GUID_HOB_DATA(Hob);
-
- EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;
- DisableVTdTranslationProtection (VTdInfo, EngineMask);
+ DisableVTdTranslationProtection (GetVTdInfoHob ());
}
return EFI_SUCCESS;
}
@@ -733,18 +827,13 @@ VTdInfoNotify (
DEBUG ((DEBUG_INFO, "MemoryInitialized - %x\n", MemoryInitialized));
- //
- // NOTE: We need reinit VTdInfo because previous information might be overriden.
- //
- InitVTdInfo ();
-
if (!MemoryInitialized) {
//
// If the memory is not initialized,
// Protect all system memory
//
- InitVTdDmarForAll ();
+ InitVTdDmarBlockAll ();
//
// Install PPI.
@@ -758,9 +847,16 @@ VTdInfoNotify (
//
Status = InitDmaBuffer ();
- ASSERT_EFI_ERROR(Status);
+ ASSERT_EFI_ERROR (Status);
- InitVTdDmarForDma ();
+ //
+ // NOTE: We need reinit VTdInfo because previous information might be overriden.
+ //
+ Status = InitVTdInfo ();
+ ASSERT_EFI_ERROR (Status);
+
+ Status = InitVTdDmarForDma ();
+ ASSERT_EFI_ERROR (Status);
}
return EFI_SUCCESS;
@@ -826,4 +922,3 @@ IntelVTdDmarInitialize (
return EFI_SUCCESS;
}
-
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h
index e23a6c8e..e1894e39 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h
@@ -9,68 +9,71 @@
#ifndef __DMA_ACCESS_LIB_H__
#define __DMA_ACCESS_LIB_H__
-#define MAX_VTD_PCI_DATA_NUMBER 0x100
-
#define VTD_64BITS_ADDRESS(Lo, Hi) (LShiftU64 (Lo, 12) | LShiftU64 (Hi, 32))
typedef struct {
- UINT8 DeviceType;
- VTD_SOURCE_ID PciSourceId;
-} PEI_PCI_DEVICE_DATA;
-
-typedef struct {
- BOOLEAN IncludeAllFlag;
- UINT32 PciDeviceDataNumber;
- UINT32 PciDeviceDataMaxNumber;
- UINT32 PciDeviceDataPageSize;
- UINT32 PciDeviceData;
-} PEI_PCI_DEVICE_INFORMATION;
+ UINT16 SegmentNumber;
+ UINT64 ReservedMemoryRegionBaseAddress;
+ UINT64 ReservedMemoryRegionLimitAddress;
+ UINTN DeviceNumber;
+ VTD_SOURCE_ID SourceId[1];
+} VTD_RMRR_INFO;
typedef struct {
- UINT32 VtdUnitBaseAddress;
+ BOOLEAN Done;
+ UINTN VtdUnitBaseAddress;
UINT16 Segment;
+ UINT8 Flags;
VTD_VER_REG VerReg;
VTD_CAP_REG CapReg;
VTD_ECAP_REG ECapReg;
BOOLEAN Is5LevelPaging;
- UINT32 FixedSecondLevelPagingEntry;
- UINT32 RmrrSecondLevelPagingEntry;
- UINT32 RootEntryTable;
- UINT32 ExtRootEntryTable;
- UINT16 RootEntryTablePageSize;
- UINT16 ExtRootEntryTablePageSize;
- PEI_PCI_DEVICE_INFORMATION PciDeviceInfo;
UINT8 EnableQueuedInvalidation;
- UINT16 QiDescLength;
+ UINT16 QueueSize;
QI_DESC *QiDesc;
UINT16 QiFreeHead;
+ UINTN FixedSecondLevelPagingEntry;
+ UINTN RootEntryTable;
+ UINTN ExtRootEntryTable;
+ UINTN RootEntryTablePageSize;
+ UINTN ExtRootEntryTablePageSize;
+ UINTN RmrrSecondLevelPagingEntry;
} VTD_UNIT_INFO;
typedef struct {
- UINT32 AcpiDmarTable;
+ EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
UINT8 HostAddressWidth;
- UINT32 VTdEngineCount;
- VTD_UNIT_INFO VtdUnitInfo[1];
+ UINTN VTdEngineCount;
+ VTD_UNIT_INFO *VtdUnitInfo;
+ VTD_RMRR_INFO *VtdRmrrInfo;
} VTD_INFO;
typedef struct {
- UINT64 DmaBufferBase;
- UINT64 DmaBufferSize;
- UINT64 DmaBufferLimit;
- UINT64 DmaBufferCurrentTop;
- UINT64 DmaBufferCurrentBottom;
+ UINTN DmaBufferBase;
+ UINTN DmaBufferSize;
+ UINTN DmaBufferCurrentTop;
+ UINTN DmaBufferCurrentBottom;
} DMA_BUFFER_INFO;
+typedef
+VOID
+(*PROCESS_DRHD_CALLBACK_FUNC) (
+ IN OUT VOID *Context,
+ IN UINT32 VTdIndex,
+ IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
+ );
+
/**
- Enable VTd translation table protection.
+ Enable VTd translation table protection for block DMA
- @param[in] VTdInfo The VTd engine context information.
- @param[in] EngineMask The mask of the VTd engine to be accessed.
+ @param[in] VtdUnitBaseAddress The base address of the VTd engine.
+
+ @retval EFI_SUCCESS DMAR translation is enabled.
+ @retval EFI_DEVICE_ERROR DMAR translation is not enabled.
**/
-VOID
-EnableVTdTranslationProtectionAll (
- IN VTD_INFO *VTdInfo,
- IN UINT64 EngineMask
+EFI_STATUS
+EnableVTdTranslationProtectionBlockDma (
+ IN UINTN VtdUnitBaseAddress
);
/**
@@ -90,34 +93,39 @@ EnableVTdTranslationProtection (
Disable VTd translation table protection.
@param[in] VTdInfo The VTd engine context information.
- @param[in] EngineMask The mask of the VTd engine to be accessed.
**/
VOID
DisableVTdTranslationProtection (
- IN VTD_INFO *VTdInfo,
- IN UINT64 EngineMask
+ IN VTD_INFO *VTdInfo
);
/**
Parse DMAR DRHD table.
@param[in] AcpiDmarTable DMAR ACPI table
+ @param[in] Callback Callback function for handle DRHD
+ @param[in] Context Callback function Context
+
+ @return EFI_SUCCESS The DMAR DRHD table is parsed.
- @return EFI_SUCCESS The DMAR DRHD table is parsed.
**/
EFI_STATUS
ParseDmarAcpiTableDrhd (
- IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
+ IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable,
+ IN PROCESS_DRHD_CALLBACK_FUNC Callback,
+ IN VOID *Context
);
/**
- Parse DMAR DRHD table.
+ Get RMRR Info from ACPI DMAR Table.
- @param[in] VTdInfo The VTd engine context information.
+ @param[in] AcpiDmarTable DMAR ACPI table
+
+ @return the VTd engine number.
**/
-VOID
-ParseDmarAcpiTableRmrr (
- IN VTD_INFO *VTdInfo
+VTD_RMRR_INFO *
+GetVtdRmrrInfo (
+ IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
);
/**
@@ -167,6 +175,30 @@ SetupTranslationTable (
IN VTD_INFO *VTdInfo
);
+/**
+ Get VTd engine number.
+
+ @param[in] AcpiDmarTable DMAR ACPI table
+
+ @return the VTd engine number.
+**/
+UINTN
+GetVtdEngineNumber (
+ IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
+ );
+
+/**
+ Setup VTd RMRR in translation table.
+
+ @param[in] VTdInfo The VTd engine context information.
+
+ @return the VTd engine number.
+**/
+EFI_STATUS
+SetupRmrr (
+ IN VTD_INFO *VTdInfo
+ );
+
/**
Flush VTD page table and context table memory.
@@ -240,4 +272,3 @@ extern EFI_GUID mVTdInfoGuid;
extern EFI_GUID mDmaBufferInfoGuid;
#endif
-
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTable.c
index a309d566..2e14632a 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTable.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTable.c
@@ -1,6 +1,7 @@
/** @file
Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
+
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -129,12 +130,12 @@ CreateSecondLevelPagingEntryTable (
FlushPageTableMemory (VTdUnitInfo, (UINTN) SecondLevelPagingEntry, EFI_PAGES_TO_SIZE (1));
}
- DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", SecondLevelPagingEntry));
+ DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINT64) (UINTN) SecondLevelPagingEntry));
//
// If no access is needed, just create not present entry.
//
if (IoMmuAccess == 0) {
- DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINTN) SecondLevelPagingEntry));
+ DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx Access 0\n", (UINT64) (UINTN) SecondLevelPagingEntry));
return SecondLevelPagingEntry;
}
@@ -244,7 +245,7 @@ CreateSecondLevelPagingEntryTable (
}
FlushPageTableMemory (VTdUnitInfo, (UINTN) &Lvl5PtEntry[Lvl5Start], (UINTN) &Lvl5PtEntry[Lvl5End + 1] - (UINTN) &Lvl5PtEntry[Lvl5Start]);
- DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINTN)SecondLevelPagingEntry));
+ DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINT64) (UINTN) SecondLevelPagingEntry));
return SecondLevelPagingEntry;
}
@@ -276,6 +277,10 @@ CreateContextEntry (
VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
UINT64 Pt;
+ if (VTdUnitInfo->RootEntryTable != 0) {
+ return EFI_SUCCESS;
+ }
+
RootPages = EFI_SIZE_TO_PAGES (sizeof (VTD_ROOT_ENTRY) * VTD_ROOT_ENTRY_NUMBER);
ContextPages = EFI_SIZE_TO_PAGES (sizeof (VTD_CONTEXT_ENTRY) * VTD_CONTEXT_ENTRY_NUMBER);
EntryTablePages = RootPages + ContextPages * (VTD_ROOT_ENTRY_NUMBER);
@@ -286,8 +291,8 @@ CreateContextEntry (
}
DEBUG ((DEBUG_ERROR, "RootEntryTable address - 0x%x\n", Buffer));
- VTdUnitInfo->RootEntryTable = (UINT32) (UINTN) Buffer;
- VTdUnitInfo->RootEntryTablePageSize = (UINT16) EntryTablePages;
+ VTdUnitInfo->RootEntryTable = (UINTN) Buffer;
+ VTdUnitInfo->RootEntryTablePageSize = EntryTablePages;
RootEntryBase = (VTD_ROOT_ENTRY *) Buffer;
Buffer = (UINT8 *) Buffer + EFI_PAGES_TO_SIZE (RootPages);
@@ -317,7 +322,7 @@ CreateContextEntry (
ContextEntry->Bits.AddressWidth = VTdUnitInfo->Is5LevelPaging ? 0x3 : 0x2;
if (VTdUnitInfo->FixedSecondLevelPagingEntry != 0) {
- SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *) (UINTN) VTdUnitInfo->FixedSecondLevelPagingEntry;
+ SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *) VTdUnitInfo->FixedSecondLevelPagingEntry;
Pt = (UINT64)RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry, 12);
ContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32) Pt;
ContextEntry->Bits.SecondLevelPageTranslationPointerHi = (UINT32) RShiftU64(Pt, 20);
@@ -359,6 +364,10 @@ CreateExtContextEntry (
VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
UINT64 Pt;
+ if (VTdUnitInfo->ExtRootEntryTable != 0) {
+ return EFI_SUCCESS;
+ }
+
RootPages = EFI_SIZE_TO_PAGES (sizeof (VTD_EXT_ROOT_ENTRY) * VTD_ROOT_ENTRY_NUMBER);
ContextPages = EFI_SIZE_TO_PAGES (sizeof (VTD_EXT_CONTEXT_ENTRY) * VTD_CONTEXT_ENTRY_NUMBER);
EntryTablePages = RootPages + ContextPages * (VTD_ROOT_ENTRY_NUMBER);
@@ -369,8 +378,8 @@ CreateExtContextEntry (
}
DEBUG ((DEBUG_ERROR, "ExtRootEntryTable address - 0x%x\n", Buffer));
- VTdUnitInfo->ExtRootEntryTable = (UINT32) (UINTN) Buffer;
- VTdUnitInfo->ExtRootEntryTablePageSize = (UINT16) EntryTablePages;
+ VTdUnitInfo->ExtRootEntryTable = (UINTN) Buffer;
+ VTdUnitInfo->ExtRootEntryTablePageSize = EntryTablePages;
ExtRootEntryBase = (VTD_EXT_ROOT_ENTRY *) Buffer;
Buffer = (UINT8 *) Buffer + EFI_PAGES_TO_SIZE (RootPages);
@@ -403,7 +412,7 @@ CreateExtContextEntry (
ExtContextEntry->Bits.AddressWidth = VTdUnitInfo->Is5LevelPaging ? 0x3 : 0x2;
if (VTdUnitInfo->FixedSecondLevelPagingEntry != 0) {
- SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *) (UINTN) VTdUnitInfo->FixedSecondLevelPagingEntry;
+ SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *) VTdUnitInfo->FixedSecondLevelPagingEntry;
Pt = (UINT64)RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry, 12);
ExtContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32) Pt;
@@ -791,9 +800,6 @@ SetSecondLevelPagingAttribute (
SplitAttribute = NeedSplitPage (BaseAddress, Length, PageAttribute);
if (SplitAttribute == PageNone) {
ConvertSecondLevelPageEntryAttribute (VTdUnitInfo, PageEntry, IoMmuAccess, &IsEntryModified);
- if (IsEntryModified) {
- //mVtdUnitInformation[VtdIndex].HasDirtyPages = TRUE;
- }
//
// Convert success, move to next
//
@@ -805,7 +811,6 @@ SetSecondLevelPagingAttribute (
DEBUG ((DEBUG_ERROR, "SplitSecondLevelPage - %r\n", Status));
return RETURN_UNSUPPORTED;
}
- //mVtdUnitInformation[VtdIndex].HasDirtyPages = TRUE;
//
// Just split current page
// Convert success in next around
@@ -837,7 +842,11 @@ CreateFixedSecondLevelPagingEntry (
VOID *Hob;
DMA_BUFFER_INFO *DmaBufferInfo;
- VTdUnitInfo->FixedSecondLevelPagingEntry = (UINT32) (UINTN) CreateSecondLevelPagingEntryTable (VTdUnitInfo, NULL, 0, SIZE_4GB, 0);
+ if (VTdUnitInfo->FixedSecondLevelPagingEntry != 0) {
+ return EFI_SUCCESS;
+ }
+
+ VTdUnitInfo->FixedSecondLevelPagingEntry = (UINTN) CreateSecondLevelPagingEntryTable (VTdUnitInfo, NULL, 0, SIZE_4GB, 0);
if (VTdUnitInfo->FixedSecondLevelPagingEntry == 0) {
DEBUG ((DEBUG_ERROR, "FixedSecondLevelPagingEntry is empty\n"));
return EFI_OUT_OF_RESOURCES;
@@ -846,14 +855,14 @@ CreateFixedSecondLevelPagingEntry (
Hob = GetFirstGuidHob (&mDmaBufferInfoGuid);
DmaBufferInfo = GET_GUID_HOB_DATA (Hob);
BaseAddress = DmaBufferInfo->DmaBufferBase;
- Length = DmaBufferInfo->DmaBufferLimit - DmaBufferInfo->DmaBufferBase;
+ Length = DmaBufferInfo->DmaBufferSize;
IoMmuAccess = EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE;
DEBUG ((DEBUG_INFO, " BaseAddress = 0x%lx\n", BaseAddress));
DEBUG ((DEBUG_INFO, " Length = 0x%lx\n", Length));
DEBUG ((DEBUG_INFO, " IoMmuAccess = 0x%lx\n", IoMmuAccess));
- Status = SetSecondLevelPagingAttribute (VTdUnitInfo, (VTD_SECOND_LEVEL_PAGING_ENTRY*) (UINTN) VTdUnitInfo->FixedSecondLevelPagingEntry, BaseAddress, Length, IoMmuAccess);
+ Status = SetSecondLevelPagingAttribute (VTdUnitInfo, (VTD_SECOND_LEVEL_PAGING_ENTRY*) VTdUnitInfo->FixedSecondLevelPagingEntry, BaseAddress, Length, IoMmuAccess);
return Status;
}
@@ -877,6 +886,9 @@ SetupTranslationTable (
for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
VtdUnitInfo = &VTdInfo->VtdUnitInfo[Index];
+ if (VtdUnitInfo->Done) {
+ continue;
+ }
Status = CreateFixedSecondLevelPagingEntry (VtdUnitInfo);
if (EFI_ERROR (Status)) {
@@ -912,83 +924,45 @@ SetupTranslationTable (
}
/**
- Find the VTd index by the Segment and SourceId.
+ Setup VTd RMRR in translation table.
@param[in] VTdInfo The VTd engine context information.
- @param[in] Segment The segment of the source.
- @param[in] SourceId The SourceId of the source.
- @param[out] ExtContextEntry The ExtContextEntry of the source.
- @param[out] ContextEntry The ContextEntry of the source.
- @return The index of the VTd engine.
- @retval (UINTN)-1 The VTd engine is not found.
+ @return the VTd engine number.
**/
-UINTN
-FindVtdIndexBySegmentSourceId (
- IN VTD_INFO *VTdInfo,
- IN UINT16 Segment,
- IN VTD_SOURCE_ID SourceId,
- OUT VTD_EXT_CONTEXT_ENTRY **ExtContextEntry,
- OUT VTD_CONTEXT_ENTRY **ContextEntry
+EFI_STATUS
+SetupRmrr (
+ IN VTD_INFO *VTdInfo
)
{
- UINTN VtdIndex;
- VTD_ROOT_ENTRY *RootEntryBase;
- VTD_ROOT_ENTRY *RootEntry;
- VTD_CONTEXT_ENTRY *ContextEntryTable;
- VTD_CONTEXT_ENTRY *ThisContextEntry;
- VTD_EXT_ROOT_ENTRY *ExtRootEntryBase;
- VTD_EXT_ROOT_ENTRY *ExtRootEntry;
- VTD_EXT_CONTEXT_ENTRY *ExtContextEntryTable;
- VTD_EXT_CONTEXT_ENTRY *ThisExtContextEntry;
+ EFI_STATUS Status;
+ UINTN Index;
- for (VtdIndex = 0; VtdIndex < VTdInfo->VTdEngineCount; VtdIndex++) {
- if (GetPciDataIndex (&VTdInfo->VtdUnitInfo[VtdIndex], Segment, SourceId) != (UINTN)-1) {
- DEBUG ((DEBUG_INFO, "Find VtdIndex(0x%x) for S%04x B%02x D%02x F%02x\n", VtdIndex, Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
- break;
- }
+ if (VTdInfo->VtdRmrrInfo == NULL) {
+ return EFI_SUCCESS;
}
- if (VtdIndex >= VTdInfo->VTdEngineCount) {
- for (VtdIndex = 0; VtdIndex < VTdInfo->VTdEngineCount; VtdIndex++) {
- if (Segment != VTdInfo->VtdUnitInfo[VtdIndex].Segment) {
- continue;
- }
- if (VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.IncludeAllFlag) {
- DEBUG ((DEBUG_INFO, "Find IncludeAllFlag VtdIndex(0x%x) for S%04x B%02x D%02x F%02x\n", VtdIndex, Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
- break;
- }
- }
+
+ if (VTdInfo->VtdRmrrInfo->DeviceNumber == 0) {
+ return EFI_SUCCESS;
}
- if (VtdIndex < VTdInfo->VTdEngineCount) {
- ExtRootEntryBase = (VTD_EXT_ROOT_ENTRY *) (UINTN) VTdInfo->VtdUnitInfo[VtdIndex].ExtRootEntryTable;
- if (ExtRootEntryBase != 0) {
- ExtRootEntry = &ExtRootEntryBase[SourceId.Index.RootIndex];
- ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *) (UINTN) VTD_64BITS_ADDRESS(ExtRootEntry->Bits.LowerContextTablePointerLo, ExtRootEntry->Bits.LowerContextTablePointerHi) ;
- ThisExtContextEntry = &ExtContextEntryTable[SourceId.Index.ContextIndex];
- if (ThisExtContextEntry->Bits.AddressWidth == 0) {
- DEBUG ((DEBUG_INFO, "ExtContextEntry AddressWidth : 0x%x\n", ThisExtContextEntry->Bits.AddressWidth));
- return (UINTN)-1;
- }
- *ExtContextEntry = ThisExtContextEntry;
- *ContextEntry = NULL;
- } else {
- RootEntryBase = (VTD_ROOT_ENTRY*) (UINTN) VTdInfo->VtdUnitInfo[VtdIndex].RootEntryTable;
- RootEntry = &RootEntryBase[SourceId.Index.RootIndex];
- ContextEntryTable = (VTD_CONTEXT_ENTRY *) (UINTN) VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry->Bits.ContextTablePointerHi) ;
- ThisContextEntry = &ContextEntryTable[SourceId.Index.ContextIndex];
- if (ThisContextEntry->Bits.AddressWidth == 0) {
- DEBUG ((DEBUG_INFO, "ContextEntry AddressWidth : 0x%x\n", ThisContextEntry->Bits.AddressWidth));
- return (UINTN)-1;
- }
- *ExtContextEntry = NULL;
- *ContextEntry = ThisContextEntry;
+ DEBUG ((DEBUG_INFO, "Setup Rmrr Info\n"));
+
+ for (Index = 0; Index < VTdInfo->VtdRmrrInfo->DeviceNumber; Index++) {
+ Status = EnableRmrrPageAttribute (
+ VTdInfo,
+ VTdInfo->VtdRmrrInfo->SegmentNumber,
+ VTdInfo->VtdRmrrInfo->SourceId[Index],
+ VTdInfo->VtdRmrrInfo->ReservedMemoryRegionBaseAddress,
+ VTdInfo->VtdRmrrInfo->ReservedMemoryRegionLimitAddress,
+ EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "EnableRmrrPageAttribute : %r\n", Status));
}
-
- return VtdIndex;
}
- return (UINTN)-1;
+ return EFI_SUCCESS;
}
/**
@@ -1013,8 +987,9 @@ EnableRmrrPageAttribute (
IN UINT64 IoMmuAccess
)
{
- EFI_STATUS Status;
- UINTN VtdIndex;
+ UINTN Index;
+ VTD_UNIT_INFO *VtdUnitInfo;
+ EFI_STATUS Status;
VTD_EXT_CONTEXT_ENTRY *ExtContextEntry;
VTD_CONTEXT_ENTRY *ContextEntry;
VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
@@ -1022,39 +997,41 @@ EnableRmrrPageAttribute (
DEBUG ((DEBUG_INFO, "EnableRmrrPageAttribute (S%04x B%02x D%02x F%02x)\n", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
- VtdIndex = FindVtdIndexBySegmentSourceId (VTdInfo, Segment, SourceId, &ExtContextEntry, &ContextEntry);
- if (VtdIndex == (UINTN)-1) {
- DEBUG ((DEBUG_ERROR, "EnableRmrrPageAttribute - Can not locate Pci device (S%04x B%02x D%02x F%02x) !\n", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function));
- return EFI_DEVICE_ERROR;
- }
-
- if (VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry == 0) {
- DEBUG ((DEBUG_INFO, "CreateSecondLevelPagingEntry - %d\n", VtdIndex));
- VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry = (UINT32)(UINTN)CreateSecondLevelPagingEntryTable (&VTdInfo->VtdUnitInfo[VtdIndex], NULL, 0, SIZE_4GB, 0);
- if (VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry == 0) {
- return EFI_OUT_OF_RESOURCES;
+ for (Index = 0; Index < VTdInfo->VTdEngineCount; Index++) {
+ VtdUnitInfo = &VTdInfo->VtdUnitInfo[Index];
+ if (VtdUnitInfo->Done) {
+ continue;
}
- Status =SetSecondLevelPagingAttribute (&VTdInfo->VtdUnitInfo[VtdIndex], (VTD_SECOND_LEVEL_PAGING_ENTRY*)(UINTN)VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry, MemoryBase, MemoryLimit + 1 - MemoryBase, IoMmuAccess);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
+ if (VtdUnitInfo->RmrrSecondLevelPagingEntry == 0) {
+ DEBUG ((DEBUG_INFO, "CreateSecondLevelPagingEntry - %d\n", Index));
+ VtdUnitInfo->RmrrSecondLevelPagingEntry = (UINTN) CreateSecondLevelPagingEntryTable (VtdUnitInfo, NULL, 0, SIZE_4GB, 0);
+ if (VtdUnitInfo->RmrrSecondLevelPagingEntry == 0) {
+ return EFI_OUT_OF_RESOURCES;
+ }
- SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *) (UINTN) VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry;
- Pt = (UINT64) RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry, 12);
- if (ExtContextEntry != NULL) {
- ExtContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32) Pt;
- ExtContextEntry->Bits.SecondLevelPageTranslationPointerHi = (UINT32) RShiftU64(Pt, 20);
- ExtContextEntry->Bits.DomainIdentifier = ((1 << (UINT8) ((UINTN) VTdInfo->VtdUnitInfo[VtdIndex].CapReg.Bits.ND * 2 + 4)) - 1);
- ExtContextEntry->Bits.Present = 1;
- FlushPageTableMemory (&VTdInfo->VtdUnitInfo[VtdIndex], (UINTN) ExtContextEntry, sizeof(*ExtContextEntry));
- } else if (ContextEntry != NULL) {
- ContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32) Pt;
- ContextEntry->Bits.SecondLevelPageTranslationPointerHi = (UINT32) RShiftU64 (Pt, 20);
- ContextEntry->Bits.DomainIdentifier = ((1 << (UINT8) ((UINTN) VTdInfo->VtdUnitInfo[VtdIndex].CapReg.Bits.ND * 2 + 4)) - 1);
- ContextEntry->Bits.Present = 1;
- FlushPageTableMemory (&VTdInfo->VtdUnitInfo[VtdIndex], (UINTN) ContextEntry, sizeof (*ContextEntry));
+ Status = SetSecondLevelPagingAttribute (VtdUnitInfo, (VTD_SECOND_LEVEL_PAGING_ENTRY*) VtdUnitInfo->RmrrSecondLevelPagingEntry, MemoryBase, MemoryLimit + 1 - MemoryBase, IoMmuAccess);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+ SecondLevelPagingEntry = (VTD_SECOND_LEVEL_PAGING_ENTRY *) VtdUnitInfo->RmrrSecondLevelPagingEntry;
+ ExtContextEntry = (VTD_EXT_CONTEXT_ENTRY *) VtdUnitInfo->ExtRootEntryTable;
+ ContextEntry = (VTD_CONTEXT_ENTRY *) VtdUnitInfo->RootEntryTable;
+ Pt = (UINT64) RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry, 12);
+ if (ExtContextEntry != NULL) {
+ ExtContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32) Pt;
+ ExtContextEntry->Bits.SecondLevelPageTranslationPointerHi = (UINT32) RShiftU64(Pt, 20);
+ ExtContextEntry->Bits.DomainIdentifier = ((1 << (UINT8) ((UINTN) VtdUnitInfo->CapReg.Bits.ND * 2 + 4)) - 1);
+ ExtContextEntry->Bits.Present = 1;
+ FlushPageTableMemory (VtdUnitInfo, (UINTN) ExtContextEntry, sizeof (*ExtContextEntry));
+ } else if (ContextEntry != NULL) {
+ ContextEntry->Bits.SecondLevelPageTranslationPointerLo = (UINT32) Pt;
+ ContextEntry->Bits.SecondLevelPageTranslationPointerHi = (UINT32) RShiftU64 (Pt, 20);
+ ContextEntry->Bits.DomainIdentifier = ((1 << (UINT8) ((UINTN) VtdUnitInfo->CapReg.Bits.ND * 2 + 4)) - 1);
+ ContextEntry->Bits.Present = 1;
+ FlushPageTableMemory (VtdUnitInfo, (UINTN) ContextEntry, sizeof (*ContextEntry));
+ }
}
return EFI_SUCCESS;
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-12-14 5:35 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-12-14 5:35 [PATCH v3 0/4] There are 4 patches for VTd drivers Sheng Wei
2021-12-14 5:35 ` [PATCH v3 1/4] IntelSiliconPkg/VTd: Fix typos Sheng Wei
2021-12-14 5:35 ` [PATCH v3 2/4] IntelSiliconPkg/VTd: Update VTd register structs Sheng Wei
2021-12-14 5:35 ` [PATCH v3 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode Sheng Wei
2021-12-14 5:35 ` [PATCH v3 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once Sheng Wei
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox