* [PATCH v5 0/4] There are 4 patches for VTd drivers
@ 2022-01-18 8:14 Sheng Wei
2022-01-18 8:14 ` [PATCH v5 1/4] IntelSiliconPkg/VTd: Fix typos Sheng Wei
` (4 more replies)
0 siblings, 5 replies; 12+ messages in thread
From: Sheng Wei @ 2022-01-18 8:14 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.
Patch v4 update:
[PATCH 4/4] Remove unused code.
[PATCH 4/4] Refine comments and vriable name.
[PATCH 4/4] Add empty pointer check.
Patch v5 update:
[PATCH 2/4] Add debug log
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 | 545 +--------------------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c | 429 +++++++---------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c | 474 ++++++++++--------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h | 119 ++---
.../Feature/VTd/IntelVTdDmarPei/TranslationTable.c | 215 ++------
.../Feature/VTd/IntelVTdDxe/DmarAcpiTable.c | 12 +-
.../Feature/VTd/IntelVTdDxe/TranslationTable.c | 22 +-
.../Feature/VTd/IntelVTdDxe/VtdReg.c | 7 +-
.../Feature/VTd/IntelVTdPmrPei/DmarTable.c | 6 +-
.../IntelSiliconPkg/Include/IndustryStandard/Vtd.h | 34 +-
10 files changed, 609 insertions(+), 1254 deletions(-)
--
2.16.2.windows.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v5 1/4] IntelSiliconPkg/VTd: Fix typos
2022-01-18 8:14 [PATCH v5 0/4] There are 4 patches for VTd drivers Sheng Wei
@ 2022-01-18 8:14 ` Sheng Wei
2022-01-18 8:31 ` Huang, Jenny
2022-01-19 8:26 ` Kowalewski, Robert
2022-01-18 8:14 ` [PATCH v5 2/4] IntelSiliconPkg/VTd: Update VTd register structs Sheng Wei
` (3 subsequent siblings)
4 siblings, 2 replies; 12+ messages in thread
From: Sheng Wei @ 2022-01-18 8:14 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>
Reviewed-by: Jenny Huang <jenny.huang@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] 12+ messages in thread
* [PATCH v5 2/4] IntelSiliconPkg/VTd: Update VTd register structs
2022-01-18 8:14 [PATCH v5 0/4] There are 4 patches for VTd drivers Sheng Wei
2022-01-18 8:14 ` [PATCH v5 1/4] IntelSiliconPkg/VTd: Fix typos Sheng Wei
@ 2022-01-18 8:14 ` Sheng Wei
2022-01-21 8:24 ` Huang, Jenny
2022-01-18 8:14 ` [PATCH v5 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode Sheng Wei
` (2 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Sheng Wei @ 2022-01-18 8:14 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>
Reviewed-by: Jenny Huang <jenny.huang@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 | 7 +++--
.../IntelSiliconPkg/Include/IndustryStandard/Vtd.h | 34 +++++++++++++++++-----
5 files changed, 68 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..1aacd39a 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));
}
/**
@@ -769,9 +769,10 @@ DumpVtdRegs (
DEBUG((DEBUG_INFO, " FRCD_REG[%d] - 0x%016lx %016lx\n", Index, FrcdReg.Uint64[1], FrcdReg.Uint64[0]));
if (FrcdReg.Uint64[1] != 0 || FrcdReg.Uint64[0] != 0) {
DEBUG((DEBUG_INFO, " Fault Info - 0x%016lx\n", VTD_64BITS_ADDRESS(FrcdReg.Bits.FILo, FrcdReg.Bits.FIHi)));
+ DEBUG((DEBUG_INFO, " Fault Bit - %d\n", FrcdReg.Bits.F));
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] 12+ messages in thread
* [PATCH v5 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode
2022-01-18 8:14 [PATCH v5 0/4] There are 4 patches for VTd drivers Sheng Wei
2022-01-18 8:14 ` [PATCH v5 1/4] IntelSiliconPkg/VTd: Fix typos Sheng Wei
2022-01-18 8:14 ` [PATCH v5 2/4] IntelSiliconPkg/VTd: Update VTd register structs Sheng Wei
@ 2022-01-18 8:14 ` Sheng Wei
2022-01-21 8:51 ` Huang, Jenny
2022-01-18 8:14 ` [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once Sheng Wei
2022-01-18 8:30 ` [PATCH v5 0/4] There are 4 patches for VTd drivers Huang, Jenny
4 siblings, 1 reply; 12+ messages in thread
From: Sheng Wei @ 2022-01-18 8:14 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>
Reviewed-by: Jenny Huang <jenny.huang@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] 12+ messages in thread
* [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once.
2022-01-18 8:14 [PATCH v5 0/4] There are 4 patches for VTd drivers Sheng Wei
` (2 preceding siblings ...)
2022-01-18 8:14 ` [PATCH v5 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode Sheng Wei
@ 2022-01-18 8:14 ` Sheng Wei
2022-01-21 8:35 ` Huang, Jenny
2022-01-18 8:30 ` [PATCH v5 0/4] There are 4 patches for VTd drivers Huang, Jenny
4 siblings, 1 reply; 12+ messages in thread
From: Sheng Wei @ 2022-01-18 8:14 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>
Reviewed-by: Jenny Huang <jenny.huang@intel.com>
Signed-off-by: Sheng Wei <w.sheng@intel.com>
---
.../Feature/VTd/IntelVTdDmarPei/DmarTable.c | 545 +--------------------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c | 433 +++++++---------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c | 474 ++++++++++--------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h | 119 ++---
.../Feature/VTd/IntelVTdDmarPei/TranslationTable.c | 196 ++------
5 files changed, 533 insertions(+), 1234 deletions(-)
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
index e9c99d0a..acfbc4a8 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
**/
@@ -104,74 +105,6 @@ DumpDmarDeviceScopeEntry (
return;
}
-/**
- Dump DMAR RMRR table.
-
- @param[in] Rmrr DMAR RMRR table
-**/
-VOID
-DumpDmarRmrr (
- IN EFI_ACPI_DMAR_RMRR_HEADER *Rmrr
- )
-{
- EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDeviceScopeEntry;
- INTN RmrrLen;
-
- if (Rmrr == NULL) {
- return;
- }
-
- DEBUG ((DEBUG_INFO,
- " ***************************************************************************\n"
- ));
- DEBUG ((DEBUG_INFO,
- " * Reserved Memory Region Reporting Structure *\n"
- ));
- DEBUG ((DEBUG_INFO,
- " ***************************************************************************\n"
- ));
- DEBUG ((DEBUG_INFO,
- (sizeof (UINTN) == sizeof (UINT64)) ?
- " RMRR address ........................................... 0x%016lx\n" :
- " RMRR address ........................................... 0x%08x\n",
- Rmrr
- ));
- DEBUG ((DEBUG_INFO,
- " Type ................................................. 0x%04x\n",
- Rmrr->Header.Type
- ));
- DEBUG ((DEBUG_INFO,
- " Length ............................................... 0x%04x\n",
- Rmrr->Header.Length
- ));
- DEBUG ((DEBUG_INFO,
- " Segment Number ....................................... 0x%04x\n",
- Rmrr->SegmentNumber
- ));
- DEBUG ((DEBUG_INFO,
- " Reserved Memory Region Base Address .................. 0x%016lx\n",
- Rmrr->ReservedMemoryRegionBaseAddress
- ));
- DEBUG ((DEBUG_INFO,
- " Reserved Memory Region Limit Address ................. 0x%016lx\n",
- Rmrr->ReservedMemoryRegionLimitAddress
- ));
-
- RmrrLen = Rmrr->Header.Length - sizeof(EFI_ACPI_DMAR_RMRR_HEADER);
- DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) (Rmrr + 1);
- while (RmrrLen > 0) {
- DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry);
- RmrrLen -= DmarDeviceScopeEntry->Length;
- DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN) DmarDeviceScopeEntry + DmarDeviceScopeEntry->Length);
- }
-
- DEBUG ((DEBUG_INFO,
- " ***************************************************************************\n\n"
- ));
-
- return;
-}
-
/**
Dump DMAR DRHD table.
@@ -312,9 +245,6 @@ DumpAcpiDMAR (
case EFI_ACPI_DMAR_TYPE_DRHD:
DumpDmarDrhd ((EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader);
break;
- case EFI_ACPI_DMAR_TYPE_RMRR:
- DumpDmarRmrr ((EFI_ACPI_DMAR_RMRR_HEADER *) DmarHeader);
- break;
default:
break;
}
@@ -329,492 +259,43 @@ DumpAcpiDMAR (
return;
}
-/**
- Get VTd engine number.
-
- @param[in] AcpiDmarTable DMAR ACPI table
-
- @return the VTd engine number.
-**/
-UINTN
-GetVtdEngineNumber (
- IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
- )
-{
- EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
- UINTN VtdIndex;
-
- 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:
- VtdIndex++;
- break;
- default:
- break;
- }
- DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) DmarHeader + DmarHeader->Length);
- }
- return VtdIndex ;
-}
-
-/**
- Get PCI device information from DMAR DevScopeEntry.
-
- @param[in] Segment The segment number.
- @param[in] DmarDevScopeEntry DMAR DevScopeEntry
- @param[out] Bus The bus number.
- @param[out] Device The device number.
- @param[out] Function The function number.
-
- @retval EFI_SUCCESS The PCI device information is returned.
-**/
-EFI_STATUS
-GetPciBusDeviceFunction (
- IN UINT16 Segment,
- IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry,
- OUT UINT8 *Bus,
- OUT UINT8 *Device,
- OUT UINT8 *Function
- )
-{
- EFI_ACPI_DMAR_PCI_PATH *DmarPciPath;
- UINT8 MyBus;
- UINT8 MyDevice;
- UINT8 MyFunction;
-
- DmarPciPath = (EFI_ACPI_DMAR_PCI_PATH *) ((UINTN) (DmarDevScopeEntry + 1));
- MyBus = DmarDevScopeEntry->StartBusNumber;
- MyDevice = DmarPciPath->Device;
- MyFunction = DmarPciPath->Function;
-
- switch (DmarDevScopeEntry->Type) {
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:
- while ((UINTN) DmarPciPath + sizeof (EFI_ACPI_DMAR_PCI_PATH) < (UINTN) DmarDevScopeEntry + DmarDevScopeEntry->Length) {
- MyBus = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (Segment, MyBus, MyDevice, MyFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
- DmarPciPath ++;
- MyDevice = DmarPciPath->Device;
- MyFunction = DmarPciPath->Function;
- }
- break;
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC:
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET:
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE:
- break;
- }
-
- *Bus = MyBus;
- *Device = MyDevice;
- *Function = MyFunction;
-
- return EFI_SUCCESS;
-}
-
-/**
- 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.
-
- @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.
-
- @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.
-
-**/
-EFI_STATUS
-RegisterPciDevice (
- IN VTD_UNIT_INFO *VTdUnitInfo,
- IN UINT16 Segment,
- IN VTD_SOURCE_ID SourceId,
- IN UINT8 DeviceType,
- IN BOOLEAN CheckExist
- )
-{
- 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"));
-
- 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;
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Process DMAR DRHD table.
-
- @param[in] VTdUnitInfo The VTd engine unit information.
- @param[in] DmarDrhd The DRHD table.
-
-**/
-VOID
-ProcessDrhd (
- IN VTD_UNIT_INFO *VTdUnitInfo,
- IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
- )
-{
- EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry;
- UINT8 Bus;
- 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"));
- }
-
- VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber = 0;
- VTdUnitInfo->PciDeviceInfo.PciDeviceDataMaxNumber = 0;
- VTdUnitInfo->PciDeviceInfo.PciDeviceDataPageSize = 0;
- VTdUnitInfo->PciDeviceInfo.PciDeviceData = 0;
-
- DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN) (DmarDrhd + 1));
- while ((UINTN)DmarDevScopeEntry < (UINTN) DmarDrhd + DmarDrhd->Header.Length) {
-
- Status = GetPciBusDeviceFunction (DmarDrhd->SegmentNumber, DmarDevScopeEntry, &Bus, &Device, &Function);
- if (EFI_ERROR (Status)) {
- return;
- }
-
- 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;
- }
- 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);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR,"RegisterPciDevice Failed !\n"));
- }
-
- 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
- ));
-
- PciDeviceDataBase = (PEI_PCI_DEVICE_DATA *) (UINTN) VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.PciDeviceData;
-
- 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
- ));
- }
-}
-
/**
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.
**/
EFI_STATUS
ParseDmarAcpiTableDrhd (
- IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
+ IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable,
+ IN PROCESS_DRHD_CALLBACK_FUNC Callback,
+ IN VOID *Context
)
{
EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
- UINTN VtdUnitNumber;
- UINTN VtdIndex;
- VTD_INFO *VTdInfo;
-
- VtdUnitNumber = GetVtdEngineNumber (AcpiDmarTable);
- if (VtdUnitNumber == 0) {
- return EFI_UNSUPPORTED;
- }
-
- 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;
+ UINT32 VtdIndex;
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);
+ if (Callback != NULL) {
+ Callback (Context, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader);
+ }
VtdIndex++;
-
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;
-}
-
-
-/**
- Process DMAR RMRR table.
-
- @param[in] VTdInfo The VTd engine context information.
- @param[in] DmarRmrr The RMRR table.
-
-**/
-VOID
-ProcessRmrr (
- IN VTD_INFO *VTdInfo,
- IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr
- )
-{
- EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry;
- UINT8 Bus;
- UINT8 Device;
- UINT8 Function;
- EFI_STATUS Status;
- VTD_SOURCE_ID SourceId;
-
- DEBUG ((DEBUG_INFO," PEI RMRR (Base 0x%016lx, Limit 0x%016lx)\n", DmarRmrr->ReservedMemoryRegionBaseAddress, DmarRmrr->ReservedMemoryRegionLimitAddress));
-
- if ((DmarRmrr->ReservedMemoryRegionBaseAddress == 0) ||
- (DmarRmrr->ReservedMemoryRegionLimitAddress == 0)) {
- return ;
- }
-
- 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;
- }
-
- Status = GetPciBusDeviceFunction (DmarRmrr->SegmentNumber, DmarDevScopeEntry, &Bus, &Device, &Function);
- if (EFI_ERROR (Status)) {
- continue;
- }
-
- 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));
- }
-
- DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN) DmarDevScopeEntry + DmarDevScopeEntry->Length);
- }
-}
-
-/**
- Parse DMAR DRHD table.
-
- @param[in] VTdInfo The VTd engine context information.
-
-**/
-VOID
-ParseDmarAcpiTableRmrr (
- IN VTD_INFO *VTdInfo
- )
-{
- 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);
- break;
- default:
- break;
- }
- DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) DmarHeader + DmarHeader->Length);
- }
+ return VtdIndex;
}
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c
index 63397a1a..0ed216bb 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..ac91eac3 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,114 @@ 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;
- 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;
+ 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.
+
+ @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);
}
/**
- Initializes the Intel VTd Info.
+ 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 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 +481,103 @@ InitVTdInfo (
VOID
)
{
- EFI_STATUS Status;
- EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
- VOID *Hob;
VTD_INFO *VTdInfo;
- UINT64 EngineMask;
+ EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
+ UINTN VtdUnitNumber;
+ VTD_UNIT_INFO *VtdUnitInfo;
+ EFI_STATUS Status;
+ UINTN NewUnitIndex;
+ UINTN PreviousUnitIndex;
- Status = PeiServicesLocatePpi (
- &gEdkiiVTdInfoPpiGuid,
- 0,
- NULL,
- (VOID **)&AcpiDmarTable
- );
- ASSERT_EFI_ERROR (Status);
+ VTdInfo = GetVTdInfoHob ();
+ ASSERT (VTdInfo != NULL);
- DumpAcpiDMAR (AcpiDmarTable);
+ AcpiDmarTable = GetAcpiDmarTable ();
+ ASSERT (AcpiDmarTable != NULL);
//
- // Clear old VTdInfo Hob.
+ // Get VTd Unit Number
//
- Hob = GetFirstGuidHob (&mVTdInfoGuid);
- if (Hob != NULL) {
- DEBUG ((DEBUG_INFO, " Find Hob : mVTdInfoGuid - 0x%x\n", Hob));
-
- VTdInfo = GET_GUID_HOB_DATA(Hob);
- EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;
- EnableVTdTranslationProtectionAll (VTdInfo, EngineMask);
-
- ReleaseVTdInfo (VTdInfo);
- VTdInfo->VTdEngineCount = 0;
+ VtdUnitNumber = ParseDmarAcpiTableDrhd (AcpiDmarTable, NULL, NULL);
+ if (VtdUnitNumber == 0) {
+ return EFI_UNSUPPORTED;
+ }
- ZeroMem (&((EFI_HOB_GUID_TYPE *) Hob)->Name, sizeof (EFI_GUID));
+ //
+ // Genrate a new Vtd Unit Info Table
+ //
+ 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
+ // Parse the DMAR ACPI Table to the new Vtd Unit Info Table
//
- 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) {
+ //
+ // New Vtd Unit Info Table Loop
+ //
+ for (NewUnitIndex = 0; NewUnitIndex < VtdUnitNumber; NewUnitIndex++) {
+ //
+ // Previous Vtd Unit Info Table Loop
+ //
+ for (PreviousUnitIndex = 0; PreviousUnitIndex < VTdInfo->VTdEngineCount; PreviousUnitIndex++) {
+ //
+ // Compare the new Vtd Unit with the previous VTd Unit
+ //
+ if (VtdUnitInfo[NewUnitIndex].VtdUnitBaseAddress == VTdInfo->VtdUnitInfo[PreviousUnitIndex].VtdUnitBaseAddress) {
+ DEBUG ((DEBUG_INFO,"Find VTD [0x%08x] Exist\n", VtdUnitInfo[NewUnitIndex].VtdUnitBaseAddress));
+ CopyMem (&VtdUnitInfo[NewUnitIndex], &VTdInfo->VtdUnitInfo[PreviousUnitIndex], sizeof (VTD_UNIT_INFO));
+ VtdUnitInfo[NewUnitIndex].Done = TRUE;
+
+ break;
+ }
+ }
+ }
+ }
+ VTdInfo->AcpiDmarTable = AcpiDmarTable;
+ VTdInfo->HostAddressWidth = AcpiDmarTable->HostAddressWidth;
+ VTdInfo->VTdEngineCount = VtdUnitNumber;
+ VTdInfo->VtdUnitInfo = VtdUnitInfo;
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;
+ EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
- 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;
- }
-
- 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 +600,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 +611,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 +621,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 +671,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 +687,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);
@@ -619,10 +695,6 @@ InitVTdDmarForDma (
return Status;
}
- // If there is RMRR memory, parse it here.
- DEBUG ((DEBUG_INFO, "PeiParseDmarAcpiTableRmrr\n"));
- ParseDmarAcpiTableRmrr (VTdInfo);
-
DEBUG ((DEBUG_INFO, "EnableVtdDmar\n"));
Status = EnableVTdTranslationProtection(VTdInfo);
if (EFI_ERROR (Status)) {
@@ -668,21 +740,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 +794,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 +814,16 @@ VTdInfoNotify (
//
Status = InitDmaBuffer ();
- ASSERT_EFI_ERROR(Status);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // NOTE: We need reinit VTdInfo because previous information might be overriden.
+ //
+ Status = InitVTdInfo ();
+ ASSERT_EFI_ERROR (Status);
- InitVTdDmarForDma ();
+ Status = InitVTdDmarForDma ();
+ ASSERT_EFI_ERROR (Status);
}
return EFI_SUCCESS;
@@ -826,4 +889,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..351a7810 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h
@@ -9,68 +9,61 @@
#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;
-
-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;
} 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_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 +83,27 @@ 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.
-**/
-EFI_STATUS
-ParseDmarAcpiTableDrhd (
- IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
- );
-
-/**
- Parse DMAR DRHD table.
+ @return the VTd engine number.
- @param[in] VTdInfo The VTd engine context information.
**/
-VOID
-ParseDmarAcpiTableRmrr (
- IN VTD_INFO *VTdInfo
+UINTN
+ParseDmarAcpiTableDrhd (
+ IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable,
+ IN PROCESS_DRHD_CALLBACK_FUNC Callback,
+ IN VOID *Context
);
/**
@@ -214,30 +200,7 @@ GetPciDataIndex (
IN VTD_SOURCE_ID SourceId
);
-/**
- Always enable the VTd page attribute for the device.
-
- @param[in] VTdInfo The VTd engine context 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.
- @param[in] MemoryBase The base of the memory.
- @param[in] MemoryLimit The limit of the memory.
- @param[in] IoMmuAccess The IOMMU access.
-
- @retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device.
-**/
-EFI_STATUS
-EnableRmrrPageAttribute (
- IN VTD_INFO *VTdInfo,
- IN UINT16 Segment,
- IN VTD_SOURCE_ID SourceId,
- IN UINT64 MemoryBase,
- IN UINT64 MemoryLimit,
- IN UINT64 IoMmuAccess
- );
-
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..c94f4a85 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);
@@ -304,7 +309,7 @@ CreateContextEntry (
RootEntry->Bits.ContextTablePointerHi = (UINT32) RShiftU64 ((UINT64) (UINTN) Buffer, 32);
RootEntry->Bits.Present = 1;
Buffer = (UINT8 *)Buffer + EFI_PAGES_TO_SIZE (ContextPages);
- ContextEntryTable = (VTD_CONTEXT_ENTRY *) (UINTN) VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry->Bits.ContextTablePointerHi) ;
+ ContextEntryTable = (VTD_CONTEXT_ENTRY *) (UINTN) VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry->Bits.ContextTablePointerHi);
for (ContextIndex = 0; ContextIndex < VTD_CONTEXT_ENTRY_NUMBER; ContextIndex++) {
SourceId.Index.ContextIndex = (UINT8) ContextIndex;
@@ -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);
@@ -390,7 +399,7 @@ CreateExtContextEntry (
ExtRootEntry->Bits.UpperContextTablePointerHi = (UINT32) RShiftU64 (RShiftU64 ((UINT64) (UINTN) Buffer, 12) + 1, 20);
ExtRootEntry->Bits.UpperPresent = 1;
Buffer = (UINT8 *) Buffer + EFI_PAGES_TO_SIZE (ContextPages);
- ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *) (UINTN) VTD_64BITS_ADDRESS (ExtRootEntry->Bits.LowerContextTablePointerLo, ExtRootEntry->Bits.LowerContextTablePointerHi) ;
+ ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *) (UINTN) VTD_64BITS_ADDRESS (ExtRootEntry->Bits.LowerContextTablePointerLo, ExtRootEntry->Bits.LowerContextTablePointerHi);
for (ContextIndex = 0; ContextIndex < VTD_CONTEXT_ENTRY_NUMBER; ContextIndex++) {
SourceId.Index.ContextIndex = (UINT8) ContextIndex;
@@ -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)) {
@@ -911,151 +923,3 @@ SetupTranslationTable (
return EFI_SUCCESS;
}
-/**
- Find the VTd index by the Segment and SourceId.
-
- @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.
-**/
-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
- )
-{
- 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;
-
- 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 (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 (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;
- }
-
- return VtdIndex;
- }
-
- return (UINTN)-1;
-}
-
-/**
- Always enable the VTd page attribute for the device.
-
- @param[in] VTdInfo The VTd engine context 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.
- @param[in] MemoryBase The base of the memory.
- @param[in] MemoryLimit The limit of the memory.
- @param[in] IoMmuAccess The IOMMU access.
-
- @retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device.
-**/
-EFI_STATUS
-EnableRmrrPageAttribute (
- IN VTD_INFO *VTdInfo,
- IN UINT16 Segment,
- IN VTD_SOURCE_ID SourceId,
- IN UINT64 MemoryBase,
- IN UINT64 MemoryLimit,
- IN UINT64 IoMmuAccess
- )
-{
- EFI_STATUS Status;
- UINTN VtdIndex;
- VTD_EXT_CONTEXT_ENTRY *ExtContextEntry;
- VTD_CONTEXT_ENTRY *ContextEntry;
- VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
- UINT64 Pt;
-
- 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;
- }
-
- 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;
- }
- }
-
- 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));
- }
-
- return EFI_SUCCESS;
-}
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v5 0/4] There are 4 patches for VTd drivers
2022-01-18 8:14 [PATCH v5 0/4] There are 4 patches for VTd drivers Sheng Wei
` (3 preceding siblings ...)
2022-01-18 8:14 ` [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once Sheng Wei
@ 2022-01-18 8:30 ` Huang, Jenny
4 siblings, 0 replies; 12+ messages in thread
From: Huang, Jenny @ 2022-01-18 8:30 UTC (permalink / raw)
To: Sheng, W, devel@edk2.groups.io
Cc: Ni, Ray, Chaganty, Rangasai V, Kowalewski, Robert
Reviewed-by: Jenny Huang <jenny.huang@intel.com>
-----Original Message-----
From: Sheng, W <w.sheng@intel.com>
Sent: Tuesday, January 18, 2022 4:14 PM
To: devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Huang, Jenny <jenny.huang@intel.com>; Kowalewski, Robert <robert.kowalewski@intel.com>
Subject: [PATCH v5 0/4] There are 4 patches for VTd drivers
[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.
Patch v4 update:
[PATCH 4/4] Remove unused code.
[PATCH 4/4] Refine comments and vriable name.
[PATCH 4/4] Add empty pointer check.
Patch v5 update:
[PATCH 2/4] Add debug log
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 | 545 +--------------------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c | 429 +++++++---------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c | 474 ++++++++++-------- .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h | 119 ++--- .../Feature/VTd/IntelVTdDmarPei/TranslationTable.c | 215 ++------
.../Feature/VTd/IntelVTdDxe/DmarAcpiTable.c | 12 +-
.../Feature/VTd/IntelVTdDxe/TranslationTable.c | 22 +-
.../Feature/VTd/IntelVTdDxe/VtdReg.c | 7 +-
.../Feature/VTd/IntelVTdPmrPei/DmarTable.c | 6 +-
.../IntelSiliconPkg/Include/IndustryStandard/Vtd.h | 34 +-
10 files changed, 609 insertions(+), 1254 deletions(-)
--
2.16.2.windows.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v5 1/4] IntelSiliconPkg/VTd: Fix typos
2022-01-18 8:14 ` [PATCH v5 1/4] IntelSiliconPkg/VTd: Fix typos Sheng Wei
@ 2022-01-18 8:31 ` Huang, Jenny
2022-01-19 8:26 ` Kowalewski, Robert
1 sibling, 0 replies; 12+ messages in thread
From: Huang, Jenny @ 2022-01-18 8:31 UTC (permalink / raw)
To: Sheng, W, devel@edk2.groups.io
Cc: Ni, Ray, Chaganty, Rangasai V, Kowalewski, Robert
Reviewed-by: Jenny Huang <jenny.huang@intel.com>
-----Original Message-----
From: Sheng, W <w.sheng@intel.com>
Sent: Tuesday, January 18, 2022 4:15 PM
To: devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Huang, Jenny <jenny.huang@intel.com>; Kowalewski, Robert <robert.kowalewski@intel.com>
Subject: [PATCH v5 1/4] IntelSiliconPkg/VTd: Fix typos
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>
Reviewed-by: Jenny Huang <jenny.huang@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/DmarTabl
+++ e.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/DmarAcpiTabl
+++ e.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 [flat|nested] 12+ messages in thread
* Re: [PATCH v5 1/4] IntelSiliconPkg/VTd: Fix typos
2022-01-18 8:14 ` [PATCH v5 1/4] IntelSiliconPkg/VTd: Fix typos Sheng Wei
2022-01-18 8:31 ` Huang, Jenny
@ 2022-01-19 8:26 ` Kowalewski, Robert
1 sibling, 0 replies; 12+ messages in thread
From: Kowalewski, Robert @ 2022-01-19 8:26 UTC (permalink / raw)
To: Sheng, W, devel@edk2.groups.io
Cc: Ni, Ray, Chaganty, Rangasai V, Huang, Jenny
Reviewed-by: Robert Kowalewski <robert.kowalewski@intel.com>
-----Original Message-----
From: Sheng, W <w.sheng@intel.com>
Sent: Tuesday, January 18, 2022 9:15 AM
To: devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Huang, Jenny <jenny.huang@intel.com>; Kowalewski, Robert <robert.kowalewski@intel.com>
Subject: [PATCH v5 1/4] IntelSiliconPkg/VTd: Fix typos
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>
Reviewed-by: Jenny Huang <jenny.huang@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/DmarTabl
+++ e.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/DmarAcpiTabl
+++ e.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
---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v5 2/4] IntelSiliconPkg/VTd: Update VTd register structs
2022-01-18 8:14 ` [PATCH v5 2/4] IntelSiliconPkg/VTd: Update VTd register structs Sheng Wei
@ 2022-01-21 8:24 ` Huang, Jenny
0 siblings, 0 replies; 12+ messages in thread
From: Huang, Jenny @ 2022-01-21 8:24 UTC (permalink / raw)
To: Sheng, W, devel@edk2.groups.io
Cc: Ni, Ray, Chaganty, Rangasai V, Kowalewski, Robert
Reviewed-by: Jenny Huang <jenny.huang@intel.com>
-----Original Message-----
From: Sheng, W <w.sheng@intel.com>
Sent: Tuesday, January 18, 2022 4:15 PM
To: devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Huang, Jenny <jenny.huang@intel.com>; Kowalewski, Robert <robert.kowalewski@intel.com>
Subject: [PATCH v5 2/4] IntelSiliconPkg/VTd: Update VTd register structs
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>
Reviewed-by: Jenny Huang <jenny.huang@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 | 7 +++--
.../IntelSiliconPkg/Include/IndustryStandard/Vtd.h | 34 +++++++++++++++++-----
5 files changed, 68 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..1aacd39a 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));
}
/**
@@ -769,9 +769,10 @@ DumpVtdRegs (
DEBUG((DEBUG_INFO, " FRCD_REG[%d] - 0x%016lx %016lx\n", Index, FrcdReg.Uint64[1], FrcdReg.Uint64[0]));
if (FrcdReg.Uint64[1] != 0 || FrcdReg.Uint64[0] != 0) {
DEBUG((DEBUG_INFO, " Fault Info - 0x%016lx\n", VTD_64BITS_ADDRESS(FrcdReg.Bits.FILo, FrcdReg.Bits.FIHi)));
+ DEBUG((DEBUG_INFO, " Fault Bit - %d\n", FrcdReg.Bits.F));
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] 12+ messages in thread
* Re: [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once.
2022-01-18 8:14 ` [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once Sheng Wei
@ 2022-01-21 8:35 ` Huang, Jenny
2022-01-24 2:44 ` Sheng Wei
0 siblings, 1 reply; 12+ messages in thread
From: Huang, Jenny @ 2022-01-21 8:35 UTC (permalink / raw)
To: Sheng, W, devel@edk2.groups.io
Cc: Ni, Ray, Chaganty, Rangasai V, Kowalewski, Robert
Reviewed-by: Jenny Huang <jenny.huang@intel.com>
-----Original Message-----
From: Sheng, W <w.sheng@intel.com>
Sent: Tuesday, January 18, 2022 4:15 PM
To: devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Huang, Jenny <jenny.huang@intel.com>; Kowalewski, Robert <robert.kowalewski@intel.com>
Subject: [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once.
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>
Reviewed-by: Jenny Huang <jenny.huang@intel.com>
Signed-off-by: Sheng Wei <w.sheng@intel.com>
---
.../Feature/VTd/IntelVTdDmarPei/DmarTable.c | 545 +--------------------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c | 433 +++++++---------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c | 474 ++++++++++--------
.../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h | 119 ++---
.../Feature/VTd/IntelVTdDmarPei/TranslationTable.c | 196 ++------
5 files changed, 533 insertions(+), 1234 deletions(-)
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
index e9c99d0a..acfbc4a8 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
**/
@@ -104,74 +105,6 @@ DumpDmarDeviceScopeEntry (
return;
}
-/**
- Dump DMAR RMRR table.
-
- @param[in] Rmrr DMAR RMRR table
-**/
-VOID
-DumpDmarRmrr (
- IN EFI_ACPI_DMAR_RMRR_HEADER *Rmrr
- )
-{
- EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDeviceScopeEntry;
- INTN RmrrLen;
-
- if (Rmrr == NULL) {
- return;
- }
-
- DEBUG ((DEBUG_INFO,
- " ***************************************************************************\n"
- ));
- DEBUG ((DEBUG_INFO,
- " * Reserved Memory Region Reporting Structure *\n"
- ));
- DEBUG ((DEBUG_INFO,
- " ***************************************************************************\n"
- ));
- DEBUG ((DEBUG_INFO,
- (sizeof (UINTN) == sizeof (UINT64)) ?
- " RMRR address ........................................... 0x%016lx\n" :
- " RMRR address ........................................... 0x%08x\n",
- Rmrr
- ));
- DEBUG ((DEBUG_INFO,
- " Type ................................................. 0x%04x\n",
- Rmrr->Header.Type
- ));
- DEBUG ((DEBUG_INFO,
- " Length ............................................... 0x%04x\n",
- Rmrr->Header.Length
- ));
- DEBUG ((DEBUG_INFO,
- " Segment Number ....................................... 0x%04x\n",
- Rmrr->SegmentNumber
- ));
- DEBUG ((DEBUG_INFO,
- " Reserved Memory Region Base Address .................. 0x%016lx\n",
- Rmrr->ReservedMemoryRegionBaseAddress
- ));
- DEBUG ((DEBUG_INFO,
- " Reserved Memory Region Limit Address ................. 0x%016lx\n",
- Rmrr->ReservedMemoryRegionLimitAddress
- ));
-
- RmrrLen = Rmrr->Header.Length - sizeof(EFI_ACPI_DMAR_RMRR_HEADER);
- DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) (Rmrr + 1);
- while (RmrrLen > 0) {
- DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry);
- RmrrLen -= DmarDeviceScopeEntry->Length;
- DmarDeviceScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN) DmarDeviceScopeEntry + DmarDeviceScopeEntry->Length);
- }
-
- DEBUG ((DEBUG_INFO,
- " ***************************************************************************\n\n"
- ));
-
- return;
-}
-
/**
Dump DMAR DRHD table.
@@ -312,9 +245,6 @@ DumpAcpiDMAR (
case EFI_ACPI_DMAR_TYPE_DRHD:
DumpDmarDrhd ((EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader);
break;
- case EFI_ACPI_DMAR_TYPE_RMRR:
- DumpDmarRmrr ((EFI_ACPI_DMAR_RMRR_HEADER *) DmarHeader);
- break;
default:
break;
}
@@ -329,492 +259,43 @@ DumpAcpiDMAR (
return;
}
-/**
- Get VTd engine number.
-
- @param[in] AcpiDmarTable DMAR ACPI table
-
- @return the VTd engine number.
-**/
-UINTN
-GetVtdEngineNumber (
- IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
- )
-{
- EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
- UINTN VtdIndex;
-
- 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:
- VtdIndex++;
- break;
- default:
- break;
- }
- DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) DmarHeader + DmarHeader->Length);
- }
- return VtdIndex ;
-}
-
-/**
- Get PCI device information from DMAR DevScopeEntry.
-
- @param[in] Segment The segment number.
- @param[in] DmarDevScopeEntry DMAR DevScopeEntry
- @param[out] Bus The bus number.
- @param[out] Device The device number.
- @param[out] Function The function number.
-
- @retval EFI_SUCCESS The PCI device information is returned.
-**/
-EFI_STATUS
-GetPciBusDeviceFunction (
- IN UINT16 Segment,
- IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry,
- OUT UINT8 *Bus,
- OUT UINT8 *Device,
- OUT UINT8 *Function
- )
-{
- EFI_ACPI_DMAR_PCI_PATH *DmarPciPath;
- UINT8 MyBus;
- UINT8 MyDevice;
- UINT8 MyFunction;
-
- DmarPciPath = (EFI_ACPI_DMAR_PCI_PATH *) ((UINTN) (DmarDevScopeEntry + 1));
- MyBus = DmarDevScopeEntry->StartBusNumber;
- MyDevice = DmarPciPath->Device;
- MyFunction = DmarPciPath->Function;
-
- switch (DmarDevScopeEntry->Type) {
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:
- while ((UINTN) DmarPciPath + sizeof (EFI_ACPI_DMAR_PCI_PATH) < (UINTN) DmarDevScopeEntry + DmarDevScopeEntry->Length) {
- MyBus = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (Segment, MyBus, MyDevice, MyFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
- DmarPciPath ++;
- MyDevice = DmarPciPath->Device;
- MyFunction = DmarPciPath->Function;
- }
- break;
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC:
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET:
- case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE:
- break;
- }
-
- *Bus = MyBus;
- *Device = MyDevice;
- *Function = MyFunction;
-
- return EFI_SUCCESS;
-}
-
-/**
- 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.
-
- @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.
-
- @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.
-
-**/
-EFI_STATUS
-RegisterPciDevice (
- IN VTD_UNIT_INFO *VTdUnitInfo,
- IN UINT16 Segment,
- IN VTD_SOURCE_ID SourceId,
- IN UINT8 DeviceType,
- IN BOOLEAN CheckExist
- )
-{
- 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"));
-
- 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;
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Process DMAR DRHD table.
-
- @param[in] VTdUnitInfo The VTd engine unit information.
- @param[in] DmarDrhd The DRHD table.
-
-**/
-VOID
-ProcessDrhd (
- IN VTD_UNIT_INFO *VTdUnitInfo,
- IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
- )
-{
- EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry;
- UINT8 Bus;
- 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"));
- }
-
- VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber = 0;
- VTdUnitInfo->PciDeviceInfo.PciDeviceDataMaxNumber = 0;
- VTdUnitInfo->PciDeviceInfo.PciDeviceDataPageSize = 0;
- VTdUnitInfo->PciDeviceInfo.PciDeviceData = 0;
-
- DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN) (DmarDrhd + 1));
- while ((UINTN)DmarDevScopeEntry < (UINTN) DmarDrhd + DmarDrhd->Header.Length) {
-
- Status = GetPciBusDeviceFunction (DmarDrhd->SegmentNumber, DmarDevScopeEntry, &Bus, &Device, &Function);
- if (EFI_ERROR (Status)) {
- return;
- }
-
- 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;
- }
- 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);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR,"RegisterPciDevice Failed !\n"));
- }
-
- 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
- ));
-
- PciDeviceDataBase = (PEI_PCI_DEVICE_DATA *) (UINTN) VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.PciDeviceData;
-
- 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
- ));
- }
-}
-
/**
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.
**/
EFI_STATUS
ParseDmarAcpiTableDrhd (
- IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
+ IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable,
+ IN PROCESS_DRHD_CALLBACK_FUNC Callback,
+ IN VOID *Context
)
{
EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
- UINTN VtdUnitNumber;
- UINTN VtdIndex;
- VTD_INFO *VTdInfo;
-
- VtdUnitNumber = GetVtdEngineNumber (AcpiDmarTable);
- if (VtdUnitNumber == 0) {
- return EFI_UNSUPPORTED;
- }
-
- 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;
+ UINT32 VtdIndex;
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);
+ if (Callback != NULL) {
+ Callback (Context, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader);
+ }
VtdIndex++;
-
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;
-}
-
-
-/**
- Process DMAR RMRR table.
-
- @param[in] VTdInfo The VTd engine context information.
- @param[in] DmarRmrr The RMRR table.
-
-**/
-VOID
-ProcessRmrr (
- IN VTD_INFO *VTdInfo,
- IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr
- )
-{
- EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry;
- UINT8 Bus;
- UINT8 Device;
- UINT8 Function;
- EFI_STATUS Status;
- VTD_SOURCE_ID SourceId;
-
- DEBUG ((DEBUG_INFO," PEI RMRR (Base 0x%016lx, Limit 0x%016lx)\n", DmarRmrr->ReservedMemoryRegionBaseAddress, DmarRmrr->ReservedMemoryRegionLimitAddress));
-
- if ((DmarRmrr->ReservedMemoryRegionBaseAddress == 0) ||
- (DmarRmrr->ReservedMemoryRegionLimitAddress == 0)) {
- return ;
- }
-
- 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;
- }
-
- Status = GetPciBusDeviceFunction (DmarRmrr->SegmentNumber, DmarDevScopeEntry, &Bus, &Device, &Function);
- if (EFI_ERROR (Status)) {
- continue;
- }
-
- 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));
- }
-
- DmarDevScopeEntry = (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN) DmarDevScopeEntry + DmarDevScopeEntry->Length);
- }
-}
-
-/**
- Parse DMAR DRHD table.
-
- @param[in] VTdInfo The VTd engine context information.
-
-**/
-VOID
-ParseDmarAcpiTableRmrr (
- IN VTD_INFO *VTdInfo
- )
-{
- 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);
- break;
- default:
- break;
- }
- DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) DmarHeader + DmarHeader->Length);
- }
+ return VtdIndex;
}
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c
index 63397a1a..0ed216bb 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..ac91eac3 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,114 @@ 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;
- 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;
+ 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.
+
+ @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);
}
/**
- Initializes the Intel VTd Info.
+ 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 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 +481,103 @@ InitVTdInfo (
VOID
)
{
- EFI_STATUS Status;
- EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
- VOID *Hob;
VTD_INFO *VTdInfo;
- UINT64 EngineMask;
+ EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
+ UINTN VtdUnitNumber;
+ VTD_UNIT_INFO *VtdUnitInfo;
+ EFI_STATUS Status;
+ UINTN NewUnitIndex;
+ UINTN PreviousUnitIndex;
- Status = PeiServicesLocatePpi (
- &gEdkiiVTdInfoPpiGuid,
- 0,
- NULL,
- (VOID **)&AcpiDmarTable
- );
- ASSERT_EFI_ERROR (Status);
+ VTdInfo = GetVTdInfoHob ();
+ ASSERT (VTdInfo != NULL);
- DumpAcpiDMAR (AcpiDmarTable);
+ AcpiDmarTable = GetAcpiDmarTable ();
+ ASSERT (AcpiDmarTable != NULL);
//
- // Clear old VTdInfo Hob.
+ // Get VTd Unit Number
//
- Hob = GetFirstGuidHob (&mVTdInfoGuid);
- if (Hob != NULL) {
- DEBUG ((DEBUG_INFO, " Find Hob : mVTdInfoGuid - 0x%x\n", Hob));
-
- VTdInfo = GET_GUID_HOB_DATA(Hob);
- EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;
- EnableVTdTranslationProtectionAll (VTdInfo, EngineMask);
-
- ReleaseVTdInfo (VTdInfo);
- VTdInfo->VTdEngineCount = 0;
+ VtdUnitNumber = ParseDmarAcpiTableDrhd (AcpiDmarTable, NULL, NULL);
+ if (VtdUnitNumber == 0) {
+ return EFI_UNSUPPORTED;
+ }
- ZeroMem (&((EFI_HOB_GUID_TYPE *) Hob)->Name, sizeof (EFI_GUID));
+ //
+ // Genrate a new Vtd Unit Info Table
+ //
+ 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
+ // Parse the DMAR ACPI Table to the new Vtd Unit Info Table
//
- 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) {
+ //
+ // New Vtd Unit Info Table Loop
+ //
+ for (NewUnitIndex = 0; NewUnitIndex < VtdUnitNumber; NewUnitIndex++) {
+ //
+ // Previous Vtd Unit Info Table Loop
+ //
+ for (PreviousUnitIndex = 0; PreviousUnitIndex < VTdInfo->VTdEngineCount; PreviousUnitIndex++) {
+ //
+ // Compare the new Vtd Unit with the previous VTd Unit
+ //
+ if (VtdUnitInfo[NewUnitIndex].VtdUnitBaseAddress == VTdInfo->VtdUnitInfo[PreviousUnitIndex].VtdUnitBaseAddress) {
+ DEBUG ((DEBUG_INFO,"Find VTD [0x%08x] Exist\n", VtdUnitInfo[NewUnitIndex].VtdUnitBaseAddress));
+ CopyMem (&VtdUnitInfo[NewUnitIndex], &VTdInfo->VtdUnitInfo[PreviousUnitIndex], sizeof (VTD_UNIT_INFO));
+ VtdUnitInfo[NewUnitIndex].Done = TRUE;
+
+ break;
+ }
+ }
+ }
+ }
+ VTdInfo->AcpiDmarTable = AcpiDmarTable;
+ VTdInfo->HostAddressWidth = AcpiDmarTable->HostAddressWidth;
+ VTdInfo->VTdEngineCount = VtdUnitNumber;
+ VTdInfo->VtdUnitInfo = VtdUnitInfo;
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;
+ EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
- 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;
- }
-
- 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 +600,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 +611,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 +621,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 +671,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 +687,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);
@@ -619,10 +695,6 @@ InitVTdDmarForDma (
return Status;
}
- // If there is RMRR memory, parse it here.
- DEBUG ((DEBUG_INFO, "PeiParseDmarAcpiTableRmrr\n"));
- ParseDmarAcpiTableRmrr (VTdInfo);
-
DEBUG ((DEBUG_INFO, "EnableVtdDmar\n"));
Status = EnableVTdTranslationProtection(VTdInfo);
if (EFI_ERROR (Status)) {
@@ -668,21 +740,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 +794,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 +814,16 @@ VTdInfoNotify (
//
Status = InitDmaBuffer ();
- ASSERT_EFI_ERROR(Status);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // NOTE: We need reinit VTdInfo because previous information might be overriden.
+ //
+ Status = InitVTdInfo ();
+ ASSERT_EFI_ERROR (Status);
- InitVTdDmarForDma ();
+ Status = InitVTdDmarForDma ();
+ ASSERT_EFI_ERROR (Status);
}
return EFI_SUCCESS;
@@ -826,4 +889,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..351a7810 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h
@@ -9,68 +9,61 @@
#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;
-
-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;
} 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_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 +83,27 @@ 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.
-**/
-EFI_STATUS
-ParseDmarAcpiTableDrhd (
- IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
- );
-
-/**
- Parse DMAR DRHD table.
+ @return the VTd engine number.
- @param[in] VTdInfo The VTd engine context information.
**/
-VOID
-ParseDmarAcpiTableRmrr (
- IN VTD_INFO *VTdInfo
+UINTN
+ParseDmarAcpiTableDrhd (
+ IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable,
+ IN PROCESS_DRHD_CALLBACK_FUNC Callback,
+ IN VOID *Context
);
/**
@@ -214,30 +200,7 @@ GetPciDataIndex (
IN VTD_SOURCE_ID SourceId
);
-/**
- Always enable the VTd page attribute for the device.
-
- @param[in] VTdInfo The VTd engine context 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.
- @param[in] MemoryBase The base of the memory.
- @param[in] MemoryLimit The limit of the memory.
- @param[in] IoMmuAccess The IOMMU access.
-
- @retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device.
-**/
-EFI_STATUS
-EnableRmrrPageAttribute (
- IN VTD_INFO *VTdInfo,
- IN UINT16 Segment,
- IN VTD_SOURCE_ID SourceId,
- IN UINT64 MemoryBase,
- IN UINT64 MemoryLimit,
- IN UINT64 IoMmuAccess
- );
-
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..c94f4a85 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);
@@ -304,7 +309,7 @@ CreateContextEntry (
RootEntry->Bits.ContextTablePointerHi = (UINT32) RShiftU64 ((UINT64) (UINTN) Buffer, 32);
RootEntry->Bits.Present = 1;
Buffer = (UINT8 *)Buffer + EFI_PAGES_TO_SIZE (ContextPages);
- ContextEntryTable = (VTD_CONTEXT_ENTRY *) (UINTN) VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry->Bits.ContextTablePointerHi) ;
+ ContextEntryTable = (VTD_CONTEXT_ENTRY *) (UINTN) VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry->Bits.ContextTablePointerHi);
for (ContextIndex = 0; ContextIndex < VTD_CONTEXT_ENTRY_NUMBER; ContextIndex++) {
SourceId.Index.ContextIndex = (UINT8) ContextIndex;
@@ -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);
@@ -390,7 +399,7 @@ CreateExtContextEntry (
ExtRootEntry->Bits.UpperContextTablePointerHi = (UINT32) RShiftU64 (RShiftU64 ((UINT64) (UINTN) Buffer, 12) + 1, 20);
ExtRootEntry->Bits.UpperPresent = 1;
Buffer = (UINT8 *) Buffer + EFI_PAGES_TO_SIZE (ContextPages);
- ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *) (UINTN) VTD_64BITS_ADDRESS (ExtRootEntry->Bits.LowerContextTablePointerLo, ExtRootEntry->Bits.LowerContextTablePointerHi) ;
+ ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *) (UINTN) VTD_64BITS_ADDRESS (ExtRootEntry->Bits.LowerContextTablePointerLo, ExtRootEntry->Bits.LowerContextTablePointerHi);
for (ContextIndex = 0; ContextIndex < VTD_CONTEXT_ENTRY_NUMBER; ContextIndex++) {
SourceId.Index.ContextIndex = (UINT8) ContextIndex;
@@ -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)) {
@@ -911,151 +923,3 @@ SetupTranslationTable (
return EFI_SUCCESS;
}
-/**
- Find the VTd index by the Segment and SourceId.
-
- @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.
-**/
-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
- )
-{
- 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;
-
- 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 (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 (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;
- }
-
- return VtdIndex;
- }
-
- return (UINTN)-1;
-}
-
-/**
- Always enable the VTd page attribute for the device.
-
- @param[in] VTdInfo The VTd engine context 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.
- @param[in] MemoryBase The base of the memory.
- @param[in] MemoryLimit The limit of the memory.
- @param[in] IoMmuAccess The IOMMU access.
-
- @retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device.
-**/
-EFI_STATUS
-EnableRmrrPageAttribute (
- IN VTD_INFO *VTdInfo,
- IN UINT16 Segment,
- IN VTD_SOURCE_ID SourceId,
- IN UINT64 MemoryBase,
- IN UINT64 MemoryLimit,
- IN UINT64 IoMmuAccess
- )
-{
- EFI_STATUS Status;
- UINTN VtdIndex;
- VTD_EXT_CONTEXT_ENTRY *ExtContextEntry;
- VTD_CONTEXT_ENTRY *ContextEntry;
- VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
- UINT64 Pt;
-
- 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;
- }
-
- 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;
- }
- }
-
- 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));
- }
-
- return EFI_SUCCESS;
-}
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v5 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode
2022-01-18 8:14 ` [PATCH v5 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode Sheng Wei
@ 2022-01-21 8:51 ` Huang, Jenny
0 siblings, 0 replies; 12+ messages in thread
From: Huang, Jenny @ 2022-01-21 8:51 UTC (permalink / raw)
To: Sheng, W, devel@edk2.groups.io
Cc: Ni, Ray, Chaganty, Rangasai V, Kowalewski, Robert
Reviewed-by: Jenny Huang <jenny.huang@intel.com>
-----Original Message-----
From: Sheng, W <w.sheng@intel.com>
Sent: Tuesday, January 18, 2022 4:15 PM
To: devel@edk2.groups.io
Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Huang, Jenny <jenny.huang@intel.com>; Kowalewski, Robert <robert.kowalewski@intel.com>
Subject: [PATCH v5 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode
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>
Reviewed-by: Jenny Huang <jenny.huang@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/IntelVTd
+++ Dmar.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 [flat|nested] 12+ messages in thread
* Re: [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once.
2022-01-21 8:35 ` Huang, Jenny
@ 2022-01-24 2:44 ` Sheng Wei
0 siblings, 0 replies; 12+ messages in thread
From: Sheng Wei @ 2022-01-24 2:44 UTC (permalink / raw)
To: Ni, Ray, Huang, Jenny, devel@edk2.groups.io
Cc: Chaganty, Rangasai V, Kowalewski, Robert
As the review comment form Ray, I will use a fixed MAX VTdUnit number in function VTdInfoNotify().
After that, it will no need to allocate memory at every function call of VTdInfoNotify().
I set the MAX VTd unit number to 42. The total memory usage will just smaller than 4k (1 page). And this number is enough for client and server projects.
I update to patch V6
@Ni, Ray Could you help review and merge the patch ?
Thank you
BR
Sheng Wei
> -----Original Message-----
> From: Huang, Jenny <jenny.huang@intel.com>
> Sent: 2022年1月21日 16:36
> To: Sheng, W <w.sheng@intel.com>; devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Kowalewski, Robert
> <robert.kowalewski@intel.com>
> Subject: RE: [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA
> buffer once.
>
> Reviewed-by: Jenny Huang <jenny.huang@intel.com>
>
> -----Original Message-----
> From: Sheng, W <w.sheng@intel.com>
> Sent: Tuesday, January 18, 2022 4:15 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Huang, Jenny <jenny.huang@intel.com>;
> Kowalewski, Robert <robert.kowalewski@intel.com>
> Subject: [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer
> once.
>
> 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>
> Reviewed-by: Jenny Huang <jenny.huang@intel.com>
> Signed-off-by: Sheng Wei <w.sheng@intel.com>
> ---
> .../Feature/VTd/IntelVTdDmarPei/DmarTable.c | 545 +--------------------
> .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c | 433 +++++++---------
> .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c | 474 ++++++++++----
> ----
> .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h | 119 ++---
> .../Feature/VTd/IntelVTdDmarPei/TranslationTable.c | 196 ++------
> 5 files changed, 533 insertions(+), 1234 deletions(-)
>
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c
> index e9c99d0a..acfbc4a8 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
>
> **/
> @@ -104,74 +105,6 @@ DumpDmarDeviceScopeEntry (
> return;
> }
>
> -/**
> - Dump DMAR RMRR table.
> -
> - @param[in] Rmrr DMAR RMRR table
> -**/
> -VOID
> -DumpDmarRmrr (
> - IN EFI_ACPI_DMAR_RMRR_HEADER *Rmrr
> - )
> -{
> - EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> *DmarDeviceScopeEntry;
> - INTN RmrrLen;
> -
> - if (Rmrr == NULL) {
> - return;
> - }
> -
> - DEBUG ((DEBUG_INFO,
> - "
> **********************************************************
> *****************\n"
> - ));
> - DEBUG ((DEBUG_INFO,
> - " * Reserved Memory Region Reporting Structure *\n"
> - ));
> - DEBUG ((DEBUG_INFO,
> - "
> **********************************************************
> *****************\n"
> - ));
> - DEBUG ((DEBUG_INFO,
> - (sizeof (UINTN) == sizeof (UINT64)) ?
> - " RMRR address ........................................... 0x%016lx\n" :
> - " RMRR address ........................................... 0x%08x\n",
> - Rmrr
> - ));
> - DEBUG ((DEBUG_INFO,
> - " Type ................................................. 0x%04x\n",
> - Rmrr->Header.Type
> - ));
> - DEBUG ((DEBUG_INFO,
> - " Length ............................................... 0x%04x\n",
> - Rmrr->Header.Length
> - ));
> - DEBUG ((DEBUG_INFO,
> - " Segment Number ....................................... 0x%04x\n",
> - Rmrr->SegmentNumber
> - ));
> - DEBUG ((DEBUG_INFO,
> - " Reserved Memory Region Base Address .................. 0x%016lx\n",
> - Rmrr->ReservedMemoryRegionBaseAddress
> - ));
> - DEBUG ((DEBUG_INFO,
> - " Reserved Memory Region Limit Address ................. 0x%016lx\n",
> - Rmrr->ReservedMemoryRegionLimitAddress
> - ));
> -
> - RmrrLen = Rmrr->Header.Length -
> sizeof(EFI_ACPI_DMAR_RMRR_HEADER);
> - DmarDeviceScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) (Rmrr + 1);
> - while (RmrrLen > 0) {
> - DumpDmarDeviceScopeEntry (DmarDeviceScopeEntry);
> - RmrrLen -= DmarDeviceScopeEntry->Length;
> - DmarDeviceScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN)
> DmarDeviceScopeEntry + DmarDeviceScopeEntry->Length);
> - }
> -
> - DEBUG ((DEBUG_INFO,
> - "
> **********************************************************
> *****************\n\n"
> - ));
> -
> - return;
> -}
> -
> /**
> Dump DMAR DRHD table.
>
> @@ -312,9 +245,6 @@ DumpAcpiDMAR (
> case EFI_ACPI_DMAR_TYPE_DRHD:
> DumpDmarDrhd ((EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeader);
> break;
> - case EFI_ACPI_DMAR_TYPE_RMRR:
> - DumpDmarRmrr ((EFI_ACPI_DMAR_RMRR_HEADER *) DmarHeader);
> - break;
> default:
> break;
> }
> @@ -329,492 +259,43 @@ DumpAcpiDMAR (
> return;
> }
>
> -/**
> - Get VTd engine number.
> -
> - @param[in] AcpiDmarTable DMAR ACPI table
> -
> - @return the VTd engine number.
> -**/
> -UINTN
> -GetVtdEngineNumber (
> - IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
> - )
> -{
> - EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
> - UINTN VtdIndex;
> -
> - 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:
> - VtdIndex++;
> - break;
> - default:
> - break;
> - }
> - DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> DmarHeader + DmarHeader->Length);
> - }
> - return VtdIndex ;
> -}
> -
> -/**
> - Get PCI device information from DMAR DevScopeEntry.
> -
> - @param[in] Segment The segment number.
> - @param[in] DmarDevScopeEntry DMAR DevScopeEntry
> - @param[out] Bus The bus number.
> - @param[out] Device The device number.
> - @param[out] Function The function number.
> -
> - @retval EFI_SUCCESS The PCI device information is returned.
> -**/
> -EFI_STATUS
> -GetPciBusDeviceFunction (
> - IN UINT16 Segment,
> - IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> *DmarDevScopeEntry,
> - OUT UINT8 *Bus,
> - OUT UINT8 *Device,
> - OUT UINT8 *Function
> - )
> -{
> - EFI_ACPI_DMAR_PCI_PATH *DmarPciPath;
> - UINT8 MyBus;
> - UINT8 MyDevice;
> - UINT8 MyFunction;
> -
> - DmarPciPath = (EFI_ACPI_DMAR_PCI_PATH *) ((UINTN)
> (DmarDevScopeEntry + 1));
> - MyBus = DmarDevScopeEntry->StartBusNumber;
> - MyDevice = DmarPciPath->Device;
> - MyFunction = DmarPciPath->Function;
> -
> - switch (DmarDevScopeEntry->Type) {
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT:
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE:
> - while ((UINTN) DmarPciPath + sizeof (EFI_ACPI_DMAR_PCI_PATH) <
> (UINTN) DmarDevScopeEntry + DmarDevScopeEntry->Length) {
> - MyBus = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (Segment,
> MyBus, MyDevice, MyFunction,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> - DmarPciPath ++;
> - MyDevice = DmarPciPath->Device;
> - MyFunction = DmarPciPath->Function;
> - }
> - break;
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC:
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET:
> - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE:
> - break;
> - }
> -
> - *Bus = MyBus;
> - *Device = MyDevice;
> - *Function = MyFunction;
> -
> - return EFI_SUCCESS;
> -}
> -
> -/**
> - 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.
> -
> - @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.
> -
> - @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.
> -
> -**/
> -EFI_STATUS
> -RegisterPciDevice (
> - IN VTD_UNIT_INFO *VTdUnitInfo,
> - IN UINT16 Segment,
> - IN VTD_SOURCE_ID SourceId,
> - IN UINT8 DeviceType,
> - IN BOOLEAN CheckExist
> - )
> -{
> - 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"));
> -
> - 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;
> - }
> - }
> -
> - return EFI_SUCCESS;
> -}
> -
> -/**
> - Process DMAR DRHD table.
> -
> - @param[in] VTdUnitInfo The VTd engine unit information.
> - @param[in] DmarDrhd The DRHD table.
> -
> -**/
> -VOID
> -ProcessDrhd (
> - IN VTD_UNIT_INFO *VTdUnitInfo,
> - IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd
> - )
> -{
> - EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> *DmarDevScopeEntry;
> - UINT8 Bus;
> - 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"));
> - }
> -
> - VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber = 0;
> - VTdUnitInfo->PciDeviceInfo.PciDeviceDataMaxNumber = 0;
> - VTdUnitInfo->PciDeviceInfo.PciDeviceDataPageSize = 0;
> - VTdUnitInfo->PciDeviceInfo.PciDeviceData = 0;
> -
> - DmarDevScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN)
> (DmarDrhd + 1));
> - while ((UINTN)DmarDevScopeEntry < (UINTN) DmarDrhd + DmarDrhd-
> >Header.Length) {
> -
> - Status = GetPciBusDeviceFunction (DmarDrhd->SegmentNumber,
> DmarDevScopeEntry, &Bus, &Device, &Function);
> - if (EFI_ERROR (Status)) {
> - return;
> - }
> -
> - 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;
> - }
> - 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);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((DEBUG_ERROR,"RegisterPciDevice Failed !\n"));
> - }
> -
> - 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
> - ));
> -
> - PciDeviceDataBase = (PEI_PCI_DEVICE_DATA *) (UINTN) VTdInfo-
> >VtdUnitInfo[VtdIndex].PciDeviceInfo.PciDeviceData;
> -
> - 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
> - ));
> - }
> -}
> -
> /**
> 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.
>
> **/
> EFI_STATUS
> ParseDmarAcpiTableDrhd (
> - IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
> + IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable,
> + IN PROCESS_DRHD_CALLBACK_FUNC Callback,
> + IN VOID *Context
> )
> {
> EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader;
> - UINTN VtdUnitNumber;
> - UINTN VtdIndex;
> - VTD_INFO *VTdInfo;
> -
> - VtdUnitNumber = GetVtdEngineNumber (AcpiDmarTable);
> - if (VtdUnitNumber == 0) {
> - return EFI_UNSUPPORTED;
> - }
> -
> - 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;
> + UINT32 VtdIndex;
>
> 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);
> + if (Callback != NULL) {
> + Callback (Context, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)
> DmarHeader);
> + }
> VtdIndex++;
> -
> 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;
> -}
> -
> -
> -/**
> - Process DMAR RMRR table.
> -
> - @param[in] VTdInfo The VTd engine context information.
> - @param[in] DmarRmrr The RMRR table.
> -
> -**/
> -VOID
> -ProcessRmrr (
> - IN VTD_INFO *VTdInfo,
> - IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr
> - )
> -{
> - EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER
> *DmarDevScopeEntry;
> - UINT8 Bus;
> - UINT8 Device;
> - UINT8 Function;
> - EFI_STATUS Status;
> - VTD_SOURCE_ID SourceId;
> -
> - DEBUG ((DEBUG_INFO," PEI RMRR (Base 0x%016lx, Limit 0x%016lx)\n",
> DmarRmrr->ReservedMemoryRegionBaseAddress, DmarRmrr-
> >ReservedMemoryRegionLimitAddress));
> -
> - if ((DmarRmrr->ReservedMemoryRegionBaseAddress == 0) ||
> - (DmarRmrr->ReservedMemoryRegionLimitAddress == 0)) {
> - return ;
> - }
> -
> - 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;
> - }
> -
> - Status = GetPciBusDeviceFunction (DmarRmrr->SegmentNumber,
> DmarDevScopeEntry, &Bus, &Device, &Function);
> - if (EFI_ERROR (Status)) {
> - continue;
> - }
> -
> - 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));
> - }
> -
> - DmarDevScopeEntry =
> (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((UINTN)
> DmarDevScopeEntry + DmarDevScopeEntry->Length);
> - }
> -}
> -
> -/**
> - Parse DMAR DRHD table.
> -
> - @param[in] VTdInfo The VTd engine context information.
> -
> -**/
> -VOID
> -ParseDmarAcpiTableRmrr (
> - IN VTD_INFO *VTdInfo
> - )
> -{
> - 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);
> - break;
> - default:
> - break;
> - }
> - DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN)
> DmarHeader + DmarHeader->Length);
> - }
> + return VtdIndex;
> }
>
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.
> c
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.
> c
> index 63397a1a..0ed216bb 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/IntelVTdDmar
> Pei.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.c
> index a8f7bfee..ac91eac3 100644
> ---
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.c
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.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,114 @@ 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;
>
> - 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;
> + 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.
> +
> + @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);
> }
>
> /**
> - Initializes the Intel VTd Info.
> + 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 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 +481,103 @@ InitVTdInfo (
> VOID
> )
> {
> - EFI_STATUS Status;
> - EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
> - VOID *Hob;
> VTD_INFO *VTdInfo;
> - UINT64 EngineMask;
> + EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
> + UINTN VtdUnitNumber;
> + VTD_UNIT_INFO *VtdUnitInfo;
> + EFI_STATUS Status;
> + UINTN NewUnitIndex;
> + UINTN PreviousUnitIndex;
>
> - Status = PeiServicesLocatePpi (
> - &gEdkiiVTdInfoPpiGuid,
> - 0,
> - NULL,
> - (VOID **)&AcpiDmarTable
> - );
> - ASSERT_EFI_ERROR (Status);
> + VTdInfo = GetVTdInfoHob ();
> + ASSERT (VTdInfo != NULL);
>
> - DumpAcpiDMAR (AcpiDmarTable);
> + AcpiDmarTable = GetAcpiDmarTable ();
> + ASSERT (AcpiDmarTable != NULL);
>
> //
> - // Clear old VTdInfo Hob.
> + // Get VTd Unit Number
> //
> - Hob = GetFirstGuidHob (&mVTdInfoGuid);
> - if (Hob != NULL) {
> - DEBUG ((DEBUG_INFO, " Find Hob : mVTdInfoGuid - 0x%x\n", Hob));
> -
> - VTdInfo = GET_GUID_HOB_DATA(Hob);
> - EngineMask = LShiftU64 (1, VTdInfo->VTdEngineCount) - 1;
> - EnableVTdTranslationProtectionAll (VTdInfo, EngineMask);
> -
> - ReleaseVTdInfo (VTdInfo);
> - VTdInfo->VTdEngineCount = 0;
> + VtdUnitNumber = ParseDmarAcpiTableDrhd (AcpiDmarTable, NULL, NULL);
> + if (VtdUnitNumber == 0) {
> + return EFI_UNSUPPORTED;
> + }
>
> - ZeroMem (&((EFI_HOB_GUID_TYPE *) Hob)->Name, sizeof (EFI_GUID));
> + //
> + // Genrate a new Vtd Unit Info Table
> + //
> + 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
> + // Parse the DMAR ACPI Table to the new Vtd Unit Info Table
> //
> - 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) {
> + //
> + // New Vtd Unit Info Table Loop
> + //
> + for (NewUnitIndex = 0; NewUnitIndex < VtdUnitNumber;
> NewUnitIndex++) {
> + //
> + // Previous Vtd Unit Info Table Loop
> + //
> + for (PreviousUnitIndex = 0; PreviousUnitIndex < VTdInfo-
> >VTdEngineCount; PreviousUnitIndex++) {
> + //
> + // Compare the new Vtd Unit with the previous VTd Unit
> + //
> + if (VtdUnitInfo[NewUnitIndex].VtdUnitBaseAddress == VTdInfo-
> >VtdUnitInfo[PreviousUnitIndex].VtdUnitBaseAddress) {
> + DEBUG ((DEBUG_INFO,"Find VTD [0x%08x] Exist\n",
> VtdUnitInfo[NewUnitIndex].VtdUnitBaseAddress));
> + CopyMem (&VtdUnitInfo[NewUnitIndex], &VTdInfo-
> >VtdUnitInfo[PreviousUnitIndex], sizeof (VTD_UNIT_INFO));
> + VtdUnitInfo[NewUnitIndex].Done = TRUE;
> +
> + break;
> + }
> + }
> + }
> + }
> + VTdInfo->AcpiDmarTable = AcpiDmarTable;
> + VTdInfo->HostAddressWidth = AcpiDmarTable->HostAddressWidth;
> + VTdInfo->VTdEngineCount = VtdUnitNumber;
> + VTdInfo->VtdUnitInfo = VtdUnitInfo;
>
> 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;
> + EFI_ACPI_DMAR_HEADER *AcpiDmarTable;
>
> - 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;
> - }
> -
> - 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 +600,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 +611,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 +621,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 +671,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 +687,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);
> @@ -619,10 +695,6 @@ InitVTdDmarForDma (
> return Status;
> }
>
> - // If there is RMRR memory, parse it here.
> - DEBUG ((DEBUG_INFO, "PeiParseDmarAcpiTableRmrr\n"));
> - ParseDmarAcpiTableRmrr (VTdInfo);
> -
> DEBUG ((DEBUG_INFO, "EnableVtdDmar\n"));
> Status = EnableVTdTranslationProtection(VTdInfo);
> if (EFI_ERROR (Status)) {
> @@ -668,21 +740,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 +794,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 +814,16 @@ VTdInfoNotify (
> //
>
> Status = InitDmaBuffer ();
> - ASSERT_EFI_ERROR(Status);
> + ASSERT_EFI_ERROR (Status);
> +
> + //
> + // NOTE: We need reinit VTdInfo because previous information might be
> overriden.
> + //
> + Status = InitVTdInfo ();
> + ASSERT_EFI_ERROR (Status);
>
> - InitVTdDmarForDma ();
> + Status = InitVTdDmarForDma ();
> + ASSERT_EFI_ERROR (Status);
> }
>
> return EFI_SUCCESS;
> @@ -826,4 +889,3 @@ IntelVTdDmarInitialize (
>
> return EFI_SUCCESS;
> }
> -
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.h
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.h
> index e23a6c8e..351a7810 100644
> ---
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.h
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar
> Pei.h
> @@ -9,68 +9,61 @@
> #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;
> -
> -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;
> } 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_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 +83,27 @@ 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.
> -**/
> -EFI_STATUS
> -ParseDmarAcpiTableDrhd (
> - IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable
> - );
> -
> -/**
> - Parse DMAR DRHD table.
> + @return the VTd engine number.
>
> - @param[in] VTdInfo The VTd engine context information.
> **/
> -VOID
> -ParseDmarAcpiTableRmrr (
> - IN VTD_INFO *VTdInfo
> +UINTN
> +ParseDmarAcpiTableDrhd (
> + IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable,
> + IN PROCESS_DRHD_CALLBACK_FUNC Callback,
> + IN VOID *Context
> );
>
> /**
> @@ -214,30 +200,7 @@ GetPciDataIndex (
> IN VTD_SOURCE_ID SourceId
> );
>
> -/**
> - Always enable the VTd page attribute for the device.
> -
> - @param[in] VTdInfo The VTd engine context 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.
> - @param[in] MemoryBase The base of the memory.
> - @param[in] MemoryLimit The limit of the memory.
> - @param[in] IoMmuAccess The IOMMU access.
> -
> - @retval EFI_SUCCESS The VTd entry is updated to always enable all
> DMA access for the specific device.
> -**/
> -EFI_STATUS
> -EnableRmrrPageAttribute (
> - IN VTD_INFO *VTdInfo,
> - IN UINT16 Segment,
> - IN VTD_SOURCE_ID SourceId,
> - IN UINT64 MemoryBase,
> - IN UINT64 MemoryLimit,
> - IN UINT64 IoMmuAccess
> - );
> -
> extern EFI_GUID mVTdInfoGuid;
> extern EFI_GUID mDmaBufferInfoGuid;
>
> #endif
> -
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTab
> le.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTab
> le.c
> index a309d566..c94f4a85 100644
> ---
> a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTab
> le.c
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/TranslationTab
> le.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);
>
> @@ -304,7 +309,7 @@ CreateContextEntry (
> RootEntry->Bits.ContextTablePointerHi = (UINT32) RShiftU64 ((UINT64)
> (UINTN) Buffer, 32);
> RootEntry->Bits.Present = 1;
> Buffer = (UINT8 *)Buffer + EFI_PAGES_TO_SIZE (ContextPages);
> - ContextEntryTable = (VTD_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry-
> >Bits.ContextTablePointerHi) ;
> + ContextEntryTable = (VTD_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS(RootEntry->Bits.ContextTablePointerLo, RootEntry-
> >Bits.ContextTablePointerHi);
>
> for (ContextIndex = 0; ContextIndex < VTD_CONTEXT_ENTRY_NUMBER;
> ContextIndex++) {
> SourceId.Index.ContextIndex = (UINT8) ContextIndex;
> @@ -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);
>
> @@ -390,7 +399,7 @@ CreateExtContextEntry (
> ExtRootEntry->Bits.UpperContextTablePointerHi = (UINT32) RShiftU64
> (RShiftU64 ((UINT64) (UINTN) Buffer, 12) + 1, 20);
> ExtRootEntry->Bits.UpperPresent = 1;
> Buffer = (UINT8 *) Buffer + EFI_PAGES_TO_SIZE (ContextPages);
> - ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS (ExtRootEntry->Bits.LowerContextTablePointerLo,
> ExtRootEntry->Bits.LowerContextTablePointerHi) ;
> + ExtContextEntryTable = (VTD_EXT_CONTEXT_ENTRY *) (UINTN)
> VTD_64BITS_ADDRESS (ExtRootEntry->Bits.LowerContextTablePointerLo,
> ExtRootEntry->Bits.LowerContextTablePointerHi);
>
> for (ContextIndex = 0; ContextIndex < VTD_CONTEXT_ENTRY_NUMBER;
> ContextIndex++) {
> SourceId.Index.ContextIndex = (UINT8) ContextIndex;
> @@ -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)) {
> @@ -911,151 +923,3 @@ SetupTranslationTable (
> return EFI_SUCCESS;
> }
>
> -/**
> - Find the VTd index by the Segment and SourceId.
> -
> - @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.
> -**/
> -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
> - )
> -{
> - 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;
> -
> - 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 (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 (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;
> - }
> -
> - return VtdIndex;
> - }
> -
> - return (UINTN)-1;
> -}
> -
> -/**
> - Always enable the VTd page attribute for the device.
> -
> - @param[in] VTdInfo The VTd engine context 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.
> - @param[in] MemoryBase The base of the memory.
> - @param[in] MemoryLimit The limit of the memory.
> - @param[in] IoMmuAccess The IOMMU access.
> -
> - @retval EFI_SUCCESS The VTd entry is updated to always enable all
> DMA access for the specific device.
> -**/
> -EFI_STATUS
> -EnableRmrrPageAttribute (
> - IN VTD_INFO *VTdInfo,
> - IN UINT16 Segment,
> - IN VTD_SOURCE_ID SourceId,
> - IN UINT64 MemoryBase,
> - IN UINT64 MemoryLimit,
> - IN UINT64 IoMmuAccess
> - )
> -{
> - EFI_STATUS Status;
> - UINTN VtdIndex;
> - VTD_EXT_CONTEXT_ENTRY *ExtContextEntry;
> - VTD_CONTEXT_ENTRY *ContextEntry;
> - VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry;
> - UINT64 Pt;
> -
> - 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;
> - }
> -
> - 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;
> - }
> - }
> -
> - 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));
> - }
> -
> - return EFI_SUCCESS;
> -}
> --
> 2.16.2.windows.1
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2022-01-24 2:44 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-01-18 8:14 [PATCH v5 0/4] There are 4 patches for VTd drivers Sheng Wei
2022-01-18 8:14 ` [PATCH v5 1/4] IntelSiliconPkg/VTd: Fix typos Sheng Wei
2022-01-18 8:31 ` Huang, Jenny
2022-01-19 8:26 ` Kowalewski, Robert
2022-01-18 8:14 ` [PATCH v5 2/4] IntelSiliconPkg/VTd: Update VTd register structs Sheng Wei
2022-01-21 8:24 ` Huang, Jenny
2022-01-18 8:14 ` [PATCH v5 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode Sheng Wei
2022-01-21 8:51 ` Huang, Jenny
2022-01-18 8:14 ` [PATCH v5 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once Sheng Wei
2022-01-21 8:35 ` Huang, Jenny
2022-01-24 2:44 ` Sheng Wei
2022-01-18 8:30 ` [PATCH v5 0/4] There are 4 patches for VTd drivers Huang, Jenny
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox