From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mx.groups.io with SMTP id smtpd.web09.5270.1612428723622906442 for ; Thu, 04 Feb 2021 00:52:03 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.100, mailfrom: heng.luo@intel.com) IronPort-SDR: Ylwa+lOX8Soyfeg0zyzbWXT065ubx1lJiPZ8tVe2xLzhr0jpyH3mkodGpvGSvjxaPdZ/UPY/87 /4OjWjJC4uWA== X-IronPort-AV: E=McAfee;i="6000,8403,9884"; a="245272294" X-IronPort-AV: E=Sophos;i="5.79,400,1602572400"; d="scan'208";a="245272294" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Feb 2021 00:51:37 -0800 IronPort-SDR: gBNaBiXIyxofjdwz1ZQRjgzEeQ/UjlymU1T1dpCMlRWGQ9Qq4svgzQT57sF89uNuCfKUcizuEz jGEJdxzJnQtg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,400,1602572400"; d="scan'208";a="393062365" Received: from hengluo-dev.ccr.corp.intel.com ([10.239.153.154]) by orsmga008.jf.intel.com with ESMTP; 04 Feb 2021 00:51:36 -0800 From: "Heng Luo" To: devel@edk2.groups.io Cc: Sai Chaganty , Nate DeSimone Subject: [Patch V2 30/40] TigerlakeSiliconPkg/IpBlock: Add Vtd component Date: Thu, 4 Feb 2021 16:49:09 +0800 Message-Id: <20210204084919.3603-30-heng.luo@intel.com> X-Mailer: git-send-email 2.24.0.windows.2 In-Reply-To: <20210204084919.3603-1-heng.luo@intel.com> References: <20210204084919.3603-1-heng.luo@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3171 Adds the following files: * IpBlock/Vtd/IncludePrivate * IpBlock/Vtd/Library * IpBlock/Vtd/LibraryPrivate Cc: Sai Chaganty Cc: Nate DeSimone Signed-off-by: Heng Luo --- Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVt= dInitLib.h | 62 +++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVt= dPolicyLib.h | 67 +++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/VtdDataHob.h = | 32 ++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/= PeiDxeSmmVtdInfoLib.inf | 45 +++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLib/= VtdInfoLib.c | 86 +++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib= /DxeVtdInitLib.c | 684 +++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib= /DxeVtdInitLib.inf | 71 +++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyL= ib/DxeVtdPolicyLib.c | 90 +++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyL= ib/DxeVtdPolicyLib.inf | 35 +++++++++++++++++++++++++++++++++++ 9 files changed, 1172 insertions(+) diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/L= ibrary/DxeVtdInitLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Incl= udePrivate/Library/DxeVtdInitLib.h new file mode 100644 index 0000000000..e439cfbac2 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/= DxeVtdInitLib.h @@ -0,0 +1,62 @@ +/** @file=0D + Header file for DXE VTD Init Lib.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _DXE_VTD_INIT_LIB_H_=0D +#define _DXE_VTD_INIT_LIB_H_=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +/**=0D + Locate the VT-d ACPI tables data file and read ACPI SSDT tables.=0D + Publish the appropriate SSDT based on current configuration and capabili= ties.=0D +=0D + @param[in] SaPolicy SA DXE Policy protocol=0D +=0D + @retval EFI_SUCCESS - Vtd initialization complete=0D + @retval Other - No Vtd function initiated=0D +**/=0D +EFI_STATUS=0D +VtdInit (=0D + IN SA_POLICY_PROTOCOL *SaPolicy=0D + );=0D +=0D +/**=0D + EndOfPcieEnum routine for update DMAR=0D +**/=0D +VOID=0D +UpdateDmarEndOfPcieEnum (=0D + VOID=0D + );=0D +#endif=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/L= ibrary/DxeVtdPolicyLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/In= cludePrivate/Library/DxeVtdPolicyLib.h new file mode 100644 index 0000000000..d55cf6bc34 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/= DxeVtdPolicyLib.h @@ -0,0 +1,67 @@ +/** @file=0D + Prototype of the DXE VTD Policy Init library.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _DXE_VTD_POLICY_INIT_LIB_H_=0D +#define _DXE_VTD_POLICY_INIT_LIB_H_=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +extern EFI_GUID gVtdDxeConfigGuid;=0D +=0D +/**=0D + This function Load default Vtd DXE policy.=0D +=0D + @param[in] ConfigBlockPointer The pointer to add VTD config block=0D +**/=0D +VOID=0D +VtdLoadDefaultDxe (=0D + IN VOID *ConfigBlockPointer=0D + );=0D +=0D +/**=0D + This function prints the DXE phase VTD policy.=0D +=0D + @param[in] SaPolicy - Instance of SA_POLICY_PROTOCOL=0D +**/=0D +VOID=0D +VtdPrintPolicyDxe (=0D + IN SA_POLICY_PROTOCOL *SaPolicy=0D + );=0D +=0D +/**=0D + This function is used to add VTD Config Block.=0D +=0D + @param[in] ConfigBlockTableAddress The pointer to add VTD config bloc= ks=0D +=0D + @retval EFI_SUCCESS The policy default is initialized.= =0D + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create b= uffer=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +VtdAddConfigBlocksDxe (=0D + IN VOID *ConfigBlockTableAddress=0D + );=0D +=0D +/**=0D + Get VTD DXE config block table total size.=0D +=0D + @retval Size of VTD DXE config block table=0D +**/=0D +UINT16=0D +EFIAPI=0D +VtdGetConfigBlockTotalSizeDxe (=0D + VOID=0D + );=0D +#endif // _DXE_VTD_POLICY_INIT_LIB_H_=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/V= tdDataHob.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/= VtdDataHob.h new file mode 100644 index 0000000000..0f9d500af9 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/VtdDataH= ob.h @@ -0,0 +1,32 @@ +/** @file=0D + The GUID definition for Vtd Data Hob=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _VTD_DATA_HOB_H_=0D +#define _VTD_DATA_HOB_H_=0D +=0D +#include =0D +#include =0D +=0D +extern EFI_GUID gVtdDataHobGuid;=0D +=0D +#pragma pack (push,1)=0D +=0D +///=0D +/// The data elements should be initialized by a Platform Module.=0D +/// The data structure is for VT-d driver initialization=0D +///=0D +typedef struct {=0D + EFI_HOB_GUID_TYPE EfiHobGuidType; ///< GUID Hob t= ype structure for gVtdDataHobGuid=0D + BOOLEAN VtdDisable; ///< 1 =3D Avoi= ds programming Vtd bars, Vtd overrides and DMAR table=0D + UINT32 BaseAddress[VTD_ENGINE_NUMBER]; ///< This field= is used to describe the base addresses for VT-d function=0D + BOOLEAN X2ApicOptOut; ///< This field= is used to enable the X2APIC_OPT_OUT bit in the DMAR table. 1=3DEnable/= Set and 0=3DDisable/Clear=0D + BOOLEAN DmaControlGuarantee; ///< This field= is used to enable the DMA_CONTROL_GUARANTEE bit in the DMAR table. 1=3D= Enable/Set and 0=3DDisable/Clear=0D + BOOLEAN InterruptRemappingSupport; ///< This field= is used to indicate Interrupt Remapping supported or not=0D + UINT32 DmaBufferBase; ///< Iommu PEI = DMA buffer base in low memory region, in Mbytes units=0D +} VTD_DATA_HOB;=0D +=0D +#pragma pack (pop)=0D +#endif=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSm= mVtdInfoLib/PeiDxeSmmVtdInfoLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpB= lock/Vtd/Library/PeiDxeSmmVtdInfoLib/PeiDxeSmmVtdInfoLib.inf new file mode 100644 index 0000000000..c7c5e56b84 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInf= oLib/PeiDxeSmmVtdInfoLib.inf @@ -0,0 +1,45 @@ +## @file=0D +# VTD Common Library.=0D +#=0D +# All function in this library is available for PEI, DXE, and SMM,=0D +# But do not support UEFI RUNTIME environment call.=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +=0D +[Defines]=0D +INF_VERSION =3D 0x00010017=0D +BASE_NAME =3D PeiDxeSmmVtdInfoLib=0D +FILE_GUID =3D A1480873-3FDA-4E90-B450-743D8031F9DE=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D BASE=0D +LIBRARY_CLASS =3D VtdInfoLib=0D +=0D +[LibraryClasses]=0D +BaseLib=0D +IoLib=0D +DebugLib=0D +PciSegmentLib=0D +HobLib=0D +VtdInfoLib=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +[Sources]=0D +VtdInfoLib.c=0D +=0D +[Pcd]=0D +gSiPkgTokenSpaceGuid.VtdEngine1BaseAddeess=0D +gSiPkgTokenSpaceGuid.VtdEngine2BaseAddeess=0D +gSiPkgTokenSpaceGuid.VtdEngine3BaseAddeess=0D +gSiPkgTokenSpaceGuid.VtdEngine4BaseAddeess=0D +gSiPkgTokenSpaceGuid.VtdEngine5BaseAddeess=0D +gSiPkgTokenSpaceGuid.VtdEngine6BaseAddeess=0D +gSiPkgTokenSpaceGuid.VtdEngine7BaseAddeess=0D +=0D +[FixedPcd]=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSm= mVtdInfoLib/VtdInfoLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Li= brary/PeiDxeSmmVtdInfoLib/VtdInfoLib.c new file mode 100644 index 0000000000..e4f08592cc --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInf= oLib/VtdInfoLib.c @@ -0,0 +1,86 @@ +/** @file=0D + VTD Info library.=0D + All function in this library is available for PEI, DXE, and SMM,=0D + But do not support UEFI RUNTIME environment call.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +/**=0D + Get VTD Engine Base Address from PCD value=0D +=0D + @param[in] VtdEngineNumber - Engine number for which VTD Base Ad= deress is required.=0D +=0D + @retval VTD Engine Base Address=0D +**/=0D +UINT32=0D +GetVtdBaseAddress (=0D + IN UINT8 VtdEngineNumber=0D + )=0D +{=0D + switch (VtdEngineNumber) {=0D + case 0:=0D + return PcdGet32(VtdEngine1BaseAddeess);=0D + break;=0D + case 2:=0D + return PcdGet32(VtdEngine3BaseAddeess);=0D + break;=0D + default:=0D + return 0x0;=0D + break;=0D + }=0D +}=0D +=0D +=0D +/**=0D + Read VTD Engine Base Address from VTD BAR Offsets.=0D +=0D + @param[in] VtdEngineNumber - Engine number for which VTD Base Ad= deress is required.=0D +=0D + @retval VTD Engine Base Address=0D +**/=0D +UINT32=0D +ReadVtdBaseAddress (=0D + IN UINT8 VtdEngineNumber=0D + )=0D +{=0D + UINT64 McD0BaseAddress;=0D + UINTN MchBar;=0D +=0D + McD0BaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0= , 0);=0D + MchBar =3D PciSegmentRead32 (McD0BaseAddress + R_SA_MCHBAR) & (= ~BIT0);=0D +=0D + switch (VtdEngineNumber) {=0D + case 0:=0D + return (MmioRead32 (MchBar + R_MCHBAR_VTD1_OFFSET) & (~BIT0));=0D + break;=0D + case 2:=0D + return (MmioRead32 (MchBar + R_MCHBAR_VTD3_OFFSET) & (~BIT0));=0D + break;=0D + default:=0D + return 0x0;=0D + break;=0D + }=0D +}=0D +=0D +/**=0D + GetMaxVtdEngineNumber: Get Maximum Vtd Engine Number=0D +=0D + @retval Vtd Engine Number=0D +**/=0D +UINT8=0D +GetMaxVtdEngineNumber(=0D + VOID=0D +)=0D +{=0D + return (UINT8)VTD_ENGINE_NUMBER;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/D= xeVtdInitLib/DxeVtdInitLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vt= d/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.c new file mode 100644 index 0000000000..faac07c45d --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdIn= itLib/DxeVtdInitLib.c @@ -0,0 +1,684 @@ +/** @file=0D + DXE Library for VTD ACPI table initialization.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +///=0D +/// Global Variables=0D +///=0D +GLOBAL_REMOVE_IF_UNREFERENCED VTD_DATA_HOB *mVtdDataHob;=0D +=0D +BOOLEAN mInterruptRemappingSupport;=0D +=0D +/**=0D + Get the corresponding device Enable/Disable bit according DevNum and Fun= Num=0D +=0D + @param[in] DevNum - Device Number=0D + @param[in] FunNum - Function Number=0D +=0D + @retval If the device is found, return disable/Enable bit in FD/Deven re= igster=0D + @retval If not found return 0xFF=0D +**/=0D +UINT16=0D +GetFunDisableBit (=0D + UINT8 DevNum,=0D + UINT8 FunNum=0D + )=0D +{=0D + UINTN Index;=0D +=0D + for (Index =3D 0; Index < mDevEnMapSize; Index++) {=0D + if (mDevEnMap[Index][0] =3D=3D ((DevNum << 0x08) | FunNum)) {=0D + return mDevEnMap[Index][1];=0D + }=0D + }=0D +=0D + return 0xFF;=0D +}=0D +=0D +/**=0D + Update the DRHD structure=0D +=0D + @param[in, out] DrhdEnginePtr - A pointer to DRHD structure=0D +**/=0D +VOID=0D +UpdateDrhd (=0D + IN OUT VOID *DrhdEnginePtr=0D + )=0D +{=0D + UINT16 Length;=0D + UINT16 DisableBit;=0D + BOOLEAN NeedRemove;=0D + EFI_ACPI_DRHD_ENGINE1_STRUCT *DrhdEngine;=0D +=0D + //=0D + // Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE1_STRUCT Pointer=0D + //=0D + DrhdEngine =3D (EFI_ACPI_DRHD_ENGINE1_STRUCT *) DrhdEnginePtr;=0D + Length =3D DrhdEngine->DrhdHeader.Header.Length;=0D + DisableBit =3D GetFunDisableBit (=0D + DrhdEngine->DeviceScope[0].PciPath.Device,=0D + DrhdEngine->DeviceScope[0].PciPath.Function=0D + );=0D + NeedRemove =3D FALSE;=0D +=0D + if ((DisableBit =3D=3D 0xFF) ||=0D + (DrhdEngine->DrhdHeader.RegisterBaseAddress =3D=3D 0) ||=0D + ((DisableBit =3D=3D 0x80) &&=0D + (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, DrhdEngi= ne->DeviceScope[0].PciPath.Device, DrhdEngine->DeviceScope[0].PciPath.Funct= ion, 0x00)) =3D=3D 0xFFFFFFFF))=0D + ) {=0D + NeedRemove =3D TRUE;=0D + }=0D + if ((DrhdEngine->DeviceScope[0].PciPath.Device =3D=3D IGD_DEV_NUM) && (D= rhdEngine->DeviceScope[0].PciPath.Function =3D=3D IGD_FUN_NUM) &&=0D + (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, DrhdEngin= e->DeviceScope[0].PciPath.Device, DrhdEngine->DeviceScope[0].PciPath.Functi= on, 0x00)) !=3D 0xFFFFFFFF)) {=0D + NeedRemove =3D FALSE;=0D + }=0D + if (NeedRemove) {=0D + Length -=3D sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);=0D + }=0D + ///=0D + /// If no devicescope is left, we set the structure length as 0x00=0D + ///=0D + if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) || (DrhdEngine->DrhdHe= ader.Flags =3D=3D 0x01)) {=0D + DrhdEngine->DrhdHeader.Header.Length =3D Length;=0D + } else {=0D + DrhdEngine->DrhdHeader.Header.Length =3D 0;=0D + }=0D +}=0D +=0D +/**=0D + Get IOAPIC ID from LPC=0D +=0D + @retval APIC ID=0D +**/=0D +UINT8=0D +GetIoApicId (=0D + VOID=0D + )=0D +{=0D + UINT32 IoApicAddress;=0D + UINT32 IoApicId;=0D +=0D + IoApicAddress =3D PcdGet32 (PcdSiIoApicBaseAddress);=0D + ///=0D + /// Get current IO APIC ID=0D + ///=0D + MmioWrite8 ((UINTN) (IoApicAddress + R_IO_APIC_MEM_INDEX_OFFSET), 0);=0D + IoApicId =3D MmioRead32 ((UINTN) (IoApicAddress + R_IO_APIC_MEM_DATA_OFF= SET)) >> 24;=0D +=0D + return (UINT8) IoApicId;=0D +}=0D +=0D +/**=0D + Update the second DRHD structure=0D +=0D + @param[in, out] DrhdEnginePtr - A pointer to DRHD structure=0D +**/=0D +VOID=0D +UpdateDrhd2 (=0D + IN OUT VOID *DrhdEnginePtr=0D + )=0D +{=0D + UINT16 Length;=0D + UINTN DeviceScopeNum;=0D + UINTN ValidDeviceScopeNum;=0D + UINT16 Index;=0D + UINT8 Bus;=0D + UINT8 Path[2];=0D + BOOLEAN NeedRemove;=0D + EFI_ACPI_DRHD_ENGINE3_STRUCT *DrhdEngine;=0D + VOID *HobPtr;=0D + PCH_INFO_HOB *PchInfoHob;=0D +=0D + ///=0D + /// Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE3_STRUCT Pointer=0D + ///=0D + DrhdEngine =3D (EFI_ACPI_DRHD_ENGINE3_STRUCT *) DrhdEnginePtr;=0D +=0D + Length =3D DrhdEngine->DrhdHeader.Header.Length;=0D + DeviceScopeNum =3D (DrhdEngine->DrhdHeader.Header.Length - EFI_ACPI_DRH= D_ENGINE_HEADER_LENGTH) / sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);=0D + Bus =3D 0;=0D + ValidDeviceScopeNum =3D 0;=0D + Path[0] =3D 0;=0D + Path[1] =3D 0;=0D +=0D + HobPtr =3D GetFirstGuidHob (&gPchInfoHobGuid);=0D + ASSERT (HobPtr !=3D NULL);=0D + if (HobPtr =3D=3D NULL) {=0D + return;=0D + }=0D + PchInfoHob =3D (PCH_INFO_HOB *) GET_GUID_HOB_DATA (HobPtr);=0D + ASSERT (PchInfoHob !=3D NULL);=0D + if (PchInfoHob =3D=3D NULL) {=0D + return;=0D + }=0D +=0D + for (Index =3D 0; Index < DeviceScopeNum; Index++) {=0D + NeedRemove =3D FALSE;=0D + /**=0D + For HPET and APIC, update device scope if Interrupt remapping is sup= ported. remove device scope=0D + if interrupt remapping is not supported.=0D + - Index =3D 0 - IOAPIC=0D + - Index =3D 1 - HPET=0D + **/=0D + if (mInterruptRemappingSupport) {=0D + if (Index =3D=3D 0) {=0D + ///=0D + /// Update source id for IoApic's device scope entry=0D + ///=0D + Bus =3D (UINT8) PchInfoHob->IoApicBusNum;=0D + Path[0] =3D (UINT8) PchInfoHob->IoApicDevNum;=0D + Path[1] =3D (UINT8) PchInfoHob->IoApicFuncNum;=0D + DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBus= Number =3D Bus;=0D + DrhdEngine->DeviceScope[Index].PciPath.Device =3D Path[0];=0D + DrhdEngine->DeviceScope[Index].PciPath.Function =3D Path[1];=0D + //=0D + // Update APIC ID=0D + //=0D + DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.Enumerat= ionId =3D GetIoApicId ();=0D + }=0D + if (Index =3D=3D 1) {=0D + ///=0D + /// Update source id for HPET's device scope entry=0D + ///=0D + Bus =3D (UINT8) PchInfoHob->HpetBusNum;=0D + Path[0] =3D (UINT8) PchInfoHob->HpetDevNum;=0D + Path[1] =3D (UINT8) PchInfoHob->HpetFuncNum;=0D + DrhdEngine->DeviceScope[Index].DeviceScopeStructureHeader.StartBus= Number =3D Bus;=0D + DrhdEngine->DeviceScope[Index].PciPath.Device =3D Path[0];=0D + DrhdEngine->DeviceScope[Index].PciPath.Function =3D Path[1];=0D + }=0D + } else {=0D + if ((Index =3D=3D 0) || (Index =3D=3D 1)) {=0D + NeedRemove =3D TRUE;=0D + }=0D + }=0D +=0D + CopyMem (=0D + &DrhdEngine->DeviceScope[ValidDeviceScopeNum],=0D + &DrhdEngine->DeviceScope[Index],=0D + sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)=0D + );=0D + if (NeedRemove) {=0D + Length -=3D sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);=0D + } else {=0D + ValidDeviceScopeNum++;=0D + }=0D + }=0D + ///=0D + /// If no devicescope is left, we set the structure length as 0x00=0D + ///=0D + if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) || (DrhdEngine->DrhdHe= ader.Flags =3D=3D 0x01)) {=0D + DrhdEngine->DrhdHeader.Header.Length =3D Length;=0D + } else {=0D + DrhdEngine->DrhdHeader.Header.Length =3D 0;=0D + }=0D +}=0D +=0D +/**=0D + Update the RMRR structure=0D +=0D + @param[in, out] RmrrPtr - A pointer to RMRR structure=0D +**/=0D +VOID=0D +UpdateRmrr (=0D + IN OUT VOID *RmrrPtr=0D + )=0D +{=0D + UINT16 Length;=0D + UINT16 DisableBit;=0D + UINTN DeviceScopeNum;=0D + UINTN ValidDeviceScopeNum;=0D + UINTN Index;=0D + BOOLEAN NeedRemove;=0D + EFI_ACPI_RMRR_USB_STRUC *Rmrr;=0D +=0D + ///=0D + /// To make sure all devicescope can be checked,=0D + /// we convert the RmrrPtr to EFI_ACPI_RMRR_USB_STRUC pointer=0D + ///=0D + Rmrr =3D (EFI_ACPI_RMRR_USB_STRUC *) RmrrPtr;=0D +=0D + Length =3D Rmrr->RmrrHeader.Header.Length;=0D + ValidDeviceScopeNum =3D 0;=0D + DeviceScopeNum =3D (Rmrr->RmrrHeader.Header.Length - EFI_ACPI_RMRR_= HEADER_LENGTH) / sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);=0D + for (Index =3D 0; Index < DeviceScopeNum; Index++) {=0D + DisableBit =3D GetFunDisableBit (=0D + Rmrr->DeviceScope[Index].PciPath.Device,=0D + Rmrr->DeviceScope[Index].PciPath.Function=0D + );=0D + NeedRemove =3D FALSE;=0D + if ((DisableBit =3D=3D 0xFF) ||=0D + ((DisableBit =3D=3D 0x80) &&=0D + (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0, Rmrr->= DeviceScope[Index].PciPath.Device, Rmrr->DeviceScope[Index].PciPath.Functio= n, 0x00)) =3D=3D 0xFFFFFFFF))=0D + ) {=0D + NeedRemove =3D TRUE;=0D + } else if (DisableBit =3D=3D 0x8F) {=0D + DEBUG ((DEBUG_ERROR, "Rmrr->RmrrHeader.ReservedMemoryRegionBaseAddre= ss %x\n", Rmrr->RmrrHeader.ReservedMemoryRegionBaseAddress));=0D +=0D + if (Rmrr->RmrrHeader.ReservedMemoryRegionBaseAddress !=3D 0) {=0D + DEBUG ((DEBUG_ERROR, "NeedRemove =3D FALSE\n"));=0D + NeedRemove =3D FALSE;=0D + } else {=0D + DEBUG ((DEBUG_ERROR, "NeedRemove =3D TRUE\n"));=0D + NeedRemove =3D TRUE;=0D + }=0D + }=0D + CopyMem (=0D + &Rmrr->DeviceScope[ValidDeviceScopeNum],=0D + &Rmrr->DeviceScope[Index],=0D + sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)=0D + );=0D +=0D + if (Rmrr->RmrrHeader.ReservedMemoryRegionLimitAddress =3D=3D 0x0) {=0D + NeedRemove =3D TRUE;=0D + }=0D +=0D + if (NeedRemove) {=0D + Length -=3D sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);=0D + } else {=0D + ValidDeviceScopeNum++;=0D + }=0D + }=0D + ///=0D + /// If No deviceScope is left, set length as 0x00=0D + ///=0D + if (Length > EFI_ACPI_RMRR_HEADER_LENGTH) {=0D + Rmrr->RmrrHeader.Header.Length =3D Length;=0D + } else {=0D + Rmrr->RmrrHeader.Header.Length =3D 0;=0D + }=0D +}=0D +=0D +/**=0D + Update the DMAR table=0D +=0D + @param[in, out] TableHeader - The table to be set=0D + @param[in, out] Version - Version to publish=0D +**/=0D +VOID=0D +DmarTableUpdate (=0D + IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader,=0D + IN OUT EFI_ACPI_TABLE_VERSION *Version=0D + )=0D +{=0D + EFI_ACPI_DMAR_TABLE *DmarTable;=0D + EFI_ACPI_DMAR_TABLE TempDmarTable;=0D + UINTN Offset;=0D + UINTN StructureLen;=0D + UINT64 McD0BaseAddress;=0D + UINT32 GttMmAdr;=0D + UINT64 McD2BaseAddress;=0D + UINT16 IgdMode;=0D + UINT16 GttMode;=0D + UINT32 IgdMemSize;=0D + UINT32 GttMemSize;=0D + EFI_STATUS Status;=0D + VTD_DXE_CONFIG *VtdDxeConfig;=0D + SA_POLICY_PROTOCOL *SaPolicy;=0D +=0D +=0D + IgdMemSize =3D 0;=0D + GttMemSize =3D 0;=0D + DmarTable =3D (EFI_ACPI_DMAR_TABLE *) TableHeader;=0D +=0D + Status =3D gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **) = &SaPolicy);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + Status =3D GetConfigBlock ((VOID *) SaPolicy, &gVtdDxeConfigGuid, (VOID = *)&VtdDxeConfig);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + ///=0D + /// Set INTR_REMAP bit (BIT 0) if interrupt remapping is supported=0D + ///=0D + if (mInterruptRemappingSupport) {=0D + DmarTable->DmarHeader.Flags |=3D BIT0;=0D + }=0D +=0D + if (mVtdDataHob->X2ApicOptOut =3D=3D 1) {=0D + DmarTable->DmarHeader.Flags |=3D BIT1;=0D + } else {=0D + DmarTable->DmarHeader.Flags &=3D 0xFD;=0D + }=0D +=0D + ///=0D + /// Set DMA_CONTROL_GUARANTEE bit (BIT 2) if Dma Control Guarantee is su= pported=0D + ///=0D + if (mVtdDataHob->DmaControlGuarantee =3D=3D 1) {=0D + DmarTable->DmarHeader.Flags |=3D BIT2;=0D + }=0D + ///=0D + /// Get OemId=0D + ///=0D + CopyMem (DmarTable->DmarHeader.Header.OemId, PcdGetPtr (PcdAcpiDefaultOe= mId), sizeof (DmarTable->DmarHeader.Header.OemId));=0D + DmarTable->DmarHeader.Header.OemTableId =3D PcdGet64 (PcdAcpiDefaul= tOemTableId);=0D + DmarTable->DmarHeader.Header.OemRevision =3D PcdGet32 (PcdAcpiDefaul= tOemRevision);=0D + DmarTable->DmarHeader.Header.CreatorId =3D PcdGet32 (PcdAcpiDefaul= tCreatorId);=0D + DmarTable->DmarHeader.Header.CreatorRevision =3D PcdGet32 (PcdAcpiDefaul= tCreatorRevision);=0D +=0D + ///=0D + /// Calculate IGD memsize=0D + ///=0D + McD0BaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0= , 0);=0D + IgdMode =3D ((PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) & B_SA_GGC_G= MS_MASK) >> N_SA_GGC_GMS_OFFSET) & 0xFF;=0D + if (IgdMode < 0xF0) {=0D + IgdMemSize =3D IgdMode * 32 * (1024) * (1024);=0D + } else {=0D + IgdMemSize =3D 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024);=0D + }=0D + ///=0D + /// Calculate GTT mem size=0D + ///=0D + GttMemSize =3D 0;=0D + GttMode =3D (PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) & B_SA_GGC_GG= MS_MASK) >> N_SA_GGC_GGMS_OFFSET;=0D + if (GttMode <=3D V_SA_GGC_GGMS_8MB) {=0D + GttMemSize =3D (1 << GttMode) * (1024) * (1024);=0D + }=0D +=0D + McD2BaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, IG= D_DEV_NUM, IGD_FUN_NUM, 0);=0D + GttMmAdr =3D (PciSegmentRead32 (McD2BaseAddress + R_SA_IGD_GTTMMADR)) & = 0xFFFFFFF0;=0D +=0D + DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress =3D (Pci= SegmentRead32 (McD0BaseAddress + R_SA_BGSM) & ~(0x01));=0D + DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress =3D Dmar= Table->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress + IgdMemSize + Gt= tMemSize - 1;=0D + DEBUG ((DEBUG_INFO, "RMRR Base address IGD %016lX\n", DmarTable->RmrrIg= d.RmrrHeader.ReservedMemoryRegionBaseAddress));=0D + DEBUG ((DEBUG_INFO, "RMRR Limit address IGD %016lX\n", DmarTable->RmrrIg= d.RmrrHeader.ReservedMemoryRegionLimitAddress));=0D +=0D + ///=0D + /// Update DRHD structures of DmarTable=0D + ///=0D + DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress =3D ReadVtdBaseAdd= ress(0);=0D + DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress =3D ReadVtdBaseAdd= ress (2);=0D +=0D + DEBUG ((DEBUG_INFO, "VTD base address 1 =3D %x\n", DmarTable->DrhdEngine= 1.DrhdHeader.RegisterBaseAddress));=0D + DEBUG ((DEBUG_INFO, "VTD base address 3 =3D %x\n", DmarTable->DrhdEngine= 3.DrhdHeader.RegisterBaseAddress));=0D + ///=0D + /// copy DmarTable to TempDmarTable to be processed=0D + ///=0D + CopyMem (&TempDmarTable, DmarTable, sizeof (EFI_ACPI_DMAR_TABLE));=0D +=0D + ///=0D + /// Update DRHD structures of temp DMAR table=0D + ///=0D + UpdateDrhd (&TempDmarTable.DrhdEngine1);=0D + UpdateDrhd2 (&TempDmarTable.DrhdEngine3);=0D +=0D + ///=0D + /// Remove unused device scope or entire DRHD structures=0D + ///=0D + Offset =3D (UINTN) (&TempDmarTable.DrhdEngine1);=0D + if (TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length !=3D 0) {=0D + Offset +=3D TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length;=0D + }=0D + if (TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length !=3D 0) {=0D + StructureLen =3D TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length;=0D + CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.DrhdEngine3, TempDma= rTable.DrhdEngine3.DrhdHeader.Header.Length);=0D + Offset +=3D StructureLen;=0D + }=0D + ///=0D + /// Remove unused device scope or entire RMRR structures=0D + ///=0D + if (TempDmarTable.RmrrIgd.RmrrHeader.Header.Length !=3D 0) {=0D + StructureLen =3D TempDmarTable.RmrrIgd.RmrrHeader.Header.Length;=0D + CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrIgd, TempDmarTab= le.RmrrIgd.RmrrHeader.Header.Length);=0D + Offset +=3D StructureLen;=0D + }=0D + Offset =3D Offset - (UINTN) &TempDmarTable;=0D + ///=0D + /// Re-calculate DMAR table check sum=0D + ///=0D + TempDmarTable.DmarHeader.Header.Checksum =3D (UINT8) (TempDmarTable.Dmar= Header.Header.Checksum + TempDmarTable.DmarHeader.Header.Length - Offset);= =0D + ///=0D + /// Set DMAR table length=0D + ///=0D + TempDmarTable.DmarHeader.Header.Length =3D (UINT32) Offset;=0D + ///=0D + /// Replace DMAR table with rebuilt table TempDmarTable=0D + ///=0D + CopyMem ((VOID *) DmarTable, (VOID *) &TempDmarTable, TempDmarTable.Dmar= Header.Header.Length);=0D +}=0D +=0D +/**=0D + EndOfPcieEnumration routine for update DMAR=0D +**/=0D +VOID=0D +UpdateDmarEndOfPcieEnum (=0D + VOID=0D + )=0D +{=0D + EFI_STATUS Status;=0D + EFI_HANDLE *HandleBuffer;=0D + UINTN NumberOfHandles;=0D + EFI_FV_FILETYPE FileType;=0D + UINT32 FvStatus;=0D + EFI_FV_FILE_ATTRIBUTES Attributes;=0D + UINTN Size;=0D + UINTN i;=0D + INTN Instance;=0D + EFI_ACPI_TABLE_VERSION Version;=0D + EFI_ACPI_COMMON_HEADER *CurrentTable;=0D + UINTN AcpiTableHandle;=0D + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;=0D + EFI_ACPI_TABLE_PROTOCOL *AcpiTable;=0D + EFI_ACPI_DESCRIPTION_HEADER *VtdAcpiTable;=0D + STATIC BOOLEAN Triggered =3D FALSE;=0D +=0D +=0D + if (Triggered) {=0D + return;=0D + }=0D +=0D + Triggered =3D TRUE;=0D +=0D + FwVol =3D NULL;=0D + AcpiTable =3D NULL;=0D + VtdAcpiTable =3D NULL;=0D +=0D + DEBUG ((DEBUG_INFO, "UpdateDmarEndOfPcieEnum \n"));=0D +=0D +=0D + ///=0D + /// Fix DMAR Table always created, skip install when disabled=0D + ///=0D + if ((mVtdDataHob->VtdDisable =3D=3D TRUE) || (PciSegmentRead32 (PCI_SEGM= ENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0, R_SA_MC_CAPID0_A_OFFSET)) & B= IT23)) {=0D + DEBUG ((DEBUG_INFO, "Vtd Disabled, skip DMAR Table install\n"));=0D + return;=0D + }=0D +=0D +=0D + ///=0D + /// Locate ACPI support protocol=0D + ///=0D + Status =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID = **) &AcpiTable);=0D +=0D + ///=0D + /// Locate protocol.=0D + /// There is little chance we can't find an FV protocol=0D + ///=0D + Status =3D gBS->LocateHandleBuffer (=0D + ByProtocol,=0D + &gEfiFirmwareVolume2ProtocolGuid,=0D + NULL,=0D + &NumberOfHandles,=0D + &HandleBuffer=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + ///=0D + /// Looking for FV with ACPI storage file=0D + ///=0D + for (i =3D 0; i < NumberOfHandles; i++) {=0D + ///=0D + /// Get the protocol on this handle=0D + /// This should not fail because of LocateHandleBuffer=0D + ///=0D + Status =3D gBS->HandleProtocol (=0D + HandleBuffer[i],=0D + &gEfiFirmwareVolume2ProtocolGuid,=0D + (VOID **) &FwVol=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + ///=0D + /// See if it has the ACPI storage file=0D + ///=0D + Size =3D 0;=0D + FvStatus =3D 0;=0D + Status =3D FwVol->ReadFile (=0D + FwVol,=0D + &gSaAcpiTableStorageGuid,=0D + NULL,=0D + &Size,=0D + &FileType,=0D + &Attributes,=0D + &FvStatus=0D + );=0D +=0D + ///=0D + /// If we found it, then we are done=0D + ///=0D + if (Status =3D=3D EFI_SUCCESS) {=0D + break;=0D + }=0D + }=0D + ///=0D + /// Our exit status is determined by the success of the previous operati= ons=0D + /// If the protocol was found, Instance already points to it.=0D + ///=0D + ///=0D + /// Free any allocated buffers=0D + ///=0D + FreePool (HandleBuffer);=0D +=0D + ///=0D + /// Sanity check that we found our data file=0D + ///=0D + ASSERT (FwVol);=0D + if (FwVol =3D=3D NULL) {=0D + return;=0D + }=0D + ///=0D + /// By default, a table belongs in all ACPI table versions published.=0D + ///=0D + Version =3D EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | E= FI_ACPI_TABLE_VERSION_3_0;=0D +=0D + ///=0D + /// Read tables from the storage file.=0D + ///=0D + Instance =3D 0;=0D + CurrentTable =3D NULL;=0D +=0D + while (Status =3D=3D EFI_SUCCESS) {=0D + Status =3D FwVol->ReadSection (=0D + FwVol,=0D + &gSaAcpiTableStorageGuid,=0D + EFI_SECTION_RAW,=0D + Instance,=0D + (VOID **) &CurrentTable,=0D + &Size,=0D + &FvStatus=0D + );=0D +=0D + if (!EFI_ERROR (Status)) {=0D + ///=0D + /// Check the Signature ID to modify the table=0D + ///=0D + if ((CurrentTable !=3D NULL) && ((EFI_ACPI_DESCRIPTION_HEADER *) Cur= rentTable)->Signature =3D=3D EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE) {=0D + VtdAcpiTable =3D (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;=0D + DmarTableUpdate (VtdAcpiTable, &Version);=0D + break;=0D + }=0D + ///=0D + /// Increment the instance=0D + ///=0D + Instance++;=0D + if (CurrentTable !=3D NULL) {=0D + gBS->FreePool (CurrentTable);=0D + CurrentTable =3D NULL;=0D + }=0D + }=0D + }=0D + ///=0D + /// Update the VTD table in the ACPI tables.=0D + ///=0D + AcpiTableHandle =3D 0;=0D + if (VtdAcpiTable !=3D NULL) {=0D + Status =3D AcpiTable->InstallAcpiTable (=0D + AcpiTable,=0D + VtdAcpiTable,=0D + VtdAcpiTable->Length,=0D + &AcpiTableHandle=0D + );=0D + FreePool (VtdAcpiTable);=0D + }=0D +}=0D +=0D +/**=0D + Locate the VT-d ACPI tables data file and read ACPI SSDT tables.=0D + Publish the appropriate SSDT based on current configuration and capabili= ties.=0D +=0D + @param[in] SaPolicy - SA DXE Policy protocol=0D +=0D + @retval EFI_SUCCESS - Vtd initialization complete=0D + @exception EFI_UNSUPPORTED - Vtd is not enabled by policy=0D +**/=0D +EFI_STATUS=0D +VtdInit (=0D + IN SA_POLICY_PROTOCOL *SaPolicy=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINT64 McD0BaseAddress;=0D + UINT64 McD2BaseAddress;=0D + SYSTEM_AGENT_NVS_AREA_PROTOCOL *SaNvsAreaProtocol;=0D + UINT8 Index;=0D +=0D + mInterruptRemappingSupport =3D FALSE;=0D + mVtdDataHob =3D NULL;=0D + mVtdDataHob =3D GetFirstGuidHob(&gVtdDataHobGuid);=0D + if (mVtdDataHob !=3D NULL) {=0D + mInterruptRemappingSupport =3D mVtdDataHob->InterruptRemappingSupport;= =0D + }=0D +=0D + ///=0D + /// Locate the SA Global NVS Protocol.=0D + ///=0D + Status =3D gBS->LocateProtocol (=0D + &gSaNvsAreaProtocolGuid,=0D + NULL,=0D + (VOID **) &SaNvsAreaProtocol=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return Status;=0D + }=0D +=0D + McD0BaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, = 0, 0);=0D + McD2BaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, IGD_BUS_NUM, I= GD_DEV_NUM, IGD_FUN_NUM, 0);=0D +=0D + if (mVtdDataHob !=3D NULL) {=0D + SaNvsAreaProtocol->Area->VtdDisable =3D mVtdDataHob->VtdDisable;=0D + }=0D +=0D + for (Index =3D 0; Index < VTD_ENGINE_NUMBER; Index++) {=0D + SaNvsAreaProtocol->Area->VtdBaseAddress[Index] =3D ReadVtdBaseAddress = (Index);=0D + }=0D + SaNvsAreaProtocol->Area->VtdEngine1Vid =3D PciSegmentRead16(McD2BaseAddr= ess + PCI_VENDOR_ID_OFFSET);=0D +=0D + if (mVtdDataHob !=3D NULL) {=0D + if ((mVtdDataHob->VtdDisable) || (PciSegmentRead32 (McD0BaseAddress + = R_SA_MC_CAPID0_A_OFFSET) & BIT23)) {=0D + DEBUG ((DEBUG_WARN, "VTd disabled or no capability!\n"));=0D + return EFI_UNSUPPORTED;=0D + }=0D + }=0D + ///=0D + /// Check SA supports VTD and VTD is enabled in setup menu=0D + ///=0D + DEBUG ((DEBUG_INFO, "VTd enabled\n"));=0D +=0D + return EFI_SUCCESS;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/D= xeVtdInitLib/DxeVtdInitLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/= Vtd/LibraryPrivate/DxeVtdInitLib/DxeVtdInitLib.inf new file mode 100644 index 0000000000..9797c31cc6 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdIn= itLib/DxeVtdInitLib.inf @@ -0,0 +1,71 @@ +## @file=0D +# Component description file for the Dxe VTD Init library.=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D +INF_VERSION =3D 0x00010017=0D +BASE_NAME =3D DxeVtdInitLib=0D +FILE_GUID =3D 9BD11E68-923C-424C-A278-716084B4C931=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D DXE_DRIVER=0D +LIBRARY_CLASS =3D DxeVtdInitLib=0D +=0D +[LibraryClasses]=0D +UefiLib=0D +UefiRuntimeServicesTableLib=0D +UefiBootServicesTableLib=0D +DebugLib=0D +PostCodeLib=0D +ConfigBlockLib=0D +HobLib=0D +IoLib=0D +PciSegmentLib=0D +BaseMemoryLib=0D +MemoryAllocationLib=0D +MmPciLib=0D +VtdInfoLib=0D +PchInfoLib=0D +PchCycleDecodingLib=0D +SaPlatformLib=0D +DxeVtdInitFruLib=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +[Sources]=0D +DxeVtdInitLib.c=0D +=0D +[Pcd]=0D +gSiPkgTokenSpaceGuid.PcdSiIoApicBaseAddress=0D +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId=0D +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId=0D +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision=0D +gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId=0D +gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision=0D +=0D +[FixedPcd]=0D +=0D +[Guids]=0D +gPchInfoHobGuid ## CONSUMES=0D +gSaAcpiTableStorageGuid=0D +gVtdDataHobGuid=0D +gVtdDxeConfigGuid=0D +=0D +[Protocols]=0D +gSaPolicyProtocolGuid ## CONSUMES=0D +gSaNvsAreaProtocolGuid ## CONSUMES=0D +gEfiFirmwareVolume2ProtocolGuid=0D +gEfiAcpiTableProtocolGuid=0D +=0D +[Depex]=0D +gEfiAcpiTableProtocolGuid AND=0D +gEfiFirmwareVolume2ProtocolGuid AND=0D +gSaPolicyProtocolGuid AND=0D +gEfiPciRootBridgeIoProtocolGuid AND=0D +gEfiPciHostBridgeResourceAllocationProtocolGuid AND # This is to ensure th= at PCI MMIO resource has been prepared and available for this driver to all= ocate.=0D +gEfiHiiDatabaseProtocolGuid=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/D= xeVtdPolicyLib/DxeVtdPolicyLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBloc= k/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.c new file mode 100644 index 0000000000..168de0c0a9 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPo= licyLib/DxeVtdPolicyLib.c @@ -0,0 +1,90 @@ +/** @file=0D + This file provides services for DXE VTD policy default initialization=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include =0D +=0D +/**=0D + This function prints the DXE phase VTD policy.=0D +=0D + @param[in] SaPolicy - Instance of SA_POLICY_PROTOCOL=0D +**/=0D +VOID=0D +VtdPrintPolicyDxe (=0D + IN SA_POLICY_PROTOCOL *SaPolicy=0D + )=0D +{=0D + EFI_STATUS Status;=0D + VTD_DXE_CONFIG *VtdDxeConfig;=0D +=0D + //=0D + // Get requisite IP Config Blocks which needs to be used here=0D + //=0D + Status =3D GetConfigBlock ((VOID *) SaPolicy, &gVtdDxeConfigGuid, (VOID = *)&VtdDxeConfig);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + DEBUG_CODE_BEGIN ();=0D + DEBUG ((DEBUG_INFO, "\n------------------------ Vtd Policy (DXE) print B= EGIN -----------------\n"));=0D + DEBUG ((DEBUG_INFO, " Revision : %d\n", VtdDxeConfig->Header.Revision));= =0D + ASSERT (VtdDxeConfig->Header.Revision =3D=3D VTD_DXE_CONFIG_REVISION);=0D + DEBUG ((DEBUG_INFO, "\n------------------------ Vtd Policy (DXE) print E= ND -----------------\n"));=0D + DEBUG_CODE_END ();=0D + return;=0D +}=0D +=0D +/**=0D + This function Load default Vtd DXE policy.=0D +=0D + @param[in] ConfigBlockPointer The pointer to add VTD config block=0D +**/=0D +VOID=0D +VtdLoadDefaultDxe (=0D + IN VOID *ConfigBlockPointer=0D + )=0D +{=0D + VTD_DXE_CONFIG *VtdDxeConfig;=0D +=0D + VtdDxeConfig =3D ConfigBlockPointer;=0D + DEBUG ((DEBUG_INFO, "VtdDxeConfig->Header.GuidHob.Name =3D %g\n", &VtdDx= eConfig->Header.GuidHob.Name));=0D + DEBUG ((DEBUG_INFO, "VtdDxeConfig->Header.GuidHob.Header.HobLength =3D 0= x%x\n", VtdDxeConfig->Header.GuidHob.Header.HobLength));=0D +}=0D +=0D +static COMPONENT_BLOCK_ENTRY mVtdDxeIpBlock =3D {=0D + &gVtdDxeConfigGuid, sizeof (VTD_DXE_CONFIG), VTD_DXE_CONFIG_REVISION, Vt= dLoadDefaultDxe=0D +};=0D +=0D +/**=0D + Get VTD DXE config block table total size.=0D +=0D + @retval Size of VTD DXE config block table=0D +**/=0D +UINT16=0D +EFIAPI=0D +VtdGetConfigBlockTotalSizeDxe (=0D + VOID=0D + )=0D +{=0D + return mVtdDxeIpBlock.Size;=0D +}=0D +=0D +/**=0D + VtdAddConfigBlocks add VTD DXE config block.=0D +=0D + @param[in] ConfigBlockTableAddress The pointer to add VTD config bloc= ks=0D +=0D + @retval EFI_SUCCESS The policy default is initialized.= =0D + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create b= uffer=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +VtdAddConfigBlocksDxe (=0D + IN VOID *ConfigBlockTableAddress=0D + )=0D +{=0D + EFI_STATUS Status;=0D + Status =3D AddComponentConfigBlocks (ConfigBlockTableAddress, &mVtdDxeIp= Block, 1);=0D + return Status;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/D= xeVtdPolicyLib/DxeVtdPolicyLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBl= ock/Vtd/LibraryPrivate/DxeVtdPolicyLib/DxeVtdPolicyLib.inf new file mode 100644 index 0000000000..1fe288416a --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPo= licyLib/DxeVtdPolicyLib.inf @@ -0,0 +1,35 @@ +## @file=0D +# Component description file for the DxeVtdPolicy library.=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D +INF_VERSION =3D 0x00010017=0D +BASE_NAME =3D DxeVtdPolicyLib=0D +FILE_GUID =3D 54754C6D-4883-4B67-BBBA-49D241539BE7=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D BASE=0D +LIBRARY_CLASS =3D DxeVtdPolicyLib=0D +=0D +[LibraryClasses]=0D +BaseMemoryLib=0D +UefiRuntimeServicesTableLib=0D +UefiBootServicesTableLib=0D +DebugLib=0D +PostCodeLib=0D +ConfigBlockLib=0D +HobLib=0D +SiConfigBlockLib=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +[Sources]=0D +DxeVtdPolicyLib.c=0D +=0D +[Guids]=0D +gVtdDxeConfigGuid=0D --=20 2.24.0.windows.2