Here is the process of modify GCMD_REG. Read GSTS_REG Reset the one-shot bits. Modify the target comamnd value. Write the command value to GCMD_REG. Wait until GSTS_REG indicates command is serviced.
Cc: Ray Ni <ray...@intel.com> Cc: Rangasai V Chaganty <rangasai.v.chaga...@intel.com> Cc: Jenny Huang <jenny.hu...@intel.com> Signed-off-by: Sheng Wei <w.sh...@intel.com> --- .../Feature/VTd/IntelVTdCoreDxe/VtdReg.c | 13 ++---- .../VTd/IntelVTdCorePei/IntelVTdDmar.c | 9 +--- .../VTd/IntelVTdDmarPei/IntelVTdDmar.c | 43 +++++++++--------- .../Feature/VTd/IntelVTdDxe/VtdReg.c | 44 +++++++++---------- .../Feature/VTd/IntelVTdPmrPei/VtdReg.c | 1 + .../IntelVTdPeiDxeLib/IntelVTdPeiDxeLib.c | 12 ++--- 6 files changed, 51 insertions(+), 71 deletions(-) diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdCoreDxe/VtdReg.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdCoreDxe/VtdReg.c index edeb4b3ff..21e2d5f1b 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdCoreDxe/VtdReg.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdCoreDxe/VtdReg.c @@ -112,13 +112,8 @@ PerpareCacheInvalidationInterface ( // Enable the queued invalidation interface through the Global Command Register. // When enabled, hardware sets the QIES field in the Global Status Register. // - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); - Reg32 |= B_GMCD_REG_QIE; - MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32); - DEBUG ((DEBUG_INFO, "Enable Queued Invalidation Interface. GCMD_REG = 0x%x\n", Reg32)); - do { - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); - } while ((Reg32 & B_GSTS_REG_QIES) == 0); + DEBUG ((DEBUG_INFO, "Enable Queued Invalidation Interface.\n")); + VtdLibSetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_QIE); VTdLogAddEvent (VTDLOG_DXE_QUEUED_INVALIDATION, VTD_LOG_QI_ENABLE, VtdUnitBaseAddress); @@ -577,7 +572,7 @@ DumpVtdCapRegs ( IN VTD_CAP_REG *CapReg ) { - DEBUG((DEBUG_INFO, " CapReg - 0x%x\n", CapReg->Uint64)); + DEBUG((DEBUG_INFO, " CapReg - 0x%lx\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)); @@ -737,7 +732,7 @@ DumpVtdIfError ( if (HasError) { REPORT_STATUS_CODE (EFI_ERROR_CODE, PcdGet32 (PcdErrorCodeVTdError)); DEBUG((DEBUG_INFO, "\n#### ERROR ####\n")); - DumpVtdRegs (mVtdUnitInformation[Num].VtdUnitBaseAddress); + DumpVtdRegs (mVtdUnitInformation[Num].VtdUnitBaseAddress); DEBUG((DEBUG_INFO, "#### ERROR ####\n\n")); // // Clear diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdCorePei/IntelVTdDmar.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdCorePei/IntelVTdDmar.c index 93207ba52..549313dbf 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdCorePei/IntelVTdDmar.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdCorePei/IntelVTdDmar.c @@ -120,13 +120,8 @@ PerpareCacheInvalidationInterface ( // Enable the queued invalidation interface through the Global Command Register. // When enabled, hardware sets the QIES field in the Global Status Register. // - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); - Reg32 |= B_GMCD_REG_QIE; - MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32); - DEBUG ((DEBUG_INFO, "Enable Queued Invalidation Interface. GCMD_REG = 0x%x\n", Reg32)); - do { - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); - } while ((Reg32 & B_GSTS_REG_QIES) == 0); + DEBUG ((DEBUG_INFO, "Enable Queued Invalidation Interface.\n")); + VtdLibSetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_QIE); VTdLogAddEvent (VTDLOG_PEI_QUEUED_INVALIDATION, VTD_LOG_QI_ENABLE, VtdUnitBaseAddress); diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c index e1b867973..533fb2b9a 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c @@ -20,6 +20,18 @@ #include <Ppi/IoMmu.h> #include "IntelVTdDmarPei.h" +VOID +SetGlobalCommandRegisterBits ( + IN UINTN VtdUnitBaseAddress, + IN UINT32 BitMask + ); + +VOID +ClearGlobalCommandRegisterBits ( + IN UINTN VtdUnitBaseAddress, + IN UINT32 BitMask + ); + /** Flush VTD page table and context table memory. @@ -58,6 +70,7 @@ FlushWriteBuffer ( if (CapReg.Bits.RWBF != 0) { Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); + Reg32 = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_WBF); do { Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); @@ -104,11 +117,7 @@ PerpareCacheInvalidationInterface ( 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 (VtdUnitBaseAddress + R_GCMD_REG, Reg32); - do { - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); - } while ((Reg32 & B_GSTS_REG_QIES) != 0); + ClearGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_QIE); MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, 0); } @@ -144,13 +153,8 @@ PerpareCacheInvalidationInterface ( // Enable the queued invalidation interface through the Global Command Register. // When enabled, hardware sets the QIES field in the Global Status Register. // - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); - Reg32 |= B_GMCD_REG_QIE; - MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32); - DEBUG ((DEBUG_INFO, "Enable Queued Invalidation Interface. GCMD_REG = 0x%x\n", Reg32)); - do { - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); - } while ((Reg32 & B_GSTS_REG_QIES) == 0); + DEBUG ((DEBUG_INFO, "Enable Queued Invalidation Interface.\n")); + SetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_QIE); return EFI_SUCCESS; } @@ -165,16 +169,9 @@ DisableQueuedInvalidationInterface ( IN VTD_UNIT_INFO *VTdUnitInfo ) { - UINT32 Reg32; - if (VTdUnitInfo->EnableQueuedInvalidation != 0) { - Reg32 = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG); - Reg32 &= (~B_GMCD_REG_QIE); - MmioWrite32 (VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg32); - DEBUG ((DEBUG_INFO, "Disable Queued Invalidation Interface. GCMD_REG = 0x%x\n", Reg32)); - do { - Reg32 = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG); - } while ((Reg32 & B_GSTS_REG_QIES) != 0); + DEBUG ((DEBUG_INFO, "Disable Queued Invalidation Interface.\n")); + ClearGlobalCommandRegisterBits (VTdUnitInfo->VtdUnitBaseAddress, B_GMCD_REG_QIE); if (VTdUnitInfo->QiDescBuffer != NULL) { FreePages(VTdUnitInfo->QiDescBuffer, EFI_SIZE_TO_PAGES (VTdUnitInfo->QiDescBufferSize)); @@ -206,7 +203,7 @@ QueuedInvalidationCheckFault ( if (FaultReg & (B_FSTS_REG_IQE | B_FSTS_REG_ITE | B_FSTS_REG_ICE)) { IqercdReg.Uint64 = MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_IQERCD_REG); - DEBUG((DEBUG_ERROR, "Detect Queue Invalidation Error [0x%08x] - IQERCD [0x%016lx]\n", FaultReg, IqercdReg.Uint64)); + DEBUG((DEBUG_ERROR, "VTD 0x%x Detect Queue Invalidation Error [0x%08x] - IQERCD [0x%016lx]\n", VTdUnitInfo->VtdUnitBaseAddress, FaultReg, IqercdReg.Uint64)); MmioWrite32 (VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG, FaultReg); return RETURN_DEVICE_ERROR; @@ -763,7 +760,7 @@ EnableVTdTranslationProtection ( if (VtdUnitInfo->ExtRootEntryTable != 0) { DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) ExtRootEntryTable 0x%x\n", Index, VtdUnitInfo->ExtRootEntryTable)); - Status = EnableDmar (VtdUnitInfo, VtdUnitInfo->ExtRootEntryTable | BIT11); + Status = EnableDmar (VtdUnitInfo, VtdUnitInfo->ExtRootEntryTable | BIT11); } else { DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) RootEntryTable 0x%x\n", Index, VtdUnitInfo->RootEntryTable)); Status = EnableDmar (VtdUnitInfo, VtdUnitInfo->RootEntryTable); diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c index 30dab4a64..2c48eefe9 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c @@ -12,6 +12,18 @@ VTD_UNIT_INFORMATION *mVtdUnitInformation; BOOLEAN mVtdEnabled; +VOID +SetGlobalCommandRegisterBits ( + IN UINTN VtdUnitBaseAddress, + IN UINT32 BitMask + ); + +VOID +ClearGlobalCommandRegisterBits ( + IN UINTN VtdUnitBaseAddress, + IN UINT32 BitMask + ); + /** Flush VTD page table and context table memory. @@ -47,6 +59,7 @@ FlushWriteBuffer ( if (mVtdUnitInformation[VtdIndex].CapReg.Bits.RWBF != 0) { Reg32 = MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GSTS_REG); + Reg32 = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_WBF); do { Reg32 = MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GSTS_REG); @@ -93,11 +106,7 @@ PerpareCacheInvalidationInterface ( Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); if ((Reg32 & B_GSTS_REG_QIES) != 0) { DEBUG ((DEBUG_ERROR,"Queued Invalidation Interface was enabled.\n")); - Reg32 &= (~B_GSTS_REG_QIES); - MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32); - do { - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); - } while ((Reg32 & B_GSTS_REG_QIES) != 0); + ClearGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_QIE); } // @@ -132,13 +141,8 @@ PerpareCacheInvalidationInterface ( // Enable the queued invalidation interface through the Global Command Register. // When enabled, hardware sets the QIES field in the Global Status Register. // - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); - Reg32 |= B_GMCD_REG_QIE; - MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32); - DEBUG ((DEBUG_INFO, "Enable Queued Invalidation Interface. GCMD_REG = 0x%x\n", Reg32)); - do { - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); - } while ((Reg32 & B_GSTS_REG_QIES) == 0); + DEBUG ((DEBUG_INFO, "Enable Queued Invalidation Interface.\n")); + SetGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_QIE); return EFI_SUCCESS; } @@ -153,19 +157,13 @@ DisableQueuedInvalidationInterface ( IN UINTN VtdIndex ) { - UINT32 Reg32; VTD_UNIT_INFORMATION *VTdUnitInfo; VTdUnitInfo = &mVtdUnitInformation[VtdIndex]; if (VTdUnitInfo->EnableQueuedInvalidation != 0) { - Reg32 = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG); - Reg32 &= (~B_GMCD_REG_QIE); - MmioWrite32 (VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg32); - DEBUG ((DEBUG_INFO, "Disable Queued Invalidation Interface. GCMD_REG = 0x%x\n", Reg32)); - do { - Reg32 = MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG); - } while ((Reg32 & B_GSTS_REG_QIES) != 0); + DEBUG ((DEBUG_INFO, "Disable Queued Invalidation Interface.\n")); + ClearGlobalCommandRegisterBits (VTdUnitInfo->VtdUnitBaseAddress, B_GMCD_REG_QIE); if (VTdUnitInfo->QiDescBuffer != NULL) { FreePages(VTdUnitInfo->QiDescBuffer, EFI_SIZE_TO_PAGES (VTdUnitInfo->QiDescBufferSize)); @@ -198,7 +196,7 @@ QueuedInvalidationCheckFault ( if (FaultReg & (B_FSTS_REG_IQE | B_FSTS_REG_ITE | B_FSTS_REG_ICE)) { IqercdReg.Uint64 = MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_IQERCD_REG); - DEBUG((DEBUG_ERROR, "Detect Queue Invalidation Error [0x%08x] - IQERCD [0x%016lx]\n", FaultReg, IqercdReg.Uint64)); + DEBUG((DEBUG_ERROR, "VTD 0x%x Detect Queue Invalidation Error [0x%08x] - IQERCD [0x%016lx]\n", mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress, FaultReg, IqercdReg.Uint64)); MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_FSTS_REG, FaultReg); return RETURN_DEVICE_ERROR; @@ -802,7 +800,7 @@ DumpVtdCapRegs ( IN VTD_CAP_REG *CapReg ) { - DEBUG((DEBUG_INFO, " CapReg - 0x%x\n", CapReg->Uint64)); + DEBUG((DEBUG_INFO, " CapReg - 0x%016lx\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)); @@ -833,7 +831,7 @@ DumpVtdECapRegs ( IN VTD_ECAP_REG *ECapReg ) { - DEBUG((DEBUG_INFO, " ECapReg - 0x%x\n", ECapReg->Uint64)); + DEBUG((DEBUG_INFO, " ECapReg - 0x%016lx\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)); diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c index 2e252fe5b..03b39d183 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/VtdReg.c @@ -54,6 +54,7 @@ FlushWriteBuffer ( if (CapReg.Bits.RWBF != 0) { Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); + Reg32 = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_WBF); do { Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); diff --git a/Silicon/Intel/IntelSiliconPkg/Library/IntelVTdPeiDxeLib/IntelVTdPeiDxeLib.c b/Silicon/Intel/IntelSiliconPkg/Library/IntelVTdPeiDxeLib/IntelVTdPeiDxeLib.c index 3e22c3d92..135e740d6 100644 --- a/Silicon/Intel/IntelSiliconPkg/Library/IntelVTdPeiDxeLib/IntelVTdPeiDxeLib.c +++ b/Silicon/Intel/IntelSiliconPkg/Library/IntelVTdPeiDxeLib/IntelVTdPeiDxeLib.c @@ -1497,6 +1497,7 @@ VtdLibFlushWriteBuffer ( if (CapReg.Bits.RWBF != 0) { Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); + Reg32 = (Reg32 & 0x96FFFFFF); // Reset the one-shot bits MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_WBF); do { Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); @@ -1664,7 +1665,6 @@ VtdLibDisableQueuedInvalidationInterface ( IN UINTN VtdUnitBaseAddress ) { - UINT32 Reg32; QI_256_DESC QiDesc; QiDesc.Uint64[0] = QI_IWD_TYPE; @@ -1674,14 +1674,8 @@ VtdLibDisableQueuedInvalidationInterface ( VtdLibSubmitQueuedInvalidationDescriptor (VtdUnitBaseAddress, &QiDesc, TRUE); - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); - Reg32 &= (~B_GMCD_REG_QIE); - MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32); - - DEBUG ((DEBUG_INFO, "Disable Queued Invalidation Interface. [%x] GCMD_REG = 0x%x\n", VtdUnitBaseAddress, Reg32)); - do { - Reg32 = MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); - } while ((Reg32 & B_GSTS_REG_QIES) != 0); + DEBUG ((DEBUG_INFO, "Disable Queued Invalidation Interface. [%x]\n", VtdUnitBaseAddress)); + VtdLibClearGlobalCommandRegisterBits (VtdUnitBaseAddress, B_GMCD_REG_QIE); MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, 0); } -- 2.26.2.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#115617): https://edk2.groups.io/g/devel/message/115617 Mute This Topic: https://groups.io/mt/104461797/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-