From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web11.3579.1669785319870356608 for ; Tue, 29 Nov 2022 21:15:20 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=ik+tB86N; spf=pass (domain: intel.com, ip: 134.134.136.20, mailfrom: w.sheng@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669785319; x=1701321319; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=RUnqecu/EPbc94Ii/Ei6d50UUVeeyqHEVsz4eNHOJ/A=; b=ik+tB86N1U8ASY4F0RTl0PXro2CcyN+1gWfdpuACE647GPVA+MipLUyM jzuT5sg8bJoS86ljJJJ7SRJzQkKokIO/79BsfkokHaNToW6NHCbVHNhby EHLzCBpyDp8L0Zvs/5WkBw0Rg7aDrfPxScuuq8LSY5j0zNNwdeTXYEvGU 0H1zexs5qF/Fm/eQo6jIjRENK2sUIBZs2Wt0elRkr3lTFgPBYIE9GcNT3 ek0LSOHK/ksl18Dbq1fD4sp0EjdWlQ7mux39PvpPV/c8nW6vixEeowqc2 r1Puo3di3T2wuf1+eg3EeqJiJcz6OSQ3U2StZyDm420jXFx/QScu0y85U g==; X-IronPort-AV: E=McAfee;i="6500,9779,10546"; a="302911514" X-IronPort-AV: E=Sophos;i="5.96,205,1665471600"; d="scan'208";a="302911514" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Nov 2022 21:15:08 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10546"; a="889146534" X-IronPort-AV: E=Sophos;i="5.96,205,1665471600"; d="scan'208";a="889146534" Received: from shwdesssddpdwei.ccr.corp.intel.com ([10.239.157.43]) by fmsmga006.fm.intel.com with ESMTP; 29 Nov 2022 21:15:05 -0800 From: "Sheng Wei" To: devel@edk2.groups.io Cc: Ray Ni , Rangasai V Chaganty , Jenny Huang , Robert Kowalewski Subject: [PATCH] IntelSiliconPkg/VTd: Use 256-bit invaildation queue descriptor Date: Wed, 30 Nov 2022 13:15:03 +0800 Message-Id: <20221130051503.1736-1-w.sheng@intel.com> X-Mailer: git-send-email 2.26.2.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 256-bit invaildation queue descriptor could be used for both abort DMA mode and legacy mode. Signed-off-by: Sheng Wei Cc: Ray Ni Cc: Rangasai V Chaganty Cc: Jenny Huang Cc: 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