[edk2-devel] [PATCH 30/40] TigerlakeSiliconPkg/IpBlock: Add Vtd component

Nate DeSimone nathaniel.l.desimone at intel.com
Thu Feb 4 03:56:29 UTC 2021


Reviewed-by: Nate DeSimone <nathaniel.l.desimone at intel.com>

> -----Original Message-----
> From: Luo, Heng <heng.luo at intel.com>
> Sent: Sunday, January 31, 2021 5:37 PM
> To: devel at edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty at intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone at intel.com>
> Subject: [PATCH 30/40] TigerlakeSiliconPkg/IpBlock: Add Vtd component
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171
> 
> Adds the following files:
>   * IpBlock/Vtd/IncludePrivate
>   * IpBlock/Vtd/Library
>   * IpBlock/Vtd/LibraryPrivate
> 
> Cc: Sai Chaganty <rangasai.v.chaganty at intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone at intel.com>
> Signed-off-by: Heng Luo <heng.luo at intel.com>
> ---
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtdI
> nitLib.h              |  62
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVtd
> PolicyLib.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/D
> xeVtdInitLib.c        | 684
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/D
> xeVtdInitLib.inf      |  71
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib
> /DxeVtdPolicyLib.c    |  90
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++
> 
> Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLib
> /DxeVtdPolicyLib.inf  |  35 +++++++++++++++++++++++++++++++++++
>  9 files changed, 1172 insertions(+)
> 
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVt
> dInitLib.h
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVt
> dInitLib.h
> new file mode 100644
> index 0000000000..e439cfbac2
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVt
> dInitLib.h
> @@ -0,0 +1,62 @@
> +/** @file
> 
> +  Header file for DXE VTD Init Lib.
> 
> +
> 
> +  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +**/
> 
> +#ifndef _DXE_VTD_INIT_LIB_H_
> 
> +#define _DXE_VTD_INIT_LIB_H_
> 
> +
> 
> +#include <Uefi.h>
> 
> +#include <Uefi/UefiBaseType.h>
> 
> +#include <Library/UefiBootServicesTableLib.h>
> 
> +#include <Library/BaseMemoryLib.h>
> 
> +#include <Library/MemoryAllocationLib.h>
> 
> +#include <Library/IoLib.h>
> 
> +#include <Library/DebugLib.h>
> 
> +#include <Library/HobLib.h>
> 
> +#include <Library/UefiLib.h>
> 
> +#include <Library/ConfigBlockLib.h>
> 
> +#include <Library/PchInfoLib.h>
> 
> +#include <Library/PchCycleDecodingLib.h>
> 
> +#include <Library/PciSegmentLib.h>
> 
> +#include <Library/VtdInfoLib.h>
> 
> +#include <Library/SaPlatformLib.h>
> 
> +#include <IndustryStandard/Acpi.h>
> 
> +#include <IndustryStandard/Pci.h>
> 
> +#include <VtdDataHob.h>
> 
> +#include <PchConfigHob.h>
> 
> +#include <PchInfoHob.h>
> 
> +#include <Register/P2sbRegs.h>
> 
> +#include <Register/IpuRegs.h>
> 
> +#include <Register/IgdRegs.h>
> 
> +#include <Register/VtdRegs.h>
> 
> +#include <DmaRemappingTable.h>
> 
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> 
> +#include <Protocol/AcpiTable.h>
> 
> +#include <Protocol/SaPolicy.h>
> 
> +#include <Protocol/SaNvsArea.h>
> 
> +#include <Protocol/FirmwareVolume2.h>
> 
> +
> 
> +/**
> 
> +  Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
> 
> +  Publish the appropriate SSDT based on current configuration and
> capabilities.
> 
> +
> 
> +  @param[in] SaPolicy            SA DXE Policy protocol
> 
> +
> 
> +  @retval EFI_SUCCESS - Vtd initialization complete
> 
> +  @retval Other       - No Vtd function initiated
> 
> +**/
> 
> +EFI_STATUS
> 
> +VtdInit (
> 
> +  IN  SA_POLICY_PROTOCOL    *SaPolicy
> 
> +  );
> 
> +
> 
> +/**
> 
> +  EndOfPcieEnum routine for update DMAR
> 
> +**/
> 
> +VOID
> 
> +UpdateDmarEndOfPcieEnum (
> 
> +  VOID
> 
> +  );
> 
> +#endif
> 
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVt
> dPolicyLib.h
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVt
> dPolicyLib.h
> new file mode 100644
> index 0000000000..d55cf6bc34
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/Library/DxeVt
> dPolicyLib.h
> @@ -0,0 +1,67 @@
> +/** @file
> 
> +  Prototype of the DXE VTD Policy Init library.
> 
> +
> 
> +  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +**/
> 
> +#ifndef _DXE_VTD_POLICY_INIT_LIB_H_
> 
> +#define _DXE_VTD_POLICY_INIT_LIB_H_
> 
> +
> 
> +#include <Uefi.h>
> 
> +#include <Library/DebugLib.h>
> 
> +#include <Library/UefiLib.h>
> 
> +#include <Library/UefiBootServicesTableLib.h>
> 
> +#include <Library/BaseMemoryLib.h>
> 
> +#include <Library/MemoryAllocationLib.h>
> 
> +#include <Protocol/SaPolicy.h>
> 
> +#include <ConfigBlock.h>
> 
> +#include <VtdConfig.h>
> 
> +#include <Library/SiConfigBlockLib.h>
> 
> +
> 
> +extern EFI_GUID gVtdDxeConfigGuid;
> 
> +
> 
> +/**
> 
> +  This function Load default Vtd DXE policy.
> 
> +
> 
> +  @param[in] ConfigBlockPointer    The pointer to add VTD config block
> 
> +**/
> 
> +VOID
> 
> +VtdLoadDefaultDxe (
> 
> +  IN VOID    *ConfigBlockPointer
> 
> +  );
> 
> +
> 
> +/**
> 
> +  This function prints the DXE phase VTD policy.
> 
> +
> 
> +  @param[in] SaPolicy - Instance of SA_POLICY_PROTOCOL
> 
> +**/
> 
> +VOID
> 
> +VtdPrintPolicyDxe (
> 
> +  IN  SA_POLICY_PROTOCOL      *SaPolicy
> 
> +  );
> 
> +
> 
> +/**
> 
> +  This function is used to add VTD Config Block.
> 
> +
> 
> +  @param[in] ConfigBlockTableAddress    The pointer to add VTD config
> blocks
> 
> +
> 
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> 
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> 
> +**/
> 
> +EFI_STATUS
> 
> +EFIAPI
> 
> +VtdAddConfigBlocksDxe (
> 
> +  IN VOID           *ConfigBlockTableAddress
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Get VTD DXE config block table total size.
> 
> +
> 
> +  @retval     Size of VTD DXE config block table
> 
> +**/
> 
> +UINT16
> 
> +EFIAPI
> 
> +VtdGetConfigBlockTotalSizeDxe (
> 
> +  VOID
> 
> +  );
> 
> +#endif // _DXE_VTD_POLICY_INIT_LIB_H_
> 
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/IncludePrivate/VtdDataHob.
> 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/VtdDataHob.
> h
> @@ -0,0 +1,32 @@
> +/** @file
> 
> +  The GUID definition for Vtd Data Hob
> 
> +
> 
> +  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +**/
> 
> +#ifndef _VTD_DATA_HOB_H_
> 
> +#define _VTD_DATA_HOB_H_
> 
> +
> 
> +#include <Library/VtdInfoLib.h>
> 
> +#include <Base.h>
> 
> +
> 
> +extern EFI_GUID gVtdDataHobGuid;
> 
> +
> 
> +#pragma pack (push,1)
> 
> +
> 
> +///
> 
> +/// The data elements should be initialized by a Platform Module.
> 
> +/// The data structure is for VT-d driver initialization
> 
> +///
> 
> +typedef struct {
> 
> +  EFI_HOB_GUID_TYPE     EfiHobGuidType;                    ///< GUID Hob type
> structure for gVtdDataHobGuid
> 
> +  BOOLEAN               VtdDisable;                        ///< 1 = Avoids programming Vtd
> bars, Vtd overrides and DMAR table
> 
> +  UINT32                BaseAddress[VTD_ENGINE_NUMBER];    ///< This field is
> used to describe the base addresses for VT-d function
> 
> +  BOOLEAN               X2ApicOptOut;                      ///< This field is used to enable
> the X2APIC_OPT_OUT bit in the DMAR table. <b>1=Enable/Set</b> and
> 0=Disable/Clear
> 
> +  BOOLEAN               DmaControlGuarantee;               ///< This field is used to
> enable the DMA_CONTROL_GUARANTEE bit in the DMAR table.
> <b>1=Enable/Set</b> and 0=Disable/Clear
> 
> +  BOOLEAN               InterruptRemappingSupport;         ///< This field is used to
> indicate Interrupt Remapping supported or not
> 
> +  UINT32                DmaBufferBase;                     ///< Iommu PEI DMA buffer
> base in low memory region, in Mbytes units
> 
> +} VTD_DATA_HOB;
> 
> +
> 
> +#pragma pack (pop)
> 
> +#endif
> 
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLi
> b/PeiDxeSmmVtdInfoLib.inf
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLi
> b/PeiDxeSmmVtdInfoLib.inf
> new file mode 100644
> index 0000000000..c7c5e56b84
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLi
> b/PeiDxeSmmVtdInfoLib.inf
> @@ -0,0 +1,45 @@
> +## @file
> 
> +# VTD Common Library.
> 
> +#
> 
> +# All function in this library is available for PEI, DXE, and SMM,
> 
> +# But do not support UEFI RUNTIME environment call.
> 
> +#
> 
> +#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> 
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +#
> 
> +##
> 
> +
> 
> +
> 
> +[Defines]
> 
> +INF_VERSION = 0x00010017
> 
> +BASE_NAME = PeiDxeSmmVtdInfoLib
> 
> +FILE_GUID = A1480873-3FDA-4E90-B450-743D8031F9DE
> 
> +VERSION_STRING = 1.0
> 
> +MODULE_TYPE = BASE
> 
> +LIBRARY_CLASS = VtdInfoLib
> 
> +
> 
> +[LibraryClasses]
> 
> +BaseLib
> 
> +IoLib
> 
> +DebugLib
> 
> +PciSegmentLib
> 
> +HobLib
> 
> +VtdInfoLib
> 
> +
> 
> +[Packages]
> 
> +MdePkg/MdePkg.dec
> 
> +TigerlakeSiliconPkg/SiPkg.dec
> 
> +
> 
> +[Sources]
> 
> +VtdInfoLib.c
> 
> +
> 
> +[Pcd]
> 
> +gSiPkgTokenSpaceGuid.VtdEngine1BaseAddeess
> 
> +gSiPkgTokenSpaceGuid.VtdEngine2BaseAddeess
> 
> +gSiPkgTokenSpaceGuid.VtdEngine3BaseAddeess
> 
> +gSiPkgTokenSpaceGuid.VtdEngine4BaseAddeess
> 
> +gSiPkgTokenSpaceGuid.VtdEngine5BaseAddeess
> 
> +gSiPkgTokenSpaceGuid.VtdEngine6BaseAddeess
> 
> +gSiPkgTokenSpaceGuid.VtdEngine7BaseAddeess
> 
> +
> 
> +[FixedPcd]
> 
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLi
> b/VtdInfoLib.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLi
> b/VtdInfoLib.c
> new file mode 100644
> index 0000000000..e4f08592cc
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/Library/PeiDxeSmmVtdInfoLi
> b/VtdInfoLib.c
> @@ -0,0 +1,86 @@
> +/** @file
> 
> +  VTD Info library.
> 
> +  All function in this library is available for PEI, DXE, and SMM,
> 
> +  But do not support UEFI RUNTIME environment call.
> 
> +
> 
> +  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +**/
> 
> +
> 
> +#include <Ppi/SiPolicy.h>
> 
> +#include <Library/IoLib.h>
> 
> +#include <Library/DebugLib.h>
> 
> +#include <Library/BaseLib.h>
> 
> +#include <Library/PciSegmentLib.h>
> 
> +#include <Library/VtdInfoLib.h>
> 
> +#include <Register/VtdRegs.h>
> 
> +
> 
> +/**
> 
> +  Get VTD Engine Base Address from PCD value
> 
> +
> 
> +  @param[in]  VtdEngineNumber        - Engine number for which VTD Base
> Adderess is required.
> 
> +
> 
> +  @retval   VTD Engine Base Address
> 
> +**/
> 
> +UINT32
> 
> +GetVtdBaseAddress (
> 
> +  IN UINT8        VtdEngineNumber
> 
> +  )
> 
> +{
> 
> +  switch (VtdEngineNumber) {
> 
> +    case 0:
> 
> +      return PcdGet32(VtdEngine1BaseAddeess);
> 
> +      break;
> 
> +    case 2:
> 
> +      return PcdGet32(VtdEngine3BaseAddeess);
> 
> +      break;
> 
> +    default:
> 
> +      return 0x0;
> 
> +      break;
> 
> +  }
> 
> +}
> 
> +
> 
> +
> 
> +/**
> 
> +  Read VTD Engine Base Address from VTD BAR Offsets.
> 
> +
> 
> +  @param[in]  VtdEngineNumber        - Engine number for which VTD Base
> Adderess is required.
> 
> +
> 
> +  @retval   VTD Engine Base Address
> 
> +**/
> 
> +UINT32
> 
> +ReadVtdBaseAddress (
> 
> +  IN UINT8        VtdEngineNumber
> 
> +  )
> 
> +{
> 
> +  UINT64              McD0BaseAddress;
> 
> +  UINTN               MchBar;
> 
> +
> 
> +  McD0BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, 0, 0, 0);
> 
> +  MchBar          = PciSegmentRead32 (McD0BaseAddress + R_SA_MCHBAR) &
> (~BIT0);
> 
> +
> 
> +  switch (VtdEngineNumber) {
> 
> +    case 0:
> 
> +      return (MmioRead32 (MchBar + R_MCHBAR_VTD1_OFFSET) & (~BIT0));
> 
> +      break;
> 
> +    case 2:
> 
> +      return (MmioRead32 (MchBar + R_MCHBAR_VTD3_OFFSET) & (~BIT0));
> 
> +      break;
> 
> +    default:
> 
> +      return 0x0;
> 
> +      break;
> 
> +  }
> 
> +}
> 
> +
> 
> +/**
> 
> +  GetMaxVtdEngineNumber: Get Maximum Vtd Engine Number
> 
> +
> 
> +  @retval Vtd Engine Number
> 
> +**/
> 
> +UINT8
> 
> +GetMaxVtdEngineNumber(
> 
> +  VOID
> 
> +)
> 
> +{
> 
> +  return (UINT8)VTD_ENGINE_NUMBER;
> 
> +}
> 
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/
> DxeVtdInitLib.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/
> DxeVtdInitLib.c
> new file mode 100644
> index 0000000000..faac07c45d
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/
> DxeVtdInitLib.c
> @@ -0,0 +1,684 @@
> +/** @file
> 
> +  DXE Library for VTD ACPI table initialization.
> 
> +
> 
> +  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +**/
> 
> +#include <Library/DxeVtdInitLib.h>
> 
> +#include <Library/DxeVtdPolicyLib.h>
> 
> +#include <Library/VtdInitFruLib.h>
> 
> +#include <Register/SaRegsHostBridge.h>
> 
> +
> 
> +///
> 
> +/// Global Variables
> 
> +///
> 
> +GLOBAL_REMOVE_IF_UNREFERENCED VTD_DATA_HOB     *mVtdDataHob;
> 
> +
> 
> +BOOLEAN mInterruptRemappingSupport;
> 
> +
> 
> +/**
> 
> +  Get the corresponding device Enable/Disable bit according DevNum and
> FunNum
> 
> +
> 
> +  @param[in] DevNum  - Device Number
> 
> +  @param[in] FunNum  - Function Number
> 
> +
> 
> +  @retval If the device is found, return disable/Enable bit in FD/Deven
> reigster
> 
> +  @retval If not found return 0xFF
> 
> +**/
> 
> +UINT16
> 
> +GetFunDisableBit (
> 
> +  UINT8 DevNum,
> 
> +  UINT8 FunNum
> 
> +  )
> 
> +{
> 
> +  UINTN Index;
> 
> +
> 
> +  for (Index = 0; Index < mDevEnMapSize; Index++) {
> 
> +    if (mDevEnMap[Index][0] == ((DevNum << 0x08) | FunNum)) {
> 
> +      return mDevEnMap[Index][1];
> 
> +    }
> 
> +  }
> 
> +
> 
> +  return 0xFF;
> 
> +}
> 
> +
> 
> +/**
> 
> +  Update the DRHD structure
> 
> +
> 
> +  @param[in, out] DrhdEnginePtr       - A pointer to DRHD structure
> 
> +**/
> 
> +VOID
> 
> +UpdateDrhd (
> 
> +  IN OUT VOID *DrhdEnginePtr
> 
> +  )
> 
> +{
> 
> +  UINT16                        Length;
> 
> +  UINT16                        DisableBit;
> 
> +  BOOLEAN                       NeedRemove;
> 
> +  EFI_ACPI_DRHD_ENGINE1_STRUCT  *DrhdEngine;
> 
> +
> 
> +  //
> 
> +  // Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE1_STRUCT Pointer
> 
> +  //
> 
> +  DrhdEngine      = (EFI_ACPI_DRHD_ENGINE1_STRUCT *) DrhdEnginePtr;
> 
> +  Length          = DrhdEngine->DrhdHeader.Header.Length;
> 
> +  DisableBit = GetFunDisableBit (
> 
> +                 DrhdEngine->DeviceScope[0].PciPath.Device,
> 
> +                 DrhdEngine->DeviceScope[0].PciPath.Function
> 
> +                 );
> 
> +  NeedRemove = FALSE;
> 
> +
> 
> +  if ((DisableBit == 0xFF) ||
> 
> +      (DrhdEngine->DrhdHeader.RegisterBaseAddress == 0) ||
> 
> +      ((DisableBit == 0x80) &&
> 
> +       (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0,
> DrhdEngine->DeviceScope[0].PciPath.Device, DrhdEngine-
> >DeviceScope[0].PciPath.Function, 0x00)) == 0xFFFFFFFF))
> 
> +      ) {
> 
> +    NeedRemove = TRUE;
> 
> +  }
> 
> +  if ((DrhdEngine->DeviceScope[0].PciPath.Device == IGD_DEV_NUM) &&
> (DrhdEngine->DeviceScope[0].PciPath.Function == IGD_FUN_NUM) &&
> 
> +      (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0,
> DrhdEngine->DeviceScope[0].PciPath.Device, DrhdEngine-
> >DeviceScope[0].PciPath.Function, 0x00)) != 0xFFFFFFFF)) {
> 
> +    NeedRemove = FALSE;
> 
> +  }
> 
> +  if (NeedRemove) {
> 
> +    Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> 
> +  }
> 
> +  ///
> 
> +  /// If no devicescope is left, we set the structure length as 0x00
> 
> +  ///
> 
> +  if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) || (DrhdEngine-
> >DrhdHeader.Flags == 0x01)) {
> 
> +    DrhdEngine->DrhdHeader.Header.Length = Length;
> 
> +  } else {
> 
> +    DrhdEngine->DrhdHeader.Header.Length = 0;
> 
> +  }
> 
> +}
> 
> +
> 
> +/**
> 
> +  Get IOAPIC ID from LPC
> 
> +
> 
> +  @retval APIC ID
> 
> +**/
> 
> +UINT8
> 
> +GetIoApicId (
> 
> +  VOID
> 
> +  )
> 
> +{
> 
> +  UINT32                IoApicAddress;
> 
> +  UINT32                IoApicId;
> 
> +
> 
> +  IoApicAddress = PcdGet32 (PcdSiIoApicBaseAddress);
> 
> +  ///
> 
> +  /// Get current IO APIC ID
> 
> +  ///
> 
> +  MmioWrite8 ((UINTN) (IoApicAddress +
> R_IO_APIC_MEM_INDEX_OFFSET), 0);
> 
> +  IoApicId = MmioRead32 ((UINTN) (IoApicAddress +
> R_IO_APIC_MEM_DATA_OFFSET)) >> 24;
> 
> +
> 
> +  return (UINT8) IoApicId;
> 
> +}
> 
> +
> 
> +/**
> 
> +  Update the second DRHD structure
> 
> +
> 
> +  @param[in, out] DrhdEnginePtr       - A pointer to DRHD structure
> 
> +**/
> 
> +VOID
> 
> +UpdateDrhd2 (
> 
> +  IN OUT VOID *DrhdEnginePtr
> 
> +  )
> 
> +{
> 
> +  UINT16                        Length;
> 
> +  UINTN                         DeviceScopeNum;
> 
> +  UINTN                         ValidDeviceScopeNum;
> 
> +  UINT16                        Index;
> 
> +  UINT8                         Bus;
> 
> +  UINT8                         Path[2];
> 
> +  BOOLEAN                       NeedRemove;
> 
> +  EFI_ACPI_DRHD_ENGINE3_STRUCT  *DrhdEngine;
> 
> +  VOID                          *HobPtr;
> 
> +  PCH_INFO_HOB                  *PchInfoHob;
> 
> +
> 
> +  ///
> 
> +  /// Convert DrhdEnginePtr to EFI_ACPI_DRHD_ENGINE3_STRUCT Pointer
> 
> +  ///
> 
> +  DrhdEngine      = (EFI_ACPI_DRHD_ENGINE3_STRUCT *) DrhdEnginePtr;
> 
> +
> 
> +  Length          = DrhdEngine->DrhdHeader.Header.Length;
> 
> +  DeviceScopeNum  = (DrhdEngine->DrhdHeader.Header.Length -
> EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) / sizeof
> (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> 
> +  Bus             = 0;
> 
> +  ValidDeviceScopeNum = 0;
> 
> +  Path[0]         = 0;
> 
> +  Path[1]         = 0;
> 
> +
> 
> +  HobPtr = GetFirstGuidHob (&gPchInfoHobGuid);
> 
> +  ASSERT (HobPtr != NULL);
> 
> +  if (HobPtr == NULL) {
> 
> +    return;
> 
> +  }
> 
> +  PchInfoHob = (PCH_INFO_HOB *) GET_GUID_HOB_DATA (HobPtr);
> 
> +  ASSERT (PchInfoHob != NULL);
> 
> +  if (PchInfoHob == NULL) {
> 
> +    return;
> 
> +  }
> 
> +
> 
> +  for (Index = 0; Index < DeviceScopeNum; Index++) {
> 
> +    NeedRemove = FALSE;
> 
> +    /**
> 
> +      For HPET and APIC, update device scope if Interrupt remapping is
> supported. remove device scope
> 
> +      if interrupt remapping is not supported.
> 
> +      - Index = 0 - IOAPIC
> 
> +      - Index = 1 - HPET
> 
> +    **/
> 
> +    if (mInterruptRemappingSupport) {
> 
> +      if (Index == 0) {
> 
> +        ///
> 
> +        /// Update source id for IoApic's device scope entry
> 
> +        ///
> 
> +        Bus = (UINT8) PchInfoHob->IoApicBusNum;
> 
> +        Path[0] = (UINT8) PchInfoHob->IoApicDevNum;
> 
> +        Path[1] = (UINT8) PchInfoHob->IoApicFuncNum;
> 
> +        DrhdEngine-
> >DeviceScope[Index].DeviceScopeStructureHeader.StartBusNumber = Bus;
> 
> +        DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
> 
> +        DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
> 
> +        //
> 
> +        // Update APIC ID
> 
> +        //
> 
> +        DrhdEngine-
> >DeviceScope[Index].DeviceScopeStructureHeader.EnumerationId =
> GetIoApicId ();
> 
> +      }
> 
> +      if (Index == 1) {
> 
> +        ///
> 
> +        /// Update source id for HPET's device scope entry
> 
> +        ///
> 
> +        Bus     = (UINT8) PchInfoHob->HpetBusNum;
> 
> +        Path[0] = (UINT8) PchInfoHob->HpetDevNum;
> 
> +        Path[1] = (UINT8) PchInfoHob->HpetFuncNum;
> 
> +        DrhdEngine-
> >DeviceScope[Index].DeviceScopeStructureHeader.StartBusNumber = Bus;
> 
> +        DrhdEngine->DeviceScope[Index].PciPath.Device = Path[0];
> 
> +        DrhdEngine->DeviceScope[Index].PciPath.Function = Path[1];
> 
> +      }
> 
> +    } else {
> 
> +      if ((Index == 0) || (Index == 1)) {
> 
> +        NeedRemove = TRUE;
> 
> +      }
> 
> +    }
> 
> +
> 
> +    CopyMem (
> 
> +      &DrhdEngine->DeviceScope[ValidDeviceScopeNum],
> 
> +      &DrhdEngine->DeviceScope[Index],
> 
> +      sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
> 
> +      );
> 
> +    if (NeedRemove) {
> 
> +      Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> 
> +    } else {
> 
> +      ValidDeviceScopeNum++;
> 
> +    }
> 
> +  }
> 
> +  ///
> 
> +  /// If no devicescope is left, we set the structure length as 0x00
> 
> +  ///
> 
> +  if ((Length > EFI_ACPI_DRHD_ENGINE_HEADER_LENGTH) || (DrhdEngine-
> >DrhdHeader.Flags == 0x01)) {
> 
> +    DrhdEngine->DrhdHeader.Header.Length = Length;
> 
> +  } else {
> 
> +    DrhdEngine->DrhdHeader.Header.Length = 0;
> 
> +  }
> 
> +}
> 
> +
> 
> +/**
> 
> +  Update the RMRR structure
> 
> +
> 
> +  @param[in, out] RmrrPtr             - A pointer to RMRR structure
> 
> +**/
> 
> +VOID
> 
> +UpdateRmrr (
> 
> +  IN OUT VOID *RmrrPtr
> 
> +  )
> 
> +{
> 
> +  UINT16                  Length;
> 
> +  UINT16                  DisableBit;
> 
> +  UINTN                   DeviceScopeNum;
> 
> +  UINTN                   ValidDeviceScopeNum;
> 
> +  UINTN                   Index;
> 
> +  BOOLEAN                 NeedRemove;
> 
> +  EFI_ACPI_RMRR_USB_STRUC *Rmrr;
> 
> +
> 
> +  ///
> 
> +  /// To make sure all devicescope can be checked,
> 
> +  /// we convert the RmrrPtr to EFI_ACPI_RMRR_USB_STRUC pointer
> 
> +  ///
> 
> +  Rmrr                = (EFI_ACPI_RMRR_USB_STRUC *) RmrrPtr;
> 
> +
> 
> +  Length              = Rmrr->RmrrHeader.Header.Length;
> 
> +  ValidDeviceScopeNum = 0;
> 
> +  DeviceScopeNum      = (Rmrr->RmrrHeader.Header.Length -
> EFI_ACPI_RMRR_HEADER_LENGTH) / sizeof
> (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> 
> +  for (Index = 0; Index < DeviceScopeNum; Index++) {
> 
> +    DisableBit = GetFunDisableBit (
> 
> +                   Rmrr->DeviceScope[Index].PciPath.Device,
> 
> +                   Rmrr->DeviceScope[Index].PciPath.Function
> 
> +                   );
> 
> +    NeedRemove = FALSE;
> 
> +    if ((DisableBit == 0xFF) ||
> 
> +        ((DisableBit == 0x80) &&
> 
> +         (PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, 0,
> Rmrr->DeviceScope[Index].PciPath.Device, Rmrr-
> >DeviceScope[Index].PciPath.Function, 0x00)) == 0xFFFFFFFF))
> 
> +        ) {
> 
> +      NeedRemove = TRUE;
> 
> +    } else if (DisableBit == 0x8F) {
> 
> +      DEBUG ((DEBUG_ERROR, "Rmrr-
> >RmrrHeader.ReservedMemoryRegionBaseAddress %x\n", Rmrr-
> >RmrrHeader.ReservedMemoryRegionBaseAddress));
> 
> +
> 
> +      if (Rmrr->RmrrHeader.ReservedMemoryRegionBaseAddress != 0) {
> 
> +        DEBUG ((DEBUG_ERROR, "NeedRemove = FALSE\n"));
> 
> +        NeedRemove = FALSE;
> 
> +      } else {
> 
> +        DEBUG ((DEBUG_ERROR, "NeedRemove = TRUE\n"));
> 
> +        NeedRemove = TRUE;
> 
> +      }
> 
> +    }
> 
> +    CopyMem (
> 
> +      &Rmrr->DeviceScope[ValidDeviceScopeNum],
> 
> +      &Rmrr->DeviceScope[Index],
> 
> +      sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE)
> 
> +      );
> 
> +
> 
> +    if (Rmrr->RmrrHeader.ReservedMemoryRegionLimitAddress == 0x0) {
> 
> +      NeedRemove = TRUE;
> 
> +    }
> 
> +
> 
> +    if (NeedRemove) {
> 
> +      Length -= sizeof (EFI_ACPI_DEV_SCOPE_STRUCTURE);
> 
> +    } else {
> 
> +      ValidDeviceScopeNum++;
> 
> +    }
> 
> +  }
> 
> +  ///
> 
> +  /// If No deviceScope is left, set length as 0x00
> 
> +  ///
> 
> +  if (Length > EFI_ACPI_RMRR_HEADER_LENGTH) {
> 
> +    Rmrr->RmrrHeader.Header.Length = Length;
> 
> +  } else {
> 
> +    Rmrr->RmrrHeader.Header.Length = 0;
> 
> +  }
> 
> +}
> 
> +
> 
> +/**
> 
> +  Update the DMAR table
> 
> +
> 
> +  @param[in, out] TableHeader         - The table to be set
> 
> +  @param[in, out] Version             - Version to publish
> 
> +**/
> 
> +VOID
> 
> +DmarTableUpdate (
> 
> +  IN OUT   EFI_ACPI_DESCRIPTION_HEADER       *TableHeader,
> 
> +  IN OUT   EFI_ACPI_TABLE_VERSION            *Version
> 
> +  )
> 
> +{
> 
> +  EFI_ACPI_DMAR_TABLE *DmarTable;
> 
> +  EFI_ACPI_DMAR_TABLE TempDmarTable;
> 
> +  UINTN               Offset;
> 
> +  UINTN               StructureLen;
> 
> +  UINT64              McD0BaseAddress;
> 
> +  UINT32              GttMmAdr;
> 
> +  UINT64              McD2BaseAddress;
> 
> +  UINT16              IgdMode;
> 
> +  UINT16              GttMode;
> 
> +  UINT32              IgdMemSize;
> 
> +  UINT32              GttMemSize;
> 
> +  EFI_STATUS          Status;
> 
> +  VTD_DXE_CONFIG      *VtdDxeConfig;
> 
> +  SA_POLICY_PROTOCOL  *SaPolicy;
> 
> +
> 
> +
> 
> +  IgdMemSize  = 0;
> 
> +  GttMemSize  = 0;
> 
> +  DmarTable   = (EFI_ACPI_DMAR_TABLE *) TableHeader;
> 
> +
> 
> +  Status = gBS->LocateProtocol (&gSaPolicyProtocolGuid, NULL, (VOID **)
> &SaPolicy);
> 
> +  ASSERT_EFI_ERROR (Status);
> 
> +
> 
> +  Status = GetConfigBlock ((VOID *) SaPolicy, &gVtdDxeConfigGuid, (VOID
> *)&VtdDxeConfig);
> 
> +  ASSERT_EFI_ERROR (Status);
> 
> +
> 
> +  ///
> 
> +  /// Set INTR_REMAP bit (BIT 0) if interrupt remapping is supported
> 
> +  ///
> 
> +  if (mInterruptRemappingSupport) {
> 
> +    DmarTable->DmarHeader.Flags |= BIT0;
> 
> +  }
> 
> +
> 
> +  if (mVtdDataHob->X2ApicOptOut == 1) {
> 
> +    DmarTable->DmarHeader.Flags |= BIT1;
> 
> +  } else {
> 
> +    DmarTable->DmarHeader.Flags &= 0xFD;
> 
> +  }
> 
> +
> 
> +  ///
> 
> +  /// Set DMA_CONTROL_GUARANTEE bit (BIT 2) if Dma Control Guarantee
> is supported
> 
> +  ///
> 
> +  if (mVtdDataHob->DmaControlGuarantee == 1) {
> 
> +    DmarTable->DmarHeader.Flags |= BIT2;
> 
> +  }
> 
> +  ///
> 
> +  /// Get OemId
> 
> +  ///
> 
> +  CopyMem (DmarTable->DmarHeader.Header.OemId, PcdGetPtr
> (PcdAcpiDefaultOemId), sizeof (DmarTable->DmarHeader.Header.OemId));
> 
> +  DmarTable->DmarHeader.Header.OemTableId      = PcdGet64
> (PcdAcpiDefaultOemTableId);
> 
> +  DmarTable->DmarHeader.Header.OemRevision     = PcdGet32
> (PcdAcpiDefaultOemRevision);
> 
> +  DmarTable->DmarHeader.Header.CreatorId       = PcdGet32
> (PcdAcpiDefaultCreatorId);
> 
> +  DmarTable->DmarHeader.Header.CreatorRevision = PcdGet32
> (PcdAcpiDefaultCreatorRevision);
> 
> +
> 
> +  ///
> 
> +  /// Calculate IGD memsize
> 
> +  ///
> 
> +  McD0BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, 0, 0, 0);
> 
> +  IgdMode = ((PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) &
> B_SA_GGC_GMS_MASK) >> N_SA_GGC_GMS_OFFSET) & 0xFF;
> 
> +  if (IgdMode < 0xF0) {
> 
> +    IgdMemSize = IgdMode * 32 * (1024) * (1024);
> 
> +  } else {
> 
> +    IgdMemSize = 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024);
> 
> +  }
> 
> +  ///
> 
> +  /// Calculate GTT mem size
> 
> +  ///
> 
> +  GttMemSize = 0;
> 
> +  GttMode = (PciSegmentRead16 (McD0BaseAddress + R_SA_GGC) &
> B_SA_GGC_GGMS_MASK) >> N_SA_GGC_GGMS_OFFSET;
> 
> +  if (GttMode <= V_SA_GGC_GGMS_8MB) {
> 
> +    GttMemSize = (1 << GttMode) * (1024) * (1024);
> 
> +  }
> 
> +
> 
> +  McD2BaseAddress = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, 0);
> 
> +  GttMmAdr = (PciSegmentRead32 (McD2BaseAddress +
> R_SA_IGD_GTTMMADR)) & 0xFFFFFFF0;
> 
> +
> 
> +  DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress
> = (PciSegmentRead32 (McD0BaseAddress + R_SA_BGSM) & ~(0x01));
> 
> +  DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress
> = DmarTable->RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress +
> IgdMemSize + GttMemSize - 1;
> 
> +  DEBUG ((DEBUG_INFO, "RMRR Base  address IGD %016lX\n", DmarTable-
> >RmrrIgd.RmrrHeader.ReservedMemoryRegionBaseAddress));
> 
> +  DEBUG ((DEBUG_INFO, "RMRR Limit address IGD %016lX\n", DmarTable-
> >RmrrIgd.RmrrHeader.ReservedMemoryRegionLimitAddress));
> 
> +
> 
> +  ///
> 
> +  /// Update DRHD structures of DmarTable
> 
> +  ///
> 
> +  DmarTable->DrhdEngine1.DrhdHeader.RegisterBaseAddress =
> ReadVtdBaseAddress(0);
> 
> +  DmarTable->DrhdEngine3.DrhdHeader.RegisterBaseAddress =
> ReadVtdBaseAddress (2);
> 
> +
> 
> +  DEBUG ((DEBUG_INFO, "VTD base address 1 = %x\n", DmarTable-
> >DrhdEngine1.DrhdHeader.RegisterBaseAddress));
> 
> +  DEBUG ((DEBUG_INFO, "VTD base address 3 = %x\n", DmarTable-
> >DrhdEngine3.DrhdHeader.RegisterBaseAddress));
> 
> +  ///
> 
> +  /// copy DmarTable to TempDmarTable to be processed
> 
> +  ///
> 
> +  CopyMem (&TempDmarTable, DmarTable, sizeof
> (EFI_ACPI_DMAR_TABLE));
> 
> +
> 
> +  ///
> 
> +  /// Update DRHD structures of temp DMAR table
> 
> +  ///
> 
> +  UpdateDrhd (&TempDmarTable.DrhdEngine1);
> 
> +  UpdateDrhd2 (&TempDmarTable.DrhdEngine3);
> 
> +
> 
> +  ///
> 
> +  /// Remove unused device scope or entire DRHD structures
> 
> +  ///
> 
> +  Offset = (UINTN) (&TempDmarTable.DrhdEngine1);
> 
> +  if (TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length != 0) {
> 
> +    Offset += TempDmarTable.DrhdEngine1.DrhdHeader.Header.Length;
> 
> +  }
> 
> +  if (TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length != 0) {
> 
> +    StructureLen =
> TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length;
> 
> +    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.DrhdEngine3,
> TempDmarTable.DrhdEngine3.DrhdHeader.Header.Length);
> 
> +    Offset += StructureLen;
> 
> +  }
> 
> +  ///
> 
> +  /// Remove unused device scope or entire RMRR structures
> 
> +  ///
> 
> +  if (TempDmarTable.RmrrIgd.RmrrHeader.Header.Length != 0) {
> 
> +    StructureLen = TempDmarTable.RmrrIgd.RmrrHeader.Header.Length;
> 
> +    CopyMem ((VOID *) Offset, (VOID *) &TempDmarTable.RmrrIgd,
> TempDmarTable.RmrrIgd.RmrrHeader.Header.Length);
> 
> +    Offset += StructureLen;
> 
> +  }
> 
> +  Offset = Offset - (UINTN) &TempDmarTable;
> 
> +  ///
> 
> +  /// Re-calculate DMAR table check sum
> 
> +  ///
> 
> +  TempDmarTable.DmarHeader.Header.Checksum = (UINT8)
> (TempDmarTable.DmarHeader.Header.Checksum +
> TempDmarTable.DmarHeader.Header.Length - Offset);
> 
> +  ///
> 
> +  /// Set DMAR table length
> 
> +  ///
> 
> +  TempDmarTable.DmarHeader.Header.Length = (UINT32) Offset;
> 
> +  ///
> 
> +  /// Replace DMAR table with rebuilt table TempDmarTable
> 
> +  ///
> 
> +  CopyMem ((VOID *) DmarTable, (VOID *) &TempDmarTable,
> TempDmarTable.DmarHeader.Header.Length);
> 
> +}
> 
> +
> 
> +/**
> 
> +  EndOfPcieEnumration routine for update DMAR
> 
> +**/
> 
> +VOID
> 
> +UpdateDmarEndOfPcieEnum (
> 
> +  VOID
> 
> +  )
> 
> +{
> 
> +  EFI_STATUS                      Status;
> 
> +  EFI_HANDLE                      *HandleBuffer;
> 
> +  UINTN                           NumberOfHandles;
> 
> +  EFI_FV_FILETYPE                 FileType;
> 
> +  UINT32                          FvStatus;
> 
> +  EFI_FV_FILE_ATTRIBUTES          Attributes;
> 
> +  UINTN                           Size;
> 
> +  UINTN                           i;
> 
> +  INTN                            Instance;
> 
> +  EFI_ACPI_TABLE_VERSION          Version;
> 
> +  EFI_ACPI_COMMON_HEADER          *CurrentTable;
> 
> +  UINTN                           AcpiTableHandle;
> 
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL   *FwVol;
> 
> +  EFI_ACPI_TABLE_PROTOCOL         *AcpiTable;
> 
> +  EFI_ACPI_DESCRIPTION_HEADER     *VtdAcpiTable;
> 
> +  STATIC BOOLEAN                  Triggered = FALSE;
> 
> +
> 
> +
> 
> +  if (Triggered) {
> 
> +    return;
> 
> +  }
> 
> +
> 
> +  Triggered     = TRUE;
> 
> +
> 
> +  FwVol         = NULL;
> 
> +  AcpiTable     = NULL;
> 
> +  VtdAcpiTable  = NULL;
> 
> +
> 
> +  DEBUG ((DEBUG_INFO, "UpdateDmarEndOfPcieEnum \n"));
> 
> +
> 
> +
> 
> +  ///
> 
> +  /// Fix DMAR Table always created, skip install when disabled
> 
> +  ///
> 
> +  if ((mVtdDataHob->VtdDisable == TRUE) || (PciSegmentRead32
> (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, 0, 0,
> R_SA_MC_CAPID0_A_OFFSET)) & BIT23)) {
> 
> +    DEBUG ((DEBUG_INFO, "Vtd Disabled, skip DMAR Table install\n"));
> 
> +    return;
> 
> +  }
> 
> +
> 
> +
> 
> +  ///
> 
> +  /// Locate ACPI support protocol
> 
> +  ///
> 
> +  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID
> **) &AcpiTable);
> 
> +
> 
> +  ///
> 
> +  /// Locate protocol.
> 
> +  /// There is little chance we can't find an FV protocol
> 
> +  ///
> 
> +  Status = gBS->LocateHandleBuffer (
> 
> +                  ByProtocol,
> 
> +                  &gEfiFirmwareVolume2ProtocolGuid,
> 
> +                  NULL,
> 
> +                  &NumberOfHandles,
> 
> +                  &HandleBuffer
> 
> +                  );
> 
> +  ASSERT_EFI_ERROR (Status);
> 
> +
> 
> +  ///
> 
> +  /// Looking for FV with ACPI storage file
> 
> +  ///
> 
> +  for (i = 0; i < NumberOfHandles; i++) {
> 
> +    ///
> 
> +    /// Get the protocol on this handle
> 
> +    /// This should not fail because of LocateHandleBuffer
> 
> +    ///
> 
> +    Status = gBS->HandleProtocol (
> 
> +                    HandleBuffer[i],
> 
> +                    &gEfiFirmwareVolume2ProtocolGuid,
> 
> +                    (VOID **) &FwVol
> 
> +                    );
> 
> +    ASSERT_EFI_ERROR (Status);
> 
> +
> 
> +    ///
> 
> +    /// See if it has the ACPI storage file
> 
> +    ///
> 
> +    Size      = 0;
> 
> +    FvStatus  = 0;
> 
> +    Status = FwVol->ReadFile (
> 
> +                      FwVol,
> 
> +                      &gSaAcpiTableStorageGuid,
> 
> +                      NULL,
> 
> +                      &Size,
> 
> +                      &FileType,
> 
> +                      &Attributes,
> 
> +                      &FvStatus
> 
> +                      );
> 
> +
> 
> +    ///
> 
> +    /// If we found it, then we are done
> 
> +    ///
> 
> +    if (Status == EFI_SUCCESS) {
> 
> +      break;
> 
> +    }
> 
> +  }
> 
> +  ///
> 
> +  /// Our exit status is determined by the success of the previous operations
> 
> +  /// If the protocol was found, Instance already points to it.
> 
> +  ///
> 
> +  ///
> 
> +  /// Free any allocated buffers
> 
> +  ///
> 
> +  FreePool (HandleBuffer);
> 
> +
> 
> +  ///
> 
> +  /// Sanity check that we found our data file
> 
> +  ///
> 
> +  ASSERT (FwVol);
> 
> +  if (FwVol == NULL) {
> 
> +    return;
> 
> +  }
> 
> +  ///
> 
> +  /// By default, a table belongs in all ACPI table versions published.
> 
> +  ///
> 
> +  Version = EFI_ACPI_TABLE_VERSION_1_0B |
> EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0;
> 
> +
> 
> +  ///
> 
> +  /// Read tables from the storage file.
> 
> +  ///
> 
> +  Instance      = 0;
> 
> +  CurrentTable  = NULL;
> 
> +
> 
> +  while (Status == EFI_SUCCESS) {
> 
> +    Status = FwVol->ReadSection (
> 
> +                      FwVol,
> 
> +                      &gSaAcpiTableStorageGuid,
> 
> +                      EFI_SECTION_RAW,
> 
> +                      Instance,
> 
> +                      (VOID **) &CurrentTable,
> 
> +                      &Size,
> 
> +                      &FvStatus
> 
> +                      );
> 
> +
> 
> +    if (!EFI_ERROR (Status)) {
> 
> +      ///
> 
> +      /// Check the Signature ID to modify the table
> 
> +      ///
> 
> +      if ((CurrentTable != NULL) && ((EFI_ACPI_DESCRIPTION_HEADER *)
> CurrentTable)->Signature == EFI_ACPI_VTD_DMAR_TABLE_SIGNATURE) {
> 
> +        VtdAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable;
> 
> +        DmarTableUpdate (VtdAcpiTable, &Version);
> 
> +        break;
> 
> +      }
> 
> +      ///
> 
> +      /// Increment the instance
> 
> +      ///
> 
> +      Instance++;
> 
> +      if (CurrentTable != NULL) {
> 
> +        gBS->FreePool (CurrentTable);
> 
> +        CurrentTable = NULL;
> 
> +      }
> 
> +    }
> 
> +  }
> 
> +  ///
> 
> +  /// Update the VTD table in the ACPI tables.
> 
> +  ///
> 
> +  AcpiTableHandle = 0;
> 
> +  if (VtdAcpiTable != NULL) {
> 
> +    Status = AcpiTable->InstallAcpiTable (
> 
> +                          AcpiTable,
> 
> +                          VtdAcpiTable,
> 
> +                          VtdAcpiTable->Length,
> 
> +                          &AcpiTableHandle
> 
> +                          );
> 
> +    FreePool (VtdAcpiTable);
> 
> +  }
> 
> +}
> 
> +
> 
> +/**
> 
> +  Locate the VT-d ACPI tables data file and read ACPI SSDT tables.
> 
> +  Publish the appropriate SSDT based on current configuration and
> capabilities.
> 
> +
> 
> +  @param[in] SaPolicy     -  SA DXE Policy protocol
> 
> +
> 
> +  @retval EFI_SUCCESS     - Vtd initialization complete
> 
> +  @exception EFI_UNSUPPORTED - Vtd is not enabled by policy
> 
> +**/
> 
> +EFI_STATUS
> 
> +VtdInit (
> 
> +  IN  SA_POLICY_PROTOCOL    *SaPolicy
> 
> +  )
> 
> +{
> 
> +  EFI_STATUS                      Status;
> 
> +  UINT64                          McD0BaseAddress;
> 
> +  UINT64                          McD2BaseAddress;
> 
> +  SYSTEM_AGENT_NVS_AREA_PROTOCOL  *SaNvsAreaProtocol;
> 
> +  UINT8                           Index;
> 
> +
> 
> +  mInterruptRemappingSupport  = FALSE;
> 
> +  mVtdDataHob = NULL;
> 
> +  mVtdDataHob = GetFirstGuidHob(&gVtdDataHobGuid);
> 
> +  if (mVtdDataHob != NULL) {
> 
> +    mInterruptRemappingSupport = mVtdDataHob-
> >InterruptRemappingSupport;
> 
> +  }
> 
> +
> 
> +  ///
> 
> +  ///  Locate the SA Global NVS Protocol.
> 
> +  ///
> 
> +  Status = gBS->LocateProtocol (
> 
> +                  &gSaNvsAreaProtocolGuid,
> 
> +                  NULL,
> 
> +                  (VOID **) &SaNvsAreaProtocol
> 
> +                  );
> 
> +  if (EFI_ERROR (Status)) {
> 
> +    return Status;
> 
> +  }
> 
> +
> 
> +  McD0BaseAddress  = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> SA_MC_BUS, 0, 0, 0);
> 
> +  McD2BaseAddress  = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM,
> IGD_BUS_NUM, IGD_DEV_NUM, IGD_FUN_NUM, 0);
> 
> +
> 
> +  if (mVtdDataHob != NULL) {
> 
> +    SaNvsAreaProtocol->Area->VtdDisable = mVtdDataHob->VtdDisable;
> 
> +  }
> 
> +
> 
> +  for (Index = 0; Index < VTD_ENGINE_NUMBER; Index++) {
> 
> +    SaNvsAreaProtocol->Area->VtdBaseAddress[Index] =
> ReadVtdBaseAddress (Index);
> 
> +  }
> 
> +  SaNvsAreaProtocol->Area->VtdEngine1Vid =
> PciSegmentRead16(McD2BaseAddress + PCI_VENDOR_ID_OFFSET);
> 
> +
> 
> +  if (mVtdDataHob != NULL) {
> 
> +    if ((mVtdDataHob->VtdDisable) || (PciSegmentRead32
> (McD0BaseAddress + R_SA_MC_CAPID0_A_OFFSET) & BIT23)) {
> 
> +      DEBUG ((DEBUG_WARN, "VTd disabled or no capability!\n"));
> 
> +      return EFI_UNSUPPORTED;
> 
> +    }
> 
> +  }
> 
> +  ///
> 
> +  /// Check SA supports VTD and VTD is enabled in setup menu
> 
> +  ///
> 
> +  DEBUG ((DEBUG_INFO, "VTd enabled\n"));
> 
> +
> 
> +  return EFI_SUCCESS;
> 
> +}
> 
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdInitLib/
> 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/DxeVtdInitLib/
> DxeVtdInitLib.inf
> @@ -0,0 +1,71 @@
> +## @file
> 
> +# Component description file for the Dxe VTD Init library.
> 
> +#
> 
> +#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> 
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +#
> 
> +##
> 
> +
> 
> +[Defines]
> 
> +INF_VERSION = 0x00010017
> 
> +BASE_NAME = DxeVtdInitLib
> 
> +FILE_GUID = 9BD11E68-923C-424C-A278-716084B4C931
> 
> +VERSION_STRING = 1.0
> 
> +MODULE_TYPE = DXE_DRIVER
> 
> +LIBRARY_CLASS = DxeVtdInitLib
> 
> +
> 
> +[LibraryClasses]
> 
> +UefiLib
> 
> +UefiRuntimeServicesTableLib
> 
> +UefiBootServicesTableLib
> 
> +DebugLib
> 
> +PostCodeLib
> 
> +ConfigBlockLib
> 
> +HobLib
> 
> +IoLib
> 
> +PciSegmentLib
> 
> +BaseMemoryLib
> 
> +MemoryAllocationLib
> 
> +MmPciLib
> 
> +VtdInfoLib
> 
> +PchInfoLib
> 
> +PchCycleDecodingLib
> 
> +SaPlatformLib
> 
> +DxeVtdInitFruLib
> 
> +
> 
> +[Packages]
> 
> +MdePkg/MdePkg.dec
> 
> +TigerlakeSiliconPkg/SiPkg.dec
> 
> +
> 
> +[Sources]
> 
> +DxeVtdInitLib.c
> 
> +
> 
> +[Pcd]
> 
> +gSiPkgTokenSpaceGuid.PcdSiIoApicBaseAddress
> 
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemId
> 
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
> 
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
> 
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
> 
> +gSiPkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
> 
> +
> 
> +[FixedPcd]
> 
> +
> 
> +[Guids]
> 
> +gPchInfoHobGuid          ## CONSUMES
> 
> +gSaAcpiTableStorageGuid
> 
> +gVtdDataHobGuid
> 
> +gVtdDxeConfigGuid
> 
> +
> 
> +[Protocols]
> 
> +gSaPolicyProtocolGuid                  ## CONSUMES
> 
> +gSaNvsAreaProtocolGuid                 ## CONSUMES
> 
> +gEfiFirmwareVolume2ProtocolGuid
> 
> +gEfiAcpiTableProtocolGuid
> 
> +
> 
> +[Depex]
> 
> +gEfiAcpiTableProtocolGuid AND
> 
> +gEfiFirmwareVolume2ProtocolGuid AND
> 
> +gSaPolicyProtocolGuid AND
> 
> +gEfiPciRootBridgeIoProtocolGuid AND
> 
> +gEfiPciHostBridgeResourceAllocationProtocolGuid AND # This is to ensure
> that PCI MMIO resource has been prepared and available for this driver to
> allocate.
> 
> +gEfiHiiDatabaseProtocolGuid
> 
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLi
> b/DxeVtdPolicyLib.c
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyL
> ib/DxeVtdPolicyLib.c
> new file mode 100644
> index 0000000000..168de0c0a9
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyL
> ib/DxeVtdPolicyLib.c
> @@ -0,0 +1,90 @@
> +/** @file
> 
> +  This file provides services for DXE VTD policy default initialization
> 
> +
> 
> +  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +**/
> 
> +
> 
> +#include <Library/DxeVtdPolicyLib.h>
> 
> +
> 
> +/**
> 
> +  This function prints the DXE phase VTD policy.
> 
> +
> 
> +  @param[in] SaPolicy - Instance of SA_POLICY_PROTOCOL
> 
> +**/
> 
> +VOID
> 
> +VtdPrintPolicyDxe (
> 
> +  IN  SA_POLICY_PROTOCOL      *SaPolicy
> 
> +  )
> 
> +{
> 
> +  EFI_STATUS                  Status;
> 
> +  VTD_DXE_CONFIG             *VtdDxeConfig;
> 
> +
> 
> +  //
> 
> +  // Get requisite IP Config Blocks which needs to be used here
> 
> +  //
> 
> +  Status = GetConfigBlock ((VOID *) SaPolicy, &gVtdDxeConfigGuid, (VOID
> *)&VtdDxeConfig);
> 
> +  ASSERT_EFI_ERROR (Status);
> 
> +
> 
> +  DEBUG_CODE_BEGIN ();
> 
> +  DEBUG ((DEBUG_INFO, "\n------------------------ Vtd Policy (DXE) print
> BEGIN -----------------\n"));
> 
> +  DEBUG ((DEBUG_INFO, " Revision : %d\n", VtdDxeConfig-
> >Header.Revision));
> 
> +  ASSERT (VtdDxeConfig->Header.Revision ==
> VTD_DXE_CONFIG_REVISION);
> 
> +  DEBUG ((DEBUG_INFO, "\n------------------------ Vtd Policy (DXE) print END -
> ----------------\n"));
> 
> +  DEBUG_CODE_END ();
> 
> +  return;
> 
> +}
> 
> +
> 
> +/**
> 
> +  This function Load default Vtd DXE policy.
> 
> +
> 
> +  @param[in] ConfigBlockPointer    The pointer to add VTD config block
> 
> +**/
> 
> +VOID
> 
> +VtdLoadDefaultDxe (
> 
> +  IN VOID    *ConfigBlockPointer
> 
> +  )
> 
> +{
> 
> +  VTD_DXE_CONFIG        *VtdDxeConfig;
> 
> +
> 
> +  VtdDxeConfig = ConfigBlockPointer;
> 
> +  DEBUG ((DEBUG_INFO, "VtdDxeConfig->Header.GuidHob.Name = %g\n",
> &VtdDxeConfig->Header.GuidHob.Name));
> 
> +  DEBUG ((DEBUG_INFO, "VtdDxeConfig-
> >Header.GuidHob.Header.HobLength = 0x%x\n", VtdDxeConfig-
> >Header.GuidHob.Header.HobLength));
> 
> +}
> 
> +
> 
> +static COMPONENT_BLOCK_ENTRY  mVtdDxeIpBlock = {
> 
> +  &gVtdDxeConfigGuid, sizeof (VTD_DXE_CONFIG),
> VTD_DXE_CONFIG_REVISION, VtdLoadDefaultDxe
> 
> +};
> 
> +
> 
> +/**
> 
> +  Get VTD DXE config block table total size.
> 
> +
> 
> +  @retval     Size of VTD DXE config block table
> 
> +**/
> 
> +UINT16
> 
> +EFIAPI
> 
> +VtdGetConfigBlockTotalSizeDxe (
> 
> +  VOID
> 
> +  )
> 
> +{
> 
> +  return mVtdDxeIpBlock.Size;
> 
> +}
> 
> +
> 
> +/**
> 
> +  VtdAddConfigBlocks add VTD DXE config block.
> 
> +
> 
> +  @param[in] ConfigBlockTableAddress    The pointer to add VTD config
> blocks
> 
> +
> 
> +  @retval EFI_SUCCESS                   The policy default is initialized.
> 
> +  @retval EFI_OUT_OF_RESOURCES          Insufficient resources to create
> buffer
> 
> +**/
> 
> +EFI_STATUS
> 
> +EFIAPI
> 
> +VtdAddConfigBlocksDxe (
> 
> +  IN VOID           *ConfigBlockTableAddress
> 
> +  )
> 
> +{
> 
> +  EFI_STATUS  Status;
> 
> +  Status = AddComponentConfigBlocks (ConfigBlockTableAddress,
> &mVtdDxeIpBlock, 1);
> 
> +  return Status;
> 
> +}
> 
> diff --git
> a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyLi
> b/DxeVtdPolicyLib.inf
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyL
> ib/DxeVtdPolicyLib.inf
> new file mode 100644
> index 0000000000..1fe288416a
> --- /dev/null
> +++
> b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Vtd/LibraryPrivate/DxeVtdPolicyL
> ib/DxeVtdPolicyLib.inf
> @@ -0,0 +1,35 @@
> +## @file
> 
> +# Component description file for the DxeVtdPolicy library.
> 
> +#
> 
> +#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
> 
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +#
> 
> +##
> 
> +
> 
> +[Defines]
> 
> +INF_VERSION = 0x00010017
> 
> +BASE_NAME = DxeVtdPolicyLib
> 
> +FILE_GUID = 54754C6D-4883-4B67-BBBA-49D241539BE7
> 
> +VERSION_STRING = 1.0
> 
> +MODULE_TYPE = BASE
> 
> +LIBRARY_CLASS = DxeVtdPolicyLib
> 
> +
> 
> +[LibraryClasses]
> 
> +BaseMemoryLib
> 
> +UefiRuntimeServicesTableLib
> 
> +UefiBootServicesTableLib
> 
> +DebugLib
> 
> +PostCodeLib
> 
> +ConfigBlockLib
> 
> +HobLib
> 
> +SiConfigBlockLib
> 
> +
> 
> +[Packages]
> 
> +MdePkg/MdePkg.dec
> 
> +TigerlakeSiliconPkg/SiPkg.dec
> 
> +
> 
> +[Sources]
> 
> +DxeVtdPolicyLib.c
> 
> +
> 
> +[Guids]
> 
> +gVtdDxeConfigGuid
> 
> --
> 2.24.0.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#71166): https://edk2.groups.io/g/devel/message/71166
Mute This Topic: https://groups.io/mt/80274144/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list