VTd Queued Invalidation IOTLB descriptor need to use CAP_REG.DWD and CAP_REG.DRD. Queued Invalidation descriptor is a 128 bits value. Register-based invalidation interface supported by hardware implementations of this architecture with Major Version 5 or lower (VER_REG).
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3964 Signed-off-by: Sheng Wei <w.sh...@intel.com> Cc: Jenny Huang <jenny.hu...@intel.com> Cc: Ray Ni <ray...@intel.com> Cc: Rangasai V Chaganty <rangasai.v.chaga...@intel.com> --- .../VTd/IntelVTdDmarPei/IntelVTdDmar.c | 32 +++++++++---------- .../VTd/IntelVTdDmarPei/IntelVTdDmarPei.h | 2 +- .../Feature/VTd/IntelVTdDxe/VtdReg.c | 2 +- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c index 0d372f6c..b5b78f77 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c @@ -79,7 +79,7 @@ PerpareCacheInvalidationInterface ( IN VTD_UNIT_INFO *VTdUnitInfo ) { - UINT16 QiDescLength; + UINT16 QueueSize; UINT64 Reg64; UINT32 Reg32; VTD_ECAP_REG ECapReg; @@ -122,18 +122,18 @@ PerpareCacheInvalidationInterface ( // Setup the IQ address, size and descriptor width through the Invalidation Queue Address Register // if (VTdUnitInfo->QiDesc == NULL) { - VTdUnitInfo->QueueSize = 0; - QiDescLength = 1 << (VTdUnitInfo->QueueSize + 8); - VTdUnitInfo->QiDesc = (QI_DESC *) AllocatePages (EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * QiDescLength)); + 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) { DEBUG ((DEBUG_ERROR,"Could not Alloc Invalidation Queue Buffer.\n")); return EFI_OUT_OF_RESOURCES; } } - DEBUG ((DEBUG_INFO, "Invalidation Queue Length : %d\n", QiDescLength)); + DEBUG ((DEBUG_INFO, "Invalidation Queue Length : %d\n", VTdUnitInfo->QiDescLength)); Reg64 = (UINT64) (UINTN) VTdUnitInfo->QiDesc; - Reg64 |= VTdUnitInfo->QueueSize; + Reg64 |= QueueSize; MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, Reg64); // @@ -164,7 +164,6 @@ DisableQueuedInvalidationInterface ( ) { UINT32 Reg32; - UINT16 QiDescLength; if (VTdUnitInfo->EnableQueuedInvalidation != 0) { Reg32 = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG); @@ -176,10 +175,9 @@ DisableQueuedInvalidationInterface ( } while ((Reg32 & B_GSTS_REG_QIES) != 0); if (VTdUnitInfo->QiDesc != NULL) { - QiDescLength = 1 << (VTdUnitInfo->QueueSize + 8); - FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * QiDescLength)); + FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES (sizeof (QI_DESC) * VTdUnitInfo->QiDescLength)); VTdUnitInfo->QiDesc = NULL; - VTdUnitInfo->QueueSize = 0; + VTdUnitInfo->QiDescLength = 0; } VTdUnitInfo->EnableQueuedInvalidation = 0; @@ -239,10 +237,10 @@ SubmitQueuedInvalidationDescriptor ( return EFI_INVALID_PARAMETER; } - QiDescLength = 1 << (VTdUnitInfo->QueueSize + 8); + QiDescLength = VTdUnitInfo->QiDescLength; BaseDesc = VTdUnitInfo->QiDesc; - DEBUG((DEBUG_INFO, "[0x%x] Submit QI Descriptor [0x%08x, 0x%08x]\n", VTdUnitInfo->VtdUnitBaseAddress, Desc->Low, Desc->High)); + DEBUG((DEBUG_INFO, "[0x%x] Submit QI Descriptor [0x%016lx, 0x%016lx]\n", VTdUnitInfo->VtdUnitBaseAddress, Desc->Low, Desc->High)); BaseDesc[VTdUnitInfo->QiFreeHead].Low = Desc->Low; BaseDesc[VTdUnitInfo->QiFreeHead].High = Desc->High; @@ -251,7 +249,6 @@ SubmitQueuedInvalidationDescriptor ( DEBUG((DEBUG_INFO,"QI Free Head=0x%x\n", VTdUnitInfo->QiFreeHead)); VTdUnitInfo->QiFreeHead = (VTdUnitInfo->QiFreeHead + 1) % QiDescLength; - Reg64Iqh = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_IQH_REG); // // Update the HW tail register indicating the presence of new descriptors. // @@ -328,6 +325,7 @@ InvalidateIOTLB ( { UINT64 Reg64; VTD_ECAP_REG ECapReg; + VTD_CAP_REG CapReg; QI_DESC QiDesc; if (VTdUnitInfo->EnableQueuedInvalidation == 0) { @@ -353,8 +351,8 @@ InvalidateIOTLB ( // // Queued Invalidation // - 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; + CapReg.Uint64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_CAP_REG); + QiDesc.Low = QI_IOTLB_DID(0) | QI_IOTLB_DR(CAP_READ_DRAIN(CapReg.Uint64)) | QI_IOTLB_DW(CAP_WRITE_DRAIN(CapReg.Uint64)) | QI_IOTLB_GRAN(1) | QI_IOTLB_TYPE; QiDesc.High = QI_IOTLB_ADDR(0) | QI_IOTLB_IH(0) | QI_IOTLB_AM(0); return SubmitQueuedInvalidationDescriptor(VTdUnitInfo, &QiDesc); @@ -364,7 +362,7 @@ InvalidateIOTLB ( } /** - Enable DMAR translation inpre-mem phase. + Enable DMAR translation in pre-mem phase. @param[in] VtdUnitBaseAddress The base address of the VTd engine. @param[in] RtaddrRegValue The value of RTADDR_REG. @@ -400,7 +398,7 @@ EnableDmarPreMem ( Reg32 = MmioRead32 (VtdUnitBaseAddress + R_FEDATA_REG); // - // Write Buffer Flush before invalidation + // Write Buffer Flush // FlushWriteBuffer (VtdUnitBaseAddress); diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h index 7bed0a53..5ade9ec3 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h @@ -21,7 +21,7 @@ typedef struct { VTD_ECAP_REG ECapReg; BOOLEAN Is5LevelPaging; UINT8 EnableQueuedInvalidation; - UINT16 QueueSize; + UINT16 QiDescLength; QI_DESC *QiDesc; UINT16 QiFreeHead; UINTN FixedSecondLevelPagingEntry; diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c index 61be2dcc..c7a56cf5 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c @@ -72,7 +72,7 @@ PerpareCacheInvalidationInterface ( UINT64 Reg64; UINT32 Reg32; - if (mVtdUnitInformation[VtdIndex].VerReg.Bits.Major <= 6) { + if (mVtdUnitInformation[VtdIndex].VerReg.Bits.Major <= 5) { mVtdUnitInformation[VtdIndex].EnableQueuedInvalidation = 0; DEBUG ((DEBUG_INFO, "Use Register-based Invalidation Interface for engine [%d]\n", VtdIndex)); return EFI_SUCCESS; -- 2.26.2.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90783): https://edk2.groups.io/g/devel/message/90783 Mute This Topic: https://groups.io/mt/92015733/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-