256-bit invaildation queue descriptor could be used for both
abort DMA mode and legacy mode.
Signed-off-by: Sheng Wei <w.sheng@...>
Cc: Ray Ni <ray.ni@...>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@...>
Cc: Jenny Huang <jenny.huang@...>
Cc: Robert Kowalewski <robert.kowalewski@...>
---
.../VTd/IntelVTdDmarPei/IntelVTdDmar.c | 188 ++++++++-----
.../VTd/IntelVTdDmarPei/IntelVTdDmarPei.h | 5 +-
.../Feature/VTd/IntelVTdDxe/DmaProtection.c | 3 +
.../Feature/VTd/IntelVTdDxe/DmaProtection.h | 5 +-
.../Feature/VTd/IntelVTdDxe/VtdReg.c | 248 +++++++++++-------
.../Include/IndustryStandard/Vtd.h | 65 ++++-
6 files changed, 355 insertions(+), 159 deletions(-)
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Inte=
lVTdDmar.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Inte=
lVTdDmar.c
index af85a3d8e..0c9805550 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma=
r.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma=
r.c
@@ -79,10 +79,11 @@ PerpareCacheInvalidationInterface (
IN VTD_UNIT_INFO *VTdUnitInfo=0D
)=0D
{=0D
- UINT16 QueueSize;=0D
- UINT64 Reg64;=0D
+ UINT8 DescriptorWidth;=0D
+ UINTN QueueSize;=0D
UINT32 Reg32;=0D
VTD_ECAP_REG ECapReg;=0D
+ VTD_IQA_REG IqaReg;=0D
UINTN VtdUnitBaseAddress;=0D
=0D
VtdUnitBaseAddress =3D VTdUnitInfo->VtdUnitBaseAddress;=0D
@@ -121,20 +122,34 @@ PerpareCacheInvalidationInterface (
//=0D
// Setup the IQ address, size and descriptor width through the Invalidat=
ion Queue Address Register=0D
//=0D
- if (VTdUnitInfo->QiDesc =3D=3D NULL) {=0D
+ if (VTdUnitInfo->QiDescBuffer =3D=3D NULL) {=0D
+ //=0D
+ // It uses 256-bit descriptor=0D
+ // Queue size is 128.=0D
+ //=0D
+ DescriptorWidth =3D 1;=0D
QueueSize =3D 0;=0D
- VTdUnitInfo->QiDescLength =3D 1 << (QueueSize + 8);=0D
- VTdUnitInfo->QiDesc =3D (QI_DESC *) AllocatePages (EFI_SIZE_TO_PAGES (=
sizeof (QI_DESC) * VTdUnitInfo->QiDescLength));=0D
- if (VTdUnitInfo->QiDesc =3D=3D NULL) {=0D
+=0D
+ VTdUnitInfo->QiDescBufferSize =3D (sizeof (QI_256_DESC) * ((UINTN) 1 <=
< (QueueSize + 7)));=0D
+ VTdUnitInfo->QiDescBuffer =3D AllocatePages (EFI_SIZE_TO_PAGES (VTdUni=
tInfo->QiDescBufferSize));=0D
+ if (VTdUnitInfo->QiDescBuffer =3D=3D NULL) {=0D
DEBUG ((DEBUG_ERROR,"Could not Alloc Invalidation Queue Buffer.\n"))=
;=0D
return EFI_OUT_OF_RESOURCES;=0D
}=0D
}=0D
=0D
- DEBUG ((DEBUG_INFO, "Invalidation Queue Length : %d\n", VTdUnitInfo->QiD=
escLength));=0D
- Reg64 =3D (UINT64) (UINTN) VTdUnitInfo->QiDesc;=0D
- Reg64 |=3D QueueSize;=0D
- MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, Reg64);=0D
+ DEBUG ((DEBUG_INFO, "Invalidation Queue Buffer Size : %d\n", VTdUnitInfo=
->QiDescBufferSize));=0D
+ //=0D
+ // 4KB Aligned address=0D
+ //=0D
+ IqaReg.Uint64 =3D (UINT64) (UINTN) VTdUnitInfo->QiDescBuffer;=0D
+ IqaReg.Bits.DW =3D DescriptorWidth;=0D
+ IqaReg.Bits.QS =3D QueueSize;=0D
+ MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, IqaReg.Uint64);=0D
+ IqaReg.Uint64 =3D MmioRead64 (VtdUnitBaseAddress + R_IQA_REG);=0D
+ DEBUG ((DEBUG_INFO, "IQA_REG [0x%lx]\n", IqaReg.Uint64));=0D
+=0D
+ DEBUG ((DEBUG_INFO, "IQH_REG [0x%lx]\n", MmioRead64 (VtdUnitBaseAddress =
+ R_IQH_REG)));=0D
=0D
//=0D
// Enable the queued invalidation interface through the Global Command R=
egister.=0D
@@ -148,8 +163,6 @@ PerpareCacheInvalidationInterface (
Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);=0D
} while ((Reg32 & B_GSTS_REG_QIES) =3D=3D 0);=0D
=0D
- VTdUnitInfo->QiFreeHead =3D 0;=0D
-=0D
return EFI_SUCCESS;=0D
}=0D
=0D
@@ -174,10 +187,10 @@ DisableQueuedInvalidationInterface (
Reg32 =3D MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);=
=0D
} while ((Reg32 & B_GSTS_REG_QIES) !=3D 0);=0D
=0D
- if (VTdUnitInfo->QiDesc !=3D NULL) {=0D
- FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES (sizeof (QI_DESC) *=
VTdUnitInfo->QiDescLength));=0D
- VTdUnitInfo->QiDesc =3D NULL;=0D
- VTdUnitInfo->QiDescLength =3D 0;=0D
+ if (VTdUnitInfo->QiDescBuffer !=3D NULL) {=0D
+ FreePages(VTdUnitInfo->QiDescBuffer, EFI_SIZE_TO_PAGES (VTdUnitInfo-=
QiDescBufferSize));=0D
+ VTdUnitInfo->QiDescBuffer =3D NULL;=0D
+ VTdUnitInfo->QiDescBufferSize =3D 0;=0D
}=0D
=0D
VTdUnitInfo->EnableQueuedInvalidation =3D 0;=0D
@@ -197,12 +210,15 @@ QueuedInvalidationCheckFault (
IN VTD_UNIT_INFO *VTdUnitInfo=0D
)=0D
{=0D
- UINT32 FaultReg;=0D
+ UINT32 FaultReg;=0D
+ VTD_IQERCD_REG IqercdReg;=0D
=0D
FaultReg =3D MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG);=
=0D
if (FaultReg & (B_FSTS_REG_IQE | B_FSTS_REG_ITE | B_FSTS_REG_ICE)) {=0D
- DEBUG((DEBUG_ERROR, "Detect Queue Invalidation Error [0x%08x]\n", Faul=
tReg));=0D
- FaultReg |=3D (B_FSTS_REG_IQE | B_FSTS_REG_ITE | B_FSTS_REG_ICE);=0D
+ IqercdReg.Uint64 =3D MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_I=
QERCD_REG);=0D
+=0D
+ DEBUG((DEBUG_ERROR, "Detect Queue Invalidation Error [0x%08x] - IQERCD=
[0x%016lx]\n", FaultReg, IqercdReg.Uint64));=0D
+=0D
MmioWrite32 (VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG, FaultReg);=
=0D
return RETURN_DEVICE_ERROR;=0D
}=0D
@@ -223,37 +239,83 @@ QueuedInvalidationCheckFault (
**/=0D
EFI_STATUS=0D
SubmitQueuedInvalidationDescriptor (=0D
- IN VTD_UNIT_INFO *VTdUnitInfo,=0D
- IN QI_DESC *Desc=0D
+ IN VTD_UNIT_INFO *VTdUnitInfo,=0D
+ IN QI_256_DESC *Desc=0D
)=0D
{=0D
- EFI_STATUS Status;=0D
- UINT16 QiDescLength;=0D
- QI_DESC *BaseDesc;=0D
- UINT64 Reg64Iqt;=0D
- UINT64 Reg64Iqh;=0D
+ EFI_STATUS Status;=0D
+ UINTN VtdUnitBaseAddress;=0D
+ UINTN QueueSize;=0D
+ UINTN QueueTail;=0D
+ UINTN QueueHead;=0D
+ QI_DESC *Qi128Desc;=0D
+ QI_256_DESC *Qi256Desc;=0D
+ VTD_IQA_REG IqaReg;=0D
+ VTD_IQT_REG IqtReg;=0D
+ VTD_IQH_REG IqhReg;=0D
=0D
if (Desc =3D=3D NULL) {=0D
return EFI_INVALID_PARAMETER;=0D
}=0D
=0D
- QiDescLength =3D VTdUnitInfo->QiDescLength;=0D
- BaseDesc =3D VTdUnitInfo->QiDesc;=0D
-=0D
- DEBUG((DEBUG_INFO, "[0x%x] Submit QI Descriptor [0x%016lx, 0x%016lx]\n",=
VTdUnitInfo->VtdUnitBaseAddress, Desc->Low, Desc->High));=0D
-=0D
- BaseDesc[VTdUnitInfo->QiFreeHead].Low =3D Desc->Low;=0D
- BaseDesc[VTdUnitInfo->QiFreeHead].High =3D Desc->High;=0D
- FlushPageTableMemory(VTdUnitInfo, (UINTN) &BaseDesc[VTdUnitInfo->QiFreeH=
ead], sizeof(QI_DESC));=0D
+ VtdUnitBaseAddress =3D VTdUnitInfo->VtdUnitBaseAddress;=0D
+ IqaReg.Uint64 =3D MmioRead64 (VtdUnitBaseAddress + R_IQA_REG);=0D
+ if (IqaReg.Bits.IQA =3D=3D 0) {=0D
+ DEBUG ((DEBUG_ERROR,"Invalidation Queue Buffer not ready [0x%lx]\n", I=
qaReg.Uint64));=0D
+ return EFI_NOT_READY;=0D
+ }=0D
+ IqtReg.Uint64 =3D MmioRead64 (VtdUnitBaseAddress + R_IQT_REG);=0D
=0D
- DEBUG((DEBUG_INFO,"QI Free Head=3D0x%x\n", VTdUnitInfo->QiFreeHead));=0D
- VTdUnitInfo->QiFreeHead =3D (VTdUnitInfo->QiFreeHead + 1) % QiDescLength=
;=0D
+ if (IqaReg.Bits.DW =3D=3D 0) {=0D
+ //=0D
+ // 128-bit descriptor=0D
+ //=0D
+ QueueSize =3D (UINTN) (1 << (IqaReg.Bits.QS + 8));=0D
+ Qi128Desc =3D (QI_DESC *) (UINTN) (IqaReg.Bits.IQA << VTD_PAGE_SHIFT);=
=0D
+ QueueTail =3D (UINTN) IqtReg.Bits128Desc.QT;=0D
+ Qi128Desc +=3D QueueTail;=0D
+ Qi128Desc->Low =3D Desc->Uint64[0];=0D
+ Qi128Desc->High =3D Desc->Uint64[1];=0D
+ FlushPageTableMemory (VTdUnitInfo, (UINTN) Qi128Desc, sizeof(QI_DESC))=
;=0D
+ QueueTail =3D (QueueTail + 1) % QueueSize;=0D
+=0D
+ DEBUG ((DEBUG_INFO, "[0x%x] Submit QI Descriptor 0x%x [0x%016lx, 0x%01=
6lx]\n",=0D
+ VtdUnitBaseAddress,=0D
+ QueueTail,=0D
+ Desc->Uint64[0],=0D
+ Desc->Uint64[1]));=0D
+=0D
+ IqtReg.Bits128Desc.QT =3D QueueTail;=0D
+ } else {=0D
+ //=0D
+ // 256-bit descriptor=0D
+ //=0D
+ QueueSize =3D (UINTN) (1 << (IqaReg.Bits.QS + 7));=0D
+ Qi256Desc =3D (QI_256_DESC *) (UINTN) (IqaReg.Bits.IQA << VTD_PAGE_SHI=
FT);=0D
+ QueueTail =3D (UINTN) IqtReg.Bits256Desc.QT;=0D
+ Qi256Desc +=3D QueueTail;=0D
+ Qi256Desc->Uint64[0] =3D Desc->Uint64[0];=0D
+ Qi256Desc->Uint64[1] =3D Desc->Uint64[1];=0D
+ Qi256Desc->Uint64[2] =3D Desc->Uint64[2];=0D
+ Qi256Desc->Uint64[3] =3D Desc->Uint64[3];=0D
+ FlushPageTableMemory (VTdUnitInfo, (UINTN) Qi256Desc, sizeof(QI_256_DE=
SC));=0D
+ QueueTail =3D (QueueTail + 1) % QueueSize;=0D
+=0D
+ DEBUG ((DEBUG_INFO, "[0x%x] Submit QI Descriptor 0x%x [0x%016lx, 0x%01=
6lx, 0x%016lx, 0x%016lx]\n",=0D
+ VtdUnitBaseAddress,=0D
+ QueueTail,=0D
+ Desc->Uint64[0],=0D
+ Desc->Uint64[1],=0D
+ Desc->Uint64[2],=0D
+ Desc->Uint64[3]));=0D
+=0D
+ IqtReg.Bits256Desc.QT =3D QueueTail;=0D
+ }=0D
=0D
//=0D
// Update the HW tail register indicating the presence of new descriptor=
s.=0D
//=0D
- Reg64Iqt =3D VTdUnitInfo->QiFreeHead << DMAR_IQ_SHIFT;=0D
- MmioWrite64 (VTdUnitInfo->VtdUnitBaseAddress + R_IQT_REG, Reg64Iqt);=0D
+ MmioWrite64 (VtdUnitBaseAddress + R_IQT_REG, IqtReg.Uint64);=0D
=0D
Status =3D EFI_SUCCESS;=0D
do {=0D
@@ -263,10 +325,15 @@ SubmitQueuedInvalidationDescriptor (
break;=0D
}=0D
=0D
- Reg64Iqh =3D MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_IQH_REG);=
=0D
- } while (Reg64Iqt !=3D Reg64Iqh);=0D
+ IqhReg.Uint64 =3D MmioRead64 (VtdUnitBaseAddress + R_IQH_REG);=0D
+ if (IqaReg.Bits.DW =3D=3D 0) {=0D
+ QueueHead =3D (UINTN) IqhReg.Bits128Desc.QH;=0D
+ } else {=0D
+ QueueHead =3D (UINTN) IqhReg.Bits256Desc.QH;=0D
+ }=0D
+ } while (QueueTail !=3D QueueHead);=0D
=0D
- DEBUG((DEBUG_ERROR,"SubmitQueuedInvalidationDescriptor end\n"));=0D
+ DEBUG((DEBUG_INFO,"SubmitQueuedInvalidationDescriptor end\n"));=0D
return Status;=0D
}=0D
=0D
@@ -281,7 +348,7 @@ InvalidateContextCache (
)=0D
{=0D
UINT64 Reg64;=0D
- QI_DESC QiDesc;=0D
+ QI_256_DESC QiDesc;=0D
=0D
if (VTdUnitInfo->EnableQueuedInvalidation =3D=3D 0) {=0D
//=0D
@@ -304,8 +371,10 @@ InvalidateContextCache (
//=0D
// Queued Invalidation=0D
//=0D
- QiDesc.Low =3D QI_CC_FM(0) | QI_CC_SID(0) | QI_CC_DID(0) | QI_CC_GRAN(=
1) | QI_CC_TYPE;=0D
- QiDesc.High =3D 0;=0D
+ QiDesc.Uint64[0] =3D QI_CC_FM(0) | QI_CC_SID(0) | QI_CC_DID(0) | QI_CC=
_GRAN(1) | QI_CC_TYPE;=0D
+ QiDesc.Uint64[1] =3D 0;=0D
+ QiDesc.Uint64[2] =3D 0;=0D
+ QiDesc.Uint64[3] =3D 0;=0D
=0D
return SubmitQueuedInvalidationDescriptor(VTdUnitInfo, &QiDesc);=0D
}=0D
@@ -326,7 +395,7 @@ InvalidateIOTLB (
UINT64 Reg64;=0D
VTD_ECAP_REG ECapReg;=0D
VTD_CAP_REG CapReg;=0D
- QI_DESC QiDesc;=0D
+ QI_256_DESC QiDesc;=0D
=0D
if (VTdUnitInfo->EnableQueuedInvalidation =3D=3D 0) {=0D
//=0D
@@ -352,8 +421,10 @@ InvalidateIOTLB (
// Queued Invalidation=0D
//=0D
CapReg.Uint64 =3D MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_CAP_=
REG);=0D
- QiDesc.Low =3D QI_IOTLB_DID(0) | QI_IOTLB_DR(CAP_READ_DRAIN(CapReg.Uin=
t64)) | QI_IOTLB_DW(CAP_WRITE_DRAIN(CapReg.Uint64)) | QI_IOTLB_GRAN(1) | QI=
_IOTLB_TYPE;=0D
- QiDesc.High =3D QI_IOTLB_ADDR(0) | QI_IOTLB_IH(0) | QI_IOTLB_AM(0);=0D
+ QiDesc.Uint64[0] =3D QI_IOTLB_DID(0) | QI_IOTLB_DR(CAP_READ_DRAIN(CapR=
eg.Uint64)) | QI_IOTLB_DW(CAP_WRITE_DRAIN(CapReg.Uint64)) | QI_IOTLB_GRAN(1=
) | QI_IOTLB_TYPE;=0D
+ QiDesc.Uint64[1] =3D QI_IOTLB_ADDR(0) | QI_IOTLB_IH(0) | QI_IOTLB_AM(0=
);=0D
+ QiDesc.Uint64[2] =3D 0;=0D
+ QiDesc.Uint64[3] =3D 0;=0D
=0D
return SubmitQueuedInvalidationDescriptor(VTdUnitInfo, &QiDesc);=0D
}=0D
@@ -390,6 +461,7 @@ ClearGlobalCommandRegisterBits (
do {=0D
Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);=0D
} while ((Reg32 & BitMask) =3D=3D BitMask);=0D
+ DEBUG ((DEBUG_INFO, "GSTS_REG : 0x%08x \n", Reg32));=0D
}=0D
=0D
/**=0D
@@ -421,6 +493,7 @@ SetGlobalCommandRegisterBits (
do {=0D
Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);=0D
} while ((Reg32 & BitMask) =3D=3D 0);=0D
+ DEBUG ((DEBUG_INFO, "GSTS_REG : 0x%08x \n", Reg32));=0D
}=0D
=0D
/**=0D
@@ -451,11 +524,6 @@ EnableDmarPreMem (
Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);=0D
DEBUG ((DEBUG_INFO, "EnableDmarPreMem: R_GSTS_REG =3D 0x%x \n", Reg32));=
=0D
=0D
- //=0D
- // Init DMAr Fault Event and Data registers=0D
- //=0D
- Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_FEDATA_REG);=0D
-=0D
//=0D
// Write Buffer Flush=0D
//=0D
@@ -513,6 +581,9 @@ EnableDmar (
//=0D
MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64) (RootEntryTab=
le | V_RTADDR_REG_TTM_ADM));=0D
=0D
+ DEBUG ((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n"=
));=0D
+ SetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_SRTP);=0D
+=0D
DEBUG((DEBUG_INFO, "Enable Abort DMA Mode...\n"));=0D
SetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_TE);=0D
=0D
@@ -520,16 +591,10 @@ EnableDmar (
DEBUG ((DEBUG_INFO, "RootEntryTable 0x%x \n", RootEntryTable));=0D
MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64) RootEntryTabl=
e);=0D
=0D
+ DEBUG ((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n"=
));=0D
+ SetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_SRTP);=0D
}=0D
=0D
- DEBUG ((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n"))=
;=0D
- SetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_SRTP);=0D
-=0D
- //=0D
- // Init DMAr Fault Event and Data registers=0D
- //=0D
- MmioRead32 (VtdUnitBaseAddress + R_FEDATA_REG);=0D
-=0D
//=0D
// Write Buffer Flush before invalidation=0D
//=0D
@@ -552,6 +617,9 @@ EnableDmar (
=0D
DEBUG ((DEBUG_INFO, "RootEntryTable 0x%x \n", RootEntryTable));=0D
MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64) RootEntryTabl=
e);=0D
+=0D
+ DEBUG ((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n"=
));=0D
+ SetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_SRTP);=0D
}=0D
=0D
//=0D
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Inte=
lVTdDmarPei.h b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/I=
ntelVTdDmarPei.h
index 5ade9ec35..4d4b912f2 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma=
rPei.h
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma=
rPei.h
@@ -21,9 +21,8 @@ typedef struct {
VTD_ECAP_REG ECapReg;=0D
BOOLEAN Is5LevelPaging;=0D
UINT8 EnableQueuedInvalidation;=0D
- UINT16 QiDescLength;=0D
- QI_DESC *QiDesc;=0D
- UINT16 QiFreeHead;=0D
+ VOID *QiDescBuffer;=0D
+ UINTN QiDescBufferSize;=0D
UINTN FixedSecondLevelPagingEntry;=0D
UINTN RootEntryTable;=0D
UINTN ExtRootEntryTable;=0D
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProte=
ction.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtecti=
on.c
index 628565ee7..878c952b7 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.c
@@ -496,6 +496,9 @@ SetupVtd (
if (EFI_ERROR (Status)) {=0D
return;=0D
}=0D
+=0D
+ DumpVtdIfError ();=0D
+=0D
DEBUG ((DEBUG_INFO, "PrepareVtdConfig\n"));=0D
PrepareVtdConfig ();=0D
=0D
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProte=
ction.h b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtecti=
on.h
index 7dd29a243..e83ebff41 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
@@ -81,9 +81,8 @@ typedef struct {
PCI_DEVICE_INFORMATION PciDeviceInfo;=0D
BOOLEAN Is5LevelPaging;=0D
UINT8 EnableQueuedInvalidation;=0D
- UINT16 QiDescLength;=0D
- QI_DESC *QiDesc;=0D
- UINT16 QiFreeHead;=0D
+ VOID *QiDescBuffer;=0D
+ UINTN QiDescBufferSize;=0D
} VTD_UNIT_INFORMATION;=0D
=0D
//=0D
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c=
b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
index 8e834f4c4..be54cf99d 100644
--- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c
@@ -68,71 +68,89 @@ PerpareCacheInvalidationInterface (
IN UINTN VtdIndex=0D
)=0D
{=0D
- UINT16 QueueSize;=0D
- UINT64 Reg64;=0D
- UINT32 Reg32;=0D
-=0D
- if (mVtdUnitInformation[VtdIndex].VerReg.Bits.Major <=3D 5) {=0D
- mVtdUnitInformation[VtdIndex].EnableQueuedInvalidation =3D 0;=0D
+ UINT8 DescriptorWidth;=0D
+ UINTN QueueSize;=0D
+ UINT32 Reg32;=0D
+ VTD_IQA_REG IqaReg;=0D
+ VTD_UNIT_INFORMATION *VTdUnitInfo;=0D
+ UINTN VtdUnitBaseAddress;=0D
+=0D
+ VTdUnitInfo =3D &mVtdUnitInformation[VtdIndex];=0D
+ VtdUnitBaseAddress =3D VTdUnitInfo->VtdUnitBaseAddress;=0D
+=0D
+ if (VTdUnitInfo->VerReg.Bits.Major <=3D 5) {=0D
+ VTdUnitInfo->EnableQueuedInvalidation =3D 0;=0D
DEBUG ((DEBUG_INFO, "Use Register-based Invalidation Interface for eng=
ine [%d]\n", VtdIndex));=0D
return EFI_SUCCESS;=0D
}=0D
=0D
- if (mVtdUnitInformation[VtdIndex].ECapReg.Bits.QI =3D=3D 0) {=0D
+ if (VTdUnitInfo->ECapReg.Bits.QI =3D=3D 0) {=0D
DEBUG ((DEBUG_ERROR, "Hardware does not support queued invalidations i=
nterface for engine [%d]\n", VtdIndex));=0D
return EFI_UNSUPPORTED;=0D
}=0D
=0D
- mVtdUnitInformation[VtdIndex].EnableQueuedInvalidation =3D 1;=0D
+ VTdUnitInfo->EnableQueuedInvalidation =3D 1;=0D
DEBUG ((DEBUG_INFO, "Use Queued Invalidation Interface for engine [%d]\n=
", VtdIndex));=0D
=0D
- Reg32 =3D MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress +=
R_GSTS_REG);=0D
+ Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);=0D
if ((Reg32 & B_GSTS_REG_QIES) !=3D 0) {=0D
DEBUG ((DEBUG_ERROR,"Queued Invalidation Interface was enabled.\n"));=
=0D
Reg32 &=3D (~B_GSTS_REG_QIES);=0D
- MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GCMD=
_REG, Reg32);=0D
+ MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32);=0D
do {=0D
- Reg32 =3D MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddre=
ss + R_GSTS_REG);=0D
+ Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);=0D
} while ((Reg32 & B_GSTS_REG_QIES) !=3D 0);=0D
}=0D
=0D
//=0D
// Initialize the Invalidation Queue Tail Register to zero.=0D
//=0D
- MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_IQT_RE=
G, 0);=0D
+ MmioWrite64 (VtdUnitBaseAddress + R_IQT_REG, 0);=0D
=0D
//=0D
// Setup the IQ address, size and descriptor width through the Invalidat=
ion Queue Address Register=0D
//=0D
- QueueSize =3D 0;=0D
- mVtdUnitInformation[VtdIndex].QiDescLength =3D 1 << (QueueSize + 8);=0D
- mVtdUnitInformation[VtdIndex].QiDesc =3D (QI_DESC *) AllocatePages (EFI_=
SIZE_TO_PAGES(sizeof(QI_DESC) * mVtdUnitInformation[VtdIndex].QiDescLength)=
);=0D
-=0D
- if (mVtdUnitInformation[VtdIndex].QiDesc =3D=3D NULL) {=0D
- mVtdUnitInformation[VtdIndex].QiDescLength =3D 0;=0D
- DEBUG ((DEBUG_ERROR,"Could not Alloc Invalidation Queue Buffer.\n"));=
=0D
- return EFI_OUT_OF_RESOURCES;=0D
+ if (VTdUnitInfo->QiDescBuffer =3D=3D NULL) {=0D
+ //=0D
+ // It uses 256-bit descriptor=0D
+ // Queue size is 128.=0D
+ //=0D
+ DescriptorWidth =3D 1;=0D
+ QueueSize =3D 0;=0D
+=0D
+ VTdUnitInfo->QiDescBufferSize =3D (sizeof (QI_256_DESC) * ((UINTN) 1 <=
< (QueueSize + 7)));=0D
+ VTdUnitInfo->QiDescBuffer =3D AllocatePages (EFI_SIZE_TO_PAGES (VTdUni=
tInfo->QiDescBufferSize));=0D
+ if (VTdUnitInfo->QiDescBuffer =3D=3D NULL) {=0D
+ DEBUG ((DEBUG_ERROR,"Could not Alloc Invalidation Queue Buffer.\n"))=
;=0D
+ return EFI_OUT_OF_RESOURCES;=0D
+ }=0D
}=0D
=0D
- DEBUG ((DEBUG_INFO, "Invalidation Queue Length : %d\n", mVtdUnitInformat=
ion[VtdIndex].QiDescLength));=0D
- Reg64 =3D (UINT64)(UINTN)mVtdUnitInformation[VtdIndex].QiDesc;=0D
- Reg64 |=3D QueueSize;=0D
- MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_IQA_RE=
G, Reg64);=0D
+ DEBUG ((DEBUG_INFO, "Invalidation Queue Buffer Size : %d\n", VTdUnitInfo=
->QiDescBufferSize));=0D
+ //=0D
+ // 4KB Aligned address=0D
+ //=0D
+ IqaReg.Uint64 =3D (UINT64) (UINTN) VTdUnitInfo->QiDescBuffer;=0D
+ IqaReg.Bits.DW =3D DescriptorWidth;=0D
+ IqaReg.Bits.QS =3D QueueSize;=0D
+ MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, IqaReg.Uint64);=0D
+ IqaReg.Uint64 =3D MmioRead64 (VtdUnitBaseAddress + R_IQA_REG);=0D
+ DEBUG ((DEBUG_INFO, "IQA_REG [0x%lx]\n", IqaReg.Uint64));=0D
+=0D
+ DEBUG ((DEBUG_INFO, "IQH_REG [0x%lx]\n", MmioRead64 (VtdUnitBaseAddress =
+ R_IQH_REG)));=0D
=0D
//=0D
// Enable the queued invalidation interface through the Global Command R=
egister.=0D
// When enabled, hardware sets the QIES field in the Global Status Regis=
ter.=0D
//=0D
- Reg32 =3D MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress +=
R_GSTS_REG);=0D
+ Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);=0D
Reg32 |=3D B_GMCD_REG_QIE;=0D
- MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GCMD_R=
EG, Reg32);=0D
+ MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32);=0D
DEBUG ((DEBUG_INFO, "Enable Queued Invalidation Interface. GCMD_REG =3D =
0x%x\n", Reg32));=0D
do {=0D
- Reg32 =3D MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress=
+ R_GSTS_REG);=0D
+ Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);=0D
} while ((Reg32 & B_GSTS_REG_QIES) =3D=3D 0);=0D
=0D
- mVtdUnitInformation[VtdIndex].QiFreeHead =3D 0;=0D
-=0D
return EFI_SUCCESS;=0D
}=0D
=0D
@@ -146,21 +164,24 @@ DisableQueuedInvalidationInterface (
IN UINTN VtdIndex=0D
)=0D
{=0D
- UINT32 Reg32;=0D
+ UINT32 Reg32;=0D
+ VTD_UNIT_INFORMATION *VTdUnitInfo;=0D
=0D
- if (mVtdUnitInformation[VtdIndex].EnableQueuedInvalidation !=3D 0) {=0D
- Reg32 =3D MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress=
+ R_GSTS_REG);=0D
+ VTdUnitInfo =3D &mVtdUnitInformation[VtdIndex];=0D
+=0D
+ if (VTdUnitInfo->EnableQueuedInvalidation !=3D 0) {=0D
+ Reg32 =3D MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);=0D
Reg32 &=3D (~B_GMCD_REG_QIE);=0D
- MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GCMD=
_REG, Reg32);=0D
+ MmioWrite32 (VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg32);=0D
DEBUG ((DEBUG_INFO, "Disable Queued Invalidation Interface. GCMD_REG =
=3D 0x%x\n", Reg32));=0D
do {=0D
- Reg32 =3D MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddre=
ss + R_GSTS_REG);=0D
+ Reg32 =3D MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG);=
=0D
} while ((Reg32 & B_GSTS_REG_QIES) !=3D 0);=0D
=0D
- if (mVtdUnitInformation[VtdIndex].QiDesc !=3D NULL) {=0D
- FreePages(mVtdUnitInformation[VtdIndex].QiDesc, EFI_SIZE_TO_PAGES(si=
zeof(QI_DESC) * mVtdUnitInformation[VtdIndex].QiDescLength));=0D
- mVtdUnitInformation[VtdIndex].QiDesc =3D NULL;=0D
- mVtdUnitInformation[VtdIndex].QiDescLength =3D 0;=0D
+ if (VTdUnitInfo->QiDescBuffer !=3D NULL) {=0D
+ FreePages(VTdUnitInfo->QiDescBuffer, EFI_SIZE_TO_PAGES (VTdUnitInfo-=
QiDescBufferSize));=0D
+ VTdUnitInfo->QiDescBuffer =3D NULL;=0D
+ VTdUnitInfo->QiDescBufferSize =3D 0;=0D
}=0D
=0D
mVtdUnitInformation[VtdIndex].EnableQueuedInvalidation =3D 0;=0D
@@ -180,27 +201,16 @@ QueuedInvalidationCheckFault (
IN UINTN VtdIndex=0D
)=0D
{=0D
- UINT32 FaultReg;=0D
+ UINT32 FaultReg;=0D
+ VTD_IQERCD_REG IqercdReg;=0D
=0D
FaultReg =3D MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddres=
s + R_FSTS_REG);=0D
=0D
- if (FaultReg & B_FSTS_REG_IQE) {=0D
- DEBUG((DEBUG_ERROR, "Detect Invalidation Queue Error [0x%08x]\n", Faul=
tReg));=0D
- FaultReg |=3D B_FSTS_REG_IQE;=0D
- MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_FSTS=
_REG, FaultReg);=0D
- return RETURN_DEVICE_ERROR;=0D
- }=0D
+ if (FaultReg & (B_FSTS_REG_IQE | B_FSTS_REG_ITE | B_FSTS_REG_ICE)) {=0D
+ IqercdReg.Uint64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnit=
BaseAddress + R_IQERCD_REG);=0D
=0D
- if (FaultReg & B_FSTS_REG_ITE) {=0D
- DEBUG((DEBUG_ERROR, "Detect Invalidation Time-out Error [0x%08x]\n", F=
aultReg));=0D
- FaultReg |=3D B_FSTS_REG_ITE;=0D
- MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_FSTS=
_REG, FaultReg);=0D
- return RETURN_DEVICE_ERROR;=0D
- }=0D
+ DEBUG((DEBUG_ERROR, "Detect Queue Invalidation Error [0x%08x] - IQERCD=
[0x%016lx]\n", FaultReg, IqercdReg.Uint64));=0D
=0D
- if (FaultReg & B_FSTS_REG_ICE) {=0D
- DEBUG((DEBUG_ERROR, "Detect Invalidation Completion Error [0x%08x]\n",=
FaultReg));=0D
- FaultReg |=3D B_FSTS_REG_ICE;=0D
MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_FSTS=
_REG, FaultReg);=0D
return RETURN_DEVICE_ERROR;=0D
}=0D
@@ -221,36 +231,83 @@ QueuedInvalidationCheckFault (
**/=0D
EFI_STATUS=0D
SubmitQueuedInvalidationDescriptor (=0D
- IN UINTN VtdIndex,=0D
- IN QI_DESC *Desc=0D
+ IN UINTN VtdIndex,=0D
+ IN QI_256_DESC *Desc=0D
)=0D
{=0D
- EFI_STATUS Status;=0D
- UINT16 QiDescLength;=0D
- QI_DESC *BaseDesc;=0D
- UINT64 Reg64Iqt;=0D
- UINT64 Reg64Iqh;=0D
+ EFI_STATUS Status;=0D
+ UINTN VtdUnitBaseAddress;=0D
+ UINTN QueueSize;=0D
+ UINTN QueueTail;=0D
+ UINTN QueueHead;=0D
+ QI_DESC *Qi128Desc;=0D
+ QI_256_DESC *Qi256Desc;=0D
+ VTD_IQA_REG IqaReg;=0D
+ VTD_IQT_REG IqtReg;=0D
+ VTD_IQH_REG IqhReg;=0D
=0D
if (Desc =3D=3D NULL) {=0D
return EFI_INVALID_PARAMETER;=0D
}=0D
=0D
- QiDescLength =3D mVtdUnitInformation[VtdIndex].QiDescLength;=0D
- BaseDesc =3D mVtdUnitInformation[VtdIndex].QiDesc;=0D
-=0D
- DEBUG((DEBUG_VERBOSE, "[%d] Submit QI Descriptor [0x%08x, 0x%08x] Free H=
ead (%d)\n", VtdIndex, Desc->Low, Desc->High, mVtdUnitInformation[VtdIndex]=
.QiFreeHead));=0D
-=0D
- BaseDesc[mVtdUnitInformation[VtdIndex].QiFreeHead].Low =3D Desc->Low;=0D
- BaseDesc[mVtdUnitInformation[VtdIndex].QiFreeHead].High =3D Desc->High;=
=0D
- FlushPageTableMemory(VtdIndex, (UINTN) &BaseDesc[mVtdUnitInformation[Vtd=
Index].QiFreeHead], sizeof(QI_DESC));=0D
+ VtdUnitBaseAddress =3D mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress;=
=0D
+ IqaReg.Uint64 =3D MmioRead64 (VtdUnitBaseAddress + R_IQA_REG);=0D
+ if (IqaReg.Bits.IQA =3D=3D 0) {=0D
+ DEBUG ((DEBUG_ERROR,"Invalidation Queue Buffer not ready [0x%lx]\n", I=
qaReg.Uint64));=0D
+ return EFI_NOT_READY;=0D
+ }=0D
+ IqtReg.Uint64 =3D MmioRead64 (VtdUnitBaseAddress + R_IQT_REG);=0D
=0D
- mVtdUnitInformation[VtdIndex].QiFreeHead =3D (mVtdUnitInformation[VtdInd=
ex].QiFreeHead + 1) % QiDescLength;=0D
+ if (IqaReg.Bits.DW =3D=3D 0) {=0D
+ //=0D
+ // 128-bit descriptor=0D
+ //=0D
+ QueueSize =3D (UINTN) (1 << (IqaReg.Bits.QS + 8));=0D
+ Qi128Desc =3D (QI_DESC *) (UINTN) (IqaReg.Bits.IQA << VTD_PAGE_SHIFT);=
=0D
+ QueueTail =3D (UINTN) IqtReg.Bits128Desc.QT;=0D
+ Qi128Desc +=3D QueueTail;=0D
+ Qi128Desc->Low =3D Desc->Uint64[0];=0D
+ Qi128Desc->High =3D Desc->Uint64[1];=0D
+ FlushPageTableMemory (VtdIndex, (UINTN) Qi128Desc, sizeof(QI_DESC));=0D
+ QueueTail =3D (QueueTail + 1) % QueueSize;=0D
+=0D
+ DEBUG ((DEBUG_VERBOSE, "[0x%x] Submit QI Descriptor 0x%x [0x%016lx, 0x=
%016lx]\n",=0D
+ VtdUnitBaseAddress,=0D
+ QueueTail,=0D
+ Desc->Uint64[0],=0D
+ Desc->Uint64[1]));=0D
+=0D
+ IqtReg.Bits128Desc.QT =3D QueueTail;=0D
+ } else {=0D
+ //=0D
+ // 256-bit descriptor=0D
+ //=0D
+ QueueSize =3D (UINTN) (1 << (IqaReg.Bits.QS + 7));=0D
+ Qi256Desc =3D (QI_256_DESC *) (UINTN) (IqaReg.Bits.IQA << VTD_PAGE_SHI=
FT);=0D
+ QueueTail =3D (UINTN) IqtReg.Bits256Desc.QT;=0D
+ Qi256Desc +=3D QueueTail;=0D
+ Qi256Desc->Uint64[0] =3D Desc->Uint64[0];=0D
+ Qi256Desc->Uint64[1] =3D Desc->Uint64[1];=0D
+ Qi256Desc->Uint64[2] =3D Desc->Uint64[2];=0D
+ Qi256Desc->Uint64[3] =3D Desc->Uint64[3];=0D
+ FlushPageTableMemory (VtdIndex, (UINTN) Qi256Desc, sizeof(QI_256_DESC)=
);=0D
+ QueueTail =3D (QueueTail + 1) % QueueSize;=0D
+=0D
+ DEBUG ((DEBUG_VERBOSE, "[0x%x] Submit QI Descriptor 0x%x [0x%016lx, 0x=
%016lx, 0x%016lx, 0x%016lx]\n",=0D
+ VtdUnitBaseAddress,=0D
+ QueueTail,=0D
+ Desc->Uint64[0],=0D
+ Desc->Uint64[1],=0D
+ Desc->Uint64[2],=0D
+ Desc->Uint64[3]));=0D
+=0D
+ IqtReg.Bits256Desc.QT =3D QueueTail;=0D
+ }=0D
=0D
//=0D
// Update the HW tail register indicating the presence of new descriptor=
s.=0D
//=0D
- Reg64Iqt =3D mVtdUnitInformation[VtdIndex].QiFreeHead << DMAR_IQ_SHIFT;=
=0D
- MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_IQT_RE=
G, Reg64Iqt);=0D
+ MmioWrite64 (VtdUnitBaseAddress + R_IQT_REG, IqtReg.Uint64);=0D
=0D
Status =3D EFI_SUCCESS;=0D
do {=0D
@@ -260,8 +317,13 @@ SubmitQueuedInvalidationDescriptor (
break;=0D
}=0D
=0D
- Reg64Iqh =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddr=
ess + R_IQH_REG);=0D
- } while (Reg64Iqt !=3D Reg64Iqh);=0D
+ IqhReg.Uint64 =3D MmioRead64 (VtdUnitBaseAddress + R_IQH_REG);=0D
+ if (IqaReg.Bits.DW =3D=3D 0) {=0D
+ QueueHead =3D (UINTN) IqhReg.Bits128Desc.QH;=0D
+ } else {=0D
+ QueueHead =3D (UINTN) IqhReg.Bits256Desc.QH;=0D
+ }=0D
+ } while (QueueTail !=3D QueueHead);=0D
=0D
return Status;=0D
}=0D
@@ -276,8 +338,8 @@ InvalidateContextCache (
IN UINTN VtdIndex=0D
)=0D
{=0D
- UINT64 Reg64;=0D
- QI_DESC QiDesc;=0D
+ UINT64 Reg64;=0D
+ QI_256_DESC QiDesc;=0D
=0D
if (mVtdUnitInformation[VtdIndex].EnableQueuedInvalidation =3D=3D 0) {=0D
//=0D
@@ -300,8 +362,10 @@ InvalidateContextCache (
//=0D
// Queued Invalidation=0D
//=0D
- QiDesc.Low =3D QI_CC_FM(0) | QI_CC_SID(0) | QI_CC_DID(0) | QI_CC_GRAN(=
1) | QI_CC_TYPE;=0D
- QiDesc.High =3D 0;=0D
+ QiDesc.Uint64[0] =3D QI_CC_FM(0) | QI_CC_SID(0) | QI_CC_DID(0) | QI_CC=
_GRAN(1) | QI_CC_TYPE;=0D
+ QiDesc.Uint64[1] =3D 0;=0D
+ QiDesc.Uint64[2] =3D 0;=0D
+ QiDesc.Uint64[3] =3D 0;=0D
=0D
return SubmitQueuedInvalidationDescriptor(VtdIndex, &QiDesc);=0D
}=0D
@@ -318,8 +382,8 @@ InvalidateIOTLB (
IN UINTN VtdIndex=0D
)=0D
{=0D
- UINT64 Reg64;=0D
- QI_DESC QiDesc;=0D
+ UINT64 Reg64;=0D
+ QI_256_DESC QiDesc;=0D
=0D
if (mVtdUnitInformation[VtdIndex].EnableQueuedInvalidation =3D=3D 0) {=0D
//=0D
@@ -342,8 +406,10 @@ InvalidateIOTLB (
//=0D
// Queued Invalidation=0D
//=0D
- QiDesc.Low =3D QI_IOTLB_DID(0) | QI_IOTLB_DR(CAP_READ_DRAIN(mVtdUnitIn=
formation[VtdIndex].CapReg.Uint64)) | QI_IOTLB_DW(CAP_WRITE_DRAIN(mVtdUnitI=
nformation[VtdIndex].CapReg.Uint64)) | QI_IOTLB_GRAN(1) | QI_IOTLB_TYPE;=0D
- QiDesc.High =3D QI_IOTLB_ADDR(0) | QI_IOTLB_IH(0) | QI_IOTLB_AM(0);=0D
+ QiDesc.Uint64[0] =3D QI_IOTLB_DID(0) | QI_IOTLB_DR(CAP_READ_DRAIN(mVtd=
UnitInformation[VtdIndex].CapReg.Uint64)) | QI_IOTLB_DW(CAP_WRITE_DRAIN(mVt=
dUnitInformation[VtdIndex].CapReg.Uint64)) | QI_IOTLB_GRAN(1) | QI_IOTLB_TY=
PE;=0D
+ QiDesc.Uint64[1] =3D QI_IOTLB_ADDR(0) | QI_IOTLB_IH(0) | QI_IOTLB_AM(0=
);=0D
+ QiDesc.Uint64[2] =3D 0;=0D
+ QiDesc.Uint64[3] =3D 0;=0D
=0D
return SubmitQueuedInvalidationDescriptor(VtdIndex, &QiDesc);=0D
}=0D
@@ -504,6 +570,7 @@ ClearGlobalCommandRegisterBits (
do {=0D
Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);=0D
} while ((Reg32 & BitMask) =3D=3D BitMask);=0D
+ DEBUG ((DEBUG_INFO, "GSTS_REG : 0x%08x \n", Reg32));=0D
}=0D
=0D
/**=0D
@@ -535,6 +602,7 @@ SetGlobalCommandRegisterBits (
do {=0D
Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG);=0D
} while ((Reg32 & BitMask) =3D=3D 0);=0D
+ DEBUG ((DEBUG_INFO, "GSTS_REG : 0x%08x \n", Reg32));=0D
}=0D
=0D
/**=0D
@@ -600,22 +668,19 @@ EnableDmar (
//=0D
UpdateRootTableAddressRegister (Index, TRUE);=0D
=0D
+ DEBUG((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n=
"));=0D
+ SetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_SRTP);=
=0D
+=0D
DEBUG((DEBUG_INFO, "Enable Abort DMA Mode...\n"));=0D
SetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_TE);=0D
=0D
} else {=0D
UpdateRootTableAddressRegister (Index, FALSE);=0D
=0D
+ DEBUG((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n=
"));=0D
+ SetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_SRTP);=
=0D
}=0D
=0D
- DEBUG((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n")=
);=0D
- SetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_SRTP);=0D
-=0D
- //=0D
- // Init DMAr Fault Event and Data registers=0D
- //=0D
- MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_FEDATA_R=
EG);=0D
-=0D
//=0D
// Write Buffer Flush before invalidation=0D
//=0D
@@ -637,6 +702,9 @@ EnableDmar (
}=0D
=0D
UpdateRootTableAddressRegister (Index, FALSE);=0D
+=0D
+ DEBUG((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n=
"));=0D
+ SetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_SRTP);=
=0D
}=0D
=0D
//=0D
diff --git a/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/Vtd.h b=
/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/Vtd.h
index 32fbdd02e..3e1b8c3c5 100644
--- a/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/Vtd.h
+++ b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/Vtd.h
@@ -259,6 +259,8 @@ typedef union {
=0D
#define R_IQA_REG 0x90=0D
=0D
+#define R_IQERCD_REG 0xB0=0D
+=0D
#define VTD_PAGE_SHIFT (12)=0D
#define VTD_PAGE_SIZE (1UL << VTD_PAGE_SHIFT)=0D
#define VTD_PAGE_MASK (((UINT64)-1) << VTD_PAGE_SHIFT)=0D
@@ -289,13 +291,20 @@ typedef union {
#define QI_IWD_STATUS_WRITE (((UINT64)1) << 5)=0D
=0D
//=0D
-// This is the queued invalidate descriptor.=0D
+// queued invalidation 128-bit descriptor=0D
//=0D
typedef struct {=0D
- UINT64 Low;=0D
- UINT64 High;=0D
+ UINT64 Low;=0D
+ UINT64 High;=0D
} QI_DESC;=0D
=0D
+//=0D
+// queued invalidation 256-bit descriptor=0D
+//=0D
+typedef struct {=0D
+ UINT64 Uint64[4];=0D
+} QI_256_DESC;=0D
+=0D
typedef union {=0D
struct {=0D
UINT8 Minor:4;=0D
@@ -411,6 +420,56 @@ typedef union {
UINT64 Uint64[2];=0D
} VTD_FRCD_REG;=0D
=0D
+typedef union {=0D
+ struct {=0D
+ UINT32 IQEI:4; // Invalidation Queue Error Info=0D
+ UINT32 Rsvd_4:28;=0D
+ UINT32 ITESID:16; // Invalidation Time-out Error Source Identifie=
r=0D
+ UINT32 ICESID:16; // Invalidation Completion Error Source Identif=
ier=0D
+ } Bits;=0D
+ UINT64 Uint64;=0D
+} VTD_IQERCD_REG;=0D
+=0D
+typedef union {=0D
+ struct {=0D
+ UINT64 Rsvd_0:4;=0D
+ UINT64 QH:15; // Queue Head=0D
+ UINT64 Rsvd_19:45;=0D
+ } Bits128Desc;=0D
+ struct {=0D
+ UINT64 Rsvd_0:4;=0D
+ UINT64 Rsvd_4:1;=0D
+ UINT64 QH:14; // Queue Head=0D
+ UINT64 Rsvd_19:45;=0D
+ } Bits256Desc;=0D
+ UINT64 Uint64;=0D
+} VTD_IQH_REG;=0D
+=0D
+typedef union {=0D
+ struct {=0D
+ UINT64 Rsvd_0:4;=0D
+ UINT64 QT:15; // Queue Tail=0D
+ UINT64 Rsvd_19:45;=0D
+ } Bits128Desc;=0D
+ struct {=0D
+ UINT64 Rsvd_0:4;=0D
+ UINT64 Rsvd_4:1;=0D
+ UINT64 QT:14; // Queue Tail=0D
+ UINT64 Rsvd_19:45;=0D
+ } Bits256Desc;=0D
+ UINT64 Uint64;=0D
+} VTD_IQT_REG;=0D
+=0D
+typedef union {=0D
+ struct {=0D
+ UINT64 QS:3; // Queue Size=0D
+ UINT64 Rsvd_3:8;=0D
+ UINT64 DW:1; // Descriptor Width=0D
+ UINT64 IQA:52; // Invalidation Queue Base Address=0D
+ } Bits;=0D
+ UINT64 Uint64;=0D
+} VTD_IQA_REG;=0D
+=0D
typedef union {=0D
struct {=0D
UINT8 Function:3;=0D
--=20
2.26.2.windows.1