public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Chiu, Chasel" <chasel.chiu@intel.com>
To: "Kubacki, Michael A" <michael.a.kubacki@intel.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Chaganty, Rangasai V" <rangasai.v.chaganty@intel.com>,
	"Gao, Liming" <liming.gao@intel.com>,
	"Desimone, Nathaniel L" <nathaniel.l.desimone@intel.com>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>,
	"Sinha, Ankit" <ankit.sinha@intel.com>
Subject: Re: [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules
Date: Sat, 17 Aug 2019 01:17:28 +0000	[thread overview]
Message-ID: <3C3EFB470A303B4AB093197B6777CCEC50462481@PGSMSX111.gar.corp.intel.com> (raw)
In-Reply-To: <20190817001603.30632-36-michael.a.kubacki@intel.com>

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Gao, Liming <liming.gao@intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add
> modules
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2083
> 
> Modules shared across board instances.
> 
> * BoardAcpiDxe - Performs DXE board ACPI initialization.
> * PciHotPlug - Performs PCI-e resource configuration.
> * PeiTbtInit - Initializes Thunderbolt policy in PEI.
> * PolicyInitDxe - Initializes policy in DXE.
> * TbtDxe - Performs Thunderbolt initialization in DXE.
> * TbtSmm - Performs Thunderbolt initialization in SMM.
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDx
> e.inf          |   71 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.i
> nf          |   62 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.
> inf         |   51 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtI
> nit.inf     |   47 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtS
> mm.inf         |   80 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.
> inf      |  176 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.
> h            |  130 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtS
> miHandler.h    |  180 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.
> h         |   32 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInit
> Dxe.h     |   38 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInit
> Dxe.h     |   41 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInit
> Dxe.h     |   52 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.
> h        |   45 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitD
> xe.h      |   56 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyI
> nitDxe.h |   37 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.
> c            |   96 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDx
> e.c            |  290 +++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c
> |  353 ++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.
> c           |  228 +++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtI
> nit.c       |  211 +++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtS
> miHandler.c    | 1609 +++++++++++++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtS
> mm.c           | 1765 ++++++++++++++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLi
> b.c         |  394 ++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.
> c         |  612 +++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInit
> Dxe.c     |   46 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInit
> Dxe.c     |  174 ++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInit
> Dxe.c     |   55 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.
> c        |   88 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitD
> xe.c      |   60 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyI
> nitDxe.c |   46 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUP
> D.asl           |   20 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.AS
> L             |   37 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBu
> s.asl          |  516 ++++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.
> asl          |  309 ++++
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platfor
> m.asl         |   76 +
> 
> Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3Pci
> eTbt.asl     |  405 +++++
>  Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl
> | 1877 ++++++++++++++++++++
>  37 files changed, 10365 insertions(+)
> 
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpi
> Dxe.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpi
> Dxe.inf
> new file mode 100644
> index 0000000000..2bbc3cb9e2
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpi
> Dxe.inf
> @@ -0,0 +1,71 @@
> +## @file
> +#  Component information file for AcpiPlatform module
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = BoardAcpiDxe
> +  FILE_GUID                      = E269E77D-6163-4F5D-8E59-21EAF114D307
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = InstallAcpiBoard
> +
> +[Sources.common]
> +  BoardAcpiDxe.c
> +  AcpiGnvsInit.c
> +  Dsdt/DSDT.ASL
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  PcAtChipsetPkg/PcAtChipsetPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  BaseLib
> +  DebugLib
> +  IoLib
> +  PcdLib
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  BaseMemoryLib
> +  HobLib
> +  AslUpdateLib
> +  BoardAcpiTableLib
> +
> +[Protocols]
> +  gEfiAcpiTableProtocolGuid                     ## CONSUMES
> +  gEfiFirmwareVolume2ProtocolGuid               ## CONSUMES
> +  gEfiMpServiceProtocolGuid                     ## CONSUMES
> +  gEfiGlobalNvsAreaProtocolGuid
> +
> +[Pcd]
> +  gBoardModuleTokenSpaceGuid.PcdAcpiGnvsAddress
> +
> +  gBoardModuleTokenSpaceGuid.PcdAcpiSleepState
> +  gBoardModuleTokenSpaceGuid.PcdAcpiHibernate
> +  gBoardModuleTokenSpaceGuid.PcdLowPowerS0Idle
> +  gBoardModuleTokenSpaceGuid.PcdDisableActiveTripPoints
> +  gBoardModuleTokenSpaceGuid.PcdDisablePassiveTripPoints
> +  gBoardModuleTokenSpaceGuid.PcdDisableCriticalTripPoints
> +
> +[Depex]
> +  gEfiAcpiTableProtocolGuid           AND
> +  gEfiFirmwareVolume2ProtocolGuid     AND
> +  gEfiPciRootBridgeIoProtocolGuid     AND
> +  gEfiVariableArchProtocolGuid        AND
> +  gEfiVariableWriteArchProtocolGuid
> +
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.inf
> new file mode 100644
> index 0000000000..dd4e41a409
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.inf
> @@ -0,0 +1,62 @@
> +## @file
> +# This module will perform specific PCI-Express devices
> +# resource configuration.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = PciHotPlug
> +  FILE_GUID                      = 3022E512-B94A-4F12-806D-7EF1177899D8
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = DXE_DRIVER
> +  ENTRY_POINT                    = PciHotPlug
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 EBC
> +#
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  BaseMemoryLib
> +  MemoryAllocationLib
> +  DevicePathLib
> +  DebugLib
> +  UefiLib
> +  HobLib
> +  PchPcieRpLib
> +  ConfigBlockLib
> +  TbtCommonLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  PciHotPlug.c
> +  PciHotPlug.h
> +
> +[Protocols]
> +  gEfiPciHotPlugInitProtocolGuid                ## PRODUCES
> +  gSaPolicyProtocolGuid                         ## CONSUMES
> +
> +[Guids]
> +  gEfiHobListGuid                               ## CONSUMES
> +  gPcieRpConfigGuid                  ## CONSUMES
> +
> +[Pcd]
> +
> +[Depex]
> +  gDxeTbtPolicyProtocolGuid
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtD
> xe.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtD
> xe.inf
> new file mode 100644
> index 0000000000..5160bb1dbb
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtD
> xe.inf
> @@ -0,0 +1,51 @@
> +## @file
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = TbtDxe
> +  FILE_GUID                      = 19C9762C-3A88-41B0-906F-8C4C2895A887
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = DXE_DRIVER
> +  ENTRY_POINT                    = TbtDxeEntryPoint
> +
> +[LibraryClasses]
> +  DebugLib
> +  BaseMemoryLib
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  UefiDriverEntryPoint
> +  HobLib
> +  UefiLib
> +  TbtCommonLib
> +  DxeTbtPolicyLib
> +  AslUpdateLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  TbtDxe.c
> +
> +[Protocols]
> +  gTbtNvsAreaProtocolGuid                       ## CONSUMES
> +  gDxeTbtPolicyProtocolGuid
> +
> +[Guids]
> +  gTbtInfoHobGuid                               ## CONSUMES
> +
> +[Depex]
> +  gEfiVariableWriteArchProtocolGuid   AND
> +  gEfiVariableArchProtocolGuid
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb
> tInit.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb
> tInit.inf
> new file mode 100644
> index 0000000000..07962ffa10
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb
> tInit.inf
> @@ -0,0 +1,47 @@
> +## @file
> +# Component information file for the TBT Init PEI module.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = PeiTbtInit
> +  FILE_GUID                      = 90BF2BFB-F998-4cbc-AD72-008D4D047A4B
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = PEIM
> +  ENTRY_POINT                    = TbtInitEntryPoint
> +
> +[LibraryClasses]
> +  PeimEntryPoint
> +  DebugLib
> +  HobLib
> +  PeiServicesLib
> +  PeiTbtPolicyLib
> +  PeiDTbtInitLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Sources]
> +  PeiTbtInit.c
> +
> +[Guids]
> +  gTbtInfoHobGuid                               ## CONSUMES
> +
> +[Ppis]
> +  gEfiEndOfPeiSignalPpiGuid                     ## CONSUMES
> +  gPeiTbtPolicyBoardInitDonePpiGuid             ## CONSUMES
> +
> +[Depex]
> +  gEfiPeiMemoryDiscoveredPpiGuid
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> Smm.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> Smm.inf
> new file mode 100644
> index 0000000000..3d4e6ceea0
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> Smm.inf
> @@ -0,0 +1,80 @@
> +## @file
> +# Component information file for the ThunderBolt Smm module.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = TbtSmm
> +  FILE_GUID                      = 5BDCD685-D80A-42E6-9867-A84CCE7F828E
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = DXE_SMM_DRIVER
> +  PI_SPECIFICATION_VERSION       = 1.10
> +  ENTRY_POINT                    = TbtSmmEntryPoint
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  UefiRuntimeServicesTableLib
> +  UefiBootServicesTableLib
> +  IoLib
> +  PciExpressLib
> +  HobLib
> +  ReportStatusCodeLib
> +  PciSegmentLib
> +  UefiLib
> +  SmmServicesTableLib
> +  GpioLib
> +  PchInfoLib
> +  TbtCommonLib
> +  PchPmcLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MinPlatformPkg/MinPlatformPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +
> +[Pcd]
> +#  gBoardModuleTokenSpaceGuid.PcdSwSmiDTbtEnumerate ## CONSUMES
> +  gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength      ##
> CONSUMES
> +
> +[FixedPcd]
> +  gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress       ## CONSUMES
> +
> +[Sources]
> +  TbtSmiHandler.h
> +  TbtSmiHandler.c
> +  TbtSmm.c
> +
> +[Protocols]
> +  gTbtNvsAreaProtocolGuid                       ## CONSUMES
> +  gEfiSmmSxDispatch2ProtocolGuid                ## CONSUMES
> +  gEfiSmmSwDispatch2ProtocolGuid                ## CONSUMES
> +  gEfiSmmVariableProtocolGuid                   ## CONSUMES
> +  gDxeTbtPolicyProtocolGuid
> +
> +[Guids]
> +  gTbtInfoHobGuid                               ## CONSUMES
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress  ## CONSUMES
> +
> +[Depex]
> +  gEfiSmmBase2ProtocolGuid            AND
> +  gEfiSmmSxDispatch2ProtocolGuid      AND
> +  gEfiSmmSwDispatch2ProtocolGuid      AND
> +  gEfiGlobalNvsAreaProtocolGuid       AND
> +  gEfiVariableWriteArchProtocolGuid   AND
> +  gEfiVariableArchProtocolGuid        AND
> +  gEfiSmmVariableProtocolGuid
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.inf
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.inf
> new file mode 100644
> index 0000000000..65c531a532
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.inf
> @@ -0,0 +1,176 @@
> +## @file
> +# Module Information file for the PolicyInit DXE driver.
> +#
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010017
> +  BASE_NAME                      = PolicyInitDxe
> +  FILE_GUID                      = 490D0119-4448-440D-8F5C-F58FB53EE057
> +  VERSION_STRING                 = 1.0
> +  MODULE_TYPE                    = DXE_DRIVER
> +  ENTRY_POINT                    = PolicyInitDxeEntryPoint
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  CpuPlatformLib
> +  DebugLib
> +  DxeServicesTableLib
> +  IoLib
> +  MemoryAllocationLib
> +  DxeSaPolicyLib
> +  DxePchPolicyLib
> +  PcdLib
> +  DxePolicyBoardConfigLib
> +  DxePolicyUpdateLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +  ConfigBlockLib
> +  DevicePathLib
> +  DxeTbtPolicyLib
> +  PchPcieRpLib
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  CoffeelakeSiliconPkg/SiPkg.dec
> +  WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec
> +  IntelSiliconPkg/IntelSiliconPkg.dec
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress                     ##
> CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase                          ##
> CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize                          ##
> CONSUMES
> +  gBoardModuleTokenSpaceGuid.PcdIntelGopEnable
> +  gBoardModuleTokenSpaceGuid.PcdPlatformFlavor
> +  gBoardModuleTokenSpaceGuid.PcdPlatformType
> +  gBoardModuleTokenSpaceGuid.PcdEcPresent
> +  gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid
> +  gBoardModuleTokenSpaceGuid.PcdTbtEnable
> +  gSiPkgTokenSpaceGuid.PcdCpuSmmMsrSaveStateEnable                      ##
> CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable
> ## CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdCpuSmmUseDelayIndication                      ##
> CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdCpuSmmUseBlockIndication                      ##
> CONSUMES
> +  gSiPkgTokenSpaceGuid.PcdCpuSmmUseSmmEnableIndication
> ## CONSUMES
> +
> +  gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeUpSupport
> +  gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeDownSupport
> +  gBoardModuleTokenSpaceGuid.PcdVirtualButtonHomeButtonSupport
> +  gBoardModuleTokenSpaceGuid.PcdVirtualButtonRotationLockSupport
> +  gBoardModuleTokenSpaceGuid.PcdSlateModeSwitchSupport
> +  gBoardModuleTokenSpaceGuid.PcdAcDcAutoSwitchSupport
> +  gBoardModuleTokenSpaceGuid.PcdPmPowerButtonGpioPin
> +  gBoardModuleTokenSpaceGuid.PcdAcpiEnableAllButtonSupport
> +  gBoardModuleTokenSpaceGuid.PcdAcpiHidDriverButtonSupport
> +  gBoardModuleTokenSpaceGuid.PcdTsOnDimmTemperature
> +  gBoardModuleTokenSpaceGuid.PcdBatteryPresent
> +
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCSupport
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCEcLess
> +  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF3Support
> +  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF4Support
> +  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF5Support
> +  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF6Support
> +  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF7Support
> +  gBoardModuleTokenSpaceGuid.PcdEcHotKeyF8Support
> +
> +  #
> +  # PSS Board Configuration.
> +  #
> +  gBoardModuleTokenSpaceGuid.PcdPssReadSN
> +  gBoardModuleTokenSpaceGuid.PcdPssI2cBusNumber
> +  gBoardModuleTokenSpaceGuid.PcdPssI2cSlaveAddress
> +
> +  gBoardModuleTokenSpaceGuid.PcdXhciAcpiTableSignature
> +  gBoardModuleTokenSpaceGuid.PcdPreferredPmProfile
> +  gBoardModuleTokenSpaceGuid.PcdFingerPrintSleepGpio
> +  gBoardModuleTokenSpaceGuid.PcdFingerPrintIrqGpio
> +  gBoardModuleTokenSpaceGuid.PcdGnssResetGpio
> +  gBoardModuleTokenSpaceGuid.PcdTouchpadIrqGpio
> +  gBoardModuleTokenSpaceGuid.PcdTouchpanelIrqGpio
> +
> +  gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecIrqGpio
> +  gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecI2cBusNumber
> +  gBoardModuleTokenSpaceGuid.PcdBleUsbPortNumber
> +  gBoardModuleTokenSpaceGuid.PcdEcSmiGpio
> +  gBoardModuleTokenSpaceGuid.PcdEcLowPowerExitGpio
> +  gBoardModuleTokenSpaceGuid.PcdHidI2cIntPad
> +  gBoardModuleTokenSpaceGuid.PcdDetectPs2KbOnCmdAck
> +  gBoardModuleTokenSpaceGuid.PcdSpdAddressOverride
> +  gBoardModuleTokenSpaceGuid.PcdDDISelection
> +  gBoardModuleTokenSpaceGuid.PcdGfxCrbDetectGpio
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1Pch
> +  gBoardModuleTokenSpaceGuid.PcdUsbCPort1Proterties
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2Pch
> +  gBoardModuleTokenSpaceGuid.PcdUsbCPort2Proterties
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3Pch
> +  gBoardModuleTokenSpaceGuid.PcdUsbCPort3Proterties
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4Pch
> +  gBoardModuleTokenSpaceGuid.PcdUsbCPort4Proterties
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5Pch
> +  gBoardModuleTokenSpaceGuid.PcdUsbCPort5Proterties
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6
> +  gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6Pch
> +  gBoardModuleTokenSpaceGuid.PcdUsbCPort6Proterties
> +  gBoardModuleTokenSpaceGuid.PcdMipiCam0LinkUsed
> +  gBoardModuleTokenSpaceGuid.PcdMipiCam1LinkUsed
> +  gBoardModuleTokenSpaceGuid.PcdMipiCam2LinkUsed
> +  gBoardModuleTokenSpaceGuid.PcdMipiCam3LinkUsed
> +  gPlatformModuleTokenSpaceGuid.PcdH8S2113Present
> +  gPlatformModuleTokenSpaceGuid.PcdNat87393Present
> +  gPlatformModuleTokenSpaceGuid.PcdNct677FPresent
> +  gBoardModuleTokenSpaceGuid.PcdConvertableDockSupport
> +  gBoardModuleTokenSpaceGuid.PcdSmcRuntimeSciPin
> +  gBoardModuleTokenSpaceGuid.PcdRealBattery1Control
> +  gBoardModuleTokenSpaceGuid.PcdRealBattery2Control
> +  gBoardModuleTokenSpaceGuid.PcdDimmPopulationError
> +  gBoardModuleTokenSpaceGuid.PcdBtIrqGpio
> +  gBoardModuleTokenSpaceGuid.PcdBtRfKillGpio
> +  gBoardModuleTokenSpaceGuid.PcdWhlErbRtd3TableEnable
> +  gBoardModuleTokenSpaceGuid.PcdTypeCPortsSupported
> +  gBoardModuleTokenSpaceGuid.PcdMipiCamSensor
> +  gBoardModuleTokenSpaceGuid.PcdH8S2113SIO
> +  gBoardModuleTokenSpaceGuid.PcdNCT6776FCOM
> +  gBoardModuleTokenSpaceGuid.PcdNCT6776FSIO
> +  gBoardModuleTokenSpaceGuid.PcdNCT6776FHWMON
> +  gBoardModuleTokenSpaceGuid.PcdGpioTier2WakeEnable
> +  gBoardModuleTokenSpaceGuid.PcdFunctionGopVbtSpecificUpdate
> +
> +[Sources]
> +  PolicyInitDxe.c
> +  SaPolicyInitDxe.c
> +  SiliconPolicyInitDxe.c
> +  GopPolicyInitDxe.c
> +  PchPolicyInitDxe.c
> +  CpuPolicyInitDxe.c
> +  BoardInitLib.c
> +
> +[Protocols]
> +  gEfiFirmwareVolume2ProtocolGuid               ## CONSUMES
> +  gDxeMePolicyGuid                              ## PRODUCES
> +  gSaPolicyProtocolGuid                         ## CONSUMES
> +  gPchPolicyProtocolGuid                        ## CONSUMES
> +  gDxeSiPolicyProtocolGuid                      ## PRODUCES
> +  gGopPolicyProtocolGuid                        ## PRODUCES
> +  gDxeCpuPolicyProtocolGuid                     ## PRODUCES
> +
> +[Guids]
> +  gCpuSmmGuid                                   ## CONSUMES
> +  gSiMemoryInfoDataGuid
> +
> +[Depex]
> +  gEfiVariableArchProtocolGuid
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.h
> new file mode 100644
> index 0000000000..f57bfb8c26
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.h
> @@ -0,0 +1,130 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCI_HOT_PLUG_H_
> +#define _PCI_HOT_PLUG_H_
> +
> +//
> +// External include files do NOT need to be explicitly specified in real EDKII
> +// environment
> +//
> +#include <Base.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <IndustryStandard/Acpi10.h>
> +#include <Protocol/PciHotPlugInit.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/UefiLib.h>
> +#include <Guid/HobList.h>
> +#include <Library/HobLib.h>
> +#include <Protocol/SaPolicy.h>
> +
> +#define PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE SIGNATURE_32 ('G', 'U',
> 'L', 'P')
> +
> +#define ACPI \
> +  { \
> +    { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),
> (UINT8) \
> +      ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (0x0A03), 0 \
> +  }
> +
> +#define PCI(device, function) \
> +  { \
> +    { HARDWARE_DEVICE_PATH, HW_PCI_DP, { (UINT8) (sizeof
> (PCI_DEVICE_PATH)), (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) } }, \
> +      (UINTN) function, (UINTN) device \
> +  }
> +
> +#define END \
> +  { \
> +    END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
> { END_DEVICE_PATH_LENGTH, 0 } \
> +  }
> +
> +#define LPC(eisaid, function) \
> +  { \
> +    { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),
> (UINT8) \
> +      ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (eisaid),
> function \
> +  }
> +
> +typedef struct PCIE_HOT_PLUG_DEVICE_PATH {
> +  ACPI_HID_DEVICE_PATH      PciRootBridgeNode;
> +  PCI_DEVICE_PATH           PciRootPortNode;
> +  EFI_DEVICE_PATH_PROTOCOL  EndDeviceNode;
> +} PCIE_HOT_PLUG_DEVICE_PATH;
> +
> +typedef struct {
> +  UINTN                           Signature;
> +  EFI_HANDLE                      Handle; // Handle for protocol this driver
> installs on
> +  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  HotPlugInitProtocol;
> +} PCI_HOT_PLUG_INSTANCE;
> +
> +/**
> +  This procedure returns a list of Root Hot Plug controllers that require
> +  initialization during boot process
> +
> +  @param[in]  This      The pointer to the instance of the
> EFI_PCI_HOT_PLUG_INIT protocol.
> +  @param[out] HpcCount  The number of Root HPCs returned.
> +  @param[out] HpcList   The list of Root HPCs. HpcCount defines the number
> of elements in this list.
> +
> +  @retval EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetRootHpcList (
> +  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL    *This,
> +  OUT UINTN                             *PhpcCount,
> +  OUT EFI_HPC_LOCATION                  **PhpcList
> +  );
> +
> +/**
> +  This procedure Initializes one Root Hot Plug Controller
> +  This process may casue initialization of its subordinate buses
> +
> +  @param[in]  This            The pointer to the instance of the
> EFI_PCI_HOT_PLUG_INIT protocol.
> +  @param[in]  HpcDevicePath   The Device Path to the HPC that is being
> initialized.
> +  @param[in]  HpcPciAddress   The address of the Hot Plug Controller
> function on the PCI bus.
> +  @param[in]  Event           The event that should be signaled when the Hot
> Plug Controller initialization is complete. Set to NULL if the caller wants to wait
> until the entire initialization process is complete. The event must be of the
> type EFI_EVT_SIGNAL.
> +  @param[out] HpcState        The state of the Hot Plug Controller hardware.
> The type EFI_Hpc_STATE is defined in section 3.1.
> +
> +  @retval   EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeRootHpc (
> +  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
> +  IN  EFI_DEVICE_PATH_PROTOCOL        *PhpcDevicePath,
> +  IN  UINT64                          PhpcPciAddress,
> +  IN  EFI_EVENT                       Event, OPTIONAL
> +  OUT EFI_HPC_STATE                   *PhpcState
> +  );
> +
> +/**
> +  Returns the resource padding required by the PCI bus that is controlled by
> the specified Hot Plug Controller.
> +
> +  @param[in]  This           The pointer to the instance of the
> EFI_PCI_HOT_PLUG_INIT protocol. initialized.
> +  @param[in]  HpcDevicePath  The Device Path to the Hot Plug Controller.
> +  @param[in]  HpcPciAddress  The address of the Hot Plug Controller
> function on the PCI bus.
> +  @param[out] HpcState       The state of the Hot Plug Controller hardware.
> The type EFI_HPC_STATE is defined in section 3.1.
> +  @param[out] Padding        This is the amount of resource padding
> required by the PCI bus under the control of the specified Hpc. Since the caller
> does not know the size of this buffer, this buffer is allocated by the callee and
> freed by the caller.
> +  @param[out] Attribute      Describes how padding is accounted for.
> +
> +  @retval     EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetResourcePadding (
> +  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
> +  IN  EFI_DEVICE_PATH_PROTOCOL        *PhpcDevicePath,
> +  IN  UINT64                          PhpcPciAddress,
> +  OUT EFI_HPC_STATE                   *PhpcState,
> +  OUT VOID                            **Padding,
> +  OUT EFI_HPC_PADDING_ATTRIBUTES      *Attributes
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> SmiHandler.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> SmiHandler.h
> new file mode 100644
> index 0000000000..b91b0f14bd
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> SmiHandler.h
> @@ -0,0 +1,180 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _TBT_SMI_HANDLER_H_
> +#define _TBT_SMI_HANDLER_H_
> +
> +#include <Library/TbtCommonLib.h>
> +#include <Library/IoLib.h>
> +#include <IndustryStandard/Pci.h>
> +
> +#ifdef PROGRESS_CODE
> +#undef PROGRESS_CODE
> +#endif
> +
> +#define MAX_TBT_DEPTH         6
> +
> +#define P2P_BRIDGE            (((PCI_CLASS_BRIDGE) << 8) |
> (PCI_CLASS_BRIDGE_P2P))
> +
> +#define BAR_ALIGN(v, a)       ((((v) - 1) | (a)) + 1)
> +
> +#define CMD_BUS_MASTER        BIT2
> +#define CMD_BM_IO             (CMD_BUS_MASTER | BIT0)
> +#define CMD_BM_MEM            (CMD_BUS_MASTER | BIT1)
> +#define CMD_BM_MEM_IO         (CMD_BUS_MASTER | BIT1 | BIT0)
> +
> +#define DEF_CACHE_LINE_SIZE   0x20
> +#define DEF_RES_IO_PER_DEV    4
> +#define DEF_RES_MEM_PER_DEV   32
> +#define DEF_RES_PMEM_PER_DEV  32
> +
> +#define DOCK_BUSSES           8
> +
> +#define DISBL_IO_REG1C        0x01F1
> +#define DISBL_MEM32_REG20     0x0000FFF0
> +#define DISBL_PMEM_REG24      0x0001FFF1
> +
> +#define count(x)              (sizeof (x) / sizeof ((x)[0]))
> +
> +#define PCIE_CAP_ID_SSID_SSVID 0x0D
> +#define INVALID_PCI_DEVICE    0xFFFFFFFF
> +#define PCI_TBT_VESC_REG2     0x510
> +
> +typedef struct _PortInfo {
> +  UINT8   IoBase;
> +  UINT8   IoLimit;
> +  UINT16  MemBase;
> +  UINT16  MemLimit;
> +  UINT64  PMemBase64;
> +  UINT64  PMemLimit64;
> +  UINT8   BusNumLimit;
> +  UINT8   ConfedEP;
> +} PORT_INFO;
> +
> +typedef struct _MEM_REGS {
> +  UINT32  Base;
> +  UINT32  Limit;
> +} MEM_REGS;
> +
> +typedef struct _PMEM_REGS {
> +  UINT64  Base64;
> +  UINT64  Limit64;
> +} PMEM_REGS;
> +
> +typedef struct _IO_REGS {
> +  UINT16  Base;
> +  UINT16  Limit;
> +} IO_REGS;
> +
> +typedef struct _BRDG_RES_CONFIG {
> +  UINT8   Cmd;
> +  UINT8   Cls;
> +  UINT8   IoBase;
> +  UINT8   IoLimit;
> +  UINT16  MemBase;
> +  UINT16  MemLimit;
> +  UINT64  PMemBase64;
> +  UINT64  PMemLimit64;
> +} BRDG_RES_CONFIG;
> +
> +typedef struct _BRDG_CONFIG {
> +  DEV_ID          DevId;
> +  UINT8           PBus;
> +  UINT8           SBus;
> +  UINT8           SubBus;
> +  BOOLEAN         IsDSBridge;
> +  BRDG_RES_CONFIG Res;
> +} BRDG_CONFIG;
> +
> +enum {
> +  HR_US_PORT,
> +  HR_DS_PORT0,
> +  HR_DS_PORT3,
> +  HR_DS_PORT4,
> +  HR_DS_PORT5,
> +  HR_DS_PORT6,
> +  MAX_CFG_PORTS
> +};
> +
> +enum {
> +  HR_DS_PORT1   = HR_DS_PORT3
> +};
> +
> +//
> +// Alpine Ridge
> +//
> +enum {
> +  AR_DS_PORT1 = HR_DS_PORT3,
> +  AR_DS_PORT2,
> +  AR_DS_PORT3,
> +  AR_DS_PORT4
> +};
> +
> +typedef struct _HR_CONFIG {
> +  UINT16  DeviceId;
> +  UINT8   HRBus;
> +  UINT8   MinDSNumber;
> +  UINT8   MaxDSNumber;
> +  UINT8   BridgeLoops;
> +} HR_CONFIG;
> +
> +STATIC const BRDG_RES_CONFIG  NOT_IN_USE_BRIDGE = {
> +  CMD_BUS_MASTER,
> +  0,
> +  DISBL_IO_REG1C & 0xFF,
> +  DISBL_IO_REG1C >> 8,
> +  DISBL_MEM32_REG20 & 0xFFFF,
> +  DISBL_MEM32_REG20 >> 16,
> +  DISBL_PMEM_REG24 & 0xFFFF,
> +  DISBL_PMEM_REG24 >> 16
> +};
> +
> +typedef union _BRDG_CIO_MAP_REG {
> +  UINT32  AB_REG;
> +  struct {
> +    UINT32  NumOfDSPorts : 5;
> +    UINT32  CioPortMap : 27;
> +  } Bits;
> +} BRDG_CIO_MAP_REG;
> +
> +//
> +// Functions
> +//
> +VOID
> +ThunderboltCallback (
> +  IN UINT8 Type
> +  );
> +
> +VOID
> +TbtDisablePCIDevicesAndBridges (
> +  IN UINT8 Type
> +  );
> +
> +VOID
> +EndOfThunderboltCallback(
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +);
> +
> +VOID
> +ConfigureTbtAspm(
> +  IN UINT8       Type,
> +  IN UINT16      Aspm
> +);
> +
> +UINT8
> +PcieFindCapId (
> +  IN UINT8   Segment,
> +  IN UINT8   Bus,
> +  IN UINT8   Device,
> +  IN UINT8   Function,
> +  IN UINT8   CapId
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLi
> b.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLi
> b.h
> new file mode 100644
> index 0000000000..ac13acc27d
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLi
> b.h
> @@ -0,0 +1,32 @@
> +/** @file
> + Header file for board Init function for DXE Init phase.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _DXE_BOARD_INIT_LIB_H_
> +#define _DXE_BOARD_INIT_LIB_H_
> +
> +#include <Uefi.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <PlatformBoardId.h>
> +#include <Register/PchRegs.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/PchPcieRpLib.h>
> +#include <Platform.h>
> +
> +EFI_STATUS
> +EFIAPI
> +BoardConfigInit (
> +   VOID
> +  );
> +
> +#endif // _DXE_BOARD_INIT_LIB_H_
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyI
> nitDxe.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyI
> nitDxe.h
> new file mode 100644
> index 0000000000..5d0e2777d8
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyI
> nitDxe.h
> @@ -0,0 +1,38 @@
> +/** @file
> +  Header file for the SiliconPolicyInitDxe Driver.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _CPU_POLICY_INIT_DXE_H_
> +#define _CPU_POLICY_INIT_DXE_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +
> +#include <Protocol/CpuPolicyProtocol.h>
> +#include <Library/DxeCpuPolicyUpdateLib.h>
> +
> +
> +/**
> +  Initialize Intel CPU DXE Policy
> +
> +  @param[in] ImageHandle          Image handle of this driver.
> +
> +  @retval EFI_SUCCESS             Initialization complete.
> +  @exception EFI_UNSUPPORTED      The chipset is unsupported by this
> driver.
> +  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver.
> +  @retval EFI_DEVICE_ERROR        Device error, driver exits abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuPolicyInitDxe (
> +  IN EFI_HANDLE           ImageHandle
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyI
> nitDxe.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyI
> nitDxe.h
> new file mode 100644
> index 0000000000..ff975efae0
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyI
> nitDxe.h
> @@ -0,0 +1,41 @@
> +/** @file
> +Header file for the GopPolicyInitDxe Driver.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _GOP_POLICY_INIT_DXE_H_
> +#define _GOP_POLICY_INIT_DXE_H_
> +
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Library/UefiLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <PlatformBoardId.h>
> +#include <Library/PcdLib.h>
> +
> +/**
> +Initialize GOP DXE Policy
> +
> +@param[in] ImageHandle          Image handle of this driver.
> +
> +@retval EFI_SUCCESS             Initialization complete.
> +@retval EFI_UNSUPPORTED         The chipset is unsupported by this driver.
> +@retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver.
> +@retval EFI_DEVICE_ERROR        Device error, driver exits abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GopPolicyInitDxe(
> +  IN EFI_HANDLE           ImageHandle
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyIn
> itDxe.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyI
> nitDxe.h
> new file mode 100644
> index 0000000000..1055fed7c8
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyI
> nitDxe.h
> @@ -0,0 +1,52 @@
> +/** @file
> +  Header file for the PchPolicyInitDxe Driver.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _PCH_POLICY_INIT_DXE_H_
> +#define _PCH_POLICY_INIT_DXE_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <FirwmareConfigurations.h>
> +#include <Protocol/PchPolicy.h>
> +#include <Library/DxePchPolicyLib.h>
> +#include <Library/DxePchPolicyUpdateLib.h>
> +
> +extern UINT8 mFirmwareConfiguration;
> +
> +/**
> +  <b>PCH DXE Policy Driver Entry Point</b> \n
> +  - <b>Introduction</b> \n
> +    Pch DXE drivers behavior can be controlled by platform policy without
> modifying reference code directly.
> +    Platform policy Protocol is initialized with default settings in this funciton.
> +    This policy Protocol has to be initialized prior to PCH initialization DXE
> drivers execution.
> +
> +  - @pre
> +    - Runtime variable service should be ready if policy initialization required.
> +
> +  - @result
> +    PCH_POLICY_PROTOCOL will be installed successfully and ready for Pch
> reference code use.
> +
> +  - <b>Porting Recommendations</b> \n
> +    Policy should be initialized basing on platform design or user selection (like
> BIOS Setup Menu)
> +
> +  @param[in] ImageHandle - Image handle of this driver.
> +
> +  @retval EFI_SUCCESS           Initialization complete.
> +  @retval EFI_OUT_OF_RESOURCES  Do not have enough resources to
> initialize the driver.
> +  @retval EFI_DEVICE_ERROR      Device error, driver exits abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchPolicyInitDxe (
> +  IN EFI_HANDLE           ImageHandle
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.h
> new file mode 100644
> index 0000000000..d2aac9823e
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.h
> @@ -0,0 +1,45 @@
> +/** @file
> +  Header file for the PolicyInitDxe Driver.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _POLICY_INIT_DXE_H_
> +#define _POLICY_INIT_DXE_H_
> +
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include "SaPolicyInitDxe.h"
> +#include "PchPolicyInitDxe.h"
> +#include "SiliconPolicyInitDxe.h"
> +#include "GopPolicyInitDxe.h"
> +#include "CpuPolicyInitDxe.h"
> +
> +#include <Library/DxeTbtPolicyLib.h>
> +/**
> +  Initialize DXE Platform Policy
> +
> +  @param[in] ImageHandle - Image handle of this driver.
> +  @param[in] SystemTable - Global system service table.
> +
> +  @retval EFI_SUCCESS           Initialization complete.
> +  @exception EFI_UNSUPPORTED       The chipset is unsupported by this
> driver.
> +  @retval EFI_OUT_OF_RESOURCES  Do not have enough resources to
> initialize the driver.
> +  @retval EFI_DEVICE_ERROR      Device error, driver exits abnormally.
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +PolicyInitDxeEntryPoint (
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyIni
> tDxe.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyIni
> tDxe.h
> new file mode 100644
> index 0000000000..0f86711e6a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyIni
> tDxe.h
> @@ -0,0 +1,56 @@
> +/** @file
> +  Header file for the SaPolicyInitDxe Driver.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SA_POLICY_INIT_DXE_H_
> +#define _SA_POLICY_INIT_DXE_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <FirwmareConfigurations.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Library/DxeSaPolicyLib.h>
> +#include <Library/DxePolicyBoardConfigLib.h>
> +#include <Library/DxeSaPolicyUpdateLib.h>
> +
> +#include <SaAccess.h>
> +
> +extern UINT8 mFirmwareConfiguration;
> +
> +/**
> +  <b>SA DXE Policy Driver Entry Point</b> \n
> +  - <b>Introduction</b> \n
> +    System Agent DXE drivers behavior can be controlled by platform policy
> without modifying reference code directly.
> +    Platform policy Protocol is initialized with default settings in this funciton.
> +    This policy Protocol has to be initialized prior to System Agent
> initialization DXE drivers execution.
> +
> +  - @pre
> +    - Runtime variable service should be ready if policy initialization required.
> +
> +  - @result
> +    SA_POLICY_PROTOCOL will be installed successfully and ready for System
> Agent reference code use.
> +
> +  - <b>Porting Recommendations</b> \n
> +    Policy should be initialized basing on platform design or user selection (like
> BIOS Setup Menu)
> +
> +  @param[in] ImageHandle - Image handle of this driver.
> +
> +  @retval EFI_SUCCESS           Initialization complete.
> +  @exception EFI_UNSUPPORTED    The chipset is unsupported by this driver.
> +  @retval EFI_OUT_OF_RESOURCES  Do not have enough resources to
> initialize the driver.
> +  @retval EFI_DEVICE_ERROR      Device error, driver exits abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SaPolicyInitDxe (
> +  IN EFI_HANDLE           ImageHandle
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolic
> yInitDxe.h
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPoli
> cyInitDxe.h
> new file mode 100644
> index 0000000000..a2c5f548fa
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPoli
> cyInitDxe.h
> @@ -0,0 +1,37 @@
> +/** @file
> +  Header file for the SiliconPolicyInitDxe Driver.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _SILICON_POLICY_INIT_DXE_H_
> +#define _SILICON_POLICY_INIT_DXE_H_
> +
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Guid/StatusCodeDataTypeId.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include <Protocol/SiPolicyProtocol.h>
> +
> +/**
> +  Initilize Intel CPU DXE Policy
> +
> +  @param[in] ImageHandle             Image handle of this driver.
> +
> +  @retval EFI_SUCCESS             Initialization complete.
> +  @exception EFI_UNSUPPORTED         The chipset is unsupported by this
> driver.
> +  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver.
> +  @retval EFI_DEVICE_ERROR        Device error, driver exits abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SiliconPolicyInitDxe (
> +  IN EFI_HANDLE           ImageHandle
> +  );
> +
> +#endif
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsIn
> it.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsIn
> it.c
> new file mode 100644
> index 0000000000..1ff129c307
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsIn
> it.c
> @@ -0,0 +1,96 @@
> +/** @file
> +  Acpi Gnvs Init Library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <PchAccess.h>
> +#include <Protocol/GlobalNvsArea.h>
> +#include <Protocol/MpService.h>
> +
> +/**
> +@brief
> +  Global NVS initialize.
> +
> +  @param[in] GlobalNvs         - Pointer of Global NVS area
> +
> +  @retval EFI_SUCCESS          - Allocate Global NVS completed.
> +  @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for
> GNVS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiGnvsInit (
> +  IN OUT VOID                   **GlobalNvs
> +  )
> +{
> +  UINTN                         Pages;
> +  EFI_PHYSICAL_ADDRESS          Address;
> +  EFI_STATUS                    Status;
> +  EFI_GLOBAL_NVS_AREA_PROTOCOL  *GNVS;
> +  EFI_MP_SERVICES_PROTOCOL      *MpService;
> +  UINTN                         NumberOfCPUs;
> +  UINTN                         NumberOfEnabledCPUs;
> +
> +  Pages = EFI_SIZE_TO_PAGES (sizeof (EFI_GLOBAL_NVS_AREA));
> +  Address = 0xffffffff; // allocate address below 4G.
> +
> +  Status  = gBS->AllocatePages (
> +                   AllocateMaxAddress,
> +                   EfiACPIMemoryNVS,
> +                   Pages,
> +                   &Address
> +                   );
> +  ASSERT_EFI_ERROR (Status);
> +  if (EFI_ERROR(Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Locate the MP services protocol
> +  // Find the MP Protocol. This is an MP platform, so MP protocol must be
> there.
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiMpServiceProtocolGuid,
> +                  NULL,
> +                  (VOID **) &MpService
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Determine the number of processors
> +  //
> +  MpService->GetNumberOfProcessors (
> +              MpService,
> +              &NumberOfCPUs,
> +              &NumberOfEnabledCPUs
> +              );
> +
> +  *GlobalNvs = (VOID *) (UINTN) Address;
> +  SetMem (*GlobalNvs, sizeof (EFI_GLOBAL_NVS_AREA), 0);
> +
> +  //
> +  // GNVS default value init here...
> +  //
> +  GNVS = (EFI_GLOBAL_NVS_AREA_PROTOCOL *) &Address;
> +
> +  GNVS->Area->ThreadCount = (UINT8)NumberOfEnabledCPUs;
> +
> +  //
> +  // Miscellaneous
> +  //
> +  GNVS->Area->PL1LimitCS = 0;
> +  GNVS->Area->PL1LimitCSValue = 4500;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpi
> Dxe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpi
> Dxe.c
> new file mode 100644
> index 0000000000..cb5f328a39
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpi
> Dxe.c
> @@ -0,0 +1,290 @@
> +/** @file
> +  ACPI Platform Driver
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Uefi.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/BoardAcpiTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/AslUpdateLib.h>
> +
> +#include <Protocol/GlobalNvsArea.h>
> +#include <Protocol/FirmwareVolume2.h>
> +#include <Protocol/AcpiTable.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_GLOBAL_NVS_AREA_PROTOCOL
> mGlobalNvsArea;
> +
> +/**
> +@brief
> +  Global NVS initialize.
> +
> +  @param[in] GlobalNvs         - Pointer of Global NVS area
> +
> +  @retval EFI_SUCCESS          - Allocate Global NVS completed.
> +  @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for
> GNVS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiGnvsInit (
> +  IN OUT VOID                   **GlobalNvs
> +  );
> +
> +//
> +// Function implementations
> +//
> +
> +/**
> +  Locate the first instance of a protocol.  If the protocol requested is an
> +  FV protocol, then it will return the first FV that contains the ACPI table
> +  storage file.
> +
> +  @param[in] Protocol           The protocol to find.
> +  @param[in] Instance           Return pointer to the first instance of the
> protocol.
> +  @param[in] Type               TRUE if the desired protocol is a FV protocol.
> +
> +  @retval EFI_SUCCESS           The function completed successfully.
> +  @retval EFI_NOT_FOUND         The protocol could not be located.
> +  @retval EFI_OUT_OF_RESOURCES  There are not enough resources to find
> the protocol.
> +**/
> +EFI_STATUS
> +LocateSupportProtocol (
> +  IN     EFI_GUID                      *Protocol,
> +  IN     EFI_GUID                      *gEfiAcpiMultiTableStorageGuid,
> +     OUT VOID                          **Instance,
> +  IN     BOOLEAN                       Type
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_HANDLE              *HandleBuffer;
> +  UINTN                   NumberOfHandles;
> +  EFI_FV_FILETYPE         FileType;
> +  UINT32                  FvStatus;
> +  EFI_FV_FILE_ATTRIBUTES  Attributes;
> +  UINTN                   Size;
> +  UINTN                   Index;
> +
> +  //
> +  // Locate protocol.
> +  //
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  Protocol,
> +                  NULL,
> +                  &NumberOfHandles,
> +                  &HandleBuffer
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // Defined errors at this time are not found and out of resources.
> +    //
> +    return Status;
> +  }
> +
> +  //
> +  // Looking for FV with ACPI storage file
> +  //
> +  for (Index = 0; Index < NumberOfHandles; Index++) {
> +
> +    //
> +    // Get the protocol on this handle
> +    // This should not fail because of LocateHandleBuffer
> +    //
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer[Index],
> +                    Protocol,
> +                    Instance
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    if (!Type) {
> +
> +      //
> +      // Not looking for the FV protocol, so find the first instance of the
> +      // protocol.  There should not be any errors because our handle buffer
> +      // should always contain at least one or LocateHandleBuffer would have
> +      // returned not found.
> +      //
> +      break;
> +    }
> +    //
> +    // See if it has the ACPI storage file
> +    //
> +    Size      = 0;
> +    FvStatus  = 0;
> +    Status = ((EFI_FIRMWARE_VOLUME2_PROTOCOL *) (*Instance))->ReadFile
> (
> +                                                              *Instance,
> +
> gEfiAcpiMultiTableStorageGuid,
> +                                                              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);
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +PublishAcpiTablesFromFv (
> +  IN EFI_GUID *gEfiAcpiMultiTableStorageGuid
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
> +  EFI_ACPI_COMMON_HEADER        *CurrentTable;
> +  UINT32                        FvStatus;
> +  UINTN                         Size;
> +  UINTN                         TableHandle;
> +  INTN                          Instance;
> +  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
> +
> +  Instance      = 0;
> +  TableHandle   = 0;
> +  CurrentTable  = NULL;
> +  FwVol         = NULL;
> +
> +  //
> +  // Find the AcpiSupport protocol
> +  //
> +  Status = LocateSupportProtocol (
> +            &gEfiAcpiTableProtocolGuid,
> +            gEfiAcpiMultiTableStorageGuid,
> +            (VOID **) &AcpiTable,
> +            FALSE
> +            );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Locate the firmware volume protocol
> +  //
> +  Status = LocateSupportProtocol (
> +            &gEfiFirmwareVolume2ProtocolGuid,
> +            gEfiAcpiMultiTableStorageGuid,
> +            (VOID **) &FwVol,
> +            TRUE
> +            );
> +
> +  //
> +  // Read tables from the storage file.
> +  //
> +
> +  while (Status == EFI_SUCCESS) {
> +    Status = FwVol->ReadSection (
> +                      FwVol,
> +                      gEfiAcpiMultiTableStorageGuid,
> +                      EFI_SECTION_RAW,
> +                      Instance,
> +                      (VOID **) &CurrentTable,
> +                      &Size,
> +                      &FvStatus
> +                      );
> +
> +    if (!EFI_ERROR (Status)) {
> +      //
> +      // Add the table
> +      //
> +      TableHandle = 0;
> +
> +      Status = AcpiTable->InstallAcpiTable (
> +                            AcpiTable,
> +                            CurrentTable,
> +                            CurrentTable->Length,
> +                            &TableHandle
> +                            );
> +
> +
> +      ASSERT_EFI_ERROR (Status);
> +
> +      //
> +      // Increment the instance
> +      //
> +      Instance++;
> +      CurrentTable = NULL;
> +    }
> +  }
> +
> +  //
> +  // Finished
> +  //
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  ACPI Platform driver installation function.
> +
> +  @param[in] ImageHandle     Handle for this drivers loaded image protocol.
> +  @param[in] SystemTable     EFI system table.
> +
> +  @retval EFI_SUCCESS        The driver installed without error.
> +  @retval EFI_ABORTED        The driver encountered an error and could not
> complete installation of
> +                             the ACPI tables.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InstallAcpiBoard (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  EFI_STATUS   Status;
> +  EFI_HANDLE   Handle;
> +
> +  AcpiGnvsInit((VOID **) &mGlobalNvsArea.Area);
> +
> +  //
> +  // This PCD set must be done before PublishAcpiTablesFromFv.
> +  // The PCD data will be used there.
> +  //
> +  PcdSet64S (PcdAcpiGnvsAddress, (UINT64)(UINTN)mGlobalNvsArea.Area);
> +
> +  //
> +  // Platform ACPI Tables
> +  //
> +  PublishAcpiTablesFromFv (&gEfiCallerIdGuid);
> +
> +  //
> +  // This protocol publish must be done after PublishAcpiTablesFromFv.
> +  // The NVS data is be updated there.
> +  //
> +  Handle = NULL;
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &Handle,
> +                  &gEfiGlobalNvsAreaProtocolGuid,
> +                  &mGlobalNvsArea,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.c
> new file mode 100644
> index 0000000000..2b36475c53
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlu
> g.c
> @@ -0,0 +1,353 @@
> +/** @file
> +  Pci Hotplug Driver : This file will perform specific PCI-EXPRESS
> +  Devics resource configuration.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Statements that include other files
> +//
> +#include "PciHotPlug.h"
> +#include <Ppi/SiPolicy.h>
> +#include <TbtBoardInfo.h>
> +#include <Library/PchPcieRpLib.h>
> +#include <Library/TbtCommonLib.h>
> +
> +#define PCIE_NUM  (20)
> +#define PEG_NUM   (3)
> +#define PADDING_BUS (1)
> +#define PADDING_NONPREFETCH_MEM (1)
> +#define PADDING_PREFETCH_MEM (1)
> +#define PADDING_IO (1)
> +#define PADDING_NUM (PADDING_BUS + PADDING_NONPREFETCH_MEM +
> PADDING_PREFETCH_MEM + PADDING_IO)
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_HPC_LOCATION
> mPcieLocation[PCIE_NUM + PEG_NUM];
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINTN mHpcCount = 0;
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED PCIE_HOT_PLUG_DEVICE_PATH
> mHotplugPcieDevicePathTemplate = {
> +  ACPI,
> +  PCI(0xFF, 0xFF), // Dummy Device no & Function no
> +  END
> +};
> +
> +/**
> +  Entry point for the driver.
> +
> +  This routine reads the PlatformType GPI on FWH and produces a protocol
> +  to be consumed by the chipset driver to effect those settings.
> +
> +  @param[in]  ImageHandle    An image handle.
> +  @param[in]  SystemTable    A pointer to the system table.
> +
> +  @retval     EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PciHotPlug (
> +  IN EFI_HANDLE                   ImageHandle,
> +  IN EFI_SYSTEM_TABLE             *SystemTable
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  PCI_HOT_PLUG_INSTANCE            *PciHotPlug;
> +  UINTN                            Index;
> +  UINTN                            RpDev;
> +  UINTN                            RpFunc;
> +  PCIE_HOT_PLUG_DEVICE_PATH       *HotplugPcieDevicePath;
> +  UINT32                           PcieRootPortHpeData = 0;
> +
> +  DEBUG ((DEBUG_INFO, "PciHotPlug Entry\n"));
> +
> +  PcieRootPortHpeData = PcdGet32 (PcdPchPcieRootPortHpe);
> +  //
> +  // PCH Rootports Hotplug device path creation
> +  //
> +  for (Index = 0; Index < PCIE_NUM; Index++) {
> +    if (((PcieRootPortHpeData >> Index) & BIT0) == BIT0) { // Check the
> Rootport no's hotplug is set
> +      Status = GetPchPcieRpDevFun (Index, &RpDev, &RpFunc); // Get the
> actual device/function no corresponding to the Rootport no provided
> +      ASSERT_EFI_ERROR (Status);
> +
> +      HotplugPcieDevicePath = NULL;
> +      HotplugPcieDevicePath = AllocatePool (sizeof
> (PCIE_HOT_PLUG_DEVICE_PATH));
> +      ASSERT (HotplugPcieDevicePath != NULL);
> +      if (HotplugPcieDevicePath == NULL) {
> +        return EFI_OUT_OF_RESOURCES;
> +      }
> +      CopyMem (HotplugPcieDevicePath, &mHotplugPcieDevicePathTemplate,
> sizeof (PCIE_HOT_PLUG_DEVICE_PATH));
> +      HotplugPcieDevicePath->PciRootPortNode.Device = (UINT8) RpDev; //
> Update real Device no
> +      HotplugPcieDevicePath->PciRootPortNode.Function = (UINT8) RpFunc;
> // Update real Function no
> +
> +      mPcieLocation[mHpcCount].HpcDevicePath =
> (EFI_DEVICE_PATH_PROTOCOL *)HotplugPcieDevicePath;
> +      mPcieLocation[mHpcCount].HpbDevicePath =
> (EFI_DEVICE_PATH_PROTOCOL *)HotplugPcieDevicePath;
> +      mHpcCount++;
> +
> +      DEBUG ((DEBUG_INFO, "(%02d) PciHotPlug (PCH RP#) : Bus 0x00, Device
> 0x%x, Function 0x%x is added to the Hotplug Device Path list \n", mHpcCount,
> RpDev, RpFunc));
> +    }
> +  }
> +
> +
> +  PciHotPlug = AllocatePool (sizeof (PCI_HOT_PLUG_INSTANCE));
> +  ASSERT (PciHotPlug != NULL);
> +  if (PciHotPlug == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  //
> +  // Initialize driver private data.
> +  //
> +  ZeroMem (PciHotPlug, sizeof (PCI_HOT_PLUG_INSTANCE));
> +
> +  PciHotPlug->Signature                               =
> PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE;
> +  PciHotPlug->HotPlugInitProtocol.GetRootHpcList      = GetRootHpcList;
> +  PciHotPlug->HotPlugInitProtocol.InitializeRootHpc   = InitializeRootHpc;
> +  PciHotPlug->HotPlugInitProtocol.GetResourcePadding  =
> GetResourcePadding;
> +
> +  Status = gBS->InstallProtocolInterface (
> +                  &PciHotPlug->Handle,
> +                  &gEfiPciHotPlugInitProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &PciHotPlug->HotPlugInitProtocol
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This procedure returns a list of Root Hot Plug controllers that require
> +  initialization during boot process
> +
> +  @param[in]  This      The pointer to the instance of the
> EFI_PCI_HOT_PLUG_INIT protocol.
> +  @param[out] HpcCount  The number of Root HPCs returned.
> +  @param[out] HpcList   The list of Root HPCs. HpcCount defines the number
> of elements in this list.
> +
> +  @retval EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetRootHpcList (
> +  IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL    *This,
> +  OUT UINTN                            *HpcCount,
> +  OUT EFI_HPC_LOCATION                 **HpcList
> +  )
> +{
> +  *HpcCount = mHpcCount;
> +  *HpcList  = mPcieLocation;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This procedure Initializes one Root Hot Plug Controller
> +  This process may casue initialization of its subordinate buses
> +
> +  @param[in]  This            The pointer to the instance of the
> EFI_PCI_HOT_PLUG_INIT protocol.
> +  @param[in]  HpcDevicePath   The Device Path to the HPC that is being
> initialized.
> +  @param[in]  HpcPciAddress   The address of the Hot Plug Controller
> function on the PCI bus.
> +  @param[in]  Event           The event that should be signaled when the Hot
> Plug Controller initialization is complete. Set to NULL if the caller wants to wait
> until the entire initialization process is complete. The event must be of the
> type EFI_EVT_SIGNAL.
> +  @param[out] HpcState        The state of the Hot Plug Controller hardware.
> The type EFI_Hpc_STATE is defined in section 3.1.
> +
> +  @retval   EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeRootHpc (
> +  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL      *This,
> +  IN  EFI_DEVICE_PATH_PROTOCOL            *HpcDevicePath,
> +  IN  UINT64                              HpcPciAddress,
> +  IN  EFI_EVENT                           Event, OPTIONAL
> +  OUT EFI_HPC_STATE                       *HpcState
> +  )
> +{
> +  if (Event) {
> +    gBS->SignalEvent (Event);
> +  }
> +
> +  *HpcState = EFI_HPC_STATE_INITIALIZED;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Returns the resource padding required by the PCI bus that is controlled by
> the specified Hot Plug Controller.
> +
> +  @param[in]  This           The pointer to the instance of the
> EFI_PCI_HOT_PLUG_INIT protocol. initialized.
> +  @param[in]  HpcDevicePath  The Device Path to the Hot Plug Controller.
> +  @param[in]  HpcPciAddress  The address of the Hot Plug Controller
> function on the PCI bus.
> +  @param[out] HpcState       The state of the Hot Plug Controller hardware.
> The type EFI_HPC_STATE is defined in section 3.1.
> +  @param[out] Padding        This is the amount of resource padding
> required by the PCI bus under the control of the specified Hpc. Since the caller
> does not know the size of this buffer, this buffer is allocated by the callee and
> freed by the caller.
> +  @param[out] Attribute      Describes how padding is accounted for.
> +
> +  @retval     EFI_SUCCESS.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetResourcePadding (
> +  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL  *This,
> +  IN  EFI_DEVICE_PATH_PROTOCOL        *HpcDevicePath,
> +  IN  UINT64                          HpcPciAddress,
> +  OUT EFI_HPC_STATE                   *HpcState,
> +  OUT VOID                            **Padding,
> +  OUT EFI_HPC_PADDING_ATTRIBUTES      *Attributes
> +  )
> +{
> +  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *PaddingResource;
> +  EFI_STATUS                        Status;
> +  UINT8                             RsvdExtraBusNum = 0;
> +  UINT16                            RsvdPcieMegaMem = 10;
> +  UINT8                             PcieMemAddrRngMax = 0;
> +  UINT16                            RsvdPciePMegaMem = 10;
> +  UINT8                             PciePMemAddrRngMax = 0;
> +  UINT8                             RsvdTbtExtraBusNum = 0;
> +  UINT16                            RsvdTbtPcieMegaMem = 10;
> +  UINT8                             TbtPcieMemAddrRngMax = 0;
> +  UINT16                            RsvdTbtPciePMegaMem = 10;
> +  UINT8                             TbtPciePMemAddrRngMax = 0;
> +  UINT8                             RsvdPcieKiloIo = 4;
> +  BOOLEAN                           SetResourceforTbt = FALSE;
> +  UINTN                             RpIndex;
> +  UINTN                             RpDev;
> +  UINTN                             RpFunc;
> +
> +DEBUG ((DEBUG_INFO, "GetResourcePadding : Start \n"));
> +
> +  PaddingResource = AllocatePool (PADDING_NUM * sizeof
> (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof
> (EFI_ACPI_END_TAG_DESCRIPTOR));
> +  ASSERT (PaddingResource != NULL);
> +  if (PaddingResource == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  *Padding = (VOID *) PaddingResource;
> +
> +  RpDev = (UINTN) ((HpcPciAddress >> 16) & 0xFF);
> +  RpFunc = (UINTN) ((HpcPciAddress >> 8) & 0xFF);
> +
> +  // Get the actual Rootport no corresponding to the device/function no
> provided
> +  if (RpDev == SA_PEG_DEV_NUM) {
> +    // PEG
> +    RpIndex = PCIE_NUM + RpFunc;
> +    DEBUG ((DEBUG_INFO, "GetResourcePadding : PEG Rootport no %02d Bus
> 0x00, Device 0x%x, Function 0x%x \n", (RpIndex-PCIE_NUM), RpDev, RpFunc));
> +  } else {
> +    // PCH
> +    Status = GetPchPcieRpNumber (RpDev, RpFunc, &RpIndex);
> +    DEBUG ((DEBUG_INFO, "GetResourcePadding : PCH Rootport no %02d Bus
> 0x00, Device 0x%x, Function 0x%x \n", RpIndex, RpDev, RpFunc));
> +  }
> +
> +  GetRootporttoSetResourcesforTbt(RpIndex, &RsvdTbtExtraBusNum,
> &RsvdTbtPcieMegaMem ,&TbtPcieMemAddrRngMax ,&RsvdTbtPciePMegaM
> em ,&TbtPciePMemAddrRngMax, &SetResourceforTbt);
> +    if (SetResourceforTbt) {
> +      RsvdExtraBusNum = RsvdTbtExtraBusNum;
> +      RsvdPcieMegaMem = RsvdTbtPcieMegaMem;
> +      PcieMemAddrRngMax = TbtPcieMemAddrRngMax;
> +      RsvdPciePMegaMem = RsvdTbtPciePMegaMem;
> +      PciePMemAddrRngMax = TbtPciePMemAddrRngMax;
> +    }
> +
> +  //
> +  // Padding for bus
> +  //
> +  ZeroMem (PaddingResource, PADDING_NUM * sizeof
> (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof
> (EFI_ACPI_END_TAG_DESCRIPTOR));
> +  *Attributes                   = EfiPaddingPciBus;
> +
> +  PaddingResource->Desc         = 0x8A;
> +  PaddingResource->Len          = 0x2B;
> +  PaddingResource->ResType      = ACPI_ADDRESS_SPACE_TYPE_BUS;
> +  PaddingResource->GenFlag      = 0x0;
> +  PaddingResource->SpecificFlag = 0;
> +  PaddingResource->AddrRangeMin = 0;
> +  PaddingResource->AddrRangeMax = 0;
> +  PaddingResource->AddrLen      = RsvdExtraBusNum;
> +
> +  //
> +  // Padding for non-prefetchable memory
> +  //
> +  PaddingResource++;
> +  PaddingResource->Desc                 = 0x8A;
> +  PaddingResource->Len                  = 0x2B;
> +  PaddingResource->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
> +  PaddingResource->GenFlag              = 0x0;
> +    if (SetResourceforTbt) {
> +    PaddingResource->AddrSpaceGranularity = 32;
> +  } else {
> +    PaddingResource->AddrSpaceGranularity = 32;
> +  }
> +  PaddingResource->SpecificFlag         = 0;
> +  //
> +  // Pad non-prefetchable
> +  //
> +  PaddingResource->AddrRangeMin = 0;
> +  PaddingResource->AddrLen      = RsvdPcieMegaMem * 0x100000;
> +  if (SetResourceforTbt) {
> +    PaddingResource->AddrRangeMax = (1 << PcieMemAddrRngMax) - 1;
> +  } else {
> +    PaddingResource->AddrRangeMax = 1;
> +  }
> +
> +  //
> +  // Padding for prefetchable memory
> +  //
> +  PaddingResource++;
> +  PaddingResource->Desc                 = 0x8A;
> +  PaddingResource->Len                  = 0x2B;
> +  PaddingResource->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
> +  PaddingResource->GenFlag              = 0x0;
> +    if (SetResourceforTbt) {
> +    PaddingResource->AddrSpaceGranularity = 32;
> +  } else {
> +    PaddingResource->AddrSpaceGranularity = 32;
> +  }
> +  PaddingResource->SpecificFlag         = 06;
> +  //
> +  // Padding for prefetchable memory
> +  //
> +  PaddingResource->AddrRangeMin = 0;
> +  if (SetResourceforTbt) {
> +    PaddingResource->AddrLen      = RsvdPciePMegaMem * 0x100000;
> +  } else {
> +    PaddingResource->AddrLen      = RsvdPcieMegaMem * 0x100000;
> +  }
> +  //
> +  // Pad 16 MB of MEM
> +  //
> +  if (SetResourceforTbt) {
> +    PaddingResource->AddrRangeMax = (1 << PciePMemAddrRngMax) - 1;
> +  } else {
> +    PaddingResource->AddrRangeMax = 1;
> +  }
> +  //
> +  // Alignment
> +  //
> +  // Padding for I/O
> +  //
> +  PaddingResource++;
> +  PaddingResource->Desc         = 0x8A;
> +  PaddingResource->Len          = 0x2B;
> +  PaddingResource->ResType      = ACPI_ADDRESS_SPACE_TYPE_IO;
> +  PaddingResource->GenFlag      = 0x0;
> +  PaddingResource->SpecificFlag = 0;
> +  PaddingResource->AddrRangeMin = 0;
> +  PaddingResource->AddrLen      = RsvdPcieKiloIo * 0x400;
> +  //
> +  // Pad 4K of IO
> +  //
> +  PaddingResource->AddrRangeMax = 1;
> +  //
> +  // Alignment
> +  //
> +  // Terminate the entries.
> +  //
> +  PaddingResource++;
> +  ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Desc     =
> ACPI_END_TAG_DESCRIPTOR;
> +  ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Checksum = 0x0;
> +
> +  *HpcState = EFI_HPC_STATE_INITIALIZED | EFI_HPC_STATE_ENABLED;
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtD
> xe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtD
> xe.c
> new file mode 100644
> index 0000000000..c670f23320
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtD
> xe.c
> @@ -0,0 +1,228 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/TbtCommonLib.h>
> +#include <Library/DxeTbtPolicyLib.h>
> +#include <TbtBoardInfo.h>
> +#include <Protocol/DxeTbtPolicy.h>
> +#include <Protocol/TbtNvsArea.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Uefi/UefiSpec.h>
> +#include <Library/PcdLib.h>
> +#include <Library/AslUpdateLib.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED TBT_NVS_AREA_PROTOCOL
> mTbtNvsAreaProtocol;
> +GLOBAL_REMOVE_IF_UNREFERENCED TBT_INFO_HOB
> *gTbtInfoHob = NULL;
> +
> +/**
> +  TBT NVS Area Initialize
> +
> +**/
> +
> +VOID
> +TbtNvsAreaInit (
> +  IN  VOID              **mTbtNvsAreaPtr
> +  )
> +{
> +  UINTN                         Pages;
> +  EFI_PHYSICAL_ADDRESS          Address;
> +  EFI_STATUS                    Status;
> +  TBT_NVS_AREA_PROTOCOL         *TbtNvsAreaProtocol;
> +  DXE_TBT_POLICY_PROTOCOL       *DxeTbtConfig;
> +
> +  DEBUG ((DEBUG_INFO, "TbtNvsAreaInit Start\n"));
> +  Status = gBS->LocateProtocol (
> +              &gDxeTbtPolicyProtocolGuid,
> +              NULL,
> +              (VOID **) &DxeTbtConfig
> +              );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Pages = EFI_SIZE_TO_PAGES (sizeof (TBT_NVS_AREA));
> +  Address = 0xffffffff; // allocate address below 4G.
> +
> +  Status  = gBS->AllocatePages (
> +                   AllocateMaxAddress,
> +                   EfiACPIMemoryNVS,
> +                   Pages,
> +                   &Address
> +                   );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  *mTbtNvsAreaPtr = (VOID *) (UINTN) Address;
> +  SetMem (*mTbtNvsAreaPtr, sizeof (TBT_NVS_AREA), 0);
> +
> +  //
> +  // TBTNvsAreaProtocol default value init here
> +  //
> +  TbtNvsAreaProtocol = (TBT_NVS_AREA_PROTOCOL *) &Address;
> +
> +  //
> +  // Initialize default values
> +  //
> +  TbtNvsAreaProtocol->Area->WAKFinished             = 0;
> +  TbtNvsAreaProtocol->Area->DiscreteTbtSupport      = ((gTbtInfoHob->
> DTbtControllerConfig.DTbtControllerEn == 1 ) ? TRUE : FALSE);
> +  TbtNvsAreaProtocol->Area->TbtAcpiRemovalSupport   = 0;
> +  TbtNvsAreaProtocol->Area->TbtGpioFilter           = (UINT8)
> DxeTbtConfig->TbtCommonConfig.Gpio5Filter;
> +//  TbtNvsAreaProtocol->Area->TrOsup                  = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TrA0OsupWa;
> +  TbtNvsAreaProtocol->Area->TbtFrcPwrEn             =
> gTbtInfoHob->DTbtCommonConfig.Gpio3ForcePwr;
> +  TbtNvsAreaProtocol->Area->TbtAspm                 = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtAspm;
> +//  TbtNvsAreaProtocol->Area->TbtL1SubStates          = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtL1SubStates;
> +  TbtNvsAreaProtocol->Area->TbtSetClkReq            = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtSetClkReq;
> +  TbtNvsAreaProtocol->Area->TbtLtr                  = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtLtr;
> +//  TbtNvsAreaProtocol->Area->TbtPtm                  = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtPtm;
> +  TbtNvsAreaProtocol->Area->TbtWakeupSupport        = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport;
> +  TbtNvsAreaProtocol->Area->TbtAcDcSwitch           = (UINT8)
> DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch;
> +  TbtNvsAreaProtocol->Area->Rtd3TbtSupport          = (UINT8)
> DxeTbtConfig->TbtCommonConfig.Rtd3Tbt;             // TBT RTD3 Enable.
> +  TbtNvsAreaProtocol->Area->Rtd3TbtOffDelay         = (UINT16)
> DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay;    // TBT RTD3 Off delay
> in ms.
> +  TbtNvsAreaProtocol->Area->Rtd3TbtClkReq           = (UINT8)
> DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq;       // TBT RTD3 ClkReq
> Mask Enable.
> +  TbtNvsAreaProtocol->Area->Rtd3TbtClkReqDelay      = (UINT16)
> DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay; // TBT RTD3 ClkReq
> mask delay in ms.
> +  TbtNvsAreaProtocol->Area->TbtWin10Support         = (UINT8)
> DxeTbtConfig->TbtCommonConfig.Win10Support; // TBT FW Execution Mode
> +
> +  //
> +  // DTBT Controller 1
> +  //
> +  TbtNvsAreaProtocol->Area->DTbtControllerEn0       = gTbtInfoHob->
> DTbtControllerConfig.DTbtControllerEn;
> +  TbtNvsAreaProtocol->Area->RootportSelected0       = gTbtInfoHob->
> DTbtControllerConfig.PcieRpNumber;
> +  TbtNvsAreaProtocol->Area->RootportSelected0Type   = gTbtInfoHob->
> DTbtControllerConfig.Type;
> +  TbtNvsAreaProtocol->Area->RootportEnabled0        = gTbtInfoHob->
> DTbtControllerConfig.DTbtControllerEn;
> +  TbtNvsAreaProtocol->Area->TbtFrcPwrGpioNo0        = gTbtInfoHob->
> DTbtControllerConfig.ForcePwrGpio.GpioPad;
> +  TbtNvsAreaProtocol->Area->TbtFrcPwrGpioLevel0     = gTbtInfoHob->
> DTbtControllerConfig.ForcePwrGpio.GpioLevel;
> +  TbtNvsAreaProtocol->Area->TbtCioPlugEventGpioNo0  = gTbtInfoHob->
> DTbtControllerConfig.CioPlugEventGpio.GpioPad;
> +  TbtNvsAreaProtocol->Area->TbtPcieRstGpioNo0       = gTbtInfoHob->
> DTbtControllerConfig.PcieRstGpio.GpioPad;
> +  TbtNvsAreaProtocol->Area->TbtPcieRstGpioLevel0    = gTbtInfoHob->
> DTbtControllerConfig.PcieRstGpio.GpioLevel;
> +
> +  TbtNvsAreaProtocol->Area->TBtCommonGpioSupport    =
> gTbtInfoHob->DTbtCommonConfig.DTbtSharedGpioConfiguration;
> +
> +  DEBUG ((DEBUG_INFO, "TbtNvsAreaInit End\n"));
> +}
> +
> +/**
> +  This function gets registered as a callback to patch TBT ASL code
> +
> +  @param[in] Event     - A pointer to the Event that triggered the callback.
> +  @param[in] Context   - A pointer to private data registered with the
> callback function.
> +  can we put this also in read me
> +**/
> +VOID
> +EFIAPI
> +TbtAcpiEndOfDxeCallback (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  )
> +{
> +  EFI_STATUS                            Status;
> +  UINT32                                Address;
> +  UINT16                                Length;
> +  UINT32                                Signature;
> +
> +  Status = InitializeAslUpdateLib ();
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Address = (UINT32) (UINTN) mTbtNvsAreaProtocol.Area;
> +  Length  = (UINT16) sizeof (TBT_NVS_AREA);
> +  DEBUG ((DEBUG_INFO, "Patch TBT NvsAreaAddress: TBT NVS Address %x
> Length %x\n", Address, Length));
> +  Status  = UpdateNameAslCode (SIGNATURE_32 ('T','N','V','B'), &Address,
> sizeof (Address));
> +  ASSERT_EFI_ERROR (Status);
> +  Status  = UpdateNameAslCode (SIGNATURE_32 ('T','N','V','L'), &Length,
> sizeof (Length));
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (gTbtInfoHob != NULL) {
> +    if (gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn == 1) {
> +      if (gTbtInfoHob->
> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting == TRUE) {
> +        DEBUG ((DEBUG_INFO, "Patch ATBT Method Name\n"));
> +        Signature = gTbtInfoHob->
> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature;
> +        Status  = UpdateNameAslCode (SIGNATURE_32 ('A','T','B','T'),
> &Signature, sizeof (Signature));
> +        ASSERT_EFI_ERROR (Status);
> +      }
> +    }
> +  }
> +
> +  return;
> +}
> +
> +/**
> +  Initialize Thunderbolt(TM) SSDT ACPI tables
> +
> +  @retval EFI_SUCCESS    ACPI tables are initialized successfully
> +  @retval EFI_NOT_FOUND  ACPI tables not found
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +TbtDxeEntryPoint (
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_HANDLE              Handle;
> + // EFI_EVENT               EndOfDxeEvent;
> +
> +  DEBUG ((DEBUG_INFO, "TbtDxeEntryPoint \n"));
> +
> +  //
> +  // Get TBT INFO HOB
> +  //
> +  gTbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
> +  if (gTbtInfoHob == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +  InstallTbtPolicy (ImageHandle);
> +  //
> +  // Update DXE TBT Policy
> +  //
> +  UpdateTbtPolicyCallback ();
> +
> +  //
> +  // Print DXE TBT Policy
> +  //
> +  TbtPrintDxePolicyConfig ();
> +
> +  //
> +  // Initialize Tbt Nvs Area
> +  //
> +  TbtNvsAreaInit ((VOID **) &mTbtNvsAreaProtocol.Area);
> +
> +
> +  //
> +  // [ACPI] Thunderbolt ACPI table
> +  //
> +
> +
> +  Handle = NULL;
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &Handle,
> +                  &gTbtNvsAreaProtocolGuid,
> +                  &mTbtNvsAreaProtocol,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Register an end of DXE event for TBT ACPI to do some patch can be put as
> description
> +  //
> +  /**
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  TbtAcpiEndOfDxeCallback,
> +                  NULL,
> +                  &gEfiEndOfDxeEventGroupGuid,
> +                  &EndOfDxeEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +**/
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb
> tInit.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb
> tInit.c
> new file mode 100644
> index 0000000000..bdd8de0cfd
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb
> tInit.c
> @@ -0,0 +1,211 @@
> +/** @file
> +  Source code file for TBT Init PEI module
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/IoLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/PeiTbtPolicyLib.h>
> +#include <Ppi/SiPolicy.h>
> +#include <Ppi/PeiTbtPolicy.h>
> +#include <Ppi/EndOfPeiPhase.h>
> +#include <TbtBoardInfo.h>
> +#include <Private/Library/PeiDTbtInitLib.h>
> +/*
> +/**
> +  This function Update and Print PEI TBT Policy after TbtPolicyBoardInitDone
> +
> +  @param[in]  PeiServices  Pointer to PEI Services Table.
> +  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification
> event that
> +                           caused this function to execute.
> +  @param[in]  Ppi          Pointer to the PPI data associated with this
> function.
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     others
> +**/
> +
> +
> +/**
> +  This function pass PEI TBT Policy to Hob at the end of PEI
> +
> +  @param[in]  PeiServices  Pointer to PEI Services Table.
> +  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification
> event that
> +                           caused this function to execute.
> +  @param[in]  Ppi          Pointer to the PPI data associated with this
> function.
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     others
> +**/
> +
> +
> +EFI_STATUS
> +EFIAPI
> +PassTbtPolicyToHob (
> +VOID
> +  )
> +{
> +  EFI_STATUS            Status;
> +  EFI_BOOT_MODE         BootMode;
> +  TBT_INFO_HOB          *TbtInfoHob;
> +  PEI_TBT_POLICY        *PeiTbtConfig;
> +
> +  DEBUG ((DEBUG_INFO, "PassTbtPolicyToHob\n"));
> +
> +  Status = PeiServicesGetBootMode (&BootMode);
> +  ASSERT_EFI_ERROR (Status);
> +  if (BootMode == BOOT_ON_S3_RESUME ) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = PeiServicesLocatePpi (
> +             &gPeiTbtPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &PeiTbtConfig
> +             );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
> +  }
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Create HOB for TBT Data
> +  //
> +  Status = PeiServicesCreateHob (
> +             EFI_HOB_TYPE_GUID_EXTENSION,
> +             sizeof (TBT_INFO_HOB),
> +             (VOID **) &TbtInfoHob
> +             );
> +  DEBUG ((DEBUG_INFO, "TbtInfoHob Created \n"));
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Initialize the TBT INFO HOB data.
> +  //
> +  TbtInfoHob->EfiHobGuidType.Name = gTbtInfoHobGuid;
> +
> +  //
> +  // Update DTBT Policy
> +  //
> +  TbtInfoHob-> DTbtControllerConfig.DTbtControllerEn = PeiTbtConfig->
> DTbtControllerConfig.DTbtControllerEn;
> +  TbtInfoHob-> DTbtControllerConfig.Type = PeiTbtConfig->
> DTbtControllerConfig.Type;
> +  TbtInfoHob-> DTbtControllerConfig.PcieRpNumber = PeiTbtConfig->
> DTbtControllerConfig.PcieRpNumber;
> +  TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioPad =
> PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad;
> +  TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioLevel =
> PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel;
> +  TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.GpioPad =
> PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.GpioPad;
> +  TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature =
> PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature;
> +  TbtInfoHob->
> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting =
> PeiTbtConfig->
> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting;
> +  TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioPad = PeiTbtConfig->
> DTbtControllerConfig.PcieRstGpio.GpioPad;
> +  TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioLevel =
> PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioLevel;
> +
> +  TbtInfoHob->DTbtCommonConfig.TbtBootOn =
> PeiTbtConfig->DTbtCommonConfig.TbtBootOn;
> +  TbtInfoHob->DTbtCommonConfig.TbtUsbOn =
> PeiTbtConfig->DTbtCommonConfig.TbtUsbOn;
> +  TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwr =
> PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr;
> +  TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwrDly =
> PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly;
> +  TbtInfoHob->DTbtCommonConfig.DTbtSharedGpioConfiguration =
> PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration;
> +  TbtInfoHob->DTbtCommonConfig.PcieRstSupport =
> PeiTbtConfig->DTbtCommonConfig.PcieRstSupport;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This function handles TbtInit task at the end of PEI
> +
> +  @param[in]  PeiServices  Pointer to PEI Services Table.
> +  @param[in]  NotifyDesc   Pointer to the descriptor for the Notification
> event that
> +                           caused this function to execute.
> +  @param[in]  Ppi          Pointer to the PPI data associated with this
> function.
> +
> +  @retval     EFI_SUCCESS  The function completes successfully
> +  @retval     others
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +TbtInitEndOfPei (
> +  VOID
> +  )
> +{
> +  EFI_STATUS      Status;
> +  BOOLEAN         DTbtExisted;
> +  PEI_TBT_POLICY  *PeiTbtConfig;
> +
> +  DEBUG ((DEBUG_INFO, "TbtInitEndOfPei Entry\n"));
> +
> +  Status       = EFI_SUCCESS;
> +  PeiTbtConfig = NULL;
> +  DTbtExisted  = FALSE;
> +
> +  Status = PeiServicesLocatePpi (
> +             &gPeiTbtPolicyPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **) &PeiTbtConfig
> +             );
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
> +  }
> +  ASSERT_EFI_ERROR (Status);
> +
> +    if (PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn == 1) {
> +      DTbtExisted = TRUE;
> +  }
> +
> +  if (DTbtExisted == TRUE) {
> +    //
> +    // Call Init function
> +    //
> +   Status = TbtInit ();
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  TBT Init PEI module entry point
> +
> +  @param[in]  FileHandle           Not used.
> +  @param[in]  PeiServices          General purpose services available to every
> PEIM.
> +
> +  @retval     EFI_SUCCESS          The function completes successfully
> +  @retval     EFI_OUT_OF_RESOURCES Insufficient resources to create
> database
> +**/
> +EFI_STATUS
> +EFIAPI
> +TbtInitEntryPoint (
> +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +{
> +  EFI_STATUS     Status;
> +
> +  DEBUG ((DEBUG_INFO, "TBT PEI EntryPoint\n"));
> +
> +  //
> +  // Install PEI TBT Policy
> +  //
> +  Status = InstallPeiTbtPolicy ();
> +  ASSERT_EFI_ERROR (Status);
> +
> +
> +  UpdatePeiTbtPolicy ();
> +
> +  TbtPrintPeiPolicyConfig ();
> +  //
> +  // Performing PassTbtPolicyToHob and TbtInitEndOfPei
> +  //
> +  Status = PassTbtPolicyToHob ();
> +
> +  Status = TbtInitEndOfPei ();
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> SmiHandler.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> SmiHandler.c
> new file mode 100644
> index 0000000000..a6bdc6ef9f
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> SmiHandler.c
> @@ -0,0 +1,1609 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "TbtSmiHandler.h"
> +#include <Library/IoLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Protocol/SmmVariable.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/SmmServicesTableLib.h>
> +#include <Library/PciSegmentLib.h>
> +#define MEM_PER_SLOT  (DEF_RES_MEM_PER_DEV << 4)
> +#define PMEM_PER_SLOT (DEF_RES_PMEM_PER_DEV << 4)
> +#define IO_PER_SLOT   (DEF_RES_IO_PER_DEV << 2)
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINTN
> gDeviceBaseAddress;
> +//
> +//US(X:0:0), DS(X+1:3:0),DS(X+1:4:0),DS(X+1:5:0),DS(X+1:6:0)
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED BRDG_CONFIG
> HrConfigs[MAX_CFG_PORTS];
> +
> +extern UINT8                      gCurrentDiscreteTbtRootPort;
> +extern UINT8                      gCurrentDiscreteTbtRootPortType;
> +
> +BOOLEAN isLegacyDevice          = FALSE;
> +STATIC UINT8 TbtSegment         = 0;
> +
> +STATIC
> +VOID
> +PortInfoInit (
> +  IN  OUT PORT_INFO *PortInfo
> +  )
> +{
> +  PortInfo->BusNumLimit = 4;
> +}
> +
> +STATIC
> +VOID
> +UnsetVesc (
> +  IN       UINT8     Bus,
> +  IN       UINT8     Dev,
> +  IN       UINT8     Fun
> +  )
> +{
> +  UINT8 Dbus;
> +  UINT32 Data32;
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +
> +  //
> +  // Check for abcence of DS bridge
> +  //
> +  if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET)) {
> +    return;
> +  }
> +
> +  //
> +  // Unset vesc_reg2[23] bit (to have an option to access below DS)
> +  //
> +  Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
> +  Data32 &= 0xFF7FFFFF;
> +  PciSegmentWrite32(gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
> +  //
> +  // Go to Device behind DS
> +  //
> +  Dbus = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  DEBUG((DEBUG_INFO, "Dbus = %d\n",Dbus));
> +  //
> +  // Check if there is something behind this Downstream Port (Up or Ep)
> +  // If there nothing  behind Downstream Port Set vesc_reg2[23] bit -> this
> will flush all future MemWr
> +  //
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Dbus,
> 0x00, 0x00, 0);
> +  if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET))
> +  {
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +  Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
> +  Data32 |= 0x00800000;
> +  PciSegmentWrite32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
> +  }
> +}// Unset_VESC_REG2
> +
> +STATIC
> +UINT16
> +MemPerSlot (
> +  IN    UINT16 CurrentUsage
> +  )
> +{
> +  if (CurrentUsage == 0) {
> +    return 0;
> +  }
> +
> +  if (CurrentUsage <= 16) {
> +    return 16;
> +  }
> +
> +  if (CurrentUsage <= 64) {
> +    return 64;
> +  }
> +
> +  if (CurrentUsage <= 128) {
> +    return 128;
> +  }
> +
> +  if (CurrentUsage <= 256) {
> +    return 256;
> +  }
> +
> +  if (CurrentUsage <= 512) {
> +    return 512;
> +  }
> +
> +  if (CurrentUsage <= 1024) {
> +    return 1024;
> +  }
> +
> +  return CurrentUsage;
> +} // MemPerSlot
> +
> +STATIC
> +UINT64
> +PMemPerSlot (
> +  IN    UINT64 CurrentUsage
> +  )
> +{
> +  if (CurrentUsage == 0) {
> +    return 0;
> +  }
> +
> +  if (CurrentUsage <= 1024ULL) {
> +    return 1024ULL;
> +  }
> +
> +  if (CurrentUsage <= 4096ULL) {
> +    return 4096ULL;
> +  }
> +
> +  return CurrentUsage;
> +} // PMemPerSlot
> +
> +STATIC
> +VOID
> +SetPhyPortResources (
> +  IN       UINT8      Bus,
> +  IN       UINT8      Dev,
> +  IN       UINT8      SubBus,
> +  IN       INT8       Depth,
> +  IN       PORT_INFO  *CurrentPi,
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  UINT8   Cmd;
> +  UINT16  DeltaMem;
> +  UINT64  DeltaPMem;
> +
> +  Cmd               = CMD_BUS_MASTER;
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> 0x00, 0);
> +
> +  PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
> +
> +  DeltaMem = PortInfo->MemBase - CurrentPi->MemBase;
> +  if (isLegacyDevice) {
> +    if (Depth >= 0 && (DeltaMem < MEM_PER_SLOT)) {
> +      PortInfo->MemBase += MEM_PER_SLOT - DeltaMem;
> +    }
> +  } else {
> +    if (DeltaMem < MemPerSlot (DeltaMem)) {
> +      PortInfo->MemBase += MemPerSlot (DeltaMem) - DeltaMem;
> +    }
> +  }
> +
> +  if (PortInfo->MemBase > CurrentPi->MemBase && (PortInfo->MemBase -
> 0x10) <= PortInfo->MemLimit) {
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase), CurrentPi->MemBase);
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryLimit), PortInfo->MemBase - 0x10);
> +    Cmd |= CMD_BM_MEM;
> +  } else {
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase), DISBL_MEM32_REG20);
> +    PortInfo->MemBase = CurrentPi->MemBase;
> +  }
> +
> +  DeltaPMem = PortInfo->PMemBase64 - CurrentPi->PMemBase64;
> +  if (isLegacyDevice) {
> +    if ((Depth >= 0) && ((UINTN)DeltaPMem < (UINTN)PMEM_PER_SLOT)) {
> +      PortInfo->PMemBase64 += PMEM_PER_SLOT - DeltaPMem;
> +    }
> +  } else {
> +    if (DeltaPMem < PMemPerSlot (DeltaPMem)) {
> +      PortInfo->PMemBase64 += PMemPerSlot (DeltaPMem) - DeltaPMem;
> +    }
> +  }
> +
> +  if (PortInfo->PMemBase64 > CurrentPi->PMemBase64 &&
> (PortInfo->PMemBase64 - 0x10) <= PortInfo->PMemLimit64) {
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryBase), (UINT16) (CurrentPi->PMemBase64 &
> 0xFFFF));
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryLimit), (UINT16) ((PortInfo->PMemBase64 - 0x10)
> & 0xFFFF));
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32), (UINT32) (CurrentPi->PMemBase64 >> 16));
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32), (UINT32) ((PortInfo->PMemBase64 - 0x10)
> >> 16));
> +    Cmd |= CMD_BM_MEM;
> +  } else {
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32), 0);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32), 0);
> +    PortInfo->PMemBase64 = CurrentPi->PMemBase64;
> +  }
> +
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET,
> DEF_CACHE_LINE_SIZE);
> +} // SetPhyPortResources
> +
> +STATIC
> +UINT32
> +SaveSetGetRestoreBar (
> +  IN  UINTN  Bar
> +  )
> +{
> +  UINT32  BarReq;
> +  UINT32  OrigBar;
> +
> +  OrigBar = PciSegmentRead32(Bar);     // Save BAR
> +  PciSegmentWrite32(Bar, 0xFFFFFFFF);  // Set BAR
> +  BarReq = PciSegmentRead32(Bar);      // Get BAR
> +  PciSegmentWrite32(Bar, OrigBar);     // Restore BAR
> +
> +  return BarReq;
> +} // SaveSetGetRestoreBar
> +
> +STATIC
> +VOID
> +SetIoBar (
> +  IN            UINTN    BAR,
> +  IN            UINT32   BarReq,
> +  IN  OUT       UINT8    *Cmd,
> +  IN  OUT       IO_REGS  *IoReg
> +  )
> +{
> +  UINT16  Alignment;
> +  UINT16  Size;
> +  UINT16  NewBase;
> +
> +  Alignment = ~(BarReq & 0xFFFC);
> +  Size      = Alignment + 1;
> +
> +  if (IoReg->Base > IoReg->Limit || !Size) {
> +    return ;
> +
> +  }
> +
> +  NewBase = BAR_ALIGN (IoReg->Base, Alignment);
> +  if (NewBase > IoReg->Limit || NewBase + Size - 1 > IoReg->Limit) {
> +    return ;
> +
> +  }
> +  PciSegmentWrite16(BAR, NewBase);
> +  IoReg->Base = NewBase + Size; // Advance to new position
> +  *Cmd      |= CMD_BM_IO; // Set Io Space Enable
> +} // SetIoBar
> +
> +STATIC
> +VOID
> +SetMemBar (
> +  IN            UINTN     BAR,
> +  IN            UINT32    BarReq,
> +  IN  OUT       UINT8     *Cmd,
> +  IN  OUT       MEM_REGS  *MemReg
> +  )
> +{
> +  UINT32  Alignment;
> +  UINT32  Size;
> +  UINT32  NewBase;
> +
> +  Alignment = ~(BarReq & 0xFFFFFFF0);
> +  Size      = Alignment + 1;
> +
> +  if (MemReg->Base > MemReg->Limit || !Size) {
> +    return ;
> +
> +  }
> +
> +  NewBase = BAR_ALIGN (MemReg->Base, Alignment);
> +  if (NewBase > MemReg->Limit || NewBase + Size - 1 > MemReg->Limit) {
> +    return ;
> +
> +  }
> +
> +  PciSegmentWrite32(BAR, NewBase);
> +  MemReg->Base = NewBase + Size; // Advance to new position
> +  *Cmd       |= CMD_BM_MEM; // Set Memory Space Enable
> +} // SetMemBar
> +
> +STATIC
> +VOID
> +SetPMem64Bar (
> +  IN              UINTN      BAR,
> +  IN              BOOLEAN    IsMaxBar,
> +  IN              UINT32     BarReq,
> +  IN    OUT       UINT8      *Cmd,
> +  IN    OUT       PMEM_REGS  *MemReg
> +  )
> +{
> +  UINT32  Alignment;
> +  UINT32  Size;
> +  UINT64  NewBase;
> +
> +  Alignment = ~(BarReq & 0xFFFFFFF0);
> +  Size      = Alignment + 1;
> +
> +  if (MemReg->Base64 > MemReg->Limit64 || !Size) {
> +    return ;
> +  }
> +
> +  NewBase = BAR_ALIGN (MemReg->Base64, Alignment);
> +  if (NewBase > MemReg->Limit64 || NewBase + Size - 1 > MemReg->Limit64)
> {
> +    return ;
> +  }
> +  PciSegmentWrite32(BAR, (UINT32)(NewBase & 0xFFFFFFFF));
> +  if (!IsMaxBar) {
> +    BAR++;
> +    PciSegmentWrite32(BAR, (UINT32)(NewBase >> 32));
> +  }
> +  MemReg->Base64 = NewBase + Size; // Advance to new position
> +  *Cmd         |= CMD_BM_MEM; // Set Memory Space Enable
> +} // SetPMem64Bar
> +
> +STATIC
> +VOID
> +SetDevResources (
> +  IN       UINT8      Bus,
> +  IN       UINT8      Dev,
> +  IN       UINT8      MaxFun,  // PCI_MAX_FUNC for devices, 1 for bridge
> +  IN       UINT8      MaxBar,     // PCI_BAR5 for devices, PCI_BAR1 for bridge
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  UINT8     Fun;
> +  UINT8     Reg;
> +  UINT32    BarReq;
> +  IO_REGS   Io;
> +  MEM_REGS  Mem;
> +  PMEM_REGS PMem;
> +  UINT8     Cmd;
> +
> +  Io.Base       = PortInfo->IoBase << 8;
> +  Io.Limit      = (PortInfo->IoLimit << 8) | 0xFF;
> +  Mem.Base      = PortInfo->MemBase << 16;
> +  Mem.Limit     = (PortInfo->MemLimit << 16) | 0xFFFF;
> +  PMem.Base64   = PortInfo->PMemBase64 << 16;
> +  PMem.Limit64  = (PortInfo->PMemLimit64 << 16) | 0xFFFF;
> +
> +  for (Fun = 0; Fun < MaxFun; ++Fun) {
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> CMD_BUS_MASTER);
> +    Cmd = PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET);
> +    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET)) {
> +      continue;
> +
> +    }
> +
> +    for (Reg = PCI_BASE_ADDRESSREG_OFFSET; Reg <= MaxBar; Reg += 4) {
> +      BarReq = SaveSetGetRestoreBar(gDeviceBaseAddress + Reg); // Perform
> BAR sizing
> +
> +      if (BarReq & BIT0) {
> +        //
> +        // I/O BAR
> +        //
> +        SetIoBar (
> +         (gDeviceBaseAddress + Reg),
> +          BarReq,
> +          &Cmd,
> +          &Io
> +          );
> +        continue;
> +      }
> +
> +      if (BarReq & BIT3) {
> +        //
> +        // P-Memory BAR
> +        //
> +        SetPMem64Bar ((gDeviceBaseAddress + Reg), MaxBar == Reg, BarReq,
> &Cmd, &PMem);
> +      } else {
> +        SetMemBar ((gDeviceBaseAddress + Reg), BarReq, &Cmd, &Mem);
> +      }
> +
> +      if (BIT2 == (BarReq & (BIT2 | BIT1))) {
> +        //
> +        // Base address is 64 bits wide
> +        //
> +        Reg += 4;
> +        if (!(BarReq & BIT3)) {
> +          //
> +          // 64-bit memory bar
> +          //
> +          PciSegmentWrite32 (gDeviceBaseAddress + Reg, 0);
> +        }
> +      }
> +    }
> +
> +    if (Cmd & BIT1) {
> +      //
> +      // If device uses I/O and MEM mapping use only MEM mepping
> +      //
> +      Cmd &= ~BIT0;
> +    }
> +
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET,
> DEF_CACHE_LINE_SIZE);
> +  }
> +  //
> +  // Update PortInfo if any changes
> +  //
> +  if (Io.Base > ((UINT32) PortInfo->IoBase << 8)) {
> +    PortInfo->IoBase = (UINT8) (BAR_ALIGN (Io.Base, 0xFFF) >> 8);
> +  }
> +
> +  if (Mem.Base > ((UINT32) PortInfo->MemBase << 16)) {
> +    PortInfo->MemBase = (UINT16) (BAR_ALIGN (Mem.Base, 0xFFFFF) >> 16);
> +  }
> +
> +  if (PMem.Base64 > (PortInfo->PMemBase64 << 16)) {
> +    PortInfo->PMemBase64 = (BAR_ALIGN (PMem.Base64, 0xFFFFF) >> 16);
> +  }
> +} // SetDevResources
> +
> +STATIC
> +VOID
> +InitARHRConfigs(
> +  IN HR_CONFIG *Hr_Config,
> +  IN UINT8 BusNumLimit,
> +  IN OUT BRDG_RES_CONFIG* HrResConf
> +)
> +{
> +  UINT8 i,j;
> +
> +  //
> +  // DS port for USB device
> +  //
> +  HrConfigs[AR_DS_PORT2].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus +
> 1;
> +  HrConfigs[AR_DS_PORT2].DevId.Dev = 2;
> +  HrConfigs[AR_DS_PORT2].DevId.Fun = 0;
> +  HrConfigs[AR_DS_PORT2].PBus = HrConfigs[AR_DS_PORT2].DevId.Bus;
> +  HrConfigs[AR_DS_PORT2].SBus = HrConfigs[AR_DS_PORT2].PBus + 1;
> +  HrConfigs[AR_DS_PORT2].SubBus = HrConfigs[AR_DS_PORT2].PBus + 1;
> +  //
> +  // CIO port
> +  //
> +  HrConfigs[AR_DS_PORT1].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus +
> 1;
> +  HrConfigs[AR_DS_PORT1].DevId.Dev = 1;
> +  HrConfigs[AR_DS_PORT1].DevId.Fun = 0;
> +  HrConfigs[AR_DS_PORT1].PBus = HrConfigs[AR_DS_PORT1].DevId.Bus;
> +  HrConfigs[AR_DS_PORT1].SBus = HrConfigs[HR_DS_PORT0].SubBus + 1;
> +  HrConfigs[AR_DS_PORT1].SubBus = BusNumLimit;
> +
> +  switch(Hr_Config->DeviceId)
> +  {
> +    //
> +    // HR with 1 DS and 1 USB
> +    //
> +    case AR_HR_2C:
> +    case AR_HR_LP:
> +    case AR_HR_C0_2C:
> +    case TR_HR_2C:
> +      Hr_Config->MinDSNumber = HrConfigs[AR_DS_PORT1].DevId.Dev;
> +      Hr_Config->MaxDSNumber = HrConfigs[AR_DS_PORT2].DevId.Dev;
> +      Hr_Config->BridgeLoops = 4;
> +      break;
> +    //
> +    // HR with 2 DS and 1 USB
> +    //
> +    case AR_HR_4C:
> +    case TR_HR_4C:
> +    case AR_HR_C0_4C:
> +      Hr_Config->MinDSNumber = 1;
> +      Hr_Config->MaxDSNumber = 4;
> +      Hr_Config->BridgeLoops = 6;
> +      for(j = 2, i = Hr_Config->MinDSNumber; j < count(HrConfigs) && i <=
> Hr_Config->MaxDSNumber; ++j, ++i)
> +      {
> +        HrConfigs[j].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
> +        HrConfigs[j].DevId.Dev = i;
> +        HrConfigs[j].DevId.Fun = 0;
> +        HrConfigs[j].PBus = HrConfigs[j].DevId.Bus;
> +        HrConfigs[j].Res.Cls = DEF_CACHE_LINE_SIZE;
> +      }
> +    break;
> +  }
> +}//InitARHRConfigs
> +
> +
> +STATIC
> +VOID
> +InitCommonHRConfigs (
> +  IN       HR_CONFIG        *Hr_Config,
> +  IN       UINT8            BusNumLimit,
> +  IN  OUT  BRDG_RES_CONFIG  *HrResConf
> +  )
> +{
> +  UINT8 i;
> +
> +  UINT8 j;
> +  for(i = 0; i < count(HrConfigs); ++i) {
> +    HrConfigs[i].IsDSBridge = TRUE;
> +  }
> +  //
> +  // US(HRBus:0:0)
> +  //
> +  HrConfigs[HR_US_PORT].DevId.Bus   = Hr_Config->HRBus;
> +  HrConfigs[HR_US_PORT].DevId.Dev   = 0;
> +  HrConfigs[HR_US_PORT].DevId.Fun   = 0;
> +  HrConfigs[HR_US_PORT].Res         = *HrResConf;
> +  HrConfigs[HR_US_PORT].Res.IoBase  = 0xF1;
> +  HrConfigs[HR_US_PORT].Res.IoLimit = 0x01;
> +  HrConfigs[HR_US_PORT].PBus        = HrConfigs[HR_US_PORT].DevId.Bus;
> +  HrConfigs[HR_US_PORT].SBus        = HrConfigs[HR_US_PORT].PBus + 1;
> +  HrConfigs[HR_US_PORT].SubBus      = BusNumLimit;
> +  HrConfigs[HR_US_PORT].IsDSBridge  = FALSE;
> +
> +  //
> +  // HIA resides here
> +  //
> +  HrConfigs[HR_DS_PORT0].DevId.Bus    =
> HrConfigs[HR_US_PORT].DevId.Bus + 1;
> +  HrConfigs[HR_DS_PORT0].DevId.Dev    = 0;
> +  HrConfigs[HR_DS_PORT0].DevId.Fun    = 0;
> +  HrConfigs[HR_DS_PORT0].Res          = NOT_IN_USE_BRIDGE;
> +  HrConfigs[HR_DS_PORT0].Res.MemBase  = HrResConf->MemLimit;
> +  HrConfigs[HR_DS_PORT0].Res.MemLimit = HrResConf->MemLimit;
> +  HrResConf->MemLimit                -= 0x10; //This 1 MB chunk will be used by
> HIA
> +  HrConfigs[HR_DS_PORT0].Res.Cmd      = CMD_BM_MEM;
> +  HrConfigs[HR_DS_PORT0].Res.Cls      = DEF_CACHE_LINE_SIZE;
> +  HrConfigs[HR_DS_PORT0].PBus         =
> HrConfigs[HR_DS_PORT0].DevId.Bus;
> +  HrConfigs[HR_DS_PORT0].SBus         = HrConfigs[HR_DS_PORT0].PBus + 1;
> +  HrConfigs[HR_DS_PORT0].SubBus       = HrConfigs[HR_DS_PORT0].PBus +
> 1;
> +
> +  switch (Hr_Config->DeviceId) {
> +  //
> +  // Alpine Ridge
> +  //
> +  case AR_HR_2C:
> +  case AR_HR_C0_2C:
> +  case AR_HR_LP:
> +  case AR_HR_4C:
> +  case AR_HR_C0_4C:
> +  //
> +  // Titan Ridge
> +  //
> +  case TR_HR_2C:
> +  case TR_HR_4C:
> +    InitARHRConfigs(Hr_Config, BusNumLimit, HrResConf);
> +    break;
> +
> +  default:
> +    //
> +    // DS(HRBus+2:3-6:0)
> +    //
> +    Hr_Config->MinDSNumber  = 3;
> +    Hr_Config->MaxDSNumber  = 6;
> +    Hr_Config->BridgeLoops  = count (HrConfigs);
> +
> +    for (j = 2, i = Hr_Config->MinDSNumber; j < count (HrConfigs) && i <=
> Hr_Config->MaxDSNumber; ++j, ++i) {
> +      HrConfigs[j].DevId.Bus  = HrConfigs[HR_US_PORT].DevId.Bus + 1;
> +      HrConfigs[j].DevId.Dev  = i;
> +      HrConfigs[j].DevId.Fun  = 0;
> +      HrConfigs[j].PBus       = HrConfigs[j].DevId.Bus;
> +      HrConfigs[j].Res.Cls    = DEF_CACHE_LINE_SIZE;
> +    }
> +  }
> +} // InitCommonHRConfigs
> +
> +STATIC
> +VOID
> +InitHRDSPort_Disable (
> +  IN       UINT8        id,
> +  IN  OUT  BRDG_CONFIG  *BrdgConf
> +  )
> +{
> +  HrConfigs[id].Res     = NOT_IN_USE_BRIDGE;
> +  HrConfigs[id].SBus    = BrdgConf->SBus;
> +  HrConfigs[id].SubBus  = BrdgConf->SBus;
> +
> +  BrdgConf->SBus++;
> +} // InitHRDSPort_Disable
> +
> +//AR only
> +
> +STATIC
> +VOID
> +InitARDSPort_1Port(
> +  IN  OUT  BRDG_CONFIG* BrdgConf
> +)
> +{
> +  UINT16 MemBase    = BrdgConf->Res.MemBase & 0xFFF0;
> +  UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
> +  UINT8  BusRange = BrdgConf->SubBus - BrdgConf->PBus - 2;
> +
> +  HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
> +  HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
> +  HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
> +  HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
> +  HrConfigs[AR_DS_PORT1].Res.MemLimit = BrdgConf->Res.MemLimit - 1;
> +  HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
> +  HrConfigs[AR_DS_PORT1].Res.PMemLimit64 =
> BrdgConf->Res.PMemLimit64;
> +  HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
> +  HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
> +
> +  BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
> +
> +  HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
> +  HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
> +  HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
> +  HrConfigs[AR_DS_PORT2].Res.MemBase = BrdgConf->Res.MemLimit;
> +  HrConfigs[AR_DS_PORT2].Res.MemLimit = BrdgConf->Res.MemLimit;
> +  HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
> +  HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
> +
> +  BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
> +}//InitARDSPort_1Port
> +
> +STATIC
> +VOID
> +InitARDSPort_2Port(
> +  IN OUT BRDG_CONFIG* BrdgConf
> +)
> +{
> +  UINT16 MemBase    = BrdgConf->Res.MemBase & 0xFFF0;
> +  UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
> +  UINT8  BusRange = BrdgConf->SubBus - BrdgConf->PBus - 3;
> +
> +  // Busses are split between ports 1 and 4
> +  BusRange /= 2;
> +
> +  HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
> +  HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
> +  HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
> +  HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
> +  HrConfigs[AR_DS_PORT1].Res.MemLimit = MemBase + 0x17F0 - 1;
> +  HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
> +  HrConfigs[AR_DS_PORT1].Res.PMemLimit64 = PMemBase64 + 0x2000 - 1;
> +  HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
> +  HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
> +
> +  BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
> +
> +  HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
> +  HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
> +  HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
> +  HrConfigs[AR_DS_PORT2].Res.MemBase = MemBase + 0x17F0;
> +  HrConfigs[AR_DS_PORT2].Res.MemLimit = MemBase + 0x1800 - 1;
> +  HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
> +  HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
> +
> +  BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
> +
> +
> +  HrConfigs[AR_DS_PORT4].Res = NOT_IN_USE_BRIDGE;
> +  HrConfigs[AR_DS_PORT4].Res.Cls = DEF_CACHE_LINE_SIZE;
> +  HrConfigs[AR_DS_PORT4].Res.Cmd = CMD_BM_MEM;
> +  HrConfigs[AR_DS_PORT4].Res.MemBase = MemBase + 0x1800;
> +  HrConfigs[AR_DS_PORT4].Res.MemLimit = BrdgConf->Res.MemLimit;
> +  HrConfigs[AR_DS_PORT4].Res.PMemBase64 = PMemBase64 + 0x2000;
> +  HrConfigs[AR_DS_PORT4].Res.PMemLimit64 =
> BrdgConf->Res.PMemLimit64;
> +  HrConfigs[AR_DS_PORT4].SBus = BrdgConf->SBus;
> +  HrConfigs[AR_DS_PORT4].SubBus = BrdgConf->SubBus;
> +
> +  BrdgConf->SBus = HrConfigs[AR_DS_PORT4].SubBus + 1;
> +}//InitARDSPort_2Port
> +
> +
> +STATIC
> +BOOLEAN
> +CheckLimits (
> +  IN    BOOLEAN          Is2PortDev,
> +  IN    BRDG_RES_CONFIG  *HrResConf,
> +  IN    UINT8            BusRange
> +  )
> +{
> +  UINT16  MemBase;
> +  UINT16  MemLimit;
> +  UINT64  PMemBase64;
> +  UINT64  PMemLimit64;
> +
> +  MemBase     = HrResConf->MemBase & 0xFFF0;
> +  MemLimit    = HrResConf->MemLimit & 0xFFF0;
> +  PMemBase64  = HrResConf->PMemBase64 & 0xFFF0;
> +  PMemLimit64 = HrResConf->PMemLimit64 & 0xFFF0;
> +  //
> +  // Check memoty alignment
> +  //
> +  if (MemBase & 0x3FF) {
> +    DEBUG((DEBUG_INFO, "M alig\n"));
> +    return FALSE;
> +  }
> +
> +  if (PMemBase64 & 0xFFF) {
> +    DEBUG((DEBUG_INFO, "PM alig\n"));
> +    return FALSE;
> +  }
> +
> +  if (Is2PortDev) {
> +    //
> +    // Check mem size
> +    //
> +    if (MemLimit + 0x10 - MemBase < 0x2E00) {
> +      DEBUG((DEBUG_INFO, "M size\n"));
> +      return FALSE;
> +    }
> +    //
> +    // Check P-mem size
> +    //
> +    if (PMemLimit64 + 0x10 - PMemBase64 < 0x4A00) {
> +      DEBUG((DEBUG_INFO, "PM size\n"));
> +      return FALSE;
> +    }
> +    //
> +    // Check bus range
> +    //
> +    if (BusRange < 106) {
> +      DEBUG((DEBUG_INFO, "Bus range\n"));
> +      return FALSE;
> +    }
> +  } else {
> +    //
> +    // Check mem size
> +    //
> +    if (MemLimit + 0x10 - MemBase < 0x1600) {
> +      DEBUG((DEBUG_INFO, "M size\n"));
> +      return FALSE;
> +    }
> +    //
> +    // Check P-mem size
> +    //
> +    if (PMemLimit64 + 0x10 - PMemBase64 < 0x2200) {
> +      DEBUG((DEBUG_INFO, "PM size\n"));
> +      return FALSE;
> +    }
> +    //
> +    // Check bus range
> +    //
> +    if (BusRange < 56) {
> +      DEBUG((DEBUG_INFO, "Bus range\n"));
> +      return FALSE;
> +    }
> +  }
> +
> +  return TRUE;
> +} // CheckLimits
> +
> +STATIC
> +BOOLEAN
> +InitHRResConfigs (
> +  IN  OUT HR_CONFIG      *Hr_Config,
> +  IN    UINT8            BusNumLimit,
> +  IN  OUT BRDG_RES_CONFIG*HrResConf
> +  )
> +{
> +  BRDG_CONFIG  BrdgConf = { { 0 } };
> +
> +  InitCommonHRConfigs (Hr_Config, BusNumLimit, HrResConf);
> +  BrdgConf.PBus   = Hr_Config->HRBus + 2;// Take into account busses
> +  BrdgConf.SBus   = Hr_Config->HRBus + 3;// for US and DS of HIA
> +  BrdgConf.SubBus = BusNumLimit;
> +  BrdgConf.Res    = *HrResConf;
> +  while (TRUE) {
> +    switch (Hr_Config->DeviceId) {
> +    case AR_HR_4C:
> +    case TR_HR_4C:
> +    case AR_HR_C0_4C:
> +      //
> +      // 2 Port host
> +      //
> +      if (CheckLimits (TRUE, HrResConf, BusNumLimit - Hr_Config->HRBus)) {
> +
> +
> +          InitARDSPort_2Port(&BrdgConf);
> +          DEBUG((DEBUG_INFO, "AR2\n"));
> +
> +        return TRUE;
> +      } else {
> +       return FALSE;
> +      }
> +    // AR only
> +  case AR_HR_2C: // 1 port host
> +  case AR_HR_C0_2C:
> +  case AR_HR_LP:
> +  case TR_HR_2C:
> +    DEBUG((DEBUG_INFO, "AR1\n"));
> +    InitARDSPort_1Port(&BrdgConf);
> +    return TRUE;
> +
> +    default:
> +      InitHRDSPort_Disable (HR_DS_PORT3, &BrdgConf);
> +      InitHRDSPort_Disable (HR_DS_PORT4, &BrdgConf);
> +      InitHRDSPort_Disable (HR_DS_PORT5, &BrdgConf);
> +      InitHRDSPort_Disable (HR_DS_PORT6, &BrdgConf);
> +      return FALSE;
> +    }
> +  }
> +} // InitHRResConfigs
> +
> +STATIC
> +BOOLEAN
> +InitializeHostRouter (
> +  OUT  HR_CONFIG  *Hr_Config,
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  UINT8           BusNumLimit;
> +  BRDG_RES_CONFIG HrResConf = { 0 };
> +  UINT8           i;
> +  BOOLEAN         Ret;
> +
> +  Ret = TRUE;
> +
> +  gDeviceBaseAddress   = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus,
> RpDevice, RpFunction, 0);
> +  Hr_Config->HRBus    = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  gDeviceBaseAddress   = PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> Hr_Config->HRBus, 0x00, 0x00, 0);
> +  Hr_Config->DeviceId = PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET);
> +  if (!(IsTbtHostRouter (Hr_Config->DeviceId))) {
> +    return FALSE;
> +  }
> +  TbtSegment = (UINT8)RpSegment;
> +
> +  HrResConf.Cmd          = CMD_BM_MEM;
> +  HrResConf.Cls          = DEF_CACHE_LINE_SIZE;
> +  gDeviceBaseAddress      = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus,
> RpDevice, RpFunction, 0);
> +  HrResConf.IoBase       = PciSegmentRead8 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
> +  HrResConf.IoLimit      = PciSegmentRead8 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
> +  HrResConf.MemBase      = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
> +  HrResConf.MemLimit     = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
> +  HrResConf.PMemBase64   = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase));
> +  HrResConf.PMemLimit64  = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit));
> +  HrResConf.PMemBase64  |= (UINT64)(PciSegmentRead32
> (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32))) << 16;
> +  HrResConf.PMemLimit64 |= (UINT64)(PciSegmentRead32
> (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32))) << 16;
> +  BusNumLimit = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
> +
> +  Ret         = InitHRResConfigs (Hr_Config, BusNumLimit, &HrResConf);
> +
> +  for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
> +    UINT8 Bus;
> +    UINT8 Dev;
> +    UINT8 Fun;
> +    Bus               = HrConfigs[i].DevId.Bus;
> +    Dev               = HrConfigs[i].DevId.Dev;
> +    Fun               = HrConfigs[i].DevId.Fun;
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev,
> Fun, 0);
> +
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET,
> HrConfigs[i].Res.Cls);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, HrConfigs[i].PBus);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, HrConfigs[i].SBus);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, HrConfigs[i].SubBus);
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase), HrConfigs[i].Res.MemBase);
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryLimit), HrConfigs[i].Res.MemLimit);
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryBase), (UINT16) (HrConfigs[i].Res.PMemBase64 &
> 0xFFFF));
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryLimit), (UINT16) (HrConfigs[i].Res.PMemLimit64 &
> 0xFFFF));
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32), (UINT32) (HrConfigs[i].Res.PMemBase64
> >> 16));
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32), (UINT32) (HrConfigs[i].Res.PMemLimit64
> >> 16));
> +    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBase), HrConfigs[i].Res.IoBase);
> +    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoLimit), HrConfigs[i].Res.IoLimit);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBaseUpper16), 0x00000000);
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> HrConfigs[i].Res.Cmd);
> +  }
> +  if (Hr_Config->DeviceId == AR_HR_2C || Hr_Config->DeviceId == AR_HR_4C
> || Hr_Config->DeviceId == AR_HR_LP) {
> +    for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
> +      if(HrConfigs[i].IsDSBridge) {
> +        UnsetVesc(HrConfigs[i].DevId.Bus, HrConfigs[i].DevId.Dev,
> HrConfigs[i].DevId.Fun);
> +      }
> +    }
> +  }
> +
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS
> (TbtSegment,(Hr_Config->HRBus + 2), 0x00, 0x00, 0);
> +  PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4),
> HrConfigs[HR_DS_PORT0].Res.MemLimit << 16);
> +  PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4),
> (HrConfigs[HR_DS_PORT0].Res.MemLimit + 0x4) << 16);
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET,
> DEF_CACHE_LINE_SIZE);
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> CMD_BM_MEM);
> +  return Ret;
> +} // InitializeHostRouter
> +STATIC
> +UINT8
> +ConfigureSlot (
> +  IN       UINT8      Bus,
> +  IN       UINT8      MAX_DEVICE,
> +  IN       INT8       Depth,
> +  IN       BOOLEAN    ArPcie,
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  UINT8      Device;
> +  UINT8      SBus;
> +  UINT8      UsedBusNumbers;
> +  UINT8      RetBusNum;
> +  PORT_INFO  CurrentSlot;
> +
> +  RetBusNum = 0;
> +
> +  for (Device = 0; Device < MAX_DEVICE; Device++) {
> +    //
> +    // Continue if device is absent
> +    //
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Device, 0x00, 0);
> +    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET)) {
> +      continue;
> +
> +    }
> +
> +    if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress +
> (PCI_CLASSCODE_OFFSET + 1))) {
> +      SetDevResources (
> +        Bus,
> +        Device,
> +        PCI_MAX_FUNC,
> +        PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4),
> +        PortInfo
> +        );
> +      continue;
> +    }
> +    //
> +    // Else Bridge
> +    //
> +    CopyMem (&CurrentSlot, PortInfo, sizeof (PORT_INFO));
> +
> +    ++RetBusNum; // UP Bridge
> +    SBus = Bus + RetBusNum; // DS Bridge
> +
> +    if (SBus + 1 >= PortInfo->BusNumLimit) {
> +      continue;
> +
> +    }
> +
> +    SetDevResources (Bus, Device, 1, PCI_BASE_ADDRESSREG_OFFSET +
> (PCI_BAR_IDX1 * 4), PortInfo);
> +
> +    //
> +    // Init UP Bridge to reach DS Bridge
> +    //
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> CMD_BM_MEM);
> +
> +  if(ArPcie) {
> +    UnsetVesc(Bus, Device, 0x00);
> +  }
> +
> +  UsedBusNumbers = ConfigureSlot(SBus, PCI_MAX_DEVICE + 1, -1, FALSE,
> PortInfo);
> +  RetBusNum += UsedBusNumbers;
> +
> +    SetPhyPortResources (
> +      Bus,
> +      Device,
> +      SBus + UsedBusNumbers,
> +      Depth,
> +      &CurrentSlot,
> +      PortInfo
> +      );
> +  }
> +  //
> +  // for (Device = 0; Device <= PCI_MAX_DEVICE; Device++)
> +  //
> +  return RetBusNum;
> +} // ConfigureSlot
> +
> +STATIC
> +VOID
> +SetCioPortResources (
> +  IN       UINT8     Bus,
> +  IN       UINT8     Dev,
> +  IN       UINT8     SBus,
> +  IN       UINT8     SubBus,
> +  IN       PORT_INFO  *portInfoBeforeChange,
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  UINT8 Cmd;
> +  Cmd               = CMD_BUS_MASTER;
> +
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev,
> 0x00, 0);
> +  PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
> +  PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
> +  PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
> +
> +  if (PortInfo->IoBase <= PortInfo->IoLimit) {
> +    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBase), PortInfo->IoBase);
> +    PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoLimit), PortInfo->IoLimit);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBaseUpper16), 0x00000000);
> +    Cmd |= CMD_BM_IO;
> +  } else {
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBase), DISBL_IO_REG1C);
> +  }
> +
> +  if (PortInfo->MemBase <= PortInfo->MemLimit) {
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase), PortInfo->MemBase);
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryLimit), PortInfo->MemLimit);
> +    Cmd |= CMD_BM_MEM;
> +  } else {
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase), DISBL_MEM32_REG20);
> +  }
> +
> +  if (PortInfo->PMemBase64 <= PortInfo->PMemLimit64) {
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryBase), (UINT16) (PortInfo->PMemBase64 &
> 0xFFFF));
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryLimit), (UINT16) (PortInfo->PMemLimit64 &
> 0xFFFF));
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32), (UINT32) (PortInfo->PMemBase64 >> 16));
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32), (UINT32) (PortInfo->PMemLimit64 >> 16));
> +    Cmd |= CMD_BM_MEM;
> +  } else {
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32), 0);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32), 0);
> +  }
> +
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
> +  PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET,
> DEF_CACHE_LINE_SIZE);
> +} // SetCioPortResources
> +
> +STATIC
> +VOID
> +SetSlotsAsUnused (
> +  IN       UINT8      Bus,
> +  IN       UINT8      MaxSlotNum,
> +  IN       UINT8      CioSlot,
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  UINT8 Slot;
> +  for (Slot = MaxSlotNum; Slot > CioSlot; --Slot) {
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Slot,
> 0x00, 0);
> +    if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET)) {
> +      continue;
> +    }
> +
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET,
> DEF_CACHE_LINE_SIZE);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
> +    PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
> +    PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.IoBase), DISBL_IO_REG1C);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.MemoryBase), DISBL_MEM32_REG20);
> +    PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
> +    PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> CMD_BUS_MASTER);
> +    PortInfo->BusNumLimit--;
> +  }
> +} // SetSlotsAsUnused
> +
> +STATIC
> +UINT16
> +FindVendorSpecificHeader(
> +  IN  UINT8  Bus
> +)
> +{
> +  PCI_EXP_EXT_HDR   *ExtHdr;
> +  UINT32            ExtHdrValue;
> +  UINT16            ExtendedRegister;
> +
> +  ExtHdr = (PCI_EXP_EXT_HDR*) &ExtHdrValue;
> +  ExtendedRegister  = 0x100;
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00,
> 0x00, 0);
> +  while (ExtendedRegister) {
> +    ExtHdrValue = PciSegmentRead32 (gDeviceBaseAddress +
> ExtendedRegister);
> +    if (ExtHdr->CapabilityId == 0xFFFF) {
> +      return 0x0000; // No Vendor-Specific Extended Capability header
> +    }
> +
> +    if (PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID ==
> ExtHdr->CapabilityId) {
> +      return ExtendedRegister;
> +    }
> +
> +    ExtendedRegister = (UINT16) ExtHdr->NextCapabilityOffset;
> +  }
> +  return 0x0000; // No Vendor-Specific Extended Capability header
> +}
> +
> +STATIC
> +UINT8
> +FindSsid_SsvidHeader (
> +  IN    UINT8  Bus
> +  )
> +{
> +  UINT8 CapHeaderId;
> +  UINT8 CapHeaderOffset;
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00,
> 0x00, 0);
> +  CapHeaderOffset   = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_CAPBILITY_POINTER_OFFSET);
> +
> +  while (CapHeaderOffset != 0) {
> +    CapHeaderId = PciSegmentRead8 (gDeviceBaseAddress +
> CapHeaderOffset);
> +
> +    if (CapHeaderId == PCIE_CAP_ID_SSID_SSVID) {
> +      return CapHeaderOffset;
> +    }
> +
> +    CapHeaderOffset = PciSegmentRead8 (gDeviceBaseAddress +
> CapHeaderOffset + 1);
> +  }
> +
> +  DEBUG((DEBUG_INFO, "SID0\n"));
> +  return 0;
> +} // FindSsid_SsvidHeader
> +
> +STATIC
> +BOOLEAN
> +GetCioSlotByDevId (
> +  IN   UINT8  Bus,
> +  OUT  UINT8  *CioSlot,
> +  OUT  UINT8  *MaxSlotNum,
> +  OUT  BOOLEAN *ArPcie
> +  )
> +{
> +  UINT16            VSECRegister;
> +  BRDG_CIO_MAP_REG  BridgMap;
> +  UINT32            BitScanRes;
> +  UINT16            DevId;
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, 0x00,
> 0x00, 0);
> +  DevId             = PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET);
> +
> +  //
> +  // Init out params in case device is not recognised
> +  //
> +  *CioSlot    = 4;
> +  *MaxSlotNum = 7;
> +  *ArPcie     = FALSE;
> +
> +  switch (DevId) {
> +    //
> +    // For known device IDs
> +    //
> +    case 0x1578:
> +      *ArPcie = TRUE;
> +  }
> +
> +  switch (DevId) {
> +  //
> +  // For known device IDs
> +  //
> +  case 0x1513:
> +  case 0x151A:
> +  case 0x151B:
> +  case 0x1547:
> +  case 0x1548:
> +    return TRUE; // Just return
> +  case 0x1549:
> +    return FALSE; // Just return
> +  }
> +
> +  VSECRegister = FindVendorSpecificHeader(Bus);
> +  if (!VSECRegister) {
> +    return TRUE; // Just return
> +  }
> +  //
> +  // Go to Bridge/CIO map register
> +  //
> +  VSECRegister += 0x18;
> +  BridgMap.AB_REG = PciSegmentRead32(gDeviceBaseAddress +
> VSECRegister);
> +  //
> +  // Check for range
> +  //
> +  if (BridgMap.Bits.NumOfDSPorts < 1 || BridgMap.Bits.NumOfDSPorts > 27) {
> +    return TRUE;
> +  //
> +  // Not a valid register
> +  //
> +  }
> +  //
> +  // Set OUT params
> +  //
> +  *MaxSlotNum = (UINT8) BridgMap.Bits.NumOfDSPorts;
> +
> +#ifdef _MSC_VER
> +  if(!_BitScanForward(&BitScanRes, BridgMap.Bits.CioPortMap)) { // No DS
> bridge which is CIO port
> +    return FALSE;
> +  }
> +#else
> +#ifdef __GNUC__
> +  if (BridgMap.Bits.CioPortMap == 0) {
> +    return FALSE;
> +  }
> +  BitScanRes = __builtin_ctz (BridgMap.Bits.CioPortMap);
> +#else
> +#error Unsupported Compiler
> +#endif
> +#endif
> +
> +  *CioSlot = (UINT8)BitScanRes;
> +  return TRUE;
> +} // GetCioSlotByDevId
> +
> +#define TBT_LEGACY_SUB_SYS_ID 0x11112222
> +
> +STATIC
> +BOOLEAN
> +IsLegacyDevice (
> +  IN    UINT8  Bus
> +  )
> +{
> +  UINT32  Sid;
> +  UINT8   SidRegister;
> +  UINT16  DevId;
> +
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00,
> 0x00, 0);
> +  DevId             = PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET);
> +  switch (DevId) {
> +  //
> +  // For known device IDs
> +  //
> +  case 0x1513:
> +  case 0x151A:
> +  case 0x151B:
> +    DEBUG((DEBUG_INFO, "Legacy "));
> +    DEBUG((DEBUG_INFO, "DevId = %d\n",DevId));
> +    return TRUE;
> +    //
> +    // Legacy device by Device Id
> +    //
> +  }
> +
> +  SidRegister = FindSsid_SsvidHeader(Bus);
> +
> +  if (!SidRegister) {
> +    return TRUE; // May be absent for legacy devices
> +  }
> +  //
> +  // Go to register
> +  //
> +  SidRegister += 0x4;
> +  Sid = PciSegmentRead32(gDeviceBaseAddress + SidRegister);
> +  DEBUG((DEBUG_INFO, "SID"));
> +  DEBUG((DEBUG_INFO, " = %d\n", Sid));
> +
> +return TBT_LEGACY_SUB_SYS_ID == Sid || 0 == Sid;
> +} // IsLegacyDevice
> +
> +STATIC
> +VOID
> +UnsetVescEp(
> +  IN  UINT8     Bus,
> +  IN  UINT8     MaxSlotNum
> +  )
> +{
> +  UINT8 i;
> +
> +  for (i = 0; i <= MaxSlotNum; ++i)
> +  {
> +    UnsetVesc(Bus, i, 0);
> +  }
> +}// Unset_VESC_REG2_EP
> +
> +STATIC
> +BOOLEAN
> +ConfigureEP (
> +  IN       INT8      Depth,
> +  IN  OUT  UINT8     *Bus,
> +  IN  OUT  PORT_INFO *PortInfo
> +  )
> +{
> +  UINT8      SBus;
> +  UINT8      CioSlot;
> +  UINT8      MaxSlotNum;
> +  BOOLEAN    ArPcie;
> +  UINT8      MaxPHYSlots;
> +  UINT8      UsedBusNumbers;
> +  UINT8      cmd;
> +  BOOLEAN    CioSlotPresent;
> +  BOOLEAN    Continue;
> +  PORT_INFO  PortInfoOrg;
> +  UINT8      CioBus;
> +
> +  CioSlot     = 4;
> +  MaxSlotNum  = 7;
> +  CopyMem (&PortInfoOrg, PortInfo, sizeof (PORT_INFO));
> +
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, *Bus,
> 0x00, 0x00, 0);
> +  cmd               = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_COMMAND_OFFSET);
> +  // AR ONLY
> +  // Endpoint on CIO slot, but not a bridge device
> +  if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress +
> (PCI_CLASSCODE_OFFSET + 1))) {
> +    DEBUG((DEBUG_INFO, "UEP\n"));
> +    // Check whether EP already configured by examining CMD register
> +    if(cmd & CMD_BUS_MASTER) // Yes, no need to touch this EP
> +    {
> +      DEBUG((DEBUG_INFO, "BMF\n"));
> +      return FALSE;
> +    }
> +    // Configure it as regular PCIe device
> +    ConfigureSlot(*Bus, PCI_MAX_DEVICE + 1, -1, FALSE, PortInfo);
> +
> +    return FALSE;
> +  }
> +
> +  //
> +  // Based on Device ID assign Cio slot and max number of PHY slots to scan
> +  //
> +  CioSlotPresent  =  GetCioSlotByDevId(*Bus, &CioSlot, &MaxSlotNum,
> &ArPcie);
> +  MaxPHYSlots     = MaxSlotNum;
> +  //
> +  // Check whether EP already configured by examining CMD register
> +  //
> +
> +  if (cmd & CMD_BUS_MASTER) {
> +    //
> +    // Yes no need to touch this EP, just move to next one in chain
> +    //
> +    CioBus = *Bus + 1;
> +    if(ArPcie){
> +      UnsetVescEp(CioBus, MaxSlotNum);
> +    }
> +    if (!CioSlotPresent) {
> +      //
> +      // Cio slot is not present in EP, just return FALSE
> +      //
> +      DEBUG((DEBUG_INFO, "BMF\n"));
> +      return FALSE;
> +    }
> +    //
> +    // Take all resources from Cio slot and return
> +    //
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,CioBus,
> CioSlot, 0x00, 0);
> +    PortInfo->BusNumLimit   = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
> +    PortInfo->IoBase        = PciSegmentRead8 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
> +    PortInfo->IoLimit       = PciSegmentRead8 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
> +    PortInfo->MemBase       = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
> +    PortInfo->MemLimit      = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
> +    PortInfo->PMemBase64    = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
> +    PortInfo->PMemLimit64   = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
> +    PortInfo->PMemBase64   |= (UINT64)(PciSegmentRead32
> (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32))) << 16;
> +    PortInfo->PMemLimit64  |= (UINT64)(PciSegmentRead32
> (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32))) << 16;
> +    PortInfo->PMemLimit64  |= 0xF;
> +    //
> +    // Jump to next EP
> +    //
> +    *Bus = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +    //
> +    // Should we continue?
> +    //
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus,
> 0x00, 0x00, 0);
> +    Continue          = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET);
> +    return Continue;
> +  }
> +  //
> +  // Set is legacy dvice
> +  //
> +  isLegacyDevice = IsLegacyDevice (*Bus);
> +
> +  SetCioPortResources (
> +    *Bus,
> +    0, // Assign all available resources to US port of EP
> +    *Bus + 1,
> +    PortInfo->BusNumLimit,
> +    0,
> +    PortInfo
> +    );
> +
> +  SBus = *Bus + 1;// Jump to DS port
> +
> +  if (CioSlotPresent) {
> +    MaxPHYSlots = CioSlot;
> +  }
> +
> +  UsedBusNumbers = ConfigureSlot(SBus, MaxPHYSlots, Depth, ArPcie,
> PortInfo);
> +  if (!CioSlotPresent) {
> +    return FALSE;
> +    //
> +    // Stop resource assignment on this chain
> +    //
> +  }
> +  //
> +  // Set rest of slots us unused
> +  //
> +  SetSlotsAsUnused (SBus, MaxSlotNum, CioSlot, PortInfo);
> +
> +  SetCioPortResources (
> +    SBus,
> +    CioSlot,
> +    SBus + UsedBusNumbers + 1,
> +    PortInfo->BusNumLimit,
> +    &PortInfoOrg,
> +    PortInfo
> +    );
> +  *Bus = SBus + UsedBusNumbers + 1;// Go to next EP
> +  if(ArPcie) {
> +    UnsetVesc(SBus, CioSlot, 0x00);
> +  }
> +  if (*Bus > PortInfo->BusNumLimit - 2) {
> +    //
> +    // In case of bus numbers are exhausted stop enumeration
> +    //
> +    return FALSE;
> +  }
> +  //
> +  // Check whether we should continue on this chain
> +  //
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus,
> 0x00, 0x00, 0);
> +  Continue          = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET);
> +  return Continue;
> +} // ConfigureEP
> +
> +STATIC
> +VOID
> +GetPortResources (
> +  IN       UINT8      Bus,
> +  IN       UINT8      Dev,
> +  IN       UINT8      Fun,
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev,
> Fun, 0);
> +  PortInfo->BusNumLimit   = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
> +  PortInfo->IoBase        = PciSegmentRead8 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.IoBase)) & 0xF0;
> +  PortInfo->IoLimit       = PciSegmentRead8 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.IoLimit)) & 0xF0;
> +  PortInfo->MemBase       = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase)) & 0xFFF0;
> +  PortInfo->MemLimit      = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit)) & 0xFFF0;
> +  PortInfo->PMemBase64    = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
> +  PortInfo->PMemLimit64   = PciSegmentRead16 (gDeviceBaseAddress +
> OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
> +  PortInfo->PMemBase64   |= (UINT64)(PciSegmentRead32
> (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32))) << 16;
> +  PortInfo->PMemLimit64  |= (UINT64)(PciSegmentRead32
> (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableLimitUpper32))) << 16;
> +  PortInfo->IoLimit |= 0xF;
> +  PortInfo->MemLimit |= 0xF;
> +  PortInfo->PMemLimit64 |= 0xF;
> +} // GetPortResources
> +
> +STATIC
> +VOID
> +ConfigurePort (
> +  IN       UINT8      Bus,
> +  IN       UINT8      Dev,
> +  IN       UINT8      Fun,
> +  IN  OUT  PORT_INFO  *PortInfo
> +  )
> +{
> +  INT8  i;
> +  UINT8 USBusNum;
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev,
> Fun, 0);
> +  USBusNum          = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,
> USBusNum, 0x00, 0x00, 0);
> +  if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET)) {
> +    //
> +    // Nothing to do if TBT device is not connected
> +    //
> +    return ;
> +  }
> +
> +  GetPortResources(Bus, Dev, Fun, PortInfo);// Take reserved resources from
> DS port
> +  //
> +  // Assign resources to EPs
> +  //
> +  for (i = 0; i < MAX_TBT_DEPTH; ++i) {
> +    PortInfo->ConfedEP++;
> +    if (!ConfigureEP (i, &USBusNum, PortInfo)) {
> +      return ;
> +    }
> +  }
> +} // ConfigurePort
> +
> +VOID
> +ThunderboltCallback (
> +  IN UINT8 Type
> +  )
> +{
> +  PORT_INFO                     PortInfoOrg  = { 0 };
> +  HR_CONFIG                     HrConfig  = { 0 };
> +  UINT8                         i;
> +  UINTN                         Segment = 0;
> +  UINTN                         Bus = 0;
> +  UINTN                         Device;
> +  UINTN                         Function;
> +
> +  DEBUG((DEBUG_INFO, "ThunderboltCallback.Entry\n"));
> +
> +  DEBUG((DEBUG_INFO, "PortInfo Initialization\n"));
> +  PortInfoInit (&PortInfoOrg);
> +  if(Type == DTBT_CONTROLLER) {
> +    if (gCurrentDiscreteTbtRootPort == 0) {
> +      DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
> +      return;
> +    }
> +    GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType,
> gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
> +    DEBUG((DEBUG_INFO, "InitializeHostRouter. \n"));
> +    if (!InitializeHostRouter (&HrConfig, Segment, Bus, Device, Function)) {
> +      return ;
> +    }
> +  //
> +  // Configure DS ports
> +  //
> +  for (i = HrConfig.MinDSNumber; i <= HrConfig.MaxDSNumber; ++i) {
> +    DEBUG((DEBUG_INFO, "ConfigurePort. \n"));
> +    ConfigurePort (HrConfig.HRBus + 1, i,0, &PortInfoOrg);
> +  }
> +
> +  DEBUG((DEBUG_INFO, "EndOfThunderboltCallback.\n"));
> +  EndOfThunderboltCallback (Segment, Bus, Device, Function);
> +
> +  }
> +  DEBUG((DEBUG_INFO, "ThunderboltCallback.Exit\n"));
> +} // ThunderboltCallback
> +
> +VOID
> +DisablePCIDevicesAndBridges (
> +  IN UINT8 MinBus,
> +  IN UINT8 MaxBus
> +  )
> +{
> +  UINT8   Bus;
> +  UINT8   Dev;
> +  UINT8   Fun;
> +  UINT8   RegVal;
> +  //
> +  //  Disable PCI device First, and then Disable PCI Bridge
> +  //
> +  for (Bus = MaxBus; Bus > MinBus; --Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus,
> Dev, Fun, 0);
> +        if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress +
> PCI_VENDOR_ID_OFFSET)) {
> +          if (Fun == 0) {
> +            break;
> +
> +          }
> +
> +          continue;
> +        }
> +
> +        RegVal = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_HEADER_TYPE_OFFSET);
> +        if (HEADER_TYPE_DEVICE == (RegVal & 1)) {
> +          //
> +          // ********     Disable PCI Device   ********
> +          // BIT0  I/O Space Enabled    BIT1  Memory Space Enabled
> +          // BIT2  Bus Master Enabled   BIT4  Memory Write and Invalidation
> Enable
> +          //
> +          PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
> +          PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4), 0);
> +          PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), 0);
> +          PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX2 * 4), 0);
> +          PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX3 * 4), 0);
> +          PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX4 * 4), 0);
> +          PciSegmentWrite32 (gDeviceBaseAddress +
> PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4), 0);
> +        }
> +      }
> +    }
> +  }
> +  //
> +  // now no more PCI dev on another side of PCI Bridge can safty disable PCI
> Bridge
> +  //
> +  for (Bus = MaxBus; Bus > MinBus; --Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus,
> Dev, Fun, 0);
> +        if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress +
> PCI_VENDOR_ID_OFFSET)) {
> +          if (Fun == 0) {
> +            break;
> +          }
> +
> +          continue;
> +        }
> +
> +        RegVal = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_HEADER_TYPE_OFFSET);
> +        if (HEADER_TYPE_PCI_TO_PCI_BRIDGE == (RegVal & BIT0)) {
> +          PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET,
> (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
> +          PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0);
> +          PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0);
> +          PciSegmentWrite8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0);
> +          PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01,
> Bridge.PrefetchableBaseUpper32), 0);
> +        }
> +      } // for ( Fun .. )
> +    } // for ( Dev ... )
> +  } // for ( Bus ... )
> +} // DisablePCIDevicesAndBridges
> +
> +VOID
> +TbtDisablePCIDevicesAndBridges (
> +  IN UINT8 Type
> +  )
> +{
> +  UINTN         Segment = 0;
> +  UINTN         Bus = 0;
> +  UINTN         Device;
> +  UINTN         Function;
> +  UINT8         MinBus;
> +  UINT8         MaxBus;
> +  UINT16        DeviceId;
> +
> +  MinBus = 1;
> +  if(Type == DTBT_CONTROLLER) {
> +    //
> +    // for(Dev = 0; Dev < 8; ++Dev)
> +    // {
> +    // PciOr8(PCI_LIB_ADDRESS(2, Dev, 0,
> PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0x40);
> +    // gBS->Stall(2000);      // 2msec
> +    // PciAnd8(PCI_LIB_ADDRESS(2, Dev, 0,
> PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0xBF);
> +    // }
> +    // gBS->Stall(200 * 1000);        // 200 msec
> +    //
> +    if (gCurrentDiscreteTbtRootPort == 0) {
> +      DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
> +      return;
> +    }
> +    GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType,
> gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device,
> Function, 0);
> +    MinBus            = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +    MaxBus            = PciSegmentRead8 (gDeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
> +    gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, MinBus,
> 0x00, 0x00, 0);
> +    DeviceId          = PciSegmentRead16 (gDeviceBaseAddress +
> PCI_DEVICE_ID_OFFSET);
> +    if (!(IsTbtHostRouter (DeviceId))) {
> +      return;
> +    }
> +    TbtSegment = (UINT8)Segment;
> +    MinBus++;
> +    //
> +    // @todo : Move this out when we dont have Loop for ITBT
> +    //
> +    DisablePCIDevicesAndBridges(MinBus, MaxBus);
> +
> +  }
> +} // DisablePCIDevicesAndBridges
> +
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> Smm.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> Smm.c
> new file mode 100644
> index 0000000000..721438c718
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/Tbt
> Smm.c
> @@ -0,0 +1,1765 @@
> +/** @file
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Module specific Includes
> +//
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/GpioLib.h>
> +#include <TbtBoardInfo.h>
> +#include <Protocol/TbtNvsArea.h>
> +#include <PchAccess.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/SmmServicesTableLib.h>
> +#include <Protocol/SmmSxDispatch2.h>
> +#include <Protocol/SmmSwDispatch2.h>
> +#include <Uefi/UefiSpec.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Guid/HobList.h>
> +#include "TbtSmiHandler.h"
> +#include <PcieRegs.h>
> +#include <Protocol/SaPolicy.h>
> +#include <Protocol/DxeTbtPolicy.h>
> +#include <Library/PchPmcLib.h>
> +#define P2P_BRIDGE                    (((PCI_CLASS_BRIDGE) << 8) |
> (PCI_CLASS_BRIDGE_P2P))
> +
> +#define CMD_BM_MEM_IO                 (CMD_BUS_MASTER | BIT1 | BIT0)
> +
> +#define DISBL_IO_REG1C                0x01F1
> +#define DISBL_MEM32_REG20             0x0000FFF0
> +#define DISBL_PMEM_REG24              0x0001FFF1
> +
> +#define DOCK_BUSSES                   8
> +
> +#define PCI_CAPABILITY_ID_PCIEXP      0x10
> +#define PCI_CAPBILITY_POINTER_OFFSET  0x34
> +
> +#define LTR_MAX_SNOOP_LATENCY_VALUE             0x0846    ///< Intel
> recommended maximum value for Snoop Latency  can we put like this ?
> +#define LTR_MAX_NON_SNOOP_LATENCY_VALUE         0x0846    ///< Intel
> recommended maximum value for Non-Snoop Latency can we put like this ?
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED TBT_NVS_AREA
> *mTbtNvsAreaPtr;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8
> gCurrentDiscreteTbtRootPort;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8
> gCurrentDiscreteTbtRootPortType;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16
> TbtLtrMaxSnoopLatency;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16
> TbtLtrMaxNoSnoopLatency;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8
> gDTbtPcieRstSupport;
> +GLOBAL_REMOVE_IF_UNREFERENCED TBT_INFO_HOB
> *gTbtInfoHob = NULL;
> +STATIC UINTN                                              mPciExpressBaseAddress;
> +STATIC UINT8                TbtSegment        = 0;
> +VOID
> +GpioWrite (
> +  IN  UINT32         GpioNumber,
> +  IN  BOOLEAN        Value
> +  )
> +{
> +  GpioSetOutputValue (GpioNumber, (UINT32)Value);
> +}
> +
> +/**
> +  Search and return the offset of desired Pci Express Capability ID
> +  CAPID list:
> +    0x0001 = Advanced Error Reporting Capability
> +    0x0002 = Virtual Channel Capability
> +    0x0003 = Device Serial Number Capability
> +    0x0004 = Power Budgeting Capability
> +
> +  @param[in] Bus                  Pci Bus Number
> +  @param[in] Device               Pci Device Number
> +  @param[in] Function             Pci Function Number
> +  @param[in] CapId                Extended CAPID to search for
> +
> +  @retval 0                       CAPID not found
> +  @retval Other                   CAPID found, Offset of desired CAPID
> +**/
> +UINT16
> +PcieFindExtendedCapId (
> +  IN UINT8   Bus,
> +  IN UINT8   Device,
> +  IN UINT8   Function,
> +  IN UINT16  CapId
> +  )
> +{
> +  UINT16  CapHeaderOffset;
> +  UINT16  CapHeaderId;
> +  UINT64  DeviceBase;
> +
> +  DeviceBase = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device,
> Function, 0);
> +
> +  ///
> +  /// Start to search at Offset 0x100
> +  /// Get Capability Header, A pointer value of 00h is used to indicate the last
> capability in the list.
> +  ///
> +  CapHeaderId     = 0;
> +  CapHeaderOffset = 0x100;
> +  while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
> +    CapHeaderId = PciSegmentRead16 (DeviceBase + CapHeaderOffset);
> +    if (CapHeaderId == CapId) {
> +      return CapHeaderOffset;
> +    }
> +    ///
> +    /// Each capability must be DWORD aligned.
> +    /// The bottom two bits of all pointers are reserved and must be
> implemented as 00b
> +    /// although software must mask them to allow for future uses of these
> bits.
> +    ///
> +    CapHeaderOffset = (PciSegmentRead16 (DeviceBase + CapHeaderOffset +
> 2) >> 4) & ((UINT16) ~(BIT0 | BIT1));
> +  }
> +
> +  return 0;
> +}
> +
> +/**
> +  Find the Offset to a given Capabilities ID
> +  CAPID list:
> +    0x01 = PCI Power Management Interface
> +    0x04 = Slot Identification
> +    0x05 = MSI Capability
> +    0x10 = PCI Express Capability
> +
> +  @param[in] Bus                  Pci Bus Number
> +  @param[in] Device               Pci Device Number
> +  @param[in] Function             Pci Function Number
> +  @param[in] CapId                CAPID to search for
> +
> +  @retval 0                       CAPID not found
> +  @retval Other                   CAPID found, Offset of desired CAPID
> +**/
> +UINT8
> +PcieFindCapId (
> +  IN UINT8   Segment,
> +  IN UINT8   Bus,
> +  IN UINT8   Device,
> +  IN UINT8   Function,
> +  IN UINT8   CapId
> +  )
> +{
> +  UINT8   CapHeaderOffset;
> +  UINT8   CapHeaderId;
> +  UINT64  DeviceBase;
> +
> +  DeviceBase = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function,
> 0);
> +
> +  if ((PciSegmentRead8 (DeviceBase + PCI_PRIMARY_STATUS_OFFSET) &
> EFI_PCI_STATUS_CAPABILITY) == 0x00) {
> +    ///
> +    /// Function has no capability pointer
> +    ///
> +    return 0;
> +  }
> +
> +  ///
> +  /// Check the header layout to determine the Offset of Capabilities Pointer
> Register
> +  ///
> +  if ((PciSegmentRead8 (DeviceBase + PCI_HEADER_TYPE_OFFSET) &
> HEADER_LAYOUT_CODE) == (HEADER_TYPE_CARDBUS_BRIDGE)) {
> +    ///
> +    /// If CardBus bridge, start at Offset 0x14
> +    ///
> +    CapHeaderOffset = 0x14;
> +  } else {
> +    ///
> +    /// Otherwise, start at Offset 0x34
> +    ///
> +    CapHeaderOffset = 0x34;
> +  }
> +  ///
> +  /// Get Capability Header, A pointer value of 00h is used to indicate the last
> capability in the list.
> +  ///
> +  CapHeaderId     = 0;
> +  CapHeaderOffset = PciSegmentRead8 (DeviceBase + CapHeaderOffset) &
> ((UINT8) ~(BIT0 | BIT1));
> +  while (CapHeaderOffset != 0 && CapHeaderId != 0xFF) {
> +    CapHeaderId = PciSegmentRead8 (DeviceBase + CapHeaderOffset);
> +    if (CapHeaderId == CapId) {
> +      return CapHeaderOffset;
> +    }
> +    ///
> +    /// Each capability must be DWORD aligned.
> +    /// The bottom two bits of all pointers (including the initial pointer at 34h)
> are reserved
> +    /// and must be implemented as 00b although software must mask them
> to allow for future uses of these bits.
> +    ///
> +    CapHeaderOffset = PciSegmentRead8 (DeviceBase + CapHeaderOffset + 1)
> & ((UINT8) ~(BIT0 | BIT1));
> +  }
> +
> +  return 0;
> +}
> +/**
> +  This function configures the L1 Substates.
> +  It can be used for Rootport and endpoint devices.
> +
> +  @param[in] DownstreamPort               Indicates if the device about to be
> programmed is a downstream port
> +  @param[in] DeviceBase                   Device PCI configuration base address
> +  @param[in] L1SubstateExtCapOffset       Pointer to L1 Substate Capability
> Structure
> +  @param[in] PortL1SubstateCapSupport     L1 Substate capability setting
> +  @param[in] PortCommonModeRestoreTime    Common Mode Restore
> Time
> +  @param[in] PortTpowerOnValue            Tpower_on Power On Wait Time
> +  @param[in] PortTpowerOnScale            Tpower-on Scale
> +
> +  @retval none
> +**/
> +VOID
> +ConfigureL1s (
> +  IN UINTN                              DeviceBase,
> +  IN UINT16                             L1SubstateExtCapOffset,
> +  IN UINT32                             PortL1SubstateCapSupport,
> +  IN UINT32                             PortCommonModeRestoreTime,
> +  IN UINT32                             PortTpowerOnValue,
> +  IN UINT32                             PortTpowerOnScale,
> +  IN UINT16                             MaxLevel
> +  )
> +{
> +
> +  PciSegmentAndThenOr32 (
> +    DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
> +    (UINT32) ~(0xFF00),
> +    (UINT32) PortCommonModeRestoreTime << 8
> +    );
> +
> +  PciSegmentAnd32(DeviceBase + L1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL2_OFFSET, 0xFFFFFF04);
> +
> +  PciSegmentOr32(DeviceBase + L1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL2_OFFSET,(UINT32) ((PortTpowerOnValue <<
> N_PCIE_EX_L1SCTL2_POWT) | PortTpowerOnScale));
> +
> +  PciSegmentAndThenOr32 (
> +    DeviceBase + L1SubstateExtCapOffset + R_PCIE_EX_L1SCTL1_OFFSET,
> +    (UINT32) ~(0xE3FF0000),
> +    (UINT32) (BIT30 | BIT23 | BIT21)
> +    );
> +
> +}
> +
> +VOID
> +RootportL1sSupport (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT16  RootL1SubstateExtCapOffset,
> +  IN UINT16  MaxL1Level
> +  )
> +{
> +  UINTN       ComponentABaseAddress;
> +  UINTN       ComponentBBaseAddress;
> +  UINT8       SecBus;
> +  UINT32      PortL1SubstateCapSupport;
> +  UINT32      PortCommonModeRestoreTime;
> +  UINT32      PortTpowerOnValue;
> +  UINT32      PortTpowerOnScale;
> +  UINT16      ComponentBL1SubstateExtCapOffset;
> +  UINT32      ComponentBL1Substates;
> +  UINT32      ComponentBCommonModeRestoreTime;
> +  UINT32      ComponentBTpowerOnValue;
> +  UINT32      ComponentBTpowerOnScale;
> +  UINT32      Data32;
> +
> +  PortL1SubstateCapSupport  = 0;
> +  PortCommonModeRestoreTime = 0;
> +  PortTpowerOnValue = 0;
> +  PortTpowerOnScale = 0;
> +  Data32 = 0;
> +
> +  ComponentABaseAddress  = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,
> Bus, Dev, Fun, 0);
> +  if (RootL1SubstateExtCapOffset != 0) {
> +    Data32 = PciSegmentRead32 (ComponentABaseAddress +
> RootL1SubstateExtCapOffset + R_PCIE_EX_L1SCAP_OFFSET);
> +    PortL1SubstateCapSupport  = (Data32) & 0x0F;
> +    PortCommonModeRestoreTime = (Data32 >> 8) & 0xFF;
> +    PortTpowerOnScale         = (Data32 >> 16) & 0x3;
> +    PortTpowerOnValue         = (Data32 >> 19) & 0x1F;
> +  } else {
> +    MaxL1Level                = 0; // If L1 Substates from Root Port side is disable,
> then Disable from Device side also.
> +  }
> +
> +  SecBus                = PciSegmentRead8 (ComponentABaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,
> SecBus, 0, 0, 0);
> +
> +  if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET)
> == 0xFFFF) {
> +    ComponentBL1SubstateExtCapOffset = PcieFindExtendedCapId (
> +                                  SecBus,
> +                                  0,
> +                                  0,
> +                                  V_PCIE_EX_L1S_CID
> +                                  );
> +    if (ComponentBL1SubstateExtCapOffset != 0) {
> +      ComponentBL1Substates = PciSegmentRead32
> (ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCAP_OFFSET);
> +      ComponentBCommonModeRestoreTime = (ComponentBL1Substates >>
> 8) & 0xFF;
> +      ComponentBTpowerOnScale         = (ComponentBL1Substates >> 16) &
> 0x3;
> +      ComponentBTpowerOnValue         = (ComponentBL1Substates >> 19) &
> 0x1F;
> +
> +      if (MaxL1Level == 3) {
> +        if (Data32 >= ComponentBL1Substates) {
> +          if (~(Data32 | BIT2)) {
> +            MaxL1Level = 1;
> +          }
> +        }
> +        else {
> +          if (~(ComponentBL1Substates | BIT2)) {
> +          MaxL1Level = 1;
> +        }
> +      }
> +    }
> +
> +      if (MaxL1Level == 3) {
> +        ConfigureL1s (
> +          ComponentABaseAddress,
> +          RootL1SubstateExtCapOffset,
> +          PortL1SubstateCapSupport,
> +          ComponentBCommonModeRestoreTime,
> +          ComponentBTpowerOnValue,
> +          ComponentBTpowerOnScale,
> +          MaxL1Level
> +          );
> +
> +      ConfigureL1s (
> +          ComponentBBaseAddress,
> +          ComponentBL1SubstateExtCapOffset,
> +          ComponentBL1Substates,
> +          PortCommonModeRestoreTime,
> +          PortTpowerOnValue,
> +          PortTpowerOnScale,
> +          MaxL1Level
> +          );
> +      }
> +
> +      if (MaxL1Level == 1) {
> +        PciSegmentOr32 (
> +          ComponentABaseAddress + RootL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL1_OFFSET,
> +          (UINT32) (BIT3 | BIT1)
> +          );
> +
> +        PciSegmentOr32 (
> +          ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL1_OFFSET,
> +          (UINT32) (BIT3 | BIT1)
> +          );
> +      }
> +      else {
> +        if (RootL1SubstateExtCapOffset != 0) {
> +          PciSegmentOr32 (
> +            ComponentABaseAddress + RootL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL1_OFFSET,
> +            (UINT32) (BIT3 | BIT1)
> +            );
> +
> +          PciSegmentOr32 (
> +            ComponentABaseAddress + RootL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL1_OFFSET,
> +            (UINT32) (BIT2 | BIT0)
> +            );
> +        }
> +        if (ComponentBL1SubstateExtCapOffset != 0) {
> +          PciSegmentOr32 (
> +            ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL1_OFFSET,
> +            (UINT32) (BIT3 | BIT1)
> +           );
> +
> +          PciSegmentOr32 (
> +            ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset +
> R_PCIE_EX_L1SCTL1_OFFSET,
> +            (UINT32) (BIT2 | BIT0)
> +            );
> +        }
> +      }
> +    }
> +  }
> +}
> +
> +VOID
> +MultiFunctionDeviceAspm (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev
> +  )
> +{
> +  UINT16  LowerAspm;
> +  UINT16  AspmVal;
> +  UINT8   Fun;
> +  UINT64  DeviceBaseAddress;
> +  UINT8   CapHeaderOffset;
> +
> +  LowerAspm = 3; // L0s and L1 Supported
> +  for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +    //
> +    // Check for Device availability
> +    //
> +    DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +    if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +      // Device not present
> +      continue;
> +    }
> +
> +    CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
> +
> +    AspmVal = (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset +
> 0x00C) >> 10) & 3;
> +    if (LowerAspm > AspmVal) {
> +      LowerAspm = AspmVal;
> +    }
> +  } //Fun
> +
> +  for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +    //
> +    // Check for Device availability
> +    //
> +    DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +    if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +      //
> +      // Device not present
> +      //
> +      continue;
> +    }
> +
> +    CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
> +
> +    PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10,
> 0xFFFC, LowerAspm);
> +  } //Fun
> +}
> +
> +UINT16
> +LimitAspmLevel (
> +  IN UINT16  SelectedAspm,
> +  IN UINT16  MaxAspmLevel
> +  )
> +{
> +  SelectedAspm = SelectedAspm & MaxAspmLevel;
> +
> +  return SelectedAspm;
> +}
> +
> +UINT16
> +FindOptimalAspm (
> +  IN UINT16   ComponentAaspm,
> +  IN UINT16   ComponentBaspm
> +  )
> +{
> +  UINT16  SelectedAspm;
> +
> +  SelectedAspm = ComponentAaspm & ComponentBaspm;
> +
> +  return SelectedAspm;
> +}
> +
> +UINT16
> +FindComponentBaspm (
> +  IN UINT8   Bus,
> +  IN UINT8   MaxBus
> +  )
> +{
> +  UINT8   BusNo;
> +  UINT8   DevNo;
> +  UINT8   FunNo;
> +  UINT64  DevBaseAddress;
> +  UINT8   RegVal;
> +  UINT8   SecBusNo;
> +  UINT16  SelectedAspm; // No ASPM Support
> +  UINT8   CapHeaderOffset_B;
> +  BOOLEAN AspmFound;
> +
> +  SelectedAspm  = 0;
> +  AspmFound     = FALSE;
> +
> +  for (BusNo = MaxBus; (BusNo != 0xFF) && (!AspmFound); --BusNo) {
> +    for (DevNo = 0; (DevNo <= PCI_MAX_DEVICE) && (!AspmFound); ++DevNo)
> {
> +      for (FunNo = 0; (FunNo <= PCI_MAX_FUNC) && (!AspmFound); ++FunNo)
> {
> +        //
> +        // Check for Device availability
> +        //
> +        DevBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, BusNo,
> DevNo, FunNo, 0);
> +        if (PciSegmentRead16 (DevBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +          //
> +          // Device not present
> +          //
> +          continue;
> +        }
> +
> +        RegVal = PciSegmentRead8 (DevBaseAddress +
> PCI_HEADER_TYPE_OFFSET);
> +        if ((RegVal & (BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6)) != 0x01) {
> +          //
> +          // Not a PCI-to-PCI bridges device
> +          //
> +          continue;
> +        }
> +
> +        SecBusNo = PciSegmentRead8 (DevBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +
> +        if (SecBusNo == Bus) {
> +          //
> +          // This is the Rootbridge for the given 'Bus' device
> +          //
> +          CapHeaderOffset_B = PcieFindCapId (TbtSegment, BusNo, DevNo,
> FunNo, 0x10);
> +          SelectedAspm      = (PciSegmentRead16 (DevBaseAddress +
> CapHeaderOffset_B + 0x00C) >> 10) & 3;
> +          AspmFound         = TRUE;
> +        }
> +      } //FunNo
> +    } //DevNo
> +  } //BusNo
> +
> +  return (SelectedAspm);
> +}
> +
> +VOID
> +NoAspmSupport (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT8   CapHeaderOffset
> +  )
> +{
> +  UINT64 DeviceBaseAddress;
> +
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10,
> 0xFFFC, 0x00);
> +}
> +
> +VOID
> +EndpointAspmSupport (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT8   CapHeaderOffset,
> +  IN UINT8   MaxBus,
> +  IN UINT16  MaxAspmLevel
> +  )
> +{
> +  UINT64  DeviceBaseAddress;
> +  UINT16  ComponentAaspm;
> +  UINT16  ComponentBaspm;
> +  UINT16  SelectedAspm;
> +
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +  ComponentAaspm    = (PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffset + 0x00C) >> 10) & 3;
> +  ComponentBaspm    = FindComponentBaspm (Bus, MaxBus);
> +  SelectedAspm      = FindOptimalAspm (ComponentAaspm,
> ComponentBaspm);
> +  SelectedAspm      = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
> +  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10,
> 0xFFFC, SelectedAspm);
> +}
> +
> +VOID
> +UpstreamAspmSupport (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT8   CapHeaderOffset,
> +  IN UINT8   MaxBus,
> +  IN UINT16  MaxAspmLevel
> +  )
> +{
> +  UINT64  DeviceBaseAddress;
> +  UINT16  ComponentAaspm;
> +  UINT16  ComponentBaspm;
> +  UINT16  SelectedAspm;
> +
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +  ComponentAaspm    = (PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffset + 0x00C) >> 10) & 3;
> +  ComponentBaspm    = FindComponentBaspm (Bus, MaxBus);
> +  SelectedAspm      = FindOptimalAspm (ComponentAaspm,
> ComponentBaspm);
> +  SelectedAspm      = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
> +  PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10,
> 0xFFFC, SelectedAspm);
> +}
> +
> +VOID
> +DownstreamAspmSupport (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT8   CapHeaderOffset,
> +  IN UINT16  MaxAspmLevel
> +  )
> +{
> +  UINT64  ComponentABaseAddress;
> +  UINT64  ComponentBBaseAddress;
> +  UINT16  ComponentAaspm;
> +  UINT16  ComponentBaspm;
> +  UINT16  SelectedAspm;
> +  UINT8   SecBus;
> +  UINT8   CapHeaderOffset_B;
> +
> +  ComponentABaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +  ComponentAaspm        = (PciSegmentRead16 (ComponentABaseAddress +
> CapHeaderOffset + 0x00C) >> 10) & 3;
> +
> +  SecBus                = PciSegmentRead8 (ComponentABaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,
> SecBus, 0, 0, 0);
> +  ComponentBaspm        = 0; // No ASPM Support
> +  if (PciSegmentRead16 (ComponentBBaseAddress +
> PCI_DEVICE_ID_OFFSET) != 0xFFFF) {
> +    CapHeaderOffset_B = PcieFindCapId (TbtSegment, SecBus, 0, 0, 0x10);
> +    ComponentBaspm    = (PciSegmentRead16 (ComponentBBaseAddress +
> CapHeaderOffset_B + 0x00C) >> 10) & 3;
> +  }
> +
> +  SelectedAspm = FindOptimalAspm (ComponentAaspm,
> ComponentBaspm);
> +  SelectedAspm = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
> +  PciSegmentAndThenOr16 (ComponentABaseAddress + CapHeaderOffset +
> 0x10, 0xFFFC, SelectedAspm);
> +}
> +
> +VOID
> +RootportAspmSupport (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT8   CapHeaderOffset,
> +  IN UINT16  MaxAspmLevel
> +  )
> +{
> +  UINT64  ComponentABaseAddress;
> +  UINT64  ComponentBBaseAddress;
> +  UINT16  ComponentAaspm;
> +  UINT16  ComponentBaspm;
> +  UINT16  SelectedAspm;
> +  UINT8   SecBus;
> +  UINT8   CapHeaderOffset_B;
> +
> +  ComponentABaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +  ComponentAaspm        = (PciSegmentRead16 (ComponentABaseAddress +
> CapHeaderOffset + 0x00C) >> 10) & 3;
> +
> +  SecBus                = PciSegmentRead8 (ComponentABaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  ComponentBBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,
> SecBus, 0, 0, 0);
> +  ComponentBaspm        = 0; // No ASPM Support
> +  if (PciSegmentRead16 (ComponentBBaseAddress +
> PCI_DEVICE_ID_OFFSET) != 0xFFFF) {
> +    CapHeaderOffset_B = PcieFindCapId (TbtSegment, SecBus, 0, 0, 0x10);
> +    ComponentBaspm    = (PciSegmentRead16 (ComponentBBaseAddress +
> CapHeaderOffset_B + 0x00C) >> 10) & 3;
> +  }
> +
> +  SelectedAspm = FindOptimalAspm (ComponentAaspm,
> ComponentBaspm);
> +  SelectedAspm = LimitAspmLevel (SelectedAspm, MaxAspmLevel);
> +  PciSegmentAndThenOr16 (ComponentABaseAddress + CapHeaderOffset +
> 0x10, 0xFFFC, SelectedAspm);
> +}
> +
> +VOID
> +ThunderboltEnableAspmWithoutLtr (
> +  IN   UINT16     MaxAspmLevel,
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  UINT8   Bus;
> +  UINT8   Dev;
> +  UINT8   Fun;
> +  UINT8   RootBus;
> +  UINT8   RootDev;
> +  UINT8   RootFun;
> +  UINT8   MinBus;
> +  UINT8   MaxBus;
> +  UINT16  DeviceId;
> +  UINT64  DeviceBaseAddress;
> +  UINT8   RegVal;
> +  UINT8   CapHeaderOffset;
> +  UINT16  DevicePortType;
> +
> +  MinBus  = 0;
> +  MaxBus  = 0;
> +
> +  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> +  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
> +  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
> +  if (!(IsTbtHostRouter (DeviceId))) {
> +    return;
> +  }
> +
> +  TbtSegment = (UINT8)RpSegment;
> +
> +  RootBus = (UINT8)RpBus;
> +  RootDev = (UINT8)RpDevice;
> +  RootFun = (UINT8)RpFunction;
> +
> +  //
> +  //  Enumerate all the bridges and devices which are available on TBT host
> controller
> +  //
> +  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      //
> +      // Check for Device availability
> +      //
> +      DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, 0, 0);
> +      if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +        //
> +        // Device not present
> +        //
> +        continue;
> +      }
> +
> +      RegVal = PciSegmentRead8 (DeviceBaseAddress +
> PCI_HEADER_TYPE_OFFSET);
> +      if ((RegVal & BIT7) == 0) {
> +        //
> +        // Not a multi-function device
> +        //
> +        continue;
> +      }
> +
> +      MultiFunctionDeviceAspm(Bus, Dev);
> +    } //Dev
> +  } //Bus
> +
> +
> +  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        //
> +        // Check for Device availability
> +        //
> +        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +          //
> +          // Device not present
> +          //
> +          continue;
> +        }
> +
> +        CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
> +        DevicePortType  = (PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffset + 0x002) >> 4) & 0xF;
> +        if(PciSegmentRead8 (DeviceBaseAddress + PCI_CLASSCODE_OFFSET) ==
> PCI_CLASS_SERIAL) {
> +          MaxAspmLevel = (UINT16) 0x1;
> +        }
> +
> +        switch (DevicePortType) {
> +        case 0:
> +          //
> +          // PCI Express Endpoint
> +          //
> +          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus,
> MaxAspmLevel);
> +          break;
> +
> +        case 1:
> +          //
> +          // Legacy PCI Express Endpoint
> +          //
> +          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus,
> MaxAspmLevel);
> +          break;
> +
> +        case 4:
> +          //
> +          // Root Port of PCI Express Root Complex
> +          //
> +          RootportAspmSupport (Bus, Dev, Fun, CapHeaderOffset,
> MaxAspmLevel);
> +          break;
> +
> +        case 5:
> +          //
> +          // Upstream Port of PCI Express Switch
> +          //
> +          UpstreamAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus,
> MaxAspmLevel);
> +          break;
> +
> +        case 6:
> +          //
> +          // Downstream Port of PCI Express Switch
> +          //
> +          DownstreamAspmSupport (Bus, Dev, Fun, CapHeaderOffset,
> MaxAspmLevel);
> +          break;
> +
> +        case 7:
> +          //
> +          // PCI Express to PCI/PCI-X Bridge
> +          //
> +          NoAspmSupport (Bus, Dev, Fun, CapHeaderOffset);
> +          break;
> +
> +        case 8:
> +          //
> +          // PCI/PCI-X to PCI Express Bridge
> +          //
> +          NoAspmSupport (Bus, Dev, Fun, CapHeaderOffset);
> +          break;
> +
> +        case 9:
> +          //
> +          // Root Complex Integrated Endpoint
> +          //
> +          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus,
> MaxAspmLevel);
> +          break;
> +
> +        case 10:
> +          //
> +          // Root Complex Event Collector
> +          //
> +          EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus,
> MaxAspmLevel);
> +          break;
> +
> +        default:
> +          break;
> +        }
> +        //
> +        // switch(DevicePortType)
> +        //
> +      }
> +      //
> +      // Fun
> +      //
> +    }
> +    //
> +    // Dev
> +    //
> +  }
> +  //
> +  // Bus
> +  //
> +  CapHeaderOffset = PcieFindCapId (TbtSegment, RootBus, RootDev, RootFun,
> 0x10);
> +  RootportAspmSupport (RootBus, RootDev, RootFun, CapHeaderOffset,
> MaxAspmLevel);
> +}
> +
> +
> +
> +VOID
> +ThunderboltEnableL1Sub (
> +  IN   UINT16     MaxL1Level,
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  UINT16  CapHeaderOffsetExtd;
> +
> +  RpBus   = 0;
> +
> +  CapHeaderOffsetExtd = PcieFindExtendedCapId ((UINT8) RpBus, (UINT8)
> RpDevice, (UINT8) RpFunction, V_PCIE_EX_L1S_CID);
> +  RootportL1sSupport ((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction,
> CapHeaderOffsetExtd, MaxL1Level);
> +}
> +
> +VOID
> +ThunderboltDisableAspmWithoutLtr (
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  UINT8   Bus;
> +  UINT8   Dev;
> +  UINT8   Fun;
> +  UINT8   RootBus;
> +  UINT8   RootDev;
> +  UINT8   RootFun;
> +  UINT8   MinBus;
> +  UINT8   MaxBus;
> +  UINT16  DeviceId;
> +  UINT64  DeviceBaseAddress;
> +  UINT8   CapHeaderOffset;
> +
> +  MinBus  = 0;
> +  MaxBus  = 0;
> +
> +  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> +  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
> +  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
> +  if (!(IsTbtHostRouter (DeviceId))) {
> +    return;
> +  }
> +
> +  TbtSegment = (UINT8)RpSegment;
> +  RootBus = (UINT8)RpBus;
> +  RootDev = (UINT8)RpDevice;
> +  RootFun = (UINT8)RpFunction;
> +
> +  //
> +  //  Enumerate all the bridges and devices which are available on TBT host
> controller
> +  //
> +  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        //
> +        // Check for Device availability
> +        //
> +        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +          //
> +          // Device not present
> +          //
> +          continue;
> +        }
> +
> +        CapHeaderOffset = PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10);
> +        PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset +
> 0x10, 0xFFFC, 0x00);
> +      } //Fun
> +    } //Dev
> +  } //Bus
> +
> +  CapHeaderOffset = PcieFindCapId (TbtSegment, RootBus, RootDev, RootFun,
> 0x10);
> +  NoAspmSupport(RootBus, RootDev, RootFun, CapHeaderOffset);
> +}
> +
> +VOID
> +TbtProgramClkReq (
> +  IN        UINT8  Bus,
> +  IN        UINT8  Device,
> +  IN        UINT8  Function,
> +  IN        UINT8  ClkReqSetup
> +  )
> +{
> +  UINT64  DeviceBaseAddress;
> +  UINT8   CapHeaderOffset;
> +  UINT16  Data16;
> +
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Device, Function, 0);
> +  CapHeaderOffset   = PcieFindCapId (TbtSegment, Bus, Device, Function,
> 0x10);
> +
> +  //
> +  // Check if CLKREQ# is supported
> +  //
> +  if ((PciSegmentRead32 (DeviceBaseAddress + CapHeaderOffset + 0x0C) &
> BIT18) != 0) {
> +    Data16 = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset +
> 0x010);
> +
> +    if (ClkReqSetup) {
> +      Data16 = Data16 | BIT8; // Enable Clock Power Management
> +    } else {
> +      Data16 =  Data16 & (UINT16)(~BIT8); // Disable Clock Power
> Management
> +    }
> +
> +    PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffset + 0x010,
> Data16);
> +  }
> +}
> +VOID
> +TbtProgramPtm(
> +   IN        UINT8  Bus,
> +   IN        UINT8  Device,
> +   IN        UINT8  Function,
> +   IN        UINT8  PtmSetup,
> +   IN        BOOLEAN IsRoot
> +)
> +{
> +   UINT64  DeviceBaseAddress;
> +   UINT16  CapHeaderOffset;
> +   UINT16  PtmControlRegister;
> +   UINT16  PtmCapabilityRegister;
> +
> +   DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS(TbtSegment, Bus,
> Device, Function, 0);
> +   CapHeaderOffset = PcieFindExtendedCapId(Bus, Device, Function, 0x001F
> /*V_PCIE_EX_PTM_CID*/);
> +   if(CapHeaderOffset != 0) {
> +      PtmCapabilityRegister = PciSegmentRead16(DeviceBaseAddress +
> CapHeaderOffset + 0x04);
> +     //
> +     // Check if PTM Requester/ Responder capability for the EP/Down stream
> etc
> +     //
> +     if ((PtmCapabilityRegister & (BIT1 | BIT0)) != 0) {
> +        PtmControlRegister = PciSegmentRead16(DeviceBaseAddress +
> CapHeaderOffset + 0x08);
> +
> +        if (PtmSetup) {
> +           PtmControlRegister = PtmControlRegister | BIT0; // Enable PTM
> +           if(IsRoot) {
> +             PtmControlRegister = PtmControlRegister | BIT1; // Enable PTM
> +           }
> +           PtmControlRegister = PtmControlRegister | (PtmCapabilityRegister &
> 0xFF00); // Programm Local Clock Granularity
> +        } else {
> +           PtmControlRegister = PtmControlRegister & (UINT16)(~(BIT0 | BIT1));
> // Disable Clock Power Management
> +        }
> +
> +        PciSegmentWrite16(DeviceBaseAddress + CapHeaderOffset + 0x08,
> PtmControlRegister);
> +     }
> +   }
> +}
> +
> +VOID
> +ConfigureTbtPm (
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction,
> +  IN   UINT8      Configuration    // 1- Clk Request , 2- PTM ,
> +  )
> +{
> +  UINT8   Bus;
> +  UINT8   Dev;
> +  UINT8   Fun;
> +  UINT8   MinBus;
> +  UINT8   MaxBus;
> +  UINT16  DeviceId;
> +  UINT64  DeviceBaseAddress;
> +
> +  MinBus  = 0;
> +  MaxBus  = 0;
> +
> +  if ((Configuration != 1) && (Configuration != 2)) {
> +    return;
> +  }
> +  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> +  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
> +  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
> +  if (!(IsTbtHostRouter (DeviceId))) {
> +    return;
> +  }
> +
> +  TbtSegment = (UINT8)RpSegment;
> +  //
> +  //  Enumerate all the bridges and devices which are available on TBT host
> controller
> +  //
> +  for (Bus = MaxBus; Bus >= MinBus; --Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        //
> +        // Check for Device availability
> +        //
> +        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +          if (Fun == 0) {
> +            //
> +            // IF Fun is zero, stop enumerating other functions of the particular
> bridge
> +            //
> +            break;
> +          }
> +          //
> +          // otherwise, just skip checking for CLKREQ support
> +          //
> +          continue;
> +        }
> +        switch (Configuration) {
> +          case 1:
> +            TbtProgramClkReq (Bus, Dev, Fun, (UINT8)
> mTbtNvsAreaPtr->TbtSetClkReq);
> +            break;
> +          case 2:
> +            TbtProgramPtm (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtPtm,
> FALSE);
> +            TbtProgramPtm((UINT8) RpBus, (UINT8) RpDevice, (UINT8)
> RpFunction, (UINT8) mTbtNvsAreaPtr->TbtPtm, TRUE);
> +            break;
> +          default:
> +            break;
> +        }
> +      } //Fun
> +    } // Dev
> +  } // Bus
> +}
> +
> +/**
> +  1) Check LTR support in device capabilities 2 register (bit 11).
> +  2) If supported enable LTR in device control 2 register (bit 10).
> +
> +**/
> +VOID
> +TbtProgramLtr (
> +  IN        UINT8  Bus,
> +  IN        UINT8  Device,
> +  IN        UINT8  Function,
> +  IN        UINT8  LtrSetup
> +  )
> +{
> +  UINT64  DeviceBaseAddress;
> +  UINT8   CapHeaderOffset;
> +  UINT16  Data16;
> +
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Device, Function, 0);
> +  CapHeaderOffset   = PcieFindCapId (TbtSegment, Bus, Device, Function,
> 0x10);
> +
> +  //
> +  // Check if LTR# is supported
> +  //
> +  if ((PciSegmentRead32 (DeviceBaseAddress + CapHeaderOffset + 0x24) &
> BIT11) != 0) {
> +    Data16 = PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset +
> 0x028);
> +
> +    if (LtrSetup) {
> +      Data16 = Data16 | BIT10; // LTR Mechanism Enable
> +    } else {
> +      Data16 =  Data16 & (UINT16)(~BIT10); // LTR Mechanism Disable
> +    }
> +
> +    PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffset + 0x028,
> Data16);
> +  }
> +}
> +
> +VOID
> +ConfigureLtr (
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  UINT8   Bus;
> +  UINT8   Dev;
> +  UINT8   Fun;
> +  UINT8   MinBus;
> +  UINT8   MaxBus;
> +  UINT16  DeviceId;
> +  UINT64  DeviceBaseAddress;
> +
> +  MinBus  = 0;
> +  MaxBus  = 0;
> +
> +  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> +  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
> +  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
> +  if (!(IsTbtHostRouter (DeviceId))) {
> +    return;
> +  }
> +
> +  TbtSegment = (UINT8)RpSegment;
> +  //
> +  //  Enumerate all the bridges and devices which are available on TBT host
> controller
> +  //
> +  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        //
> +        // Check for Device availability
> +        //
> +        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +          if (Fun == 0) {
> +            //
> +            // IF Fun is zero, stop enumerating other functions of the particular
> bridge
> +            //
> +            break;
> +          }
> +          //
> +          // otherwise, just skip checking for LTR support
> +          //
> +          continue;
> +        }
> +
> +        TbtProgramLtr (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtLtr);
> +
> +      } //Fun
> +    } // Dev
> +  } // Bus
> +  TbtProgramLtr ((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunction,
> (UINT8) mTbtNvsAreaPtr->TbtLtr);
> +}
> +
> +/*
> +  US ports and endpoints which declare support must also have the LTR
> capability structure (cap ID 18h).
> +  In this structure you need to enter the max snoop latency and max
> non-snoop latency in accordance with the format specified in the PCIe spec.
> +  The latency value itself is platform specific so you'll need to get it from the
> platform architect or whatever.
> +*/
> +VOID
> +ThunderboltGetLatencyLtr (
> +  VOID
> +  )
> +{
> +  PCH_SERIES       PchSeries;
> +
> +  PchSeries = GetPchSeries ();
> +
> +  if(gCurrentDiscreteTbtRootPortType == DTBT_TYPE_PEG) {
> +  // PEG selector
> +  TbtLtrMaxSnoopLatency = LTR_MAX_SNOOP_LATENCY_VALUE;
> +  TbtLtrMaxNoSnoopLatency = LTR_MAX_NON_SNOOP_LATENCY_VALUE;
> +  } else if (gCurrentDiscreteTbtRootPortType == DTBT_TYPE_PCH) {
> +  // PCH selector
> +
> +    if (PchSeries == PchLp) {
> +      TbtLtrMaxSnoopLatency = 0x1003;
> +      TbtLtrMaxNoSnoopLatency = 0x1003;
> +    }
> +    if (PchSeries == PchH) {
> +      TbtLtrMaxSnoopLatency = 0x0846;
> +      TbtLtrMaxNoSnoopLatency = 0x0846;
> +    }
> +  }
> +}
> +
> +VOID
> +SetLatencyLtr (
> +  IN UINT8   Bus,
> +  IN UINT8   Dev,
> +  IN UINT8   Fun,
> +  IN UINT16  CapHeaderOffsetExtd,
> +  IN UINT16  LtrMaxSnoopLatency,
> +  IN UINT16  LtrMaxNoSnoopLatency
> +  )
> +{
> +  UINT64 DeviceBaseAddress;
> +  if(CapHeaderOffsetExtd == 0) {
> +    return;
> +  }
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,
> Fun, 0);
> +  PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffsetExtd + 0x004,
> LtrMaxSnoopLatency);
> +  PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffsetExtd + 0x006,
> LtrMaxNoSnoopLatency);
> +}
> +
> +VOID
> +ThunderboltSetLatencyLtr (
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  UINT8   Bus;
> +  UINT8   Dev;
> +  UINT8   Fun;
> +  UINT8   MinBus;
> +  UINT8   MaxBus;
> +  UINT16  DeviceId;
> +  UINT64  DeviceBaseAddress;
> +  UINT8   CapHeaderOffsetStd;
> +  UINT16  CapHeaderOffsetExtd;
> +  UINT16  DevicePortType;
> +
> +  MinBus  = 0;
> +  MaxBus  = 0;
> +
> +  MinBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
> +  MaxBus    = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> RpBus, RpDevice, RpFunction,
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET));
> +  DeviceId  = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment,
> MinBus, 0x00, 0x00, PCI_DEVICE_ID_OFFSET));
> +  if (!(IsTbtHostRouter (DeviceId))) {
> +    return;
> +  }
> +
> +  TbtSegment = (UINT8)RpSegment;
> +
> +  for (Bus = MinBus; Bus <= MaxBus; ++Bus) {
> +    for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
> +      for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
> +        //
> +        // Check for Device availability
> +        //
> +        DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus,
> Dev, Fun, 0);
> +        if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) ==
> 0xFFFF) {
> +          //
> +          // Device not present
> +          //
> +          continue;
> +        }
> +
> +        CapHeaderOffsetStd = PcieFindCapId (TbtSegment, Bus, Dev, Fun,
> 0x10);
> +        DevicePortType  = (PciSegmentRead16 (DeviceBaseAddress +
> CapHeaderOffsetStd + 0x002) >> 4) & 0xF;
> +
> +        CapHeaderOffsetExtd = PcieFindExtendedCapId (Bus, Dev, Fun,
> 0x0018);
> +
> +        switch (DevicePortType) {
> +        case 0:
> +          //
> +          // PCI Express Endpoint
> +          //
> +          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd,
> TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
> +          break;
> +
> +        case 1:
> +          //
> +          // Legacy PCI Express Endpoint
> +          //
> +          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd,
> TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
> +          break;
> +
> +        case 4:
> +          //
> +          // Root Port of PCI Express Root Complex
> +          //
> +          // Do-nothing
> +          break;
> +
> +        case 5:
> +          //
> +          // Upstream Port of PCI Express Switch
> +          //
> +          SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd,
> TbtLtrMaxSnoopLatency, TbtLtrMaxNoSnoopLatency);
> +          break;
> +
> +        case 6:
> +          //
> +          // Downstream Port of PCI Express Switch
> +          //
> +          // Do-nothing
> +          break;
> +
> +        case 7:
> +          //
> +          // PCI Express to PCI/PCI-X Bridge
> +          //
> +          // Do-nothing
> +          break;
> +
> +        case 8:
> +          //
> +          // PCI/PCI-X to PCI Express Bridge
> +          //
> +          // Do-nothing
> +          break;
> +
> +        case 9:
> +          //
> +          // Root Complex Integrated Endpoint
> +          //
> +          // Do-nothing
> +          break;
> +
> +        case 10:
> +          //
> +          // Root Complex Event Collector
> +          //
> +          // Do-nothing
> +          break;
> +
> +        default:
> +          break;
> +        }
> +        //
> +        // switch(DevicePortType)
> +        //
> +      }
> +      //
> +      // Fun
> +      //
> +    }
> +    //
> +    // Dev
> +    //
> +  }
> +  //
> +  // Bus
> +  //
> +}
> +
> +static
> +VOID
> +Stall (
> +  UINTN     Usec
> +  )
> +{
> +  UINTN   Index;
> +  UINT32  Data32;
> +  UINT32  PrevData;
> +  UINTN   Counter;
> +
> +  Counter = (UINTN) ((Usec * 10) / 3);
> +  //
> +  // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
> +  // periods, thus attempting to ensure Microseconds of stall time.
> +  //
> +  if (Counter != 0) {
> +
> +    PrevData = IoRead32 (PcdGet16 (PcdAcpiBaseAddress) +
> R_PCH_ACPI_PM1_TMR);
> +    for (Index = 0; Index < Counter;) {
> +      Data32 = IoRead32 (PcdGet16 (PcdAcpiBaseAddress) +
> R_PCH_ACPI_PM1_TMR);
> +      if (Data32 < PrevData) {
> +        //
> +        // Reset if there is a overlap
> +        //
> +        PrevData = Data32;
> +        continue;
> +      }
> +
> +      Index += (Data32 - PrevData);
> +      PrevData = Data32;
> +    }
> +  }
> +
> +  return ;
> +}
> +/**
> +  Called during Sx entry, initates TbtSetPcie2TbtCommand HandShake to set
> GO2SX_NO_WAKE
> +  for Tbt devices if WakeupSupport is not present.
> +
> +  @param[in] DispatchHandle         - The unique handle assigned to this
> handler by SmiHandlerRegister().
> +  @param[in] DispatchContext        - Points to an optional handler context
> which was specified when the
> +                                      handler was registered.
> +  @param[in, out] CommBuffer        - A pointer to a collection of data in
> memory that will
> +                                      be conveyed from a non-SMM environment into
> an SMM environment.
> +  @param[in, out] CommBufferSize    - The size of the CommBuffer.
> +
> +  @retval EFI_SUCCESS               - The interrupt was handled successfully.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SxDTbtEntryCallback (
> +  IN  EFI_HANDLE                    DispatchHandle,
> +  IN  CONST VOID                    *DispatchContext,
> +  IN  OUT VOID                      *CommBuffer OPTIONAL,
> +  IN  UINTN                         *CommBufferSize OPTIONAL
> +  )
> +{
> +  UINT16          DeviceId;
> +  UINT8           CableConnected;
> +  UINT8           RootportSelected;
> +  UINT8           HoustRouteBus;
> +  volatile UINT32 *PowerState;
> +  UINT32          PowerStatePrev;
> +  BOOLEAN         SecSubBusAssigned;
> +  UINT64          DeviceBaseAddress;
> +  UINT8           CapHeaderOffset;
> +  UINTN           RpDev;
> +  UINTN           RpFunc;
> +  EFI_STATUS      Status;
> +  UINT32          Timeout;
> +  UINT32          RegisterValue;
> +  UINT64          Tbt2Pcie;
> +  UINTN           Index;
> +  UINT32          TbtCioPlugEventGpioNo;
> +  UINT32          TbtFrcPwrGpioNo;
> +  UINT8           TbtFrcPwrGpioLevel;
> +  UINT32          TbtPcieRstGpioNo;
> +  UINT8           TbtPcieRstGpioLevel;
> +  EFI_SMM_SX_REGISTER_CONTEXT   *EntryDispatchContext;
> +
> +  CableConnected    = 0;
> +  HoustRouteBus     = 3;
> +  SecSubBusAssigned = FALSE;
> +  Timeout = 600;
> +  RootportSelected      = 0;
> +  TbtCioPlugEventGpioNo = 0;
> +  TbtFrcPwrGpioNo       = 0;
> +  TbtFrcPwrGpioLevel    = 0;
> +  TbtPcieRstGpioNo      = 0;
> +  TbtPcieRstGpioLevel   = 0;
> +  Index = 0;
> +
> +  EntryDispatchContext = (EFI_SMM_SX_REGISTER_CONTEXT*)
> DispatchContext;
> +
> +//  CableConnected = GetTbtHostRouterStatus ();
> +  //SaveTbtHostRouterStatus (CableConnected & 0xF0);
> +  //
> +  // Get the Power State and Save
> +  //
> +  if (((mTbtNvsAreaPtr->DTbtControllerEn0 == 0) && (Index == 0)))  {
> +
> +  RootportSelected      = mTbtNvsAreaPtr->RootportSelected0;
> +  TbtCioPlugEventGpioNo = mTbtNvsAreaPtr->TbtCioPlugEventGpioNo0;
> +  TbtFrcPwrGpioNo       = mTbtNvsAreaPtr->TbtFrcPwrGpioNo0;
> +  TbtFrcPwrGpioLevel    = mTbtNvsAreaPtr->TbtFrcPwrGpioLevel0;
> +  TbtPcieRstGpioNo      = mTbtNvsAreaPtr->TbtPcieRstGpioNo0;
> +  TbtPcieRstGpioLevel   = mTbtNvsAreaPtr->TbtPcieRstGpioLevel0;
> +  }
> +
> +  Status = GetDTbtRpDevFun (gCurrentDiscreteTbtRootPortType,
> RootportSelected - 1, &RpDev, &RpFunc);
> +  ASSERT_EFI_ERROR (Status);
> +  CapHeaderOffset = PcieFindCapId (TbtSegment, 0x00, (UINT8)RpDev,
> (UINT8)RpFunc, 0x01);
> +  DeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, 0x00,
> (UINT32)RpDev, (UINT32)RpFunc, 0);
> +  PowerState        = &*((volatile UINT32 *) (mPciExpressBaseAddress +
> DeviceBaseAddress + CapHeaderOffset + 4)); //PMCSR
> +  PowerStatePrev    = *PowerState;
> +  *PowerState &= 0xFFFFFFFC;
> +
> +  HoustRouteBus = PciSegmentRead8 (DeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
> +  //
> +  // Check the Subordinate bus .If it is Zero ,assign temporary bus to
> +  // find the device presence .
> +  //
> +  if (HoustRouteBus == 0) {
> +    PciSegmentWrite8 (DeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0xF0);
> +    PciSegmentWrite8 (DeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0xF0);
> +    HoustRouteBus     = 0xF0;
> +    SecSubBusAssigned = TRUE;
> +  }
> +  //
> +  // Clear Interrupt capability of TBT CIO Plug Event Pin to make sure no SCI is
> getting generated,
> +  // This GPIO will be reprogrammed while resuming as part of Platform GPIO
> Programming.
> +  //
> +  GpioSetPadInterruptConfig (TbtCioPlugEventGpioNo, GpioIntDis);
> +  //
> +  // Read the TBT Host router DeviceID
> +  //
> +  DeviceId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (TbtSegment,
> HoustRouteBus, 0, 0, PCI_DEVICE_ID_OFFSET));
> +
> +  //
> +  // Check For HostRouter Presence
> +  //
> +  if (IsTbtHostRouter (DeviceId)) {
> +    //    CableConnected = GetTbtHostRouterStatus ();
> +    if (!((CableConnected & (DTBT_SAVE_STATE_OFFSET << Index)) ==
> (DTBT_SAVE_STATE_OFFSET << Index))) {
> +      CableConnected = CableConnected | (DTBT_SAVE_STATE_OFFSET <<
> Index);
> +   //     SaveTbtHostRouterStatus (CableConnected);
> +    }
> +  }
> +
> +  //
> +  // Check value of Tbt2Pcie reg, if Tbt is not present, bios needs to apply force
> power prior to sending mailbox command
> +  //
> +  GET_TBT2PCIE_REGISTER_ADDRESS(TbtSegment, HoustRouteBus, 0x00,
> 0x00, Tbt2Pcie)
> +  RegisterValue = PciSegmentRead32 (Tbt2Pcie);
> +  if (0xFFFFFFFF == RegisterValue) {
> +
> +    GpioWrite (TbtFrcPwrGpioNo,TbtFrcPwrGpioLevel);
> +
> +    while (Timeout -- > 0) {
> +      RegisterValue = PciSegmentRead32 (Tbt2Pcie);
> +      if (0xFFFFFFFF != RegisterValue) {
> +        break;
> +      }
> +      Stall(1* (UINTN)1000);
> +    }
> +    //
> +    // Before entering Sx state BIOS should execute GO2SX/NO_WAKE mailbox
> command for AIC.
> +    // However BIOS shall not execute go2sx mailbox command on S5/reboot
> cycle.
> +    //
> +
> +    if( (EntryDispatchContext->Type == SxS3) || (EntryDispatchContext->Type
> == SxS4))
> +    {
> +      if(!mTbtNvsAreaPtr->TbtWakeupSupport) {
> +        //Wake Disabled, GO2SX_NO_WAKE Command
> +        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX_NO_WAKE,
> HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
> +      } else {
> +        //Wake Enabled, GO2SX Command
> +        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX, HoustRouteBus, 0, 0,
> TBT_5S_TIMEOUT);
> +      }
> +    }
> +    if (mTbtNvsAreaPtr->TbtFrcPwrEn == 0) {
> +      GpioWrite (TbtFrcPwrGpioNo,!(TbtFrcPwrGpioLevel));
> +    }
> +  } else {
> +    //
> +    // Before entering Sx state BIOS should execute GO2SX/NO_WAKE mailbox
> command for AIC.
> +    // However BIOS shall not execute go2sx mailbox command on S5/reboot
> cycle.
> +    //
> +    if( (EntryDispatchContext->Type == SxS3) || (EntryDispatchContext->Type
> == SxS4))
> +    {
> +      if(!mTbtNvsAreaPtr->TbtWakeupSupport) {
> +        //Wake Disabled, GO2SX_NO_WAKE Command
> +        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX_NO_WAKE,
> HoustRouteBus, 0, 0, TBT_5S_TIMEOUT);
> +      } else {
> +        //Wake Enabled, GO2SX Command
> +        TbtSetPcie2TbtCommand (PCIE2TBT_GO2SX, HoustRouteBus, 0, 0,
> TBT_5S_TIMEOUT);
> +      }
> +    }
> +  }
> +  *PowerState = PowerStatePrev;
> +  //
> +  // Restore the bus number in case we assigned temporarily
> +  //
> +  if (SecSubBusAssigned) {
> +    PciSegmentWrite8 (DeviceBaseAddress +
> PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0x00);
> +    PciSegmentWrite8 (DeviceBaseAddress +
> PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0x00);
> +  }
> +  if (gDTbtPcieRstSupport) {
> +    GpioWrite (TbtPcieRstGpioNo,TbtPcieRstGpioLevel);
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +VOID
> +ThunderboltSwSmiCallback (
> +  IN UINT8 Type
> +  )
> +{
> +  UINT8 ThunderboltSmiFunction;
> +
> +  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback Entry\n"));
> +  ThunderboltSmiFunction = mTbtNvsAreaPtr->ThunderboltSmiFunction;
> +  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback.
> ThunderboltSmiFunction=%d\n", ThunderboltSmiFunction));
> +  if (Type == DTBT_CONTROLLER) {
> +    gCurrentDiscreteTbtRootPort     =
> mTbtNvsAreaPtr->CurrentDiscreteTbtRootPort;
> +    gCurrentDiscreteTbtRootPortType =
> mTbtNvsAreaPtr->CurrentDiscreteTbtRootPortType;
> +  }
> +
> +  switch (ThunderboltSmiFunction) {
> +  case 21:
> +    ThunderboltCallback (Type);
> +    break;
> +
> +  case 22:
> +    TbtDisablePCIDevicesAndBridges (Type);
> +    break;
> +
> +  case 23:
> +    ConfigureTbtAspm (Type, (UINT16) 0x02);
> +    break;
> +
> +  case 24:
> +    ConfigureTbtAspm (Type, (UINT16) 0x01);
> +    break;
> +
> +  default:
> +    break;
> +  }
> +  DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback Exit.\n"));
> +}
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +DiscreteThunderboltSwSmiCallback (
> +  IN EFI_HANDLE                     DispatchHandle,
> +  IN  CONST VOID                    *DispatchContext,
> +  IN  OUT VOID                      *CommBuffer OPTIONAL,
> +  IN  UINTN                         *CommBufferSize OPTIONAL
> +  )
> +{
> +  ThunderboltSwSmiCallback(DTBT_CONTROLLER);
> +  return EFI_SUCCESS;
> +}
> +EFI_STATUS
> +TbtRegisterHandlers (
> +  IN BOOLEAN Type
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  UINTN                         SmiInputValue;
> +  EFI_SMM_HANDLER_ENTRY_POINT2   SxHandler;
> +  EFI_SMM_HANDLER_ENTRY_POINT2   SwHandler;
> +  EFI_SMM_SX_DISPATCH2_PROTOCOL *SxDispatchProtocol;
> +  EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
> +  EFI_SMM_SX_REGISTER_CONTEXT   EntryDispatchContext;
> +  EFI_SMM_SW_REGISTER_CONTEXT   SwContext;
> +  EFI_HANDLE                    SwDispatchHandle;
> +  EFI_HANDLE                    S3DispatchHandle;
> +  EFI_HANDLE                    S4DispatchHandle;
> +  EFI_HANDLE                    S5DispatchHandle;
> +
> +  Status = EFI_UNSUPPORTED;
> +
> +  if(Type == DTBT_CONTROLLER) {
> +    SxHandler = SxDTbtEntryCallback;
> +    SwHandler = DiscreteThunderboltSwSmiCallback;
> +    SmiInputValue = PcdGet8 (PcdSwSmiDTbtEnumerate);
> +    gDTbtPcieRstSupport =
> gTbtInfoHob->DTbtCommonConfig.PcieRstSupport;
> +    Status = EFI_SUCCESS;
> +  }
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  SwDispatchHandle        = NULL;
> +  S3DispatchHandle        = NULL;
> +  S4DispatchHandle        = NULL;
> +  S5DispatchHandle        = NULL;
> +
> +   Status = gSmst->SmmLocateProtocol (
> +                    &gEfiSmmSxDispatch2ProtocolGuid,
> +                    NULL,
> +                    (VOID **) &SxDispatchProtocol
> +                    );
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Register S3 entry phase call back function
> +  //
> +  EntryDispatchContext.Type   = SxS3;
> +  EntryDispatchContext.Phase  = SxEntry;
> +  Status = SxDispatchProtocol->Register (
> +                                SxDispatchProtocol,
> +                                SxHandler,
> +                                &EntryDispatchContext,
> +                                &S3DispatchHandle
> +                                );
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Register S4 entry phase call back function
> +  //
> +  EntryDispatchContext.Type   = SxS4;
> +  EntryDispatchContext.Phase  = SxEntry;
> +  Status = SxDispatchProtocol->Register (
> +                                SxDispatchProtocol,
> +                                SxHandler,
> +                                &EntryDispatchContext,
> +                                &S4DispatchHandle
> +                                );
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Register S5 entry phase call back function
> +  //
> +  EntryDispatchContext.Type   = SxS5;
> +  EntryDispatchContext.Phase  = SxEntry;
> +  Status = SxDispatchProtocol->Register (
> +                                SxDispatchProtocol,
> +                                SxHandler,
> +                                &EntryDispatchContext,
> +                                &S5DispatchHandle
> +                                );
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Locate the SMM SW dispatch protocol
> +  //
> +  Status = gSmst->SmmLocateProtocol (
> +                    &gEfiSmmSwDispatch2ProtocolGuid,
> +                    NULL,
> +                    (VOID **) &SwDispatch
> +                    );
> +
> +  ASSERT_EFI_ERROR (Status);
> +  //
> +  // Register SWSMI handler
> +  //
> +  SwContext.SwSmiInputValue = SmiInputValue;
> +  Status = SwDispatch->Register (
> +                        SwDispatch,
> +                        SwHandler,
> +                        &SwContext,
> +                        &SwDispatchHandle
> +                        );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +EFI_STATUS
> +InSmmFunction (
> +  IN  EFI_HANDLE        ImageHandle,
> +  IN  EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS                    Status;
> +
> +  Status = EFI_SUCCESS;
> +
> +  Status = TbtRegisterHandlers(DTBT_CONTROLLER);
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +TbtSmmEntryPoint (
> +  IN EFI_HANDLE               ImageHandle,
> +  IN EFI_SYSTEM_TABLE         *SystemTable
> +  )
> +{
> +  TBT_NVS_AREA_PROTOCOL         *TbtNvsAreaProtocol;
> +  EFI_STATUS                    Status;
> +
> +  DEBUG ((DEBUG_INFO, "TbtSmmEntryPoint\n"));
> +
> +  mPciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress);
> +  //
> +  // Locate Tbt shared data area
> +  //
> +  Status = gBS->LocateProtocol (&gTbtNvsAreaProtocolGuid, NULL, (VOID **)
> &TbtNvsAreaProtocol);
> +  ASSERT_EFI_ERROR (Status);
> +  mTbtNvsAreaPtr = TbtNvsAreaProtocol->Area;
> +
> +  //
> +  // Get TBT INFO HOB
> +  //
> +  gTbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
> +  if (gTbtInfoHob == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  return InSmmFunction (ImageHandle, SystemTable);
> +}
> +
> +VOID
> +EndOfThunderboltCallback (
> +  IN   UINTN      RpSegment,
> +  IN   UINTN      RpBus,
> +  IN   UINTN      RpDevice,
> +  IN   UINTN      RpFunction
> +  )
> +{
> +  if(mTbtNvsAreaPtr->TbtL1SubStates != 0) {
> +    ThunderboltEnableL1Sub (mTbtNvsAreaPtr->TbtL1SubStates, RpSegment,
> RpBus, RpDevice, RpFunction);
> +  }
> +  ConfigureTbtPm(RpSegment, RpBus, RpDevice, RpFunction, 1);
> +  if (!mTbtNvsAreaPtr->TbtAspm) { //Aspm disable case
> +    ThunderboltDisableAspmWithoutLtr (RpSegment, RpBus, RpDevice,
> RpFunction);
> +  } else { //Aspm enable case
> +    ThunderboltEnableAspmWithoutLtr
> ((UINT16)mTbtNvsAreaPtr->TbtAspm, RpSegment, RpBus, RpDevice,
> RpFunction);
> +  }
> +
> +  if (mTbtNvsAreaPtr->TbtLtr) {
> +    ThunderboltGetLatencyLtr ();
> +    ThunderboltSetLatencyLtr (RpSegment, RpBus, RpDevice, RpFunction);
> +  }
> +  ConfigureLtr (RpSegment, RpBus, RpDevice, RpFunction);
> +  ConfigureTbtPm(RpSegment, RpBus, RpDevice, RpFunction, 2);
> +} // EndOfThunderboltCallback
> +
> +VOID
> +ConfigureTbtAspm (
> +  IN UINT8        Type,
> +  IN UINT16       Aspm
> +  )
> +{
> +  UINTN                         RpSegment = 0;
> +  UINTN                         RpBus = 0;
> +  UINTN                         RpDevice;
> +  UINTN                         RpFunction;
> +
> +  if(Type == DTBT_CONTROLLER) {
> +    if (gCurrentDiscreteTbtRootPort == 0) {
> +      return;
> +    }
> +    GetDTbtRpDevFun(DTBT_CONTROLLER, gCurrentDiscreteTbtRootPort - 1,
> &RpDevice, &RpFunction);
> +
> +    ConfigureTbtPm (RpSegment, RpBus, RpDevice, RpFunction, 1);
> +    if (!mTbtNvsAreaPtr->TbtAspm) { //Aspm disable case
> +      ThunderboltDisableAspmWithoutLtr (RpSegment, RpBus, RpDevice,
> RpFunction);
> +    } else { //Aspm enable case
> +      ThunderboltEnableAspmWithoutLtr ((UINT16) Aspm, RpSegment, RpBus,
> RpDevice, RpFunction);
> +    }
> +
> +  if (mTbtNvsAreaPtr->TbtLtr) {
> +      ThunderboltGetLatencyLtr ();
> +      ThunderboltSetLatencyLtr (RpSegment, RpBus, RpDevice, RpFunction);
> +    }
> +    ConfigureLtr (RpSegment, RpBus, RpDevice, RpFunction);
> +  } // EndOfThunderboltCallback
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimer
> Lib.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTime
> rLib.c
> new file mode 100644
> index 0000000000..ec06eee73f
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTime
> rLib.c
> @@ -0,0 +1,394 @@
> +/** @file
> +  ACPI Timer implements one instance of Timer Library.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +#include <Library/TimerLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <IndustryStandard/Acpi.h>
> +//
> +// OVERRIDE: OverrideBegin
> +//
> +#include <Register/Cpuid.h>
> +//
> +// OVERRIDE: OverrideEnd
> +//
> +
> +
> +/**
> +  Internal function to retrieves the 64-bit frequency in Hz.
> +
> +  Internal function to retrieves the 64-bit frequency in Hz.
> +
> +  @return The frequency in Hz.
> +
> +**/
> +UINT64
> +InternalGetPerformanceCounterFrequency (
> +  VOID
> +  );
> +
> +/**
> +  The constructor function enables ACPI IO space.
> +
> +  If ACPI I/O space not enabled, this function will enable it.
> +  It will always return RETURN_SUCCESS.
> +
> +  @retval EFI_SUCCESS   The constructor always returns RETURN_SUCCESS.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +AcpiTimerLibConstructor (
> +  VOID
> +  )
> +{
> +  UINTN   Bus;
> +  UINTN   Device;
> +  UINTN   Function;
> +  UINTN   EnableRegister;
> +  UINT8   EnableMask;
> +
> +  //
> +  // ASSERT for the invalid PCD values. They must be configured to the real
> value.
> +  //
> +  ASSERT (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0xFFFF);
> +  ASSERT (PcdGet16 (PcdAcpiIoPortBaseAddress)      != 0xFFFF);
> +
> +  //
> +  // If the register offset to the BAR for the ACPI I/O Port Base Address is
> 0x0000, then
> +  // no PCI register programming is required to enable access to the the ACPI
> registers
> +  // specified by PcdAcpiIoPortBaseAddress
> +  //
> +  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) == 0x0000) {
> +    return RETURN_SUCCESS;
> +  }
> +
> +  //
> +  // ASSERT for the invalid PCD values. They must be configured to the real
> value.
> +  //
> +  ASSERT (PcdGet8  (PcdAcpiIoPciDeviceNumber)   != 0xFF);
> +  ASSERT (PcdGet8  (PcdAcpiIoPciFunctionNumber) != 0xFF);
> +  ASSERT (PcdGet16 (PcdAcpiIoPciEnableRegisterOffset) != 0xFFFF);
> +
> +  //
> +  // Retrieve the PCD values for the PCI configuration space required to
> program the ACPI I/O Port Base Address
> +  //
> +  Bus            = PcdGet8  (PcdAcpiIoPciBusNumber);
> +  Device         = PcdGet8  (PcdAcpiIoPciDeviceNumber);
> +  Function       = PcdGet8  (PcdAcpiIoPciFunctionNumber);
> +  EnableRegister = PcdGet16 (PcdAcpiIoPciEnableRegisterOffset);
> +  EnableMask     = PcdGet8  (PcdAcpiIoBarEnableMask);
> +
> +  //
> +  // If ACPI I/O space is not enabled yet, program ACPI I/O base address and
> enable it.
> +  //
> +  if ((PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister)) &
> EnableMask) != EnableMask) {
> +    PciWrite16 (
> +      PCI_LIB_ADDRESS (Bus, Device, Function, PcdGet16
> (PcdAcpiIoPciBarRegisterOffset)),
> +      PcdGet16 (PcdAcpiIoPortBaseAddress)
> +      );
> +    PciOr8 (
> +      PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister),
> +      EnableMask
> +      );
> +  }
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Internal function to retrieve the ACPI I/O Port Base Address.
> +
> +  Internal function to retrieve the ACPI I/O Port Base Address.
> +
> +  @return The 16-bit ACPI I/O Port Base Address.
> +
> +**/
> +UINT16
> +InternalAcpiGetAcpiTimerIoPort (
> +  VOID
> +  )
> +{
> +  UINT16  Port;
> +
> +  Port = PcdGet16 (PcdAcpiIoPortBaseAddress);
> +
> +  //
> +  // If the register offset to the BAR for the ACPI I/O Port Base Address is not
> 0x0000, then
> +  // read the PCI register for the ACPI BAR value in case the BAR has been
> programmed to a
> +  // value other than PcdAcpiIoPortBaseAddress
> +  //
> +  if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) != 0x0000) {
> +    Port = PciRead16 (PCI_LIB_ADDRESS (
> +                        PcdGet8  (PcdAcpiIoPciBusNumber),
> +                        PcdGet8  (PcdAcpiIoPciDeviceNumber),
> +                        PcdGet8  (PcdAcpiIoPciFunctionNumber),
> +                        PcdGet16 (PcdAcpiIoPciBarRegisterOffset)
> +                        ));
> +  }
> +
> +  return (Port & PcdGet16 (PcdAcpiIoPortBaseAddressMask)) + PcdGet16
> (PcdAcpiPm1TmrOffset);
> +}
> +
> +/**
> +  Stalls the CPU for at least the given number of ticks.
> +
> +  Stalls the CPU for at least the given number of ticks. It's invoked by
> +  MicroSecondDelay() and NanoSecondDelay().
> +
> +  @param  Delay     A period of time to delay in ticks.
> +
> +**/
> +VOID
> +InternalAcpiDelay (
> +  IN UINT32  Delay
> +  )
> +{
> +  UINT16   Port;
> +  UINT32   Ticks;
> +  UINT32   Times;
> +
> +  Port   = InternalAcpiGetAcpiTimerIoPort ();
> +  Times  = Delay >> 22;
> +  Delay &= BIT22 - 1;
> +  do {
> +    //
> +    // The target timer count is calculated here
> +    //
> +    Ticks = IoBitFieldRead32 (Port, 0, 23) + Delay;
> +    Delay = BIT22;
> +    //
> +    // Wait until time out
> +    // Delay >= 2^23 could not be handled by this function
> +    // Timer wrap-arounds are handled correctly by this function
> +    //
> +    while (((Ticks - IoBitFieldRead32 (Port, 0, 23)) & BIT23) == 0) {
> +      CpuPause ();
> +    }
> +  } while (Times-- > 0);
> +}
> +
> +/**
> +  Stalls the CPU for at least the given number of microseconds.
> +
> +  Stalls the CPU for the number of microseconds specified by MicroSeconds.
> +
> +  @param  MicroSeconds  The minimum number of microseconds to delay.
> +
> +  @return MicroSeconds
> +
> +**/
> +UINTN
> +EFIAPI
> +MicroSecondDelay (
> +  IN UINTN  MicroSeconds
> +  )
> +{
> +  InternalAcpiDelay (
> +    (UINT32)DivU64x32 (
> +              MultU64x32 (
> +                MicroSeconds,
> +                ACPI_TIMER_FREQUENCY
> +                ),
> +              1000000u
> +              )
> +    );
> +  return MicroSeconds;
> +}
> +
> +/**
> +  Stalls the CPU for at least the given number of nanoseconds.
> +
> +  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
> +
> +  @param  NanoSeconds The minimum number of nanoseconds to delay.
> +
> +  @return NanoSeconds
> +
> +**/
> +UINTN
> +EFIAPI
> +NanoSecondDelay (
> +  IN UINTN  NanoSeconds
> +  )
> +{
> +  InternalAcpiDelay (
> +    (UINT32)DivU64x32 (
> +              MultU64x32 (
> +                NanoSeconds,
> +                ACPI_TIMER_FREQUENCY
> +                ),
> +              1000000000u
> +              )
> +    );
> +  return NanoSeconds;
> +}
> +
> +/**
> +  Retrieves the current value of a 64-bit free running performance counter.
> +
> +  Retrieves the current value of a 64-bit free running performance counter.
> The
> +  counter can either count up by 1 or count down by 1. If the physical
> +  performance counter counts by a larger increment, then the counter values
> +  must be translated. The properties of the counter can be retrieved from
> +  GetPerformanceCounterProperties().
> +
> +  @return The current value of the free running performance counter.
> +
> +**/
> +UINT64
> +EFIAPI
> +GetPerformanceCounter (
> +  VOID
> +  )
> +{
> +  return AsmReadTsc ();
> +}
> +
> +/**
> +  Retrieves the 64-bit frequency in Hz and the range of performance counter
> +  values.
> +
> +  If StartValue is not NULL, then the value that the performance counter starts
> +  with immediately after is it rolls over is returned in StartValue. If
> +  EndValue is not NULL, then the value that the performance counter end with
> +  immediately before it rolls over is returned in EndValue. The 64-bit
> +  frequency of the performance counter in Hz is always returned. If StartValue
> +  is less than EndValue, then the performance counter counts up. If StartValue
> +  is greater than EndValue, then the performance counter counts down. For
> +  example, a 64-bit free running counter that counts up would have a
> StartValue
> +  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
> +  that counts down would have a StartValue of 0xFFFFFF and an EndValue of
> 0.
> +
> +  @param  StartValue  The value the performance counter starts with when
> it
> +                      rolls over.
> +  @param  EndValue    The value that the performance counter ends with
> before
> +                      it rolls over.
> +
> +  @return The frequency in Hz.
> +
> +**/
> +UINT64
> +EFIAPI
> +GetPerformanceCounterProperties (
> +  OUT UINT64  *StartValue,  OPTIONAL
> +  OUT UINT64  *EndValue     OPTIONAL
> +  )
> +{
> +  if (StartValue != NULL) {
> +    *StartValue = 0;
> +  }
> +
> +  if (EndValue != NULL) {
> +    *EndValue = 0xffffffffffffffffULL;
> +  }
> +  return InternalGetPerformanceCounterFrequency ();
> +}
> +
> +/**
> +  Converts elapsed ticks of performance counter to time in nanoseconds.
> +
> +  This function converts the elapsed ticks of running performance counter to
> +  time value in unit of nanoseconds.
> +
> +  @param  Ticks     The number of elapsed ticks of running performance
> counter.
> +
> +  @return The elapsed time in nanoseconds.
> +
> +**/
> +UINT64
> +EFIAPI
> +GetTimeInNanoSecond (
> +  IN UINT64  Ticks
> +  )
> +{
> +  UINT64  Frequency;
> +  UINT64  NanoSeconds;
> +  UINT64  Remainder;
> +  INTN    Shift;
> +  Frequency = GetPerformanceCounterProperties (NULL, NULL);
> +
> +  //
> +  //          Ticks
> +  // Time = --------- x 1,000,000,000
> +  //        Frequency
> +  //
> +  NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency,
> &Remainder), 1000000000u);
> +
> +  //
> +  // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.
> +  // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should <
> 2^(64-30) = 2^34,
> +  // i.e. highest bit set in Remainder should <= 33.
> +  //
> +  Shift = MAX (0, HighBitSet64 (Remainder) - 33);
> +  Remainder = RShiftU64 (Remainder, (UINTN) Shift);
> +  Frequency = RShiftU64 (Frequency, (UINTN) Shift);
> +  NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder,
> 1000000000u), Frequency, NULL);
> +
> +  return NanoSeconds;
> +}
> +
> +//
> +// OVERRIDE: OverrideBegin
> +//
> +/**
> +  Calculate TSC frequency.
> +
> +  The TSC counting frequency is determined by using CPUID leaf 0x15 that is
> the preferred
> +  method for Skylake and beyond.  Frequency in MHz = Core XTAL frequency
> * EBX/EAX.
> +  In newer flavors of the CPU, core xtal frequency is returned in ECX (or 0 if not
> +  supported).  If ECX is 0, 24MHz is assumed.
> +  @return The number of TSC counts per second.
> +
> +**/
> +UINT64
> +InternalCalculateTscFrequency (
> +  VOID
> +  )
> +{
> +  UINT64      TscFrequency;
> +  UINT64      CoreXtalFrequency;
> +  UINT32      RegEax;
> +  UINT32      RegEbx;
> +  UINT32      RegEcx;
> +
> +  //
> +  // Use CPUID leaf 0x15.
> +  // TSC frequency = (Core Xtal Frequency) * EBX/EAX.  EBX returns 0 if not
> +  // supported. ECX, if non zero, provides Core Xtal Frequency in hertz
> +  // (SDM Dec 2016).
> +  //
> +  AsmCpuid (CPUID_TIME_STAMP_COUNTER, &RegEax, &RegEbx, &RegEcx,
> NULL);
> +  ASSERT (RegEbx != 0);
> +
> +  //
> +  // If core xtal frequency (ECX) returns 0, it is safe to use 24MHz for post
> +  // Skylake client CPU's.
> +  //
> +  if (RegEcx == 0) {
> +    CoreXtalFrequency = 24000000ul;
> +  } else {
> +    CoreXtalFrequency = (UINT64)RegEcx;
> +  }
> +
> +  //
> +  // Calculate frequency.  For integer division, round up/down result
> +  // correctly by adding denominator/2 to the numerator prior to division.
> +  //
> +  TscFrequency = DivU64x32 (MultU64x32 (CoreXtalFrequency, RegEbx) +
> (UINT64)(RegEax >> 1), RegEax);
> +
> +  return TscFrequency;
> +}
> +//
> +// OVERRIDE: OverrideEnd
> +//
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLi
> b.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLi
> b.c
> new file mode 100644
> index 0000000000..2bba58eed3
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLi
> b.c
> @@ -0,0 +1,612 @@
> +/** @file
> +  Source code for the board configuration init function in DXE init phase.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "BoardInitLib.h"
> +#include <Library/HobLib.h>
> +#include <MemInfoHob.h>
> +#include <Library/PchSerialIoLib.h>
> +#include <PlatformBoardConfig.h>
> +#include <GpioPinsCnlLp.h>
> +#include <GpioPinsCnlH.h>
> +#include <Library/PchInfoLib.h>
> +#include <Library/PchEspiLib.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <TbtBoardInfo.h>
> +#include <Library/CpuPlatformLib.h>
> +#include <GopConfigLib.h>
> +//
> +// Null function for nothing GOP VBT update.
> +//
> +VOID
> +GopVbtSpecificUpdateNull(
> +  IN CHILD_STRUCT **ChildStructPtr
> +);
> +
> +//
> +// for CFL U DDR4
> +//
> +VOID
> +CflUDdr4GopVbtSpecificUpdate(
> +  IN CHILD_STRUCT **ChildStructPtr
> +);
> +
> +/**
> +  Updates DIMM slots status for Desktop,server and workstation boards
> +
> +**/
> +VOID
> +UpdateDimmPopulationConfig(
> +  VOID
> +  )
> +{
> +  MEMORY_INFO_DATA_HOB    *MemInfo;
> +  UINT8                   Slot0;
> +  UINT8                   Slot1;
> +  UINT8                   Slot2;
> +  UINT8                   Slot3;
> +  CONTROLLER_INFO         *ControllerInfo;
> +  EFI_HOB_GUID_TYPE       *GuidHob;
> +
> +  GuidHob = NULL;
> +  MemInfo = NULL;
> +
> +  GuidHob = GetFirstGuidHob (&gSiMemoryInfoDataGuid);
> +  ASSERT (GuidHob != NULL);
> +  if (GuidHob != NULL) {
> +    MemInfo = (MEMORY_INFO_DATA_HOB *) GET_GUID_HOB_DATA
> (GuidHob);
> +  }
> +  if (MemInfo != NULL) {
> +    if (PcdGet8 (PcdPlatformFlavor) == FlavorDesktop ||
> +        PcdGet8 (PcdPlatformFlavor) == FlavorUpServer ||
> +        PcdGet8 (PcdPlatformFlavor) == FlavorWorkstation) {
> +      ControllerInfo = &MemInfo->Controller[0];
> +      Slot0 = ControllerInfo->ChannelInfo[0].DimmInfo[0].Status;
> +      Slot1 = ControllerInfo->ChannelInfo[0].DimmInfo[1].Status;
> +      Slot2 = ControllerInfo->ChannelInfo[1].DimmInfo[0].Status;
> +      Slot3 = ControllerInfo->ChannelInfo[1].DimmInfo[1].Status;
> +
> +      //
> +      // Channel 0          Channel 1
> +      // Slot0   Slot1      Slot0   Slot1      - Population            AIO board
> +      // 0          0          0          0          - Invalid        - Invalid
> +      // 0          0          0          1          - Valid          - Invalid
> +      // 0          0          1          0          - Invalid        - Valid
> +      // 0          0          1          1          - Valid          - Valid
> +      // 0          1          0          0          - Valid          - Invalid
> +      // 0          1          0          1          - Valid          - Invalid
> +      // 0          1          1          0          - Invalid        - Invalid
> +      // 0          1          1          1          - Valid          - Invalid
> +      // 1          0          0          0          - Invalid        - Valid
> +      // 1          0          0          1          - Invalid        - Invalid
> +      // 1          0          1          0          - Invalid        - Valid
> +      // 1          0          1          1          - Invalid        - Valid
> +      // 1          1          0          0          - Valid          - Valid
> +      // 1          1          0          1          - Valid          - Invalid
> +      // 1          1          1          0          - Invalid        - Valid
> +      // 1          1          1          1          - Valid          - Valid
> +      //
> +
> +      if ((Slot0 && (Slot1 == 0)) || (Slot2 && (Slot3 == 0))) {
> +        PcdSetBoolS (PcdDimmPopulationError, TRUE);
> +      }
> +    }
> +  }
> +}
> +
> +/**
> +  Init Misc Platform Board Config Block.
> +
> +  @param[in]  BoardId           An unsigned integer represent the board id.
> +
> +  @retval     EFI_SUCCESS       The function completed successfully.
> +**/
> +EFI_STATUS
> +BoardMiscInit (
> +  IN UINT16 BoardId
> +  )
> +{
> +//  PcdSet64S (PcdFuncBoardHookPlatformSetupOverride, (UINT64) (UINTN)
> BoardHookPlatformSetup);
> +
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS (PcdPssReadSN, TRUE);
> +      PcdSet8S (PcdPssI2cSlaveAddress, 0x6E);
> +      PcdSet8S (PcdPssI2cBusNumber, 0x04);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdPssReadSN, FALSE);
> +      PcdSet8S (PcdPssI2cSlaveAddress, 0x6E);
> +      PcdSet8S (PcdPssI2cBusNumber, 0x04);
> +      break;
> +  }
> +
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Init Platform Board Config Block for ACPI platform.
> +
> +  @param[in]  BoardId           An unsigned integer represent the board id.
> +
> +  @retval     EFI_SUCCESS       The function completed successfully.
> +**/
> +EFI_STATUS
> +InitAcpiPlatformPcd (
> +  IN UINT16 BoardId
> +  )
> +{
> +  TBT_INFO_HOB  *TbtInfoHob = NULL;
> +
> +  TbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
> +
> +  //
> +  // Update OEM table ID
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      if ((TbtInfoHob != NULL) &&
> (TbtInfoHob->DTbtControllerConfig[0].DTbtControllerEn == 1)) {
> +        PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_', 'w', 'h',
> 'l', 't', '4'));
> +      } else {
> +        PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_', 'w', 'h',
> 'l', 'd', '4'));
> +      }
> +      break;
> +    default:
> +      PcdSet64S (PcdXhciAcpiTableSignature, 0);
> +      break;
> +  }
> +
> +  //
> +  // Modify Preferred_PM_Profile field based on Board SKU's. Default is set to
> Mobile
> +  //
> +  PcdSet8S (PcdPreferredPmProfile, EFI_ACPI_2_0_PM_PROFILE_MOBILE);
> +
> +  //
> +  // Assign FingerPrint, Gnss, TouchPanel, Audio related GPIO.
> +  //
> +  switch(BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdFingerPrintSleepGpio, GPIO_CNL_LP_GPP_B17);
> +      PcdSet32S (PcdFingerPrintIrqGpio,   GPIO_CNL_LP_GPP_B16);
> +      //
> +      // Configure WWAN Reset pin
> +      //
> +      PcdSet32S (PcdGnssResetGpio,      GPIO_CNL_LP_GPP_F1);
> +      PcdSet32S (PcdTouchpanelIrqGpio,  GPIO_CNL_LP_GPP_D10);
> +      PcdSet32S (PcdTouchpadIrqGpio,    GPIO_CNL_LP_GPP_B3);
> +      PcdSet32S (PcdHdaI2sCodecIrqGpio, GPIO_CNL_LP_GPP_C8);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  //
> +  // Configure GPIOs for discrete USB BT module
> +  //
> +  switch(BoardId) {
> +
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdBtIrqGpio,    GPIO_CNL_LP_GPP_B2);
> +      PcdSet32S (PcdBtRfKillGpio, GPIO_CNL_LP_GPP_B4);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  //
> +  // Board Specific Init
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS(PcdWhlErbRtd3TableEnable, TRUE);
> +      PcdSet8S (PcdHdaI2sCodecI2cBusNumber, 0); // I2S Audio Codec
> conntected to I2C0
> +      PcdSet8S (PcdBleUsbPortNumber, 9);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Init Common Platform Board Config Block.
> +
> +  @param[in]  BoardId           An unsigned integer represent the board id.
> +
> +  @retval     EFI_SUCCESS       The function completed successfully.
> +**/
> +EFI_STATUS
> +InitCommonPlatformPcd (
> +  IN UINT16 BoardId
> +  )
> +{
> +  PCD64_BLOB Data64;
> +  TBT_INFO_HOB  *TbtInfoHob = NULL;
> +
> +  TbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
> +
> +
> +  //
> +  // Enable EC SMI# for SMI
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdEcSmiGpio, GPIO_CNL_LP_GPP_E3);
> +      PcdSet32S (PcdEcLowPowerExitGpio, GPIO_CNL_LP_GPP_B23);
> +      break;
> +  };
> +
> +  //
> +  // HID I2C Interrupt GPIO.
> +  //
> +  switch (BoardId) {
> +    default:
> +      // on all supported boards interrupt input is on same GPIO pad. How
> convenient.
> +      PcdSet32S (PcdHidI2cIntPad, GPIO_CNL_LP_GPP_D10);
> +      break;
> +  }
> +
> +  //
> +  // PS2 KB Specific Init for Sds Serial platform.
> +  //
> +  if (BoardId == BoardIdWhiskeyLakeRvp) {
> +    PcdSetBoolS (PcdDetectPs2KbOnCmdAck, TRUE);
> +  } else {
> +    PcdSetBoolS (PcdDetectPs2KbOnCmdAck,  FALSE);
> +  }
> +
> +  switch (BoardId) {
> +    default:
> +      PcdSetBoolS (PcdSpdAddressOverride, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // DDISelection
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet8S (PcdDDISelection, 1);
> +      break;
> +    default:
> +      PcdSet8S (PcdDDISelection, 0);
> +      break;
> +  }
> +
> +  //
> +  // GFX Detect
> +  //
> +  switch (BoardId) {
> +    default:
> +      // Not all the boards support GFX_CRB_DET. This is not an error.
> +      Data64.BoardGpioConfig.Type = BoardGpioTypeNotSupported;
> +      break;
> +  }
> +
> +  PcdSet64S (PcdGfxCrbDetectGpio, Data64.Blob);
> +
> +  //
> +  // USB Type-C
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS(PcdUsbTypeCSupport, TRUE);
> +      // Discete Ports
> +      PcdSet8S(PcdTypeCPortsSupported, 2);
> +      // TBT Port 1  mapping and properties [TBT AIC]
> +      PcdSet8S(PcdUsbTypeCPort1, 1);
> +      PcdSet8S(PcdUsbTypeCPort1Pch, 5);
> +      // TBT Port 2  mapping and properties [TBT AIC]
> +      PcdSet8S(PcdUsbTypeCPort2, 2);
> +      PcdSet8S(PcdUsbTypeCPort2Pch, 7);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdUsbTypeCSupport, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // Battery Present
> +  //
> +  switch (BoardId) {
> +  default:
> +    PcdSet8S (PcdBatteryPresent, BOARD_REAL_BATTERY_SUPPORTED |
> BOARD_VIRTUAL_BATTERY_SUPPORTED);
> +    break;
> +  }
> +
> +  //
> +  // TS-on-DIMM temperature
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS (PcdTsOnDimmTemperature, TRUE);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdTsOnDimmTemperature, FALSE);
> +      break;
> +  }
> +  //
> +  // Real Battery 1 Control & Real Battery 2 Control
> +  //
> +  PcdSet8S (PcdRealBattery1Control, 1);
> +  PcdSet8S (PcdRealBattery2Control, 2);
> +
> +  //
> +  // Mipi Camera Sensor
> +  //
> +  PcdSetBoolS (PcdMipiCamSensor, FALSE);
> +  //
> +  // Mipi Camera Sensor Link Used
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet8S (PcdMipiCam0LinkUsed, 3);
> +      PcdSet8S (PcdMipiCam1LinkUsed, 6);
> +      PcdSet8S (PcdMipiCam2LinkUsed, 9);
> +      PcdSet8S (PcdMipiCam3LinkUsed, 7);
> +      break;
> +    default:
> +      break;
> +  }
> +
> +  //
> +  // H8S2113 SIO
> +  //
> +  switch(BoardId) {
> +    default:
> +    PcdSetBoolS (PcdH8S2113SIO, FALSE);
> +    break;
> +  }
> +
> +
> +  //
> +  // NCT6776F COM, SIO & HWMON
> +  //
> +  PcdSetBoolS (PcdNCT6776FCOM, FALSE);
> +  PcdSetBoolS (PcdNCT6776FSIO, FALSE);
> +  PcdSetBoolS (PcdNCT6776FHWMON, FALSE);
> +
> +  //
> +  // SMC Runtime Sci Pin
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdSmcRuntimeSciPin, (UINT32) GPIO_CNL_LP_GPP_E16);
> +      break;
> +    default:
> +      PcdSet32S (PcdSmcRuntimeSciPin, 0x00);
> +      break;
> +  }
> +
> +  //
> +  // Convertable Dock Support
> +  //
> +  switch (BoardId) {
> +    default:
> +      PcdSetBoolS (PcdConvertableDockSupport, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // Ec Hotkey F3, F4, F5, F6, F7 and F8 Support
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet8S (PcdEcHotKeyF3Support, 1);
> +      PcdSet8S (PcdEcHotKeyF4Support, 1);
> +      PcdSet8S (PcdEcHotKeyF5Support, 1);
> +      PcdSet8S (PcdEcHotKeyF6Support, 1);
> +      PcdSet8S (PcdEcHotKeyF7Support, 1);
> +      PcdSet8S (PcdEcHotKeyF8Support, 1);
> +      break;
> +    default:
> +      PcdSet8S (PcdEcHotKeyF3Support, 0);
> +      PcdSet8S (PcdEcHotKeyF4Support, 0);
> +      PcdSet8S (PcdEcHotKeyF5Support, 0);
> +      PcdSet8S (PcdEcHotKeyF6Support, 0);
> +      PcdSet8S (PcdEcHotKeyF7Support, 0);
> +      PcdSet8S (PcdEcHotKeyF8Support, 0);
> +      break;
> +  }
> +
> +  //
> +  // Virtual Button Volume Up & Done Support
> +  // Virtual Button Home Button Support
> +  // Virtual Button Rotation Lock Support
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS (PcdVirtualButtonVolumeUpSupport, TRUE);
> +      PcdSetBoolS (PcdVirtualButtonVolumeDownSupport, TRUE);
> +      PcdSetBoolS (PcdVirtualButtonHomeButtonSupport, FALSE);
> +      PcdSetBoolS (PcdVirtualButtonRotationLockSupport, FALSE);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdVirtualButtonVolumeUpSupport, FALSE);
> +      PcdSetBoolS (PcdVirtualButtonVolumeDownSupport, FALSE);
> +      PcdSetBoolS (PcdVirtualButtonHomeButtonSupport, FALSE);
> +      PcdSetBoolS (PcdVirtualButtonRotationLockSupport, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // Slate Mode Switch Support
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS (PcdSlateModeSwitchSupport, TRUE);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdSlateModeSwitchSupport, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // Ac Dc Auto Switch Support
> +  //
> +  switch (BoardId) {
> +  default:
> +    PcdSetBoolS (PcdAcDcAutoSwitchSupport, TRUE);
> +    break;
> +  }
> +
> +  //
> +  // Pm Power Button Gpio Pin
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSet32S (PcdPmPowerButtonGpioPin, (UINT32) GPIO_CNL_LP_GPD3);
> +      break;
> +    default:
> +      PcdSet32S (PcdPmPowerButtonGpioPin, 0x00);
> +      break;
> +  }
> +
> +  //
> +  // Acpi Enable All Button Support
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS (PcdAcpiEnableAllButtonSupport, TRUE);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdAcpiEnableAllButtonSupport, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // Acpi Hid Driver Button Support
> +  //
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      PcdSetBoolS (PcdAcpiHidDriverButtonSupport, TRUE);
> +      break;
> +    default:
> +      PcdSetBoolS (PcdAcpiHidDriverButtonSupport, FALSE);
> +      break;
> +  }
> +
> +  //
> +  // USB Type C EC less
> +  //
> +  switch (BoardId) {
> +    default:
> +      PcdSetBoolS (PcdUsbTypeCEcLess, FALSE);
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Check if given rootport has device connected and enable wake capability
> +
> +  @param[in]  RpNum           An unsigned integer represent the root port
> number.
> +
> +  @retval                     TRUE if endpoint was connected
> +  @retval                     FALSE if no endpoint was detected
> +**/
> +BOOLEAN
> +IsPcieEndPointPresent (
> +  IN UINT8 RpNum
> +  )
> +{
> +  EFI_STATUS    Status;
> +  UINTN         RpDev;
> +  UINTN         RpFun;
> +  UINT64        RpBaseAddress;
> +
> +  Status = GetPchPcieRpDevFun (RpNum, &RpDev, &RpFun);
> +  if (!EFI_ERROR (Status)) {
> +    //
> +    // check if device is present
> +    //
> +    RpBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
> +                      DEFAULT_PCI_SEGMENT_NUMBER_PCH,
> +                      DEFAULT_PCI_BUS_NUMBER_PCH,
> +                      RpDev,
> +                      RpFun,
> +                      0
> +                      );
> +
> +    if ((PciSegmentRead16 (RpBaseAddress) != 0xFFFF) &&
> +        (PciSegmentRead16 (RpBaseAddress + R_PCH_PCIE_CFG_SLSTS) &
> B_PCIE_SLSTS_PDS)) {
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +
> +}
> +
> +/**
> +  Enable Tier2 GPIO Sci wake capability.
> +
> +  @param[in]  BoardId   An unsigned integrer represent the board id.
> +
> +  @retval EFI_SUCCESS   The function completed successfully.
> +**/
> +EFI_STATUS
> +Tier2GpioWakeSupport (
> +  IN UINT16 BoardId
> +  )
> +{
> +  BOOLEAN Tier2GpioWakeEnable;
> +
> +  Tier2GpioWakeEnable = FALSE;
> +  switch (BoardId) {
> +    case BoardIdWhiskeyLakeRvp:
> +      //
> +      // Root port #14: M.2 WLAN
> +      //
> +      if (IsPcieEndPointPresent (13)) {
> +        Tier2GpioWakeEnable = TRUE;
> +      }
> +      break;
> +    default:
> +      break;
> +  }
> +  PcdSetBoolS (PcdGpioTier2WakeEnable, Tier2GpioWakeEnable);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Board configuration init function for DXE phase.
> +
> +  @param  Content  pointer to the buffer contain init information for board
> init.
> +
> +  @retval EFI_SUCCESS             The function completed successfully.
> +**/
> +EFI_STATUS
> +EFIAPI
> +BoardConfigInit (
> +    VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT16     BoardId;
> +
> +  BoardId = BoardIdWhiskeyLakeRvp;
> +
> +  Status = InitAcpiPlatformPcd (BoardId);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = InitCommonPlatformPcd (BoardId);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = BoardMiscInit (BoardId);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  Status = Tier2GpioWakeSupport (BoardId);
> +  ASSERT_EFI_ERROR(Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyI
> nitDxe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyI
> nitDxe.c
> new file mode 100644
> index 0000000000..eb7c3bbea0
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyI
> nitDxe.c
> @@ -0,0 +1,46 @@
> +/** @file
> +  This file is SampleCode for Intel Silicon DXE Platform Policy initialzation.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <CpuPolicyInitDxe.h>
> +
> +DXE_CPU_POLICY_PROTOCOL mCpuPolicyData;
> +
> +/**
> +  Initialize Intel CPU DXE Platform Policy
> +
> +  @param[in] ImageHandle        Image handle of this driver.
> +
> +  @retval EFI_SUCCESS           Initialization complete.
> +  @exception EFI_UNSUPPORTED    The chipset is unsupported by this driver.
> +  @retval EFI_OUT_OF_RESOURCES  Do not have enough resources to
> initialize the driver.
> +  @retval EFI_DEVICE_ERROR      Device error, driver exits abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuPolicyInitDxe (
> +  IN EFI_HANDLE       ImageHandle
> +  )
> +{
> +  EFI_STATUS                Status;
> +
> +  ZeroMem(&mCpuPolicyData, sizeof (DXE_CPU_POLICY_PROTOCOL));
> +  mCpuPolicyData.Revision                         =
> DXE_CPU_POLICY_PROTOCOL_REVISION;
> +
> +  UpdateDxeSiCpuPolicy(&mCpuPolicyData);
> +
> +  //
> +  // Install CpuInstallPolicyProtocol.
> +  // While installed, RC assumes the Policy is ready and finalized. So please
> +  // update and override any setting before calling this function.
> +  //
> +  Status = CpuInstallPolicyProtocol(ImageHandle, &mCpuPolicyData);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyI
> nitDxe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyI
> nitDxe.c
> new file mode 100644
> index 0000000000..66aab2d198
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyI
> nitDxe.c
> @@ -0,0 +1,174 @@
> +/** @file
> +  This file initialises and Installs GopPolicy Protocol.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "GopPolicyInitDxe.h"
> +#include <Protocol/GopPolicy.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED GOP_POLICY_PROTOCOL
> mGOPPolicy;
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT32                     mVbtSize = 0;
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS
> mVbtAddress = 0;
> +
> +//
> +// Function implementations
> +//
> +
> +/**
> +
> +  @param[out] CurrentLidStatus
> +
> +  @retval     EFI_SUCCESS
> +  @retval     EFI_UNSUPPORTED
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +GetPlatformLidStatus (
> +  OUT LID_STATUS *CurrentLidStatus
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +
> +  @param[out] CurrentDockStatus
> +
> +  @retval     EFI_SUCCESS
> +  @retval     EFI_UNSUPPORTED
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetPlatformDockStatus (
> +  OUT DOCK_STATUS  CurrentDockStatus
> +  )
> +{
> +    return EFI_UNSUPPORTED;
> +}
> +
> +
> +/**
> +
> +  @param[out] VbtAddress
> +  @param[out] VbtSize
> +
> +  @retval     EFI_SUCCESS
> +  @retval     EFI_NOT_FOUND
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetVbtData (
> +  OUT EFI_PHYSICAL_ADDRESS *VbtAddress,
> +  OUT UINT32               *VbtSize
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  UINTN                         FvProtocolCount;
> +  EFI_HANDLE                    *FvHandles;
> +  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
> +  UINTN                         Index;
> +  UINT32                        AuthenticationStatus;
> +  UINT8                         *Buffer;
> +  UINTN                         VbtBufferSize;
> +
> +  Status = EFI_NOT_FOUND;
> +  if ( mVbtAddress == 0) {
> +    Fv           = NULL;
> +    Buffer       = 0;
> +    FvHandles    = NULL;
> +    Status = gBS->LocateHandleBuffer (
> +                    ByProtocol,
> +                    &gEfiFirmwareVolume2ProtocolGuid,
> +                    NULL,
> +                    &FvProtocolCount,
> +                    &FvHandles
> +                    );
> +    if (!EFI_ERROR (Status)) {
> +      for (Index = 0; Index < FvProtocolCount; Index++) {
> +        Status = gBS->HandleProtocol (
> +                        FvHandles[Index],
> +                        &gEfiFirmwareVolume2ProtocolGuid,
> +                        (VOID **) &Fv
> +                        );
> +        VbtBufferSize = 0;
> +        Status = Fv->ReadSection (
> +                       Fv,
> +                       PcdGetPtr(PcdIntelGraphicsVbtFileGuid),
> +                       EFI_SECTION_RAW,
> +                       0,
> +                       (VOID **) &Buffer,
> +                       &VbtBufferSize,
> +                       &AuthenticationStatus
> +                       );
> +        if (!EFI_ERROR (Status)) {
> +          *VbtAddress = (EFI_PHYSICAL_ADDRESS)Buffer;
> +          *VbtSize = (UINT32)VbtBufferSize;
> +          mVbtAddress = *VbtAddress;
> +          mVbtSize = *VbtSize;
> +          Status = EFI_SUCCESS;
> +          break;
> +        }
> +      }
> +    } else {
> +      Status = EFI_NOT_FOUND;
> +    }
> +
> +    if (FvHandles != NULL) {
> +      FreePool (FvHandles);
> +      FvHandles = NULL;
> +    }
> +  } else {
> +    *VbtAddress = mVbtAddress;
> +    *VbtSize = mVbtSize;
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +Initialize GOP DXE Policy
> +
> +@param[in] ImageHandle          Image handle of this driver.
> +
> +@retval EFI_SUCCESS             Initialization complete.
> +@retval EFI_UNSUPPORTED         The chipset is unsupported by this driver.
> +@retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver.
> +@retval EFI_DEVICE_ERROR        Device error, driver exits abnormally.
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +GopPolicyInitDxe (
> +  IN EFI_HANDLE       ImageHandle
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  //
> +  // Initialize the EFI Driver Library
> +  //
> +  SetMem (&mGOPPolicy, sizeof (GOP_POLICY_PROTOCOL), 0);
> +
> +  mGOPPolicy.Revision                = GOP_POLICY_PROTOCOL_REVISION_03;
> +  mGOPPolicy.GetPlatformLidStatus    = GetPlatformLidStatus;
> +  mGOPPolicy.GetVbtData              = GetVbtData;
> +  mGOPPolicy.GetPlatformDockStatus   = GetPlatformDockStatus;
> +
> +  //
> +  // Install protocol to allow access to this Policy.
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &ImageHandle,
> +                  &gGopPolicyProtocolGuid,
> +                  &mGOPPolicy,
> +                  NULL
> +                  );
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyIn
> itDxe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyI
> nitDxe.c
> new file mode 100644
> index 0000000000..2a1604fa13
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyI
> nitDxe.c
> @@ -0,0 +1,55 @@
> +/** @file
> +  This file is SampleCode for PCH DXE Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PchPolicyInitDxe.h"
> +
> +//
> +// Function implementations
> +//
> +
> +/**
> +  Initialize PCH DXE Policy
> +
> +  @param[in] ImageHandle          Image handle of this driver.
> +
> +  @retval EFI_SUCCESS             Initialization complete.
> +  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver.
> +  @retval EFI_DEVICE_ERROR        Device error, driver exits abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PchPolicyInitDxe (
> +  IN EFI_HANDLE                   ImageHandle
> +  )
> +{
> +  EFI_STATUS               Status;
> +  PCH_POLICY_PROTOCOL      *PchPolicy;
> +
> +  //
> +  // Call CreatePchDxeConfigBlocks to create & initialize platform policy
> structure
> +  // and get all Intel default policy settings.
> +  //
> +  Status = CreatePchDxeConfigBlocks (&PchPolicy);
> +  DEBUG((DEBUG_INFO, "PchPolicy->TableHeader.NumberOfBlocks =
> 0x%x\n", PchPolicy->TableHeader.NumberOfBlocks));
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (mFirmwareConfiguration != FwConfigDefault) {
> +    UpdateDxePchPolicy (PchPolicy);
> +  }
> +
> +  //
> +  // Install PchInstallPolicyProtocol.
> +  // While installed, RC assumes the Policy is ready and finalized. So please
> +  // update and override any setting before calling this function.
> +  //
> +  Status = PchInstallPolicyProtocol (ImageHandle, PchPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.c
> new file mode 100644
> index 0000000000..ccaa57ce16
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitD
> xe.c
> @@ -0,0 +1,88 @@
> +/** @file
> +  This file is a wrapper for Platform Policy driver. Get Setup
> +  Value to initialize Intel DXE Platform Policy.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PolicyInitDxe.h"
> +#include <CpuSmm.h>
> +#include "BoardInitLib.h"
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT8
> mFirmwareConfiguration = 0;
> +
> +/**
> +  Initialize  DXE Platform Policy
> +
> +  @param[in] ImageHandle       Image handle of this driver.
> +  @param[in] SystemTable       Global system service table.
> +
> +  @retval EFI_SUCCESS           Initialization complete.
> +  @exception EFI_UNSUPPORTED    The chipset is unsupported by this driver.
> +  @retval EFI_OUT_OF_RESOURCES  Do not have enough resources to
> initialize the driver.
> +  @retval EFI_DEVICE_ERROR      Device error, driver exits abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PolicyInitDxeEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS           Status;
> +
> +  Status = BoardConfigInit();
> +
> +  mFirmwareConfiguration = FwConfigProduction;
> +  //
> +  // SystemAgent Dxe Platform Policy Initialization
> +  //
> +  Status = SaPolicyInitDxe (ImageHandle);
> +  DEBUG ((DEBUG_INFO, "SystemAgent Dxe Platform Policy Initialization
> done\n"));
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // PCH Dxe Platform Policy Initialization
> +  //
> +  Status = PchPolicyInitDxe (ImageHandle);
> +  DEBUG ((DEBUG_INFO, "PCH Dxe Platform Policy Initialization done\n"));
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Silicon Dxe Platform Policy Initialization
> +  //
> +  Status = SiliconPolicyInitDxe (ImageHandle);
> +  DEBUG ((DEBUG_INFO, "Silicon Dxe Platform Policy Initialization done\n"));
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // CPU DXE Platform Policy Initialization
> +  //
> +  Status = CpuPolicyInitDxe (ImageHandle);
> +  DEBUG ((DEBUG_INFO, "Cpu Dxe Platform Policy Initialization done\n"));
> +  ASSERT_EFI_ERROR (Status);
> +
> +
> +  if (PcdGetBool(PcdIntelGopEnable)) {
> +    //
> +    // GOP Dxe Policy Initialization
> +    //
> +    Status = GopPolicyInitDxe(ImageHandle);
> +    DEBUG((DEBUG_INFO, "GOP Dxe Policy Initialization done\n"));
> +    ASSERT_EFI_ERROR(Status);
> +  }
> +  if (PcdGetBool(PcdTbtEnable)) {
> +    //
> +    // Update TBT Policy
> +    //
> +    Status = InstallTbtPolicy (ImageHandle);
> +    DEBUG ((DEBUG_INFO, "Install Tbt Policy done\n"));
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  return Status;
> +
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyIni
> tDxe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyIni
> tDxe.c
> new file mode 100644
> index 0000000000..c0095c09c3
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyIni
> tDxe.c
> @@ -0,0 +1,60 @@
> +/** @file
> +  This file is SampleCode for SA DXE Policy initialization.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "SaPolicyInitDxe.h"
> +
> +
> +//
> +// Function implementations
> +//
> +
> +/**
> +  Initialize SA DXE Policy
> +
> +  @param[in] ImageHandle          Image handle of this driver.
> +
> +  @retval EFI_SUCCESS             Initialization complete.
> +  @exception EFI_UNSUPPORTED      The chipset is unsupported by this
> driver.
> +  @retval EFI_OUT_OF_RESOURCES    Do not have enough resources to
> initialize the driver.
> +  @retval EFI_DEVICE_ERROR        Device error, driver exits abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SaPolicyInitDxe (
> +  IN EFI_HANDLE                   ImageHandle
> +  )
> +{
> +  EFI_STATUS               Status;
> +  SA_POLICY_PROTOCOL       *SaPolicy;
> +
> +  //
> +  // Call CreateSaDxeConfigBlocks to create & initialize platform policy
> structure
> +  // and get all Intel default policy settings.
> +  //
> +  Status = CreateSaDxeConfigBlocks(&SaPolicy);
> +  DEBUG((DEBUG_INFO, "SaPolicy->TableHeader.NumberOfBlocks = 0x%x\n ",
> SaPolicy->TableHeader.NumberOfBlocks));
> +  ASSERT_EFI_ERROR(Status);
> +
> +  UpdateDxeSaPolicyBoardConfig (SaPolicy);
> +
> +  if (mFirmwareConfiguration != FwConfigDefault) {
> +
> +    UpdateDxeSaPolicy (SaPolicy);
> +  }
> +
> +  //
> +  // Install SaInstallPolicyProtocol.
> +  // While installed, RC assumes the Policy is ready and finalized. So please
> +  // update and override any setting before calling this function.
> +  //
> +  Status = SaInstallPolicyProtocol (ImageHandle, SaPolicy);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolic
> yInitDxe.c
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPoli
> cyInitDxe.c
> new file mode 100644
> index 0000000000..15adca5cdd
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPoli
> cyInitDxe.c
> @@ -0,0 +1,46 @@
> +/** @file
> +  This file is SampleCode for Intel Silicon DXE Platform Policy initialzation.
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <SiliconPolicyInitDxe.h>
> +#include <Library/BaseLib.h>
> +
> +DXE_SI_POLICY_PROTOCOL mSiPolicyData  = { 0 };
> +
> +/**
> +  Initilize Intel Cpu DXE Platform Policy
> +
> +  @param[in] ImageHandle        Image handle of this driver.
> +
> +  @retval EFI_SUCCESS           Initialization complete.
> +  @exception EFI_UNSUPPORTED    The chipset is unsupported by this driver.
> +  @retval EFI_OUT_OF_RESOURCES  Do not have enough resources to
> initialize the driver.
> +  @retval EFI_DEVICE_ERROR      Device error, driver exits abnormally.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SiliconPolicyInitDxe (
> +  IN EFI_HANDLE       ImageHandle
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  mSiPolicyData.Revision                         =
> DXE_SI_POLICY_PROTOCOL_REVISION;
> +
> +  ///
> +  /// Install the DXE_SI_POLICY_PROTOCOL interface
> +  ///
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &ImageHandle,
> +                  &gDxeSiPolicyProtocolGuid,
> +                  &mSiPolicyData,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +  return Status;
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLU
> PD.asl
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLU
> PD.asl
> new file mode 100644
> index 0000000000..7e44f5585a
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLU
> PD.asl
> @@ -0,0 +1,20 @@
> +/** @file
> +  ACPI DSDT table
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//////////////////////////////////////////////////////////////////////////////
> /////
> +//Values are set like this to have ASL compiler reserve enough space for
> objects
> +//////////////////////////////////////////////////////////////////////////////
> /////
> +//
> +// Available Sleep states
> +//
> +Name(SS1,0)
> +Name(SS2,0)
> +Name(SS3,1)
> +Name(SS4,1)
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.
> ASL
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.
> ASL
> new file mode 100644
> index 0000000000..dd85f07bd2
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.
> ASL
> @@ -0,0 +1,37 @@
> +/** @file
> +  ACPI DSDT table
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PlatformBoardId.h"
> +
> +DefinitionBlock (
> +  "DSDT.aml",
> +  "DSDT",
> +  0x02, // DSDT revision.
> +        // A Revision field value greater than or equal to 2 signifies that integers
> +        // declared within the Definition Block are to be evaluated as 64-bit
> values
> +  "INTEL",   // OEM ID (6 byte string)
> +  "WHL     ",// OEM table ID  (8 byte string)
> +  0x0 // OEM version of DSDT table (4 byte Integer)
> +)
> +
> +// BEGIN OF ASL SCOPE
> +{
> +  // Miscellaneous services enabled in Project
> +  Include ("AMLUPD.asl")
> +  Include ("PciTree.asl")
> +  Include ("Platform.asl")
> +
> +  Name(\_S0, Package(4){0x0,0x0,0,0}) // mandatory System state
> +  if(SS1) { Name(\_S1, Package(4){0x1,0x0,0,0})}
> +  if(SS3) { Name(\_S3, Package(4){0x5,0x0,0,0})}
> +  if(SS4) { Name(\_S4, Package(4){0x6,0x0,0,0})}
> +  Name(\_S5, Package(4){0x7,0x0,0,0}) // mandatory System state
> +
> +}// End of ASL File
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostB
> us.asl
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Host
> Bus.asl
> new file mode 100644
> index 0000000000..aa302b6e3b
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Host
> Bus.asl
> @@ -0,0 +1,516 @@
> +/** @file
> +  This file contains the SystemAgent PCI Configuration space
> +  definition.
> +  It defines various System Agent PCI Configuration Space registers
> +  which will be used to dynamically produce all resources in the Host Bus.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +//
> +// Define various System Agent (SA) PCI Configuration Space
> +// registers which will be used to dynamically produce all
> +// resources in the Host Bus _CRS.
> +//
> +OperationRegion (HBUS, PCI_Config, 0x00, 0x100)
> +Field (HBUS, DWordAcc, NoLock, Preserve)
> +{
> +  Offset(0x40),   // EPBAR (0:0:0:40)
> +  EPEN, 1,        // Enable
> +      , 11,
> +  EPBR, 20,       // EPBAR [31:12]
> +
> +  Offset(0x48),   // MCHBAR (0:0:0:48)
> +  MHEN, 1,        // Enable
> +      , 14,
> +  MHBR, 17,       // MCHBAR [31:15]
> +
> +  Offset(0x50),   // GGC (0:0:0:50)
> +  GCLK, 1,        // GGCLCK
> +
> +  Offset(0x54),   // DEVEN (0:0:0:54)
> +  D0EN, 1,        // DEV0 Enable
> +  D1F2, 1,        // DEV1 FUN2 Enable
> +  D1F1, 1,        // DEV1 FUN1 Enable
> +  D1F0, 1,        // DEV1 FUN0 Enable
> +
> +  Offset(0x60),   // PCIEXBAR (0:0:0:60)
> +  PXEN, 1,        // Enable
> +  PXSZ, 2,        // PCI Express Size
> +      , 23,
> +  PXBR, 6,        // PCI Express BAR [31:26]
> +
> +  Offset(0x68),   // DMIBAR (0:0:0:68)
> +  DIEN, 1,        // Enable
> +      , 11,
> +  DIBR, 20,       // DMIBAR [31:12]
> +
> +  Offset(0x70),   // MESEG_BASE (0:0:0:70)
> +      , 20,
> +  MEBR, 12,       // MESEG_BASE [31:20]
> +
> +  Offset(0x80),   // PAM0 Register (0:0:0:80)
> +  PMLK, 1,        // PAM Lock bit.
> +      , 3,
> +  PM0H, 2,        // PAM 0, High Nibble
> +      , 2,
> +
> +  Offset(0x81),   // PAM1 Register (0:0:0:81)
> +  PM1L, 2,        // PAM1, Low  Nibble
> +      , 2,
> +  PM1H, 2,        // PAM1, High Nibble
> +      , 2,
> +
> +  Offset(0x82),   // PAM2 Register (0:0:0:82)
> +  PM2L, 2,        // PAM2, Low  Nibble
> +      , 2,
> +  PM2H, 2,        // PAM2, High Nibble
> +      , 2,
> +
> +  Offset(0x83),   // PAM3 Register (0:0:0:83)
> +  PM3L, 2,        // PAM3, Low  Nibble
> +      , 2,
> +  PM3H, 2,        // PAM3, High Nibble
> +      , 2,
> +
> +  Offset(0x84),   // PAM4 Register (0:0:0:84)
> +  PM4L, 2,        // PAM4, Low  Nibble
> +      , 2,
> +  PM4H, 2,        // PAM4, High Nibble
> +      , 2,
> +
> +  Offset(0x85),   // PAM5 Register (0:0:0:85)
> +  PM5L, 2,        // PAM5, Low  Nibble
> +      , 2,
> +  PM5H, 2,        // PAM5, High Nibble
> +      , 2,
> +
> +  Offset(0x86),   // PAM6 Register (0:0:0:86)
> +  PM6L, 2,        // PAM6, Low  Nibble
> +      , 2,
> +  PM6H, 2,        // PAM6, High Nibble
> +      , 2,
> +
> +  Offset(0xA8),   // Top of Upper Usable DRAM Register (0:0:0:A8)
> +      , 20,
> +  TUUD, 19,       // TOUUD [38:20]
> +
> +  Offset(0xBC),   // Top of Lower Usable DRAM Register (0:0:0:BC)
> +      , 20,
> +  TLUD, 12,       // TOLUD [31:20]
> +
> +  Offset(0xC8),   // ERRSTS register (0:0:0:C8)
> +      , 7,
> +  HTSE, 1         // Host Thermal Sensor Event for SMI/SCI/SERR
> +}
> +
> +//
> +// Define a buffer that will store all the bus, memory, and IO information
> +// relating to the Host Bus.  This buffer will be dynamically altered in
> +// the _CRS and passed back to the OS.
> +//
> +Name(BUF0,ResourceTemplate()
> +{
> +  //
> +  // Bus Number Allocation: Bus 0 to 0xFF
> +  //
> +  WORDBusNumber(ResourceProducer,MinFixed,MaxFixed,PosDecode,0x00,
> +    0x0000,0x00FF,0x00,0x0100,,,PB00)
> +
> +  //
> +  // I/O Region Allocation 0 ( 0x0000 - 0x0CF7 )
> +  //
> +  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
> +    0x00,0x0000,0x0CF7,0x00,0x0CF8,,,PI00)
> +
> +  //
> +  // PCI Configuration Registers ( 0x0CF8 - 0x0CFF )
> +  //
> +  Io(Decode16,0x0CF8,0x0CF8,1,0x08)
> +
> +  //
> +  // I/O Region Allocation 1 ( 0x0D00 - 0xFFFF )
> +  //
> +  DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange,
> +    0x00,0x0D00,0xFFFF,0x00,0xF300,,,PI01)
> +
> +  //
> +  // Video Buffer Area ( 0xA0000 - 0xBFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xA0000,0xBFFFF,0x00,0x20000,,,A000)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xC0000 - 0xC3FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xC0000,0xC3FFF,0x00,0x4000,,,C000)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xC4000 - 0xC7FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xC4000,0xC7FFF,0x00,0x4000,,,C400)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xC8000 - 0xCBFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xC8000,0xCBFFF,0x00,0x4000,,,C800)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xCC000 - 0xCFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xCC000,0xCFFFF,0x00,0x4000,,,CC00)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xD0000 - 0xD3FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xD0000,0xD3FFF,0x00,0x4000,,,D000)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xD4000 - 0xD7FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xD4000,0xD7FFF,0x00,0x4000,,,D400)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xD8000 - 0xDBFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xD8000,0xDBFFF,0x00,0x4000,,,D800)
> +
> +  //
> +  // ISA Add-on BIOS Area ( 0xDC000 - 0xDFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xDC000,0xDFFFF,0x00,0x4000,,,DC00)
> +
> +  //
> +  // BIOS Extension Area ( 0xE0000 - 0xE3FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xE0000,0xE3FFF,0x00,0x4000,,,E000)
> +
> +  //
> +  // BIOS Extension Area ( 0xE4000 - 0xE7FFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xE4000,0xE7FFF,0x00,0x4000,,,E400)
> +
> +  //
> +  // BIOS Extension Area ( 0xE8000 - 0xEBFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xE8000,0xEBFFF,0x00,0x4000,,,E800)
> +
> +  //
> +  // BIOS Extension Area ( 0xEC000 - 0xEFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xEC000,0xEFFFF,0x00,0x4000,,,EC00)
> +
> +  //
> +  // BIOS Area ( 0xF0000 - 0xFFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +    ReadWrite,0x00,0xF0000,0xFFFFF,0x00,0x10000,,,F000)
> +
> +//  //
> +//  // Memory Hole Region ( 0xF00000 - 0xFFFFFF )
> +//  //
> +//
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,
> +//    ReadWrite,0x00,0xF00000,0xFFFFFF,0x00,0x100000,,,HOLE)
> +
> +  //
> +  // PCI Memory Region ( TOLUD - 0xDFFFFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> +    ReadWrite,0x00,0x00000000,0xDFFFFFFF,0x00,0xE0000000,,,PM01)
> +
> +  //
> +  // PCI Memory Region ( TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE) )
> +  // (This is dummy range for OS compatibility, will patch it in _CRS)
> +  //
> +
> QWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> +    ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02)
> +
> +  //
> +  // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF )
> +  //
> +
> DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCache
> able,
> +    ReadWrite,0x00,0xFC800000,0xFE7FFFFF,0x00,0x2000000,,,PM03)
> +})
> +
> +Name(EP_B, 0) // to store EP BAR
> +Name(MH_B, 0) // to store MCH BAR
> +Name(PC_B, 0) // to store PCIe BAR
> +Name(PC_L, 0) // to store PCIe BAR Length
> +Name(DM_B, 0) // to store DMI BAR
> +
> +//
> +// Get EP BAR
> +//
> +Method(GEPB,0,Serialized)
> +{
> +  if(LEqual(EP_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.EPBR,12,EP_B)
> +  }
> +  Return(EP_B)
> +}
> +
> +//
> +// Get MCH BAR
> +//
> +Method(GMHB,0,Serialized)
> +{
> +  if(LEqual(MH_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.MHBR,15,MH_B)
> +  }
> +  Return(MH_B)
> +}
> +
> +//
> +// Get PCIe BAR
> +//
> +Method(GPCB,0,Serialized)
> +{
> +  if(LEqual(PC_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.PXBR,26,PC_B)
> +  }
> +  Return(PC_B)
> +}
> +
> +//
> +// Get PCIe Length
> +//
> +Method(GPCL,0,Serialized)
> +{
> +  if(LEqual(PC_L,0)) {
> +    ShiftRight(0x10000000, \_SB.PCI0.PXSZ,PC_L)
> +  }
> +  Return(PC_L)
> +}
> +
> +//
> +// Get DMI BAR
> +//
> +Method(GDMB,0,Serialized)
> +{
> +  if(LEqual(DM_B,0))
> +  {
> +    ShiftLeft(\_SB.PCI0.DIBR,12,DM_B)
> +  }
> +  Return(DM_B)
> +}
> +
> +
> +Method(_CRS,0,Serialized)
> +{
> +  //
> +  // Fix up Max Bus Number and Length
> +  //
> +  Store(\_SB.PCI0.GPCL(),Local0)
> +  CreateWordField(BUF0, ^PB00._MAX, PBMX)
> +  Store(Subtract(ShiftRight(Local0,20),2), PBMX)
> +  CreateWordField(BUF0, ^PB00._LEN, PBLN)
> +  Store(Subtract(ShiftRight(Local0,20),1), PBLN)
> +  //
> +  // Fix up all of the Option ROM areas from 0xC0000-0xFFFFF.
> +  //
> +  If(PM1L)  // \_SB.PCI0
> +  {
> +    // PAMx != 0.  Set length = 0.
> +
> +    CreateDwordField(BUF0, ^C000._LEN,C0LN)
> +    Store(Zero,C0LN)
> +  }
> +
> +  If(LEqual(PM1L,1))
> +  {
> +    CreateBitField(BUF0, ^C000._RW,C0RW)
> +    Store(Zero,C0RW)
> +  }
> +
> +  If(PM1H)
> +  {
> +    CreateDwordField(BUF0, ^C400._LEN,C4LN)
> +    Store(Zero,C4LN)
> +  }
> +
> +  If(LEqual(PM1H,1))
> +  {
> +    CreateBitField(BUF0, ^C400._RW,C4RW)
> +    Store(Zero,C4RW)
> +  }
> +
> +  If(PM2L)
> +  {
> +    CreateDwordField(BUF0, ^C800._LEN,C8LN)
> +    Store(Zero,C8LN)
> +  }
> +
> +  If(LEqual(PM2L,1))
> +  {
> +    CreateBitField(BUF0, ^C800._RW,C8RW)
> +    Store(Zero,C8RW)
> +  }
> +
> +  If(PM2H)
> +  {
> +    CreateDwordField(BUF0, ^CC00._LEN,CCLN)
> +    Store(Zero,CCLN)
> +  }
> +
> +  If(LEqual(PM2H,1))
> +  {
> +    CreateBitField(BUF0, ^CC00._RW,CCRW)
> +    Store(Zero,CCRW)
> +  }
> +
> +  If(PM3L)
> +  {
> +    CreateDwordField(BUF0, ^D000._LEN,D0LN)
> +    Store(Zero,D0LN)
> +  }
> +
> +  If(LEqual(PM3L,1))
> +  {
> +    CreateBitField(BUF0, ^D000._RW,D0RW)
> +    Store(Zero,D0RW)
> +  }
> +
> +  If(PM3H)
> +  {
> +    CreateDwordField(BUF0, ^D400._LEN,D4LN)
> +    Store(Zero,D4LN)
> +  }
> +
> +  If(LEqual(PM3H,1))
> +  {
> +    CreateBitField(BUF0, ^D400._RW,D4RW)
> +    Store(Zero,D4RW)
> +  }
> +
> +  If(PM4L)
> +  {
> +    CreateDwordField(BUF0, ^D800._LEN,D8LN)
> +    Store(Zero,D8LN)
> +  }
> +
> +  If(LEqual(PM4L,1))
> +  {
> +    CreateBitField(BUF0, ^D800._RW,D8RW)
> +    Store(Zero,D8RW)
> +  }
> +
> +  If(PM4H)
> +  {
> +    CreateDwordField(BUF0, ^DC00._LEN,DCLN)
> +    Store(Zero,DCLN)
> +  }
> +
> +  If(LEqual(PM4H,1))
> +  {
> +    CreateBitField(BUF0, ^DC00._RW,DCRW)
> +    Store(Zero,DCRW)
> +  }
> +
> +  If(PM5L)
> +  {
> +    CreateDwordField(BUF0, ^E000._LEN,E0LN)
> +    Store(Zero,E0LN)
> +  }
> +
> +  If(LEqual(PM5L,1))
> +  {
> +    CreateBitField(BUF0, ^E000._RW,E0RW)
> +    Store(Zero,E0RW)
> +  }
> +
> +  If(PM5H)
> +  {
> +    CreateDwordField(BUF0, ^E400._LEN,E4LN)
> +    Store(Zero,E4LN)
> +  }
> +
> +  If(LEqual(PM5H,1))
> +  {
> +    CreateBitField(BUF0, ^E400._RW,E4RW)
> +    Store(Zero,E4RW)
> +  }
> +
> +  If(PM6L)
> +  {
> +    CreateDwordField(BUF0, ^E800._LEN,E8LN)
> +    Store(Zero,E8LN)
> +  }
> +
> +  If(LEqual(PM6L,1))
> +  {
> +    CreateBitField(BUF0, ^E800._RW,E8RW)
> +    Store(Zero,E8RW)
> +  }
> +
> +  If(PM6H)
> +  {
> +    CreateDwordField(BUF0, ^EC00._LEN,ECLN)
> +    Store(Zero,ECLN)
> +  }
> +
> +  If(LEqual(PM6H,1))
> +  {
> +    CreateBitField(BUF0, ^EC00._RW,ECRW)
> +    Store(Zero,ECRW)
> +  }
> +
> +  If(PM0H)
> +  {
> +    CreateDwordField(BUF0, ^F000._LEN,F0LN)
> +    Store(Zero,F0LN)
> +  }
> +
> +  If(LEqual(PM0H,1))
> +  {
> +    CreateBitField(BUF0, ^F000._RW,F0RW)
> +    Store(Zero,F0RW)
> +  }
> +
> +  //
> +  // Create pointers to Memory Sizing values.
> +  //
> +  CreateDwordField(BUF0, ^PM01._MIN,M1MN)
> +  CreateDwordField(BUF0, ^PM01._MAX,M1MX)
> +  CreateDwordField(BUF0, ^PM01._LEN,M1LN)
> +
> +  //
> +  // Set Memory Size Values. TLUD represents bits 31:20 of phyical
> +  // TOM, so shift these bits into the correct position and fix up
> +  // the Memory Region available to PCI.
> +  //
> +  Store (0x50800000, M1LN)
> +  Store (0x8F800000, M1MN)
> +  Subtract (Add (M1MN, M1LN), 1, M1MX)
> +
> +  //
> +  // Create pointers to Memory Sizing values.
> +  // Patch PM02 range basing on memory size and OS type
> +  //
> +  CreateQwordField(BUF0, ^PM02._LEN,MSLN)
> +  //
> +  // Set resource length to 0
> +  //
> +  Store (0, MSLN)
> +
> +  D8XH (0, 0xC5)
> +  D8XH (1, 0xAA)
> +
> +  Return(BUF0)
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTre
> e.asl
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTre
> e.asl
> new file mode 100644
> index 0000000000..ff3b0dbe08
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTre
> e.asl
> @@ -0,0 +1,309 @@
> +/** @file
> +  ACPI DSDT table
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +Scope(\_SB) {
> +  Name(PD00, Package(){
> +// If the setting changed in PCH PxRcConfig policy, platform should also
> update static assignment here.
> +// PCI Bridge
> +// D31: cAVS, SMBus, GbE, Nothpeak
> +    Package(){0x001FFFFF, 0, 0, 11 },
> +    Package(){0x001FFFFF, 1, 0, 10 },
> +    Package(){0x001FFFFF, 2, 0, 11 },
> +    Package(){0x001FFFFF, 3, 0, 11 },
> +// D30: SerialIo and SCS - can't use PIC
> +// D29: PCI Express Port 9-16
> +    Package(){0x001DFFFF, 0, 0, 11 },
> +    Package(){0x001DFFFF, 1, 0, 10 },
> +    Package(){0x001DFFFF, 2, 0, 11 },
> +    Package(){0x001DFFFF, 3, 0, 11 },
> +// D28: PCI Express Port 1-8
> +    Package(){0x001CFFFF, 0, 0, 11 },
> +    Package(){0x001CFFFF, 1, 0, 10 },
> +    Package(){0x001CFFFF, 2, 0, 11 },
> +    Package(){0x001CFFFF, 3, 0, 11 },
> +// D27: PCI Express Port 17-20
> +    Package(){0x001BFFFF, 0, 0, 11 },
> +    Package(){0x001BFFFF, 1, 0, 10 },
> +    Package(){0x001BFFFF, 2, 0, 11 },
> +    Package(){0x001BFFFF, 3, 0, 11 },
> +// D25: SerialIo - can't use PIC
> +// D23: SATA controller
> +    Package(){0x0017FFFF, 0, 0, 11 },
> +// D22: CSME (HECI, IDE-R, Keyboard and Text redirection
> +    Package(){0x0016FFFF, 0, 0, 11 },
> +    Package(){0x0016FFFF, 1, 0, 10 },
> +    Package(){0x0016FFFF, 2, 0, 11 },
> +    Package(){0x0016FFFF, 3, 0, 11 },
> +// D21: SerialIo - can't use PIC
> +// D20: xHCI, OTG, Thermal Subsystem, Camera IO Host Controller
> +// D20: xHCI, OTG, CNVi WiFi, SDcard
> +    Package(){0x0014FFFF, 0, 0, 11 },
> +    Package(){0x0014FFFF, 1, 0, 10 },
> +    Package(){0x0014FFFF, 2, 0, 11 },
> +    Package(){0x0014FFFF, 3, 0, 11 },
> +// D19: Integrated Sensor Hub - can't use PIC
> +// D18: Thermal, UFS, SerialIo SPI2 - can't use PIC
> +    Package(){0x0012FFFF, 0, 0, 11 },
> +    Package(){0x0012FFFF, 1, 0, 10 },
> +    Package(){0x0012FFFF, 2, 0, 11 },
> +    Package(){0x0012FFFF, 3, 0, 11 },
> +
> +// Host Bridge
> +// P.E.G. Root Port D1F0
> +    Package(){0x0001FFFF, 0, 0, 11 },
> +    Package(){0x0001FFFF, 1, 0, 10 },
> +    Package(){0x0001FFFF, 2, 0, 11 },
> +    Package(){0x0001FFFF, 3, 0, 11 },
> +// P.E.G. Root Port D1F1
> +// P.E.G. Root Port D1F2
> +// SA IGFX Device
> +    Package(){0x0002FFFF, 0, 0, 11 },
> +// SA Thermal Device
> +    Package(){0x0004FFFF, 0, 0, 11 },
> +// SA IPU Device
> +    Package(){0x0005FFFF, 0, 0, 11 },
> +// SA GNA Device
> +    Package(){0x0008FFFF, 0, 0, 11 },
> +  })
> +  Name(AR00, Package(){
> +// PCI Bridge
> +// D31: cAVS, SMBus, GbE, Nothpeak
> +    Package(){0x001FFFFF, 0, 0, 16 },
> +    Package(){0x001FFFFF, 1, 0, 17 },
> +    Package(){0x001FFFFF, 2, 0, 18 },
> +    Package(){0x001FFFFF, 3, 0, 19 },
> +// D30: SerialIo and SCS
> +    Package(){0x001EFFFF, 0, 0, 20 },
> +    Package(){0x001EFFFF, 1, 0, 21 },
> +    Package(){0x001EFFFF, 2, 0, 22 },
> +    Package(){0x001EFFFF, 3, 0, 23 },
> +// D29: PCI Express Port 9-16
> +    Package(){0x001DFFFF, 0, 0, 16 },
> +    Package(){0x001DFFFF, 1, 0, 17 },
> +    Package(){0x001DFFFF, 2, 0, 18 },
> +    Package(){0x001DFFFF, 3, 0, 19 },
> +// D28: PCI Express Port 1-8
> +    Package(){0x001CFFFF, 0, 0, 16 },
> +    Package(){0x001CFFFF, 1, 0, 17 },
> +    Package(){0x001CFFFF, 2, 0, 18 },
> +    Package(){0x001CFFFF, 3, 0, 19 },
> +// D27: PCI Express Port 17-20
> +    Package(){0x001BFFFF, 0, 0, 16 },
> +    Package(){0x001BFFFF, 1, 0, 17 },
> +    Package(){0x001BFFFF, 2, 0, 18 },
> +    Package(){0x001BFFFF, 3, 0, 19 },
> +// D26: eMMC
> +    Package(){0x001AFFFF, 0, 0, 16 },
> +    Package(){0x001AFFFF, 1, 0, 17 },
> +    Package(){0x001AFFFF, 2, 0, 18 },
> +    Package(){0x001AFFFF, 3, 0, 19 },
> +// D25: SerialIo
> +    Package(){0x0019FFFF, 0, 0, 32 },
> +    Package(){0x0019FFFF, 1, 0, 33 },
> +    Package(){0x0019FFFF, 2, 0, 34 },
> +// D23: SATA controller
> +    Package(){0x0017FFFF, 0, 0, 16 },
> +// D22: CSME (HECI, IDE-R, Keyboard and Text redirection
> +    Package(){0x0016FFFF, 0, 0, 16 },
> +    Package(){0x0016FFFF, 1, 0, 17 },
> +    Package(){0x0016FFFF, 2, 0, 18 },
> +    Package(){0x0016FFFF, 3, 0, 19 },
> +// D21: SerialIo
> +    Package(){0x0015FFFF, 0, 0, 16 },
> +    Package(){0x0015FFFF, 1, 0, 17 },
> +    Package(){0x0015FFFF, 2, 0, 18 },
> +    Package(){0x0015FFFF, 3, 0, 19 },
> +// D20: xHCI, OTG, Thermal Subsystem, Camera IO Host Controller
> +// D20: xHCI, OTG, CNVi WiFi, SDcard
> +    Package(){0x0014FFFF, 0, 0, 16 },
> +    Package(){0x0014FFFF, 1, 0, 17 },
> +    Package(){0x0014FFFF, 2, 0, 18 },
> +    Package(){0x0014FFFF, 3, 0, 19 },
> +// D19: Integrated Sensor Hub
> +    Package(){0x0013FFFF, 0, 0, 20 },
> +// D18: Thermal, UFS, SerialIo SPI 2
> +    Package(){0x0012FFFF, 0, 0, 16 },
> +    Package(){0x0012FFFF, 1, 0, 24 },
> +    Package(){0x0012FFFF, 2, 0, 18 },
> +    Package(){0x0012FFFF, 3, 0, 19 },
> +
> +// Host Bridge
> +// P.E.G. Root Port D1F0
> +    Package(){0x0001FFFF, 0, 0, 16 },
> +    Package(){0x0001FFFF, 1, 0, 17 },
> +    Package(){0x0001FFFF, 2, 0, 18 },
> +    Package(){0x0001FFFF, 3, 0, 19 },
> +// P.E.G. Root Port D1F1
> +// P.E.G. Root Port D1F2
> +// SA IGFX Device
> +    Package(){0x0002FFFF, 0, 0, 16 },
> +// SA Thermal Device
> +    Package(){0x0004FFFF, 0, 0, 16 },
> +// SA IPU Device
> +    Package(){0x0005FFFF, 0, 0, 16 },
> +// SA GNA Device
> +    Package(){0x0008FFFF, 0, 0, 16 },
> +  })
> +  Name(PD04, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 10 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR04, Package(){
> +    Package(){0x0000FFFF, 0, 0, 16 },
> +    Package(){0x0000FFFF, 1, 0, 17 },
> +    Package(){0x0000FFFF, 2, 0, 18 },
> +    Package(){0x0000FFFF, 3, 0, 19 },
> +  })
> +  Name(PD05, Package(){
> +    Package(){0x0000FFFF, 0, 0, 10 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR05, Package(){
> +    Package(){0x0000FFFF, 0, 0, 17 },
> +    Package(){0x0000FFFF, 1, 0, 18 },
> +    Package(){0x0000FFFF, 2, 0, 19 },
> +    Package(){0x0000FFFF, 3, 0, 16 },
> +  })
> +  Name(PD06, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 10 },
> +  })
> +  Name(AR06, Package(){
> +    Package(){0x0000FFFF, 0, 0, 18 },
> +    Package(){0x0000FFFF, 1, 0, 19 },
> +    Package(){0x0000FFFF, 2, 0, 16 },
> +    Package(){0x0000FFFF, 3, 0, 17 },
> +  })
> +  Name(PD07, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 10 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR07, Package(){
> +    Package(){0x0000FFFF, 0, 0, 19 },
> +    Package(){0x0000FFFF, 1, 0, 16 },
> +    Package(){0x0000FFFF, 2, 0, 17 },
> +    Package(){0x0000FFFF, 3, 0, 18 },
> +  })
> +  Name(PD08, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 10 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR08, Package(){
> +    Package(){0x0000FFFF, 0, 0, 16 },
> +    Package(){0x0000FFFF, 1, 0, 17 },
> +    Package(){0x0000FFFF, 2, 0, 18 },
> +    Package(){0x0000FFFF, 3, 0, 19 },
> +  })
> +  Name(PD09, Package(){
> +    Package(){0x0000FFFF, 0, 0, 10 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR09, Package(){
> +    Package(){0x0000FFFF, 0, 0, 17 },
> +    Package(){0x0000FFFF, 1, 0, 18 },
> +    Package(){0x0000FFFF, 2, 0, 19 },
> +    Package(){0x0000FFFF, 3, 0, 16 },
> +  })
> +  Name(PD0E, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 10 },
> +  })
> +  Name(AR0E, Package(){
> +    Package(){0x0000FFFF, 0, 0, 18 },
> +    Package(){0x0000FFFF, 1, 0, 19 },
> +    Package(){0x0000FFFF, 2, 0, 16 },
> +    Package(){0x0000FFFF, 3, 0, 17 },
> +  })
> +  Name(PD0F, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 10 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR0F, Package(){
> +    Package(){0x0000FFFF, 0, 0, 19 },
> +    Package(){0x0000FFFF, 1, 0, 16 },
> +    Package(){0x0000FFFF, 2, 0, 17 },
> +    Package(){0x0000FFFF, 3, 0, 18 },
> +  })
> +  Name(PD02, Package(){
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 10 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR02, Package(){
> +// P.E.G. Port Slot x16
> +    Package(){0x0000FFFF, 0, 0, 16 },
> +    Package(){0x0000FFFF, 1, 0, 17 },
> +    Package(){0x0000FFFF, 2, 0, 18 },
> +    Package(){0x0000FFFF, 3, 0, 19 },
> +  })
> +  Name(PD0A, Package(){
> +// P.E.G. Port Slot x8
> +    Package(){0x0000FFFF, 0, 0, 10 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 11 },
> +  })
> +  Name(AR0A, Package(){
> +// P.E.G. Port Slot x8
> +    Package(){0x0000FFFF, 0, 0, 17 },
> +    Package(){0x0000FFFF, 1, 0, 18 },
> +    Package(){0x0000FFFF, 2, 0, 19 },
> +    Package(){0x0000FFFF, 3, 0, 16 },
> +  })
> +  Name(PD0B, Package(){
> +// P.E.G. Port Slot x4
> +    Package(){0x0000FFFF, 0, 0, 11 },
> +    Package(){0x0000FFFF, 1, 0, 11 },
> +    Package(){0x0000FFFF, 2, 0, 11 },
> +    Package(){0x0000FFFF, 3, 0, 10 },
> +  })
> +  Name(AR0B, Package(){
> +// P.E.G. Port Slot x4
> +    Package(){0x0000FFFF, 0, 0, 18 },
> +    Package(){0x0000FFFF, 1, 0, 19 },
> +    Package(){0x0000FFFF, 2, 0, 16 },
> +    Package(){0x0000FFFF, 3, 0, 17 },
> +  })
> +
> +//---------------------------------------------------------------------------
> +// Begin PCI tree object scope
> +//---------------------------------------------------------------------------
> +  Device(PCI0) { // PCI Bridge "Host Bridge"
> +    Name(_HID, EISAID("PNP0A08")) // Indicates PCI Express/PCI-X Mode2
> host hierarchy
> +    Name(_CID, EISAID("PNP0A03")) // To support legacy OS that doesn't
> understand the new HID
> +    Name(_SEG, 0)
> +    Name(_ADR, 0x00000000)
> +    Method(^BN00, 0){ return(0x0000) }  // Returns default Bus number for
> Peer PCI busses. Name can be overriden with control method placed directly
> under Device scope
> +    Method(_BBN, 0){ return(BN00()) } // Bus number, optional for the Root
> PCI Bus
> +    Name(_UID, 0x0000)  // Unique Bus ID, optional
> +    Method(_PRT,0) {
> +      If(PICM) {Return(AR00)} // APIC mode
> +      Return (PD00) // PIC Mode
> +    } // end _PRT
> +
> +  Include("HostBus.asl")
> +  } // end PCI0 Bridge "Host Bridge"
> +} // end _SB scope
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platfo
> rm.asl
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platfo
> rm.asl
> new file mode 100644
> index 0000000000..951c01455f
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platfo
> rm.asl
> @@ -0,0 +1,76 @@
> +/** @file
> +  ACPI DSDT table
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +// Define Port 80 as an ACPI Operating Region to use for debugging.  Please
> +// note that the Intel CRBs have the ability to ouput a Word to
> +// Port 80h for debugging purposes, so the model implemented here may not
> be
> +// able to be used on OEM Designs.
> +
> +OperationRegion(PRT0,SystemIO,0x80,2)
> +Field(PRT0,WordAcc,Lock,Preserve)
> +{
> +  P80B, 16
> +}
> +
> +// Port 80h Update:
> +//    Update 2 bytes of Port 80h.
> +//
> +//  Arguments:
> +//    Arg0: 0 = Write Port 80h
> +//          1 = Write Port 81h
> +//    Arg1: 8-bit Value to write
> +//
> +//  Return Value:
> +//    None
> +
> +Name(P80T, 0) // temp buffer for P80
> +
> +Method(D8XH,2,Serialized)
> +{
> +  If(LEqual(Arg0,0))    // Write Port 80h
> +  {
> +    Store(Or(And(P80T,0xFF00),Arg1),P80T)
> +  }
> +  If(LEqual(Arg0,1))    // Write Port 81h
> +  {
> +    Store(Or(And(P80T,0x00FF),ShiftLeft(Arg1,8)),P80T)
> +  }
> +  Store(P80T,P80B)
> +}
> +
> +//
> +// Define SW SMI port as an ACPI Operating Region to use for generate SW
> SMI.
> +//
> +OperationRegion(SPRT,SystemIO, 0xB2,2)
> +Field (SPRT, ByteAcc, Lock, Preserve) {
> +  SSMP, 8
> +}
> +
> +// The _PIC Control Method is optional for ACPI design.  It allows the
> +// OS to inform the ASL code which interrupt controller is being used,
> +// the 8259 or APIC.  The reference code in this document will address
> +// PCI IRQ Routing and resource allocation for both cases.
> +//
> +// The values passed into _PIC are:
> +//   0 = 8259
> +//   1 = IOAPIC
> +
> +Method(\_PIC,1)
> +{
> +  Store(Arg0,PICM)
> +}
> +
> +Scope (\)
> +{
> +  //
> +  // Global Name, returns current Interrupt controller mode;
> +  // updated from _PIC control method
> +  //
> +  Name(PICM, 0)
> +}
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3P
> cieTbt.asl
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3P
> cieTbt.asl
> new file mode 100644
> index 0000000000..38d60d6dbd
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3P
> cieTbt.asl
> @@ -0,0 +1,405 @@
> +/** @file
> +  ACPI RTD3 SSDT table for SPT PCIe
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#define PID_ICC                                   0xDC
> +#define R_PCH_PCR_ICC_MSKCKRQ                     0x100C                  ///<
> Mask Control CLKREQ
> +
> +External(PCRA,MethodObj)
> +External(PCRO,MethodObj)
> +External(\MMRP, MethodObj)
> +External(\MMTB, MethodObj)
> +External(\TRDO, IntObj)
> +External(\TRD3, IntObj)
> +External(\TBPE, IntObj)
> +External(\TOFF, IntObj)
> +External(\TBSE, IntObj)
> +External(\TBOD, IntObj)
> +External(\TBRP, IntObj)
> +External(\TBHR, IntObj)
> +External(\RTBC, IntObj)
> +External(\TBCD, IntObj)
> +
> +Name(G2SD, 0) // Go2Sx done, set by GO2S, cleaned by _ON
> +
> +Name(WKEN, 0)
> +
> +  Method(_S0W, 0)
> +  {
> +  /// This method returns the lowest D-state supported by PCIe root port
> during S0 state
> +
> +   ///- PMEs can be generated from D3hot for ULT
> +      Return(4)
> +
> +  /** @defgroup pcie_s0W PCIE _S0W **/
> +  } // End _S0W
> +
> +  Method (_DSD, 0) {
> +    Return (
> +      Package () {
> +        ToUUID("6211E2C0-58A3-4AF3-90E1-927A4E0C55A4"),
> +        Package () {
> +          Package (2) {"HotPlugSupportInD3", 1},
> +        }
> +      }
> +    ) // End of Return ()
> +  }
> +
> +    Method(_DSW, 3)
> +    {
> +    /// This method is used to enable/disable wake from PCIe (WKEN)
> +      If (LGreaterEqual(Arg1, 1)) { /// If entering Sx, need to disable WAKE#
> from generating runtime PME
> +                                    /// Also set 2 to TOFF.
> +        Store(0, WKEN)
> +        Store (2, TOFF)
> +      } Else {  /// If Staying in S0
> +        If(LAnd(Arg0, Arg2)) ///- Check if Exiting D0 and arming for wake
> +        { ///- Set PME
> +          Store(1, WKEN)
> +          Store (1, TOFF)
> +        } Else { ///- Disable runtime PME, either because staying in D0 or
> disabling wake
> +          Store(0, WKEN)
> +          Store(0, TOFF)
> +        }
> +      }
> +
> +    /** @defgroup pcie_dsw PCIE _DSW **/
> +    } // End _DSW
> +
> +
> +    PowerResource(PXP, 0, 0)
> +    {
> +    /// Define the PowerResource for PCIe slot
> +    /// Method: _STA(), _ON(), _OFF()
> +    /** @defgroup pcie_pxp PCIE Power Resource **/
> +
> +      Method(_STA, 0)
> +      {
> +          Return(PSTA())
> +      }  /** @defgroup pcie_sta PCIE _STA method **/
> +
> +      Method(_ON) /// Turn on core power to PCIe Slot
> +      {
> +        Store(1, TRDO)
> +        PON()
> +        Store(0, TRDO)
> +      } /** @defgroup pcie_on PCIE _ON method **/
> +
> +      Method(_OFF) /// Turn off core power to PCIe Slot
> +      {
> +        Store(1, TRD3)
> +        POFF()
> +        Store(0, TRD3)
> +      } // End of Method_OFF
> +    } // End PXP
> +
> +    Method(PSTA, 0)
> +    {
> +    /// Returns the status of PCIe slot core power
> +      // detect power pin status
> +      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) {
> +        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
> +          if(LEqual(\_SB.GGOV(DeRefOf(Index(PWRG,
> 2))),DeRefOf(Index(PWRG, 3)))){
> +            Return (1)
> +          } Else {
> +            Return (0)
> +          }
> +        } // GPIO mode
> +        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
> +          if(LEqual(\_SB.PCI0.GEXP.GEPS(DeRefOf(Index(PWRG,
> 1)),DeRefOf(Index(PWRG, 2))),DeRefOf(Index(PWRG, 3)))){
> +            Return (1)
> +          } Else {
> +            Return (0)
> +          }
> +        } // IOEX mode
> +      }
> +      // detect reset pin status
> +      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) {
> +        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
> +          if(LEqual(\_SB.GGOV(DeRefOf(Index(RSTG, 2))),DeRefOf(Index(RSTG,
> 3)))){
> +            Return (1)
> +          } Else {
> +            Return (0)
> +          }
> +        } // GPIO mode
> +        if(LEqual(DeRefOf(Index(RSTG, 0)),2))  { // IOEX mode
> +          if(LEqual(\_SB.PCI0.GEXP.GEPS(DeRefOf(Index(RSTG,
> 1)),DeRefOf(Index(RSTG, 2))),DeRefOf(Index(RSTG, 3)))){
> +            Return (1)
> +          } Else {
> +            Return (0)
> +          }
> +        } // IOEX mode
> +      }
> +      Return (0)
> +    }  /** @defgroup pcie_sta PCIE _STA method **/
> +
> +    Method (SXEX, 0, Serialized) {
> +
> +      Store(\MMTB(TBSE), Local7)
> +      OperationRegion(TBDI, SystemMemory, Local7, 0x550)// TBT HR PCICFG
> MMIO
> +      Field(TBDI,DWordAcc, NoLock, Preserve) {
> +        DIVI, 32,
> +        CMDR, 32,
> +        Offset(0x548),
> +        TB2P, 32,
> +        P2TB, 32
> +      }
> +
> +      Store(100, Local1)
> +      Store(0x09, P2TB) // Write SX_EXIT_TBT_CONNECTED to PCIe2TBT
> +      While (LGreater(Local1, 0)) {
> +
> +        Store(Subtract(Local1, 1), Local1)
> +        Store(TB2P, Local2)
> +        If (LEqual(Local2, 0xFFFFFFFF)) { // Device gone
> +          Return()
> +        }
> +        If (And(Local2, 1)) { // Done
> +          break
> +        }
> +        Sleep(5)
> +      }
> +      Store(0x0, P2TB) // Write 0 to PCIe2TBT
> +
> +      // Fast Link bring-up flow
> +      Store(500, Local1)
> +      While (LGreater(Local1, 0)) {
> +        Store(Subtract(Local1, 1), Local1)
> +        Store(TB2P, Local2)
> +        If (LEqual(Local2, 0xFFFFFFFF)) {// Device gone
> +          Return()
> +        }
> +        If (LNotEqual(DIVI, 0xFFFFFFFF)) {
> +          break
> +        }
> +        Sleep(10)
> +      }
> +    } // End of Method(SXEX, 0, Serialized)
> +
> +    Method(PON) /// Turn on core power to PCIe Slot
> +    {
> +
> +      Store(\MMRP(\TBSE), Local7)
> +      OperationRegion(L23P,SystemMemory,Local7,0xE4)
> +      Field(L23P,WordAcc, NoLock, Preserve)
> +      {
> +        Offset(0xA4),// PMCSR
> +        PSD0, 2, // PowerState
> +        Offset(0xE2),// 0xE2, RPPGEN - Root Port Power Gating Enable
> +        , 2,
> +        L2TE, 1,      // 2,   L23_Rdy Entry Request (L23ER)
> +        L2TR, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
> +      }
> +
> +      Store(\MMTB(\TBSE), Local6)
> +      OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG
> MMIO
> +      Field(TBDI,DWordAcc, NoLock, Preserve) {
> +        DIVI, 32,
> +        CMDR, 32,
> +        Offset(0xA4),
> +        TBPS, 2, // PowerState of TBT
> +        Offset(0x548),
> +        TB2P, 32,
> +        P2TB, 32
> +      }
> +
> +      Store(0, TOFF)
> +      // Check RTD3 power enable, if already ON, no need to execute sx_exit
> +      If (TBPE) {
> +        Return()
> +      }
> +
> +      Store(0,G2SD)
> +      If (\RTBC) {
> +        /// de-assert CLK_REQ MSK
> +        if(LNotEqual(DeRefOf(Index(SCLK, 0)),0)) { // if power gating enabled
> +          PCRA(PID_ICC,R_PCH_PCR_ICC_MSKCKRQ,Not(DeRefOf(Index(SCLK,
> 1))))  // And ~SCLK to clear bit
> +        }
> +        Sleep(\TBCD)
> +      }
> +
> +      /// Turn ON Power for PCIe Slot
> +      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) { // if power gating enabled
> +        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
> +          \_SB.SGOV(DeRefOf(Index(PWRG, 2)),DeRefOf(Index(PWRG, 3)))
> +          Store(1, TBPE)
> +          Sleep(PEP0)     /// Sleep for programmable delay
> +        }
> +        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
> +          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG,
> 2)),DeRefOf(Index(PWRG, 3)))
> +          Store(1, TBPE)
> +          Sleep(PEP0)     /// Sleep for programmable delay
> +        }
> +      }
> +
> +      /// De-Assert Reset Pin
> +      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) { // if reset pin enabled
> +        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
> +          \_SB.SGOV(DeRefOf(Index(RSTG, 2)),DeRefOf(Index(RSTG, 3)))
> +        }
> +        if(LEqual(DeRefOf(Index(RSTG, 0)),2)) { // IOEX mode
> +          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG,
> 2)),DeRefOf(Index(RSTG, 3)))
> +        }
> +      }
> +
> +      /// Clear DLSULPPGE, then set L23_Rdy to Detect Transition  (L23R2DT)
> +      Store(0, DPGE)
> +      Store(1, L2TR)
> +      Sleep(16)
> +      Store(0, Local0)
> +      /// Wait up to 12 ms for transition to Detect
> +      While(L2TR) {
> +        If(Lgreater(Local0, 4))    // Debug - Wait for 5 ms
> +        {
> +          Break
> +        }
> +        Sleep(16)
> +        Increment(Local0)
> +      }
> +      /// Once in Detect, wait up to 124 ms for Link Active (typically happens in
> under 70ms)
> +      /// Worst case per PCIe spec from Detect to Link Active is:
> +      /// 24ms in Detect (12+12), 72ms in Polling (24+48), 28ms in Config
> (24+2+2+2+2)
> +      Store(1, DPGE)
> +      Store(0, Local0)
> +      While(LEqual(LASX,0)) {
> +        If(Lgreater(Local0, 8))
> +        {
> +          Break
> +        }
> +        Sleep(16)
> +        Increment(Local0)
> +      }
> +      Store(0, LEDM) /// Set PCIEDBG.DMIL1EDM (324[3]) = 0
> +
> +      // TBT special sleep.
> +      Store(PSD0, Local1)
> +      Store(0, PSD0)// D0
> +      Store(20, Local2) // Poll for TBT, up to 200 ms
> +
> +      While (LGreater(Local2, 0)) {
> +        Store(Subtract(Local2, 1), Local2)
> +        Store(TB2P, Local3)
> +        If (LNotEqual(Local3, 0xFFFFFFFF)) { // Done
> +          break
> +        }
> +        Sleep(10)
> +      }
> +
> +      If (LLessEqual(Local2, 0)) {
> +      }
> +      SXEX()
> +      Store(Local1, PSD0) // Back to Local1
> +    } /** @defgroup pcie_on PCIE _ON method **/
> +
> +    Method(POFF) { /// Turn off core power to PCIe Slot
> +      If (LEqual(TOFF, 0)) {
> +        Return()
> +      }
> +      Store(\MMRP(\TBSE), Local7)
> +      OperationRegion(L23P, SystemMemory, Local7, 0xE4)
> +      Field(L23P,WordAcc, NoLock, Preserve)
> +      {
> +        Offset(0xA4),// PMCSR
> +        PSD0, 2, // PowerState
> +        Offset(0xE2),// 0xE2, RPPGEN - Root Port Power Gating Enable
> +        , 2,
> +        L2TE, 1,      // 2,   L23_Rdy Entry Request (L23ER)
> +        L2TR, 1,       // 3,   L23_Rdy to Detect Transition (L23R2DT)
> +      }
> +
> +      Store(\MMTB(TBSE), Local6)
> +      OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG
> MMIO
> +      Field(TBDI,DWordAcc, NoLock, Preserve) {
> +        DIVI, 32,
> +        CMDR, 32,
> +        Offset(0xA4),
> +        TBPS, 2, // PowerState of TBT
> +        Offset(0x548),
> +        TB2P, 32,
> +        P2TB, 32
> +      }
> +
> +      Store(PSD0, Local1)
> +      Store(0, PSD0)// D0
> +
> +      Store(P2TB, Local3)
> +
> +      If (Lgreater(TOFF, 1)) {
> +        Sleep(10)
> +        Store(Local1, PSD0) // Back to Local1
> +        Return()
> +      }
> +      Store(0, TOFF)
> +
> +      Store(Local1, PSD0) // Back to Local1
> +
> +      /// Set L23_Rdy Entry Request (L23ER)
> +      Store(1, L2TE)
> +      Sleep(16)
> +      Store(0, Local0)
> +      While(L2TE) {
> +        If(Lgreater(Local0, 4))    /// Debug - Wait for 5 ms
> +        {
> +          Break
> +        }
> +        Sleep(16)
> +        Increment(Local0)
> +      }
> +      Store(1, LEDM) /// PCIEDBG.DMIL1EDM (324[3]) = 1
> +
> +      /// Assert Reset Pin
> +      if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) { // if reset pin enabled
> +        if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
> +          \_SB.SGOV(DeRefOf(Index(RSTG, 2)),Xor(DeRefOf(Index(RSTG, 3)),1))
> +        }
> +        if(LEqual(DeRefOf(Index(RSTG, 0)),2)) { // IOEX mode
> +          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG,
> 2)),Xor(DeRefOf(Index(RSTG, 3)),1))
> +        }
> +      }
> +      If (\RTBC) {
> +        /// assert CLK_REQ MSK
> +        if(LNotEqual(DeRefOf(Index(SCLK, 0)),0)) { // if power gating enabled
> +          PCRO(PID_ICC,R_PCH_PCR_ICC_MSKCKRQ,DeRefOf(Index(SCLK, 1)))
> // Or SCLK to set bit
> +          Sleep(16)
> +        }
> +      }
> +
> +      /// Power OFF for TBT
> +      if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) { // if power gating enabled
> +        if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
> +          \_SB.SGOV(DeRefOf(Index(PWRG, 2)),Xor(DeRefOf(Index(PWRG,
> 3)),1))
> +        }
> +        if(LEqual(DeRefOf(Index(PWRG, 0)),2))  { // IOEX mode
> +          \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG,
> 2)),Xor(DeRefOf(Index(PWRG, 3)),1))
> +        }
> +      }
> +
> +      Store(0, TBPE)
> +
> +      Store(1, LDIS) /// Set Link Disable
> +      Store(0, LDIS) /// Toggle link disable
> +
> +      /// enable WAKE
> +      If (WKEN) {
> +        If (LNotEqual(DeRefOf(Index(WAKG, 0)),0)) { // if power gating enabled
> +          If (LEqual(DeRefOf(Index(WAKG, 0)),1)) { // GPIO mode
> +            \_SB.SGOV(DeRefOf(Index(WAKG, 2)),DeRefOf(Index(WAKG, 3)))
> +            \_SB.SHPO(DeRefOf(Index(WAKG, 2)), 0) // set gpio ownership to
> ACPI(0=ACPI mode, 1=GPIO mode)
> +          }
> +          If (LEqual(DeRefOf(Index(WAKG, 0)),2))  { // IOEX mode
> +            \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(WAKG,
> 1)),DeRefOf(Index(WAKG, 2)),DeRefOf(Index(WAKG, 3)))
> +          }
> +        }
> +      }
> +      Sleep(\TBOD)
> +      /** @defgroup pcie_off PCIE _OFF method **/
> +    } // End of Method_OFF
> +
> +    Name(_PR0, Package(){PXP})
> +    Name(_PR3, Package(){PXP})
> +
> +
> diff --git
> a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.as
> l
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.as
> l
> new file mode 100644
> index 0000000000..66584c21c5
> --- /dev/null
> +++
> b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.as
> l
> @@ -0,0 +1,1877 @@
> +/** @file
> + Thunderbolt ACPI methods
> +
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#define DTBT_CONTROLLER                   0x00
> +#define DTBT_TYPE_PCH                     0x01
> +#define DTBT_TYPE_PEG                     0x02
> +#define DTBT_SMI_HANDLER_NUMBER           0xF7
> +#define TBT_SMI_ENUMERATION_FUNCTION      21
> +#define TBT_SMI_RESET_SWITCH_FUNCTION     22
> +#define TBT_SMI_DISABLE_MSI_FUNCTION      23
> +#ifndef  BIT29
> +#define  BIT29    0x20000000
> +#endif
> +
> +Name(LDLY, 300) //300 ms
> +Name (TNVB, 0xFFFF0000)  // TBT NVS Base address
> +Name (TNVL, 0xAA55)      // TBT NVS Length
> +Include ("Acpi/TbtNvs.asl")
> +
> +External(\_SB.PCI0.RP02.L23D, MethodObj)
> +External(\_SB.PCI0.RP03.L23D, MethodObj)
> +External(\_SB.PCI0.RP04.L23D, MethodObj)
> +External(\_SB.PCI0.RP05.L23D, MethodObj)
> +External(\_SB.PCI0.RP06.L23D, MethodObj)
> +External(\_SB.PCI0.RP07.L23D, MethodObj)
> +External(\_SB.PCI0.RP08.L23D, MethodObj)
> +External(\_SB.PCI0.RP09.L23D, MethodObj)
> +External(\_SB.PCI0.RP10.L23D, MethodObj)
> +External(\_SB.PCI0.RP11.L23D, MethodObj)
> +External(\_SB.PCI0.RP12.L23D, MethodObj)
> +External(\_SB.PCI0.RP13.L23D, MethodObj)
> +External(\_SB.PCI0.RP14.L23D, MethodObj)
> +External(\_SB.PCI0.RP15.L23D, MethodObj)
> +External(\_SB.PCI0.RP16.L23D, MethodObj)
> +External(\_SB.PCI0.RP17.L23D, MethodObj)
> +External(\_SB.PCI0.RP18.L23D, MethodObj)
> +External(\_SB.PCI0.RP19.L23D, MethodObj)
> +External(\_SB.PCI0.RP20.L23D, MethodObj)
> +External(\_SB.PCI0.RP21.L23D, MethodObj)
> +External(\_SB.PCI0.RP22.L23D, MethodObj)
> +External(\_SB.PCI0.RP23.L23D, MethodObj)
> +External(\_SB.PCI0.RP24.L23D, MethodObj)
> +
> +External(\_SB.PCI0.RP01.DL23, MethodObj)
> +External(\_SB.PCI0.RP02.DL23, MethodObj)
> +External(\_SB.PCI0.RP03.DL23, MethodObj)
> +External(\_SB.PCI0.RP04.DL23, MethodObj)
> +External(\_SB.PCI0.RP05.DL23, MethodObj)
> +External(\_SB.PCI0.RP06.DL23, MethodObj)
> +External(\_SB.PCI0.RP07.DL23, MethodObj)
> +External(\_SB.PCI0.RP08.DL23, MethodObj)
> +External(\_SB.PCI0.RP09.DL23, MethodObj)
> +External(\_SB.PCI0.RP10.DL23, MethodObj)
> +External(\_SB.PCI0.RP11.DL23, MethodObj)
> +External(\_SB.PCI0.RP12.DL23, MethodObj)
> +External(\_SB.PCI0.RP13.DL23, MethodObj)
> +External(\_SB.PCI0.RP14.DL23, MethodObj)
> +External(\_SB.PCI0.RP15.DL23, MethodObj)
> +External(\_SB.PCI0.RP16.DL23, MethodObj)
> +External(\_SB.PCI0.RP17.DL23, MethodObj)
> +External(\_SB.PCI0.RP18.DL23, MethodObj)
> +External(\_SB.PCI0.RP19.DL23, MethodObj)
> +External(\_SB.PCI0.RP20.DL23, MethodObj)
> +External(\_SB.PCI0.RP21.DL23, MethodObj)
> +External(\_SB.PCI0.RP22.DL23, MethodObj)
> +External(\_SB.PCI0.RP23.DL23, MethodObj)
> +External(\_SB.PCI0.RP24.DL23, MethodObj)
> +
> +External(\_SB.PCI0.RTEN, MethodObj)
> +External(\_SB.PCI0.RTDS, MethodObj)
> +External(\_SB.PCI0.RP01.PON, MethodObj)
> +External(\_SB.PCI0.RP02.PON, MethodObj)
> +External(\_SB.PCI0.RP03.PON, MethodObj)
> +External(\_SB.PCI0.RP04.PON, MethodObj)
> +External(\_SB.PCI0.RP05.PON, MethodObj)
> +External(\_SB.PCI0.RP06.PON, MethodObj)
> +External(\_SB.PCI0.RP07.PON, MethodObj)
> +External(\_SB.PCI0.RP08.PON, MethodObj)
> +External(\_SB.PCI0.RP09.PON, MethodObj)
> +External(\_SB.PCI0.RP10.PON, MethodObj)
> +External(\_SB.PCI0.RP11.PON, MethodObj)
> +External(\_SB.PCI0.RP12.PON, MethodObj)
> +External(\_SB.PCI0.RP13.PON, MethodObj)
> +External(\_SB.PCI0.RP14.PON, MethodObj)
> +External(\_SB.PCI0.RP15.PON, MethodObj)
> +External(\_SB.PCI0.RP16.PON, MethodObj)
> +External(\_SB.PCI0.RP17.PON, MethodObj)
> +External(\_SB.PCI0.RP18.PON, MethodObj)
> +External(\_SB.PCI0.RP19.PON, MethodObj)
> +External(\_SB.PCI0.RP20.PON, MethodObj)
> +External(\_SB.PCI0.RP21.PON, MethodObj)
> +External(\_SB.PCI0.RP22.PON, MethodObj)
> +External(\_SB.PCI0.RP23.PON, MethodObj)
> +External(\_SB.PCI0.RP24.PON, MethodObj)
> +External(\_SB.PCI0.PEG0.PG00._ON, MethodObj)
> +External(\_SB.PCI0.PEG1.PG01._ON, MethodObj)
> +External(\_SB.PCI0.PEG2.PG02._ON, MethodObj)
> +
> +Name(TRDO, 0) // 1 during TBT RTD3 _ON
> +Name(TRD3, 0) // 1 during TBT RTD3 _OFF
> +Name(TBPE, 0) // Reflects RTD3_PWR_EN value
> +Name(TOFF, 0) // param to TBT _OFF method
> +
> +  Method (TBON, 0, Serialized) {
> +    // TBT On process before entering Sx state.
> +    Store(1, TRDO)
> +    Switch (ToInteger(\RPS0)) { // TBT Root port Selector
> +      Case (1) {
> +        If (CondRefOf(\_SB.PCI0.RP01.PON)) {
> +          \_SB.PCI0.RP01.PON()
> +        }
> +      }
> +      Case (2) {
> +        If (CondRefOf(\_SB.PCI0.RP02.PON)) {
> +          \_SB.PCI0.RP02.PON()
> +        }
> +      }
> +      Case (3) {
> +        If (CondRefOf(\_SB.PCI0.RP03.PON)) {
> +          \_SB.PCI0.RP03.PON()
> +        }
> +      }
> +      Case (4) {
> +        If (CondRefOf(\_SB.PCI0.RP04.PON)) {
> +          \_SB.PCI0.RP04.PON()
> +        }
> +      }
> +      Case (5) {
> +        If (CondRefOf(\_SB.PCI0.RP05.PON)) {
> +          \_SB.PCI0.RP05.PON()
> +        }
> +      }
> +      Case (6) {
> +        If (CondRefOf(\_SB.PCI0.RP06.PON)) {
> +          \_SB.PCI0.RP06.PON()
> +        }
> +      }
> +      Case (7) {
> +        If (CondRefOf(\_SB.PCI0.RP07.PON)) {
> +          \_SB.PCI0.RP07.PON()
> +        }
> +      }
> +      Case (8) {
> +        If (CondRefOf(\_SB.PCI0.RP08.PON)) {
> +          \_SB.PCI0.RP08.PON()
> +        }
> +      }
> +      Case (9) {
> +        If (CondRefOf(\_SB.PCI0.RP09.PON)) {
> +          \_SB.PCI0.RP09.PON()
> +        }
> +      }
> +      Case (10) {
> +        If (CondRefOf(\_SB.PCI0.RP10.PON)) {
> +          \_SB.PCI0.RP10.PON()
> +        }
> +      }
> +      Case (11) {
> +        If (CondRefOf(\_SB.PCI0.RP11.PON)) {
> +          \_SB.PCI0.RP11.PON()
> +        }
> +      }
> +      Case (12) {
> +        If (CondRefOf(\_SB.PCI0.RP12.PON)) {
> +          \_SB.PCI0.RP12.PON()
> +        }
> +      }
> +      Case (13) {
> +        If (CondRefOf(\_SB.PCI0.RP13.PON)) {
> +          \_SB.PCI0.RP13.PON()
> +        }
> +      }
> +      Case (14) {
> +        If (CondRefOf(\_SB.PCI0.RP14.PON)) {
> +          \_SB.PCI0.RP14.PON()
> +        }
> +      }
> +      Case (15) {
> +        If (CondRefOf(\_SB.PCI0.RP15.PON)) {
> +          \_SB.PCI0.RP15.PON()
> +        }
> +      }
> +      Case (16) {
> +        If (CondRefOf(\_SB.PCI0.RP16.PON)) {
> +          \_SB.PCI0.RP16.PON()
> +        }
> +      }
> +      Case (17) {
> +        If (CondRefOf(\_SB.PCI0.RP17.PON)) {
> +          \_SB.PCI0.RP17.PON()
> +        }
> +      }
> +      Case (18) {
> +        If (CondRefOf(\_SB.PCI0.RP18.PON)) {
> +          \_SB.PCI0.RP18.PON()
> +        }
> +      }
> +      Case (19) {
> +        If (CondRefOf(\_SB.PCI0.RP19.PON)) {
> +          \_SB.PCI0.RP19.PON()
> +        }
> +      }
> +      Case (20) {
> +        If (CondRefOf(\_SB.PCI0.RP20.PON)) {
> +          \_SB.PCI0.RP20.PON()
> +        }
> +      }
> +      Case (21) {
> +        If (CondRefOf(\_SB.PCI0.RP21.PON)) {
> +          \_SB.PCI0.RP21.PON()
> +        }
> +      }
> +      Case (22) {
> +        If (CondRefOf(\_SB.PCI0.RP22.PON)) {
> +          \_SB.PCI0.RP22.PON()
> +        }
> +      }
> +      Case (23) {
> +        If (CondRefOf(\_SB.PCI0.RP23.PON)) {
> +          \_SB.PCI0.RP23.PON()
> +        }
> +      }
> +      Case (24) {
> +        If (CondRefOf(\_SB.PCI0.RP24.PON)) {
> +          \_SB.PCI0.RP24.PON()
> +        }
> +      }
> +    }//Switch(ToInteger(RPS0)) // TBT Selector
> +    Store(0, TRDO)
> +  } // End of TBON
> +  //
> +  // Name: TBTD
> +  // Description: Function to return the TBT RP# device no
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  // Return: TBT RP# device no
> +  //
> +  Method(TBTD,2)
> +  {
> +    ADBG("TBTD")
> +    If (LEqual(Arg1, DTBT_TYPE_PCH)) {
> +      Switch(ToInteger(Arg0))
> +      {
> +        Case (Package () {1, 2, 3, 4, 5, 6, 7, 8})
> +        {
> +          Store(0x1C, Local0) //Device28-Function0...Function7 =
> 11100.000...111
> +        }
> +        Case (Package () {9, 10, 11, 12, 13, 14, 15, 16})
> +        {
> +          Store(0x1D, Local0) //Device29-Function0...Function7 =
> 11101.000...111
> +        }
> +        Case (Package () {17, 18, 19, 20, 21, 22, 23, 24})
> +        {
> +          Store(0x1B, Local0) //Device27-Function0...Function3 =
> 11011.000...011
> +        }
> +      }
> +    } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
> +      Switch(ToInteger(Arg0))
> +      {
> +        Case (Package () {1, 2, 3})
> +        {
> +          Store(0x1, Local0) //Device1-Function0...Function2 = 00001.000...010
> +        }
> +      }
> +    } Else {
> +      Store(0xFF, Local0)
> +    }
> +
> +    ADBG("Device no")
> +    ADBG(Local0)
> +
> +    Return(Local0)
> +  } // End of Method(TBTD,1)
> +
> +  //
> +  // Name: TBTF
> +  // Description: Function to return the TBT RP# function no
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  // Return: TBT RP# function no
> +  //
> +  Method(TBTF,2)
> +  {
> +    ADBG("TBTF")
> +    If (LEqual(Arg1, DTBT_TYPE_PCH)) {
> +      Switch(ToInteger(Arg0))
> +      {
> +        Case (1)
> +        {
> +          Store(And(\RPA1,0xF), Local0) //Device28-Function0 = 11100.000
> +        }
> +        Case (2)
> +        {
> +          Store(And(\RPA2,0xF), Local0) //Device28-Function1 = 11100.001
> +        }
> +        Case (3)
> +        {
> +          Store(And(\RPA3,0xF), Local0) //Device28-Function2 = 11100.010
> +        }
> +        Case (4)
> +        {
> +          Store(And(\RPA4,0xF), Local0) //Device28-Function3 = 11100.011
> +        }
> +        Case (5)
> +        {
> +          Store(And(\RPA5,0xF), Local0) //Device28-Function4 = 11100.100
> +        }
> +        Case (6)
> +        {
> +          Store(And(\RPA6,0xF), Local0) //Device28-Function5 = 11100.101
> +        }
> +        Case (7)
> +        {
> +          Store(And(\RPA7,0xF), Local0) //Device28-Function6 = 11100.110
> +        }
> +        Case (8)
> +        {
> +          Store(And(\RPA8,0xF), Local0) //Device28-Function7 = 11100.111
> +        }
> +        Case (9)
> +        {
> +          Store(And(\RPA9,0xF), Local0) //Device29-Function0 = 11101.000
> +        }
> +        Case (10)
> +        {
> +          Store(And(\RPAA,0xF), Local0) //Device29-Function1 = 11101.001
> +        }
> +        Case (11)
> +        {
> +          Store(And(\RPAB,0xF), Local0) //Device29-Function2 = 11101.010
> +        }
> +        Case (12)
> +        {
> +          Store(And(\RPAC,0xF), Local0) //Device29-Function3 = 11101.011
> +        }
> +        Case (13)
> +        {
> +          Store(And(\RPAD,0xF), Local0) //Device29-Function4 = 11101.100
> +        }
> +        Case (14)
> +        {
> +          Store(And(\RPAE,0xF), Local0) //Device29-Function5 = 11101.101
> +        }
> +        Case (15)
> +        {
> +          Store(And(\RPAF,0xF), Local0) //Device29-Function6 = 11101.110
> +        }
> +        Case (16)
> +        {
> +          Store(And(\RPAG,0xF), Local0) //Device29-Function7 = 11101.111
> +        }
> +        Case (17)
> +        {
> +          Store(And(\RPAH,0xF), Local0) //Device27-Function0 = 11011.000
> +        }
> +        Case (18)
> +        {
> +          Store(And(\RPAI,0xF), Local0) //Device27-Function1 = 11011.001
> +        }
> +        Case (19)
> +        {
> +          Store(And(\RPAJ,0xF), Local0) //Device27-Function2 = 11011.010
> +        }
> +        Case (20)
> +        {
> +          Store(And(\RPAK,0xF), Local0) //Device27-Function3 = 11011.011
> +        }
> +        Case (21)
> +        {
> +          Store(And(\RPAL,0xF), Local0) //Device27-Function4 = 11011.100
> +        }
> +        Case (22)
> +        {
> +          Store(And(\RPAM,0xF), Local0) //Device27-Function5 = 11011.101
> +        }
> +        Case (23)
> +        {
> +          Store(And(\RPAN,0xF), Local0) //Device27-Function6 = 11011.110
> +        }
> +        Case (24)
> +        {
> +          Store(And(\RPAO,0xF), Local0) //Device27-Function7 = 11011.111
> +        }
> +      }
> +    } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
> +      Switch(ToInteger(Arg0))
> +      {
> +        Case (1)
> +        {
> +          Store(0x0, Local0) //Device1-Function0 = 00001.000
> +        }
> +        Case (2)
> +        {
> +          Store(0x1, Local0) //Device1-Function1 = 00001.001
> +        }
> +        Case (3)
> +        {
> +          Store(0x2, Local0) //Device1-Function2 = 00001.010
> +        }
> +      }
> +    } Else {
> +      Store(0xFF, Local0)
> +    }
> +
> +    ADBG("Function no")
> +    ADBG(Local0)
> +
> +    Return(Local0)
> +  } // End of Method(TBTF,1)
> +
> +  //
> +  // Name: MMRP
> +  // Description: Function to return the Pci base address of TBT rootport
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  //
> +
> +  Method(MMRP, 2, Serialized)
> +  {
> +    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
> +    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
> +    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
> +
> +    Return(Local0)
> +  } // End of Method(MMRP)
> +
> +  //
> +  // Name: MMRP
> +  // Description: Function to return the Pci base address of TBT Up stream
> port
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  //
> +  Method(MMTB, 2, Serialized)
> +  {
> +    ADBG("MMTB")
> +
> +    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
> +
> +    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
> +    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
> +
> +    OperationRegion (MMMM, SystemMemory, Local0, 0x1A)
> +    Field (MMMM, AnyAcc, NoLock, Preserve)
> +    {
> +      Offset(0x19),
> +      SBUS, 8
> +    }
> +    Store(SBUS, Local2)
> +    Store(\_SB.PCI0.GPCB(), Local0)
> +    Multiply(Local2, 0x100000, Local2)
> +    Add(Local2, Local0, Local0) // TBT HR US port
> +
> +    ADBG("TBT-US-ADR")
> +    ADBG(Local0)
> +
> +    Return(Local0)
> +  } // End of Method(MMTB, 1, Serialized)
> +  //
> +  // Name: FFTB
> +  // Description: Function to  Check for FFFF in TBT PCIe
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  // Return: 1 if TBT PCIe space has value FFFF, 0 if not
> +  //
> +  Method(FFTB, 2, Serialized)
> +  {
> +    ADBG("FFTB")
> +
> +    Add(MMTB(Arg0, Arg1), 0x548, Local0)
> +    OperationRegion(PXVD,SystemMemory,Local0,0x08)
> +    Field(PXVD,DWordAcc, NoLock, Preserve)
> +    {
> +      TB2P, 32,
> +      P2TB, 32
> +    }
> +
> +    Store(TB2P, Local1)
> +
> +    If(LEqual(Local1, 0xFFFFFFFF))
> +    {
> +      ADBG("FFTb 1")
> +      Return (1)
> +    }
> +    Else
> +    {
> +      ADBG("FFTb 0")
> +      Return (0)
> +    }
> +  } // End of Method(FFTB)
> +
> +Name(TDMA, 0x80000000) // Address of Thunderbolt(TM) debug memory
> buffer, fixed up during POST
> +
> +Scope(\_GPE)
> +{
> +  //
> +  //
> +  //OS up Mail Box command execution to host router upstream port each
> time
> +  //exiting from Sx State .Avoids intermediate
> +  //PCIe Scan by OS during resorce allocation
> +  // Arg0 : PCIe Base address
> +  // Arg1 : Controller Type 0x00 : DTBT
> +  //Developer notes: Called twice
> +  // 1. During OS INIT (booting to OS from S3-S5/Reboot)
> +  // 2. Up on Hot plug
> +  //
> +  Method(OSUP, 2, Serialized)
> +  {
> +    ADBG("OSUP")
> +
> +    Add(Arg0, 0x540, Local0)
> +    OperationRegion(PXVD,SystemMemory,Local0,0x10)
> +    Field(PXVD,DWordAcc, NoLock, Preserve)
> +    {
> +      IT2P, 32,
> +      IP2T, 32,
> +      DT2P, 32,
> +      DP2T, 32
> +    }
> +
> +    Store(100, Local1)
> +    Store(0x0D, DP2T) // Write OS_Up to PCIe2TBT
> +
> +    While(LGreater(Local1, 0))
> +    {
> +      Store(Subtract(Local1, 1), Local1)
> +      Store(DT2P, Local2)
> +
> +      If(LAnd(LEqual(Local2, 0xFFFFFFFF),LEqual(Arg1, DTBT_CONTROLLER)))//
> Device gone
> +      {
> +        ADBG("Dev gone")
> +        Return(2)
> +      }
> +      If(And(Local2, 1)) // Done
> +      {
> +        ADBG("Cmd acknowledged")
> +        break
> +      }
> +      Sleep(50)
> +    }
> +    If(LEqual(TRWA,1))
> +    {
> +      Store(0xC, DP2T) // Write OSUP to PCIe2TBT
> +    }
> +    Else
> +    {
> +      Store(0x0, DP2T) // Write 0 to PCIe2TBT
> +    }
> +
> +    //Store(0x00, P2TB) // Write 0 to PCIe2TBT
> +
> +    ADBG("End-of-OSUP")
> +
> +    Return(1)
> +  } // End of Method(OSUP, 1, Serialized)
> +
> +  //
> +  // Check for FFFF in TBT
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  //
> +
> +  Method(TBFF, 2, Serialized)
> +  {
> +    ADBG("TBFF")
> +
> +    Store(MMTB(Arg0, Arg1), Local0)
> +    OperationRegion (PXVD, SystemMemory, Local0, 0x8)
> +    Field (PXVD, DWordAcc, NoLock, Preserve) {
> +      VEDI, 32, // Vendor/Device ID
> +      CMDR, 32 // CMD register
> +    }
> +
> +    Store(VEDI, Local1)
> +
> +    If (LEqual(Local1, 0xFFFFFFFF)) {
> +      If (LNotEqual(\TWIN, 0)) { // TBT Enumeration is Native mode?
> +        If (LEqual(CMDR, 0xFFFFFFFF)) { // Device Gone
> +          Return (2)// Notify only
> +        }
> +        Return (1)// Exit w/o notify
> +      } Else {
> +        Return (OSUP(Local0, DTBT_CONTROLLER))
> +      }
> +    } Else
> +    {
> +      ADBG("Dev Present")
> +      Return (0)
> +    }
> +  } // End of Method(TBFF, 1, Serialized)
> +
> +  //
> +  // Secondary bus of TBT RP
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  //
> +
> +  Method(TSUB, 2, Serialized)
> +  {
> +    ADBG("TSUB")
> +
> +    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
> +
> +    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
> +    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
> +
> +    ADBG("ADR")
> +    ADBG(Local0)
> +
> +    OperationRegion (MMMM, SystemMemory, Local0, 0x1A)
> +    Field (MMMM, AnyAcc, NoLock, Preserve)
> +    {
> +      Offset(0x19),
> +      SBUS, 8
> +    }
> +
> +    ADBG("Sec Bus")
> +    ADBG(SBUS)
> +
> +    Return(SBUS)
> +  } // End of Method(TSUB, 0, Serialized)
> +
> +  //
> +  // Pmem of TBT RP
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  //
> +
> +  Method(TSUP, 2, Serialized)
> +  {
> +    ADBG("TSUB")
> +
> +    Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address
> +
> +    Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no
> +    Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no
> +
> +    ADBG("ADR:")
> +    ADBG(Local0)
> +
> +    OperationRegion (MMMM, SystemMemory, Local0, 0x30)
> +    Field (MMMM, AnyAcc, NoLock, Preserve)
> +    {
> +      CMDS, 32,
> +      Offset(0x19),
> +      SBUS, 8,
> +      SBU5, 8,
> +      Offset(0x1C),
> +      SEIO, 32,
> +      MMBL, 32,
> +      PMBL, 32,
> +
> +    }
> +
> +    ADBG("Pmem of TBT RP:")
> +    ADBG(PMBL)
> +
> +    Return(PMBL)
> +  } // End of Method(TSUP, 0, Serialized)
> +
> +  //
> +  // Wait for secondary bus in TBT RP
> +  // Input: Arg0 -> Tbt Root Port value from Tbt NVS
> +  // Input: Arg1 -> Tbt port type value from Tbt NVS
> +  //
> +
> +  Method(WSUB, 2, Serialized)
> +  {
> +    ADBG(Concatenate("WSUB=", ToHexString(Arg0)))
> +    ADBG(ToHexString(Timer))
> +
> +    Store(0, Local0)
> +    Store(0, Local1)
> +    While(1)
> +    {
> +      Store(TSUP(Arg0, Arg1), Local1)
> +      If(LGreater(Local1, 0x1FFF1))
> +      {
> +        ADBG("WSUB-Finished")
> +        Break
> +      }
> +      Else
> +      {
> +        Add(Local0, 1, Local0)
> +        If(LGreater(Local0, 1000))
> +        {
> +          Sleep(1000)
> +          ADBG("WSUB-Deadlock")
> +        }
> +        Else
> +        {
> +          Sleep(16)
> +        }
> +      }
> +    }
> +     ADBG(Concatenate("WSUb=", ToHexString(Local1)))
> +  } // End of Method(WSUB)
> +
> +  // Wait for _WAK finished
> +  Method(WWAK)
> +  {
> +    ADBG("WWAK")
> +
> +    Wait(WFEV, 0xFFFF)
> +    Signal(WFEV) // Set it, to enter on next HP
> +  } // End of Method(WWAK)
> +
> +  Method(NTFY, 2, Serialized)
> +  {
> +    ADBG("NTFY")
> +
> +    If(LEqual(NOHP,1))
> +    {
> +      If (LEqual(Arg1, DTBT_TYPE_PCH)) {
> +        Switch(ToInteger(Arg0)) // TBT Selector
> +        {
> +          Case (1)
> +          {
> +            ADBG("Notify RP01")
> +            Notify(\_SB.PCI0.RP01,0)
> +          }
> +          Case (2)
> +          {
> +            ADBG("Notify RP02")
> +            Notify(\_SB.PCI0.RP02,0)
> +          }
> +          Case (3)
> +          {
> +            ADBG("Notify RP03")
> +            Notify(\_SB.PCI0.RP03,0)
> +          }
> +          Case (4)
> +          {
> +            ADBG("Notify RP04")
> +            Notify(\_SB.PCI0.RP04,0)
> +          }
> +          Case (5)
> +          {
> +            ADBG("Notify RP05")
> +            Notify(\_SB.PCI0.RP05,0)
> +          }
> +          Case (6)
> +          {
> +            ADBG("Notify RP06")
> +            Notify(\_SB.PCI0.RP06,0)
> +          }
> +          Case (7)
> +          {
> +            ADBG("Notify RP07")
> +            Notify(\_SB.PCI0.RP07,0)
> +          }
> +          Case (8)
> +          {
> +            ADBG("Notify RP08")
> +            Notify(\_SB.PCI0.RP08,0)
> +          }
> +          Case (9)
> +          {
> +            ADBG("Notify RP09")
> +            Notify(\_SB.PCI0.RP09,0)
> +          }
> +          Case (10)
> +          {
> +            ADBG("Notify RP10")
> +            Notify(\_SB.PCI0.RP10,0)
> +          }
> +          Case (11)
> +          {
> +            ADBG("Notify RP11")
> +            Notify(\_SB.PCI0.RP11,0)
> +          }
> +          Case (12)
> +          {
> +            ADBG("Notify RP12")
> +            Notify(\_SB.PCI0.RP12,0)
> +          }
> +          Case (13)
> +          {
> +            ADBG("Notify RP13")
> +            Notify(\_SB.PCI0.RP13,0)
> +          }
> +          Case (14)
> +          {
> +            ADBG("Notify RP14")
> +            Notify(\_SB.PCI0.RP14,0)
> +          }
> +          Case (15)
> +          {
> +            ADBG("Notify RP15")
> +            Notify(\_SB.PCI0.RP15,0)
> +          }
> +          Case (16)
> +          {
> +            ADBG("Notify RP16")
> +            Notify(\_SB.PCI0.RP16,0)
> +          }
> +          Case (17)
> +          {
> +            ADBG("Notify RP17")
> +            Notify(\_SB.PCI0.RP17,0)
> +          }
> +          Case (18)
> +          {
> +            ADBG("Notify RP18")
> +            Notify(\_SB.PCI0.RP18,0)
> +          }
> +          Case (19)
> +          {
> +            ADBG("Notify RP19")
> +            Notify(\_SB.PCI0.RP19,0)
> +          }
> +          Case (20)
> +          {
> +            ADBG("Notify RP20")
> +            Notify(\_SB.PCI0.RP20,0)
> +          }
> +          Case (21)
> +          {
> +            ADBG("Notify RP21")
> +            Notify(\_SB.PCI0.RP21,0)
> +          }
> +          Case (22)
> +          {
> +            ADBG("Notify RP22")
> +            Notify(\_SB.PCI0.RP22,0)
> +          }
> +          Case (23)
> +          {
> +            ADBG("Notify RP23")
> +            Notify(\_SB.PCI0.RP23,0)
> +          }
> +          Case (24)
> +          {
> +            ADBG("Notify RP24")
> +            Notify(\_SB.PCI0.RP24,0)
> +          }
> +        }//Switch(ToInteger(TBSS)) // TBT Selector
> +      } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) {
> +        Switch(ToInteger(Arg0))
> +        {
> +          Case (1)
> +          {
> +            ADBG("Notify PEG0")
> +            Notify(\_SB.PCI0.PEG0,0)
> +          }
> +          Case (2)
> +          {
> +            ADBG("Notify PEG1")
> +            Notify(\_SB.PCI0.PEG1,0)
> +          }
> +          Case (3)
> +          {
> +            ADBG("Notify PEG2")
> +            Notify(\_SB.PCI0.PEG2,0)
> +          }
> +        }
> +      }//Switch(ToInteger(TBSS)) // TBT Selector
> +    }//If(NOHP())
> +    P8XH(0,0xC2)
> +    P8XH(1,0xC2)
> +  }// End of Method(NTFY)
> +
> +//
> +//  TBT BIOS, GPIO 5 filtering,
> +//  Hot plug of 12V USB devices, into TBT host router, cause electrical noise on
> PCH GPIOs,
> +//  This noise cause false hot-plug events, and negatively influence BIOS
> assisted hot-plug.
> +//  WHL-PCH GPIO does not implement Glitch Filter logic (refer to GPIO HAS)
> on any GPIO pad. Native functions have to implement their own digital
> glitch-filter logic
> +//  if needed. As HW filter was not implemented on WHL PCH, because of that
> SW workaround should be implemented in BIOS.
> +//  Register 0x544(Bios mailbox) bit 0 definition:
> +//  if BIOS reads bit as 1, BIOS will clear the bit and continue normal flow, if bit
> is 0 BIOS will exit from method
> +//
> +
> +  Method(GNIS,2, Serialized)
> +  {
> +
> +    ADBG("GNIS")
> +    If(LEqual(GP5F, 0))
> +    {
> +      ADBG("GNIS_Dis=0")
> +      Return(0)
> +    }
> +    //
> +    // BIOS mailbox command for GPIO filter
> +    //
> +    Add(MMTB(Arg0, Arg1), 0x544, Local0)
> +    OperationRegion(PXVD,SystemMemory,Local0,0x08)
> +
> +    Field(PXVD,DWordAcc, NoLock, Preserve)
> +    {
> +      HPFI, 1,
> +      Offset(0x4),
> +      TB2P, 32
> +    }
> +    Store(TB2P, Local1)
> +    ADBG(Concatenate("TB2P=", ToHexString(Local1)))
> +    If(LEqual(Local1, 0xFFFFFFFF)) // Disconnect?
> +    {
> +      ADBG("GNIS=0")
> +      Return(0)
> +    }
> +    Store(HPFI, Local2)
> +    ADBG(Concatenate("HPFI=", ToHexString(Local2)))
> +    If(LEqual(Local2, 0x01))
> +    {
> +      Store(0x00, HPFI)
> +      ADBG("GNIS=0")
> +      Return(0)
> +    }
> +    // Any other values treated as a GPIO noise
> +    ADBG("GNIS=1")
> +    Return(1)
> +  }
> +
> +  Method(CHKP,2, Serialized)
> +  {
> +    Add(MMTB(Arg0, Arg1), 0x544, Local0)
> +    OperationRegion(PXVE,SystemMemory,Local0,0x08)
> +
> +    Field(PXVE,DWordAcc, NoLock, Preserve)
> +    {
> +      HPFI, 1,
> +      Offset(0x4),
> +      TB2P, 32
> +    }
> +    Store(TB2P, Local1)
> +    And(Local1,BIT29,Local1)
> +    ADBG(Concatenate("Local1=", ToHexString(Local1)))
> +    //ADBG(Concatenate("BIT29=", ToHexString(LAnd(Local1,BIT29))))
> +    If(LEqual(Local1, BIT29))
> +    {
> +      Return(1)
> +    }
> +    Else
> +    {
> +      Return(0)
> +    }
> +  }
> +
> +  //
> +  // Method to Handle enumerate PCIe structure through
> +  // SMI for Thunderbolt(TM) devices
> +  //
> +  Method(XTBT,2, Serialized)
> +  {
> +    ADBG("XTBT")
> +    ADBG("RP :")
> +    ADBG(Arg0)
> +    Store(Arg0, DTCP) // Root port to enumerate
> +    Store(Arg1, DTPT)   // Root port Type
> +    If(LEqual(Arg0, RPS0)) {
> +      Store (1, Local0)
> +    } ElseIf (LEqual(Arg0, RPS1)) {
> +      Store (2, Local0)
> +    } Else {
> +      Store (0, Local0)
> +      Return ()
> +    }
> +
> +    If (TRDO) {
> +      ADBG("Durng TBT_ON")
> +      Return ()
> +    }
> +
> +    If (TRD3) {
> +      ADBG("During TBT_OFF")
> +      Return ()
> +    }
> +    WWAK()
> +    WSUB(Arg0, Arg1)
> +    If(GNIS(Arg0, Arg1))
> +    {
> +      Return()
> +    }
> +
> +    OperationRegion(SPRT,SystemIO, 0xB2,2)
> +    Field (SPRT, ByteAcc, Lock, Preserve)
> +    {
> +      SSMP, 8
> +    }
> +
> +    ADBG("TBT-HP-Handler")
> +
> +    Acquire(OSUM, 0xFFFF)
> +    Store(TBFF(Arg0, Arg1), Local1)
> +    If(LEqual(Local1, 1))// Only HR
> +    {
> +      Sleep(16)
> +      Release(OSUM)
> +      ADBG("OS_Up_Received")
> +      Return ()
> +    }
> +    If(LEqual(Local1, 2)) // Disconnect
> +    {
> +      NTFY(Arg0, Arg1)
> +      Sleep(16)
> +      Release(OSUM)
> +      ADBG("Disconnect")
> +      Return ()
> +    }
> +
> +    // HR and EP
> +    If(LEqual(SOHP, 1))
> +    {
> +      // Trigger SMI to enumerate PCIe Structure
> +      ADBG("TBT SW SMI")
> +      Store(21, TBSF)
> +      Store(0xF7, SSMP)
> +    }
> +    NTFY(Arg0, Arg1)
> +    Sleep(16)
> +    Release(OSUM)
> +
> +    ADBG("End-of-XTBT")
> +  } // End of Method(XTBT)
> +
> +  //
> +  // Calling Method to Handle enumerate PCIe structure through
> +  // SMI for Thunderbolt(TM) devices for Tier 1 GPIOs
> +  // Used in Two ways ,
> +  // If CIO GPIO(1 Tier) is Different for the Controllers, this will be used as 1 Tier
> GPIO Handler for 1st controller
> +  // If CIO GPIO(1 Tier) is Same for all the controllers, this will be used as 1 Tier
> GPIO Handler for All the controllers
> +  //
> +  Method(ATBT)
> +  {
> +    ADBG("ATBT")
> +    //
> +    // Calling Method to Handle enumerate PCIe structure through
> +    //
> +    If(LEqual(CGST,0)) { // If GPIO is Different for each controller
> +      If(LEqual(RPN0,1))
> +      {
> +        XTBT(RPS0, RPT0)
> +      }
> +    } Else {
> +      If(LEqual(RPN0,1))
> +      {
> +        XTBT(RPS0, RPT0)
> +      }
> +      ElseIf(LEqual(RPN1,1))
> +      {
> +        XTBT(RPS1, RPT1)
> +      }
> +    }
> +    ADBG("End-of-ATBT")
> +  } // End of Method(ATBT)
> +
> +  Method(BTBT)
> +  {
> +    ADBG("BTBT")
> +    //
> +    // Calling Method to Handle enumerate PCIe structure through
> +    //
> +    If(LEqual(CGST,0)) { // If GPIO is Different for each controller
> +      If(LEqual(RPN1,1))
> +      {
> +        XTBT(RPS1, RPT1)
> +      }
> +    }
> +    ADBG("End-of-BTBT")
> +  } // End of Method(BTBT)
> +  //
> +  // Method to call OSPU Mail box command
> +  // Arg0 : Controller type 0x00 : Discrete 0x80 : Integrated TBT
> +  // Arg1 : TBT RP Selector / DMA
> +  // Arg2 : TBT Type (PCH or PEG)
> +  //
> +  Method(TINI, 3, Serialized)
> +  {
> +    ADBG("TINI")
> +    If(Lequal (Arg0, DTBT_CONTROLLER))
> +    {
> +      //ADBG("DTBT")
> +    Store(MMRP(Arg1, Arg2), Local0)
> +      OperationRegion(RP_X,SystemMemory,Local0,0x20)
> +      Field(RP_X,DWordAcc, NoLock, Preserve)
> +      {
> +        REG0, 32,
> +        REG1, 32,
> +        REG2, 32,
> +        REG3, 32,
> +        REG4, 32,
> +        REG5, 32,
> +        REG6, 32,
> +        REG7, 32
> +      }
> +      Store(REG6, Local1)
> +      Store(0x00F0F000, REG6)
> +      Store(MMTB(Arg1, Arg2), Local2)
> +      OSUP(Local2, DTBT_CONTROLLER)
> +      Store(Local1, REG6)
> +    }
> +    ADBG("End-of-TINI")
> +  }
> +
> +} // End of Scope (\_GPE)
> +
> +Scope (\_SB)
> +{
> +  //
> +  // The code needs to be executed for TBT Hotplug Handler event (2-tier GPI
> GPE event architecture) is presented here
> +  //
> +  Method(THDR, 3, Serialized)
> +  {
> +    ADBG("THDR")
> +    \_SB.CAGS(Arg0)
> +    \_GPE.XTBT(Arg1, Arg2)
> +  } // End of Method(THDR, 3, Serialized)
> +} // End of Scope(\_SB)
> +
> +Scope (\_SB)
> +{
> +  //
> +  // Name: CGWR [Combined GPIO Write]
> +  // Description: Function to write into GPIO
> +  // Input: Arg0 -> GpioPad / Expander pin
> +  //        Arg1 -> Value
> +  // Return: Nothing
> +  //
> +  Method(CGWR, 2, Serialized)
> +  {
> +    // PCH
> +    If (CondRefOf(\_SB.SGOV))
> +    {
> +      \_SB.SGOV(Arg0, Arg1)
> +    }
> +  } // End of Method(CGWR, 4, Serialized)
> +
> +  //
> +  // Name: CGRD [Combined GPIO Read]
> +  // Description: Function to read from GPIO
> +  // Input: Arg0 -> GpioPad / Expander pin
> +  //        Arg1 -> 0: GPO [GPIO TX State]
> +  //                1: GPI [GPIO RX State]
> +  // Return: Value
> +  //
> +  Method(CGRD, 2, Serialized)
> +  {
> +    Store(1, Local0)
> +    // PCH
> +    If (LEqual(Arg1, 0))
> +    {
> +      // GPIO TX State
> +      If (CondRefOf(\_SB.GGOV))
> +      {
> +        Store(\_SB.GGOV(Arg0), Local0)
> +      }
> +    }
> +    ElseIf (LEqual(Arg1, 1))
> +    {
> +      // GPIO RX State
> +      If (CondRefOf(\_SB.GGIV))
> +      {
> +        Store(\_SB.GGIV(Arg0), Local0)
> +      }
> +    }
> +    Return(Local0)
> +  } // End of Method(CGRD, 4, Serialized)
> +  //
> +  // Name: WRGP [GPIO Write]
> +  // Description: Function to write into GPIO
> +  // Input: Arg0 -> COMMON_GPIO_CONFIG GpioInfo
> +  //        Arg1 -> Value
> +  // Return: Nothing
> +  //
> +  Method(WRGP, 2, Serialized)
> +  {
> +    Store(Arg0, Local0)
> +    Store(Arg0, Local1)
> +    And(Local0, 0xFFFFFFFF, Local0) // Low  32 bits (31:00)
> +    ShiftRight(Local1, 32, Local1)  // High 32 bits (63:32)
> +    If (LEqual(And(Local0, 0xFF), 1))
> +    {
> +      // PCH
> +      \_SB.CGWR(Local1, Arg1)
> +    }
> +  } // End of Method(WRGP, 2, Serialized)
> +
> +  //
> +  // Name: RDGP [GPIO Read]
> +  // Description: Function to write into GPIO
> +  // Input: Arg0 -> COMMON_GPIO_CONFIG GpioInfo
> +  //        Arg1 -> In case of PCH Gpio Read {GPIO TX(0)/RX(1) State indicator}
> +  // Return: Value
> +  //
> +  Method(RDGP, 2, Serialized)
> +  {
> +    Store(1, Local7)
> +    Store(Arg0, Local0)
> +    Store(Arg0, Local1)
> +    And(Local0, 0xFFFFFFFF, Local0) // Low  32 bits (31:00)
> +    ShiftRight(Local1, 32, Local1)  // High 32 bits (63:32)
> +    If (LEqual(And(Local0, 0xFF), 1))
> +    {
> +      // PCH
> +      Store(\_SB.CGRD(Local1, Arg1), Local7)
> +    }
> +    Return(Local7)
> +  } // End of Method(RDGP, 2, Serialized)
> +
> +} // End of Scope(\_SB)
> +
> +Scope(\_SB)
> +{
> +  // Asserts/De-asserts TBT force power
> +  Method(TBFP, 2)
> +  {
> +    If(Arg0)
> +    {
> +      // Implementation dependent way to assert TBT force power
> +      If(LEqual(Arg1, 1)) {
> +        CGWR(FPG0, FP0L)
> +      }
> +      Else {
> +        CGWR(FPG1, FP1L)
> +      }
> +    }
> +    Else
> +    {
> +      // Implementation dependent way to de-assert TBT force power
> +      If(LEqual(Arg1, 1)) {
> +        CGWR(FPG0, LNot(FP0L))
> +      }
> +      Else {
> +        CGWR(FPG1, LNot(FP1L))
> +      }
> +    }
> +  }
> +
> +  // WMI ACPI device to control TBT force power
> +  Device(WMTF)
> +  {
> +    // pnp0c14 is pnp id assigned to WMI mapper
> +    Name(_HID, "PNP0C14")
> +    Name(_UID, "TBFP")
> +
> +    Name(_WDG, Buffer() {
> +      // {86CCFD48-205E-4A77-9C48-2021CBEDE341}
> +      0x48, 0xFD, 0xCC, 0x86,
> +      0x5E, 0x20,
> +      0x77, 0x4A,
> +      0x9C, 0x48,
> +      0x20, 0x21, 0xCB, 0xED, 0xE3, 0x41,
> +      84, 70,    // Object Id (TF)
> +      1,         // Instance Count
> +      0x02       // Flags (WMIACPI_REGFLAG_METHOD)
> +    })
> +
> +    // Set TBT force power
> +    // Arg2 is force power value
> +    Method(WMTF, 3)
> +    {
> +      CreateByteField(Arg2,0,FP)
> +
> +      If(FP)
> +      {
> +        TBFP(1, 1)
> +      }
> +      Else
> +      {
> +        TBFP(0, 1)
> +      }
> +    }
> +  }
> +} // End of Scope(\_SB)
> +
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 1),LEqual(RPS1, 1))))
> +{
> +  Scope(\_SB.PCI0.RP01)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP01)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 2),LEqual(RPS1, 2))))
> +{
> +  Scope(\_SB.PCI0.RP02)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP02)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 3),LEqual(RPS1, 3))))
> +{
> +  Scope(\_SB.PCI0.RP03)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP03)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 4),LEqual(RPS1, 4))))
> +{
> +  Scope(\_SB.PCI0.RP04)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP04)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 5),LEqual(RPS1, 5))))
> +{
> +  Scope(\_SB.PCI0.RP05)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP05)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 6),LEqual(RPS1, 6))))
> +{
> +  Scope(\_SB.PCI0.RP06)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP06)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 7),LEqual(RPS1, 7))))
> +{
> +  Scope(\_SB.PCI0.RP07)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP07)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 8),LEqual(RPS1, 8))))
> +{
> +  Scope(\_SB.PCI0.RP08)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP08)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 9),LEqual(RPS1, 9))))
> +{
> +  Scope(\_SB.PCI0.RP09)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP09)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 10),LEqual(RPS1, 10))))
> +{
> +  Scope(\_SB.PCI0.RP10)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP10)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 11),LEqual(RPS1, 11))))
> +{
> +  Scope(\_SB.PCI0.RP11)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP11)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 12),LEqual(RPS1, 12))))
> +{
> +  Scope(\_SB.PCI0.RP12)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP12)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 13),LEqual(RPS1, 13))))
> +{
> +  Scope(\_SB.PCI0.RP13)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP13)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 14),LEqual(RPS1, 14))))
> +{
> +  Scope(\_SB.PCI0.RP14)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP14)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 15),LEqual(RPS1, 15))))
> +{
> +  Scope(\_SB.PCI0.RP15)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP15)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 16),LEqual(RPS1, 16))))
> +{
> +  Scope(\_SB.PCI0.RP16)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP16)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 17),LEqual(RPS1, 17))))
> +{
> +  Scope(\_SB.PCI0.RP17)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP17)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 18),LEqual(RPS1, 18))))
> +{
> +  Scope(\_SB.PCI0.RP18)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP18)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 19),LEqual(RPS1, 19))))
> +{
> +  Scope(\_SB.PCI0.RP19)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP19)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 20),LEqual(RPS1, 20))))
> +{
> +  Scope(\_SB.PCI0.RP20)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.RP20)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 21),LEqual(RPS1, 21))))
> +{
> +  Scope(\_SB.PCI0.PEG0)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.PEG0)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 22),LEqual(RPS1, 22))))
> +{
> +  Scope(\_SB.PCI0.PEG1)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.PEG1)
> +}
> +
> +If(LAnd(LEqual(TBTS, 1),LOr(LEqual(RPS0, 23),LEqual(RPS1, 23))))
> +{
> +  Scope(\_SB.PCI0.PEG2)
> +  {
> +    Device(HRUS)// Host router Upstream port
> +    {
> +      Name(_ADR, 0x00000000)
> +
> +      Method(_RMV)
> +      {
> +        Return(TARS)
> +      } // end _RMV
> +    }
> +  }//End of Scope(\_SB.PCI0.PEG2)
> +}
> +
> +Scope(\_SB)
> +{
> +    //
> +    // Name: PERB
> +    // Description: Function to read a Byte from PCIE-MMIO
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Register offset
> +    // Return: Byte data read from PCIE-MMIO
> +    //
> +    Method(PERB,5,Serialized)
> +    {
> +      ADBG("PERB")
> +
> +      Store(Arg0, Local7)
> +      Or(Local7, ShiftLeft(Arg1, 20), Local7)
> +      Or(Local7, ShiftLeft(Arg2, 15), Local7)
> +      Or(Local7, ShiftLeft(Arg3, 12), Local7)
> +      Or(Local7, Arg4, Local7)
> +
> +      OperationRegion(PCI0, SystemMemory, Local7, 1)
> +      Field(PCI0, ByteAcc,NoLock,Preserve)
> +      {
> +        TEMP, 8
> +      }
> +
> +      Return(TEMP)
> +    } // End of Method(PERB,5,Serialized)
> +
> +    //
> +    // Name: PEWB
> +    // Description: Function to write a Byte into PCIE-MMIO
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Register offset
> +    //        Arg5 -> Data
> +    // Return: Nothing
> +    //
> +    Method(PEWB,6,Serialized)
> +    {
> +      ADBG("PEWB")
> +
> +      Store(Arg0, Local7)
> +      Or(Local7, ShiftLeft(Arg1, 20), Local7)
> +      Or(Local7, ShiftLeft(Arg2, 15), Local7)
> +      Or(Local7, ShiftLeft(Arg3, 12), Local7)
> +      Or(Local7, Arg4, Local7)
> +
> +      OperationRegion(PCI0, SystemMemory, Local7, 1)
> +      Field(PCI0, ByteAcc,NoLock,Preserve)
> +      {
> +        TEMP, 8
> +      }
> +
> +      Store(Arg5,TEMP)
> +    } // End of Method(PEWB,6,Serialized)
> +
> +    //
> +    // Name: PERW
> +    // Description: Function to read a Word from PCIE-MMIO
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Register offset
> +    // Return: Word data read from PCIE-MMIO
> +    //
> +    Method(PERW,5,Serialized)
> +    {
> +      ADBG("PERW")
> +
> +      Store(Arg0, Local7)
> +      Or(Local7, ShiftLeft(Arg1, 20), Local7)
> +      Or(Local7, ShiftLeft(Arg2, 15), Local7)
> +      Or(Local7, ShiftLeft(Arg3, 12), Local7)
> +      Or(Local7, Arg4, Local7)
> +
> +      OperationRegion(PCI0, SystemMemory, Local7, 2)
> +      Field(PCI0, ByteAcc,NoLock,Preserve)
> +      {
> +        TEMP, 16
> +      }
> +
> +      Return(TEMP)
> +    } // End of Method(PERW,5,Serialized)
> +
> +    //
> +    // Name: PEWW
> +    // Description: Function to write a Word into PCIE-MMIO
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Register offset
> +    //        Arg5 -> Data
> +    // Return: Nothing
> +    //
> +    Method(PEWW,6,Serialized)
> +    {
> +      ADBG("PEWW")
> +
> +      Store(Arg0, Local7)
> +      Or(Local7, ShiftLeft(Arg1, 20), Local7)
> +      Or(Local7, ShiftLeft(Arg2, 15), Local7)
> +      Or(Local7, ShiftLeft(Arg3, 12), Local7)
> +      Or(Local7, Arg4, Local7)
> +
> +      OperationRegion(PCI0, SystemMemory, Local7, 2)
> +      Field(PCI0, ByteAcc,NoLock,Preserve)
> +      {
> +        TEMP, 16
> +      }
> +
> +      Store(Arg5,TEMP)
> +    } // End of Method(PEWW,6,Serialized)
> +
> +    //
> +    // Name: PERD
> +    // Description: Function to read a Dword from PCIE-MMIO
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Register offset
> +    // Return: Dword data read from PCIE-MMIO
> +    //
> +    Method(PERD,5,Serialized)
> +    {
> +      ADBG("PERD")
> +
> +      Store(Arg0, Local7)
> +      Or(Local7, ShiftLeft(Arg1, 20), Local7)
> +      Or(Local7, ShiftLeft(Arg2, 15), Local7)
> +      Or(Local7, ShiftLeft(Arg3, 12), Local7)
> +      Or(Local7, Arg4, Local7)
> +
> +      OperationRegion(PCI0, SystemMemory, Local7, 4)
> +      Field(PCI0, ByteAcc,NoLock,Preserve)
> +      {
> +        TEMP, 32
> +      }
> +
> +      Return(TEMP)
> +    } // End of Method(PERD,5,Serialized)
> +
> +    //
> +    // Name: PEWD
> +    // Description: Function to write a Dword into PCIE-MMIO
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Register offset
> +    //        Arg5 -> Data
> +    // Return: Nothing
> +    //
> +    Method(PEWD,6,Serialized)
> +    {
> +      ADBG("PEWD")
> +
> +      Store(Arg0, Local7)
> +      Or(Local7, ShiftLeft(Arg1, 20), Local7)
> +      Or(Local7, ShiftLeft(Arg2, 15), Local7)
> +      Or(Local7, ShiftLeft(Arg3, 12), Local7)
> +      Or(Local7, Arg4, Local7)
> +
> +      OperationRegion(PCI0, SystemMemory, Local7, 4)
> +      Field(PCI0, ByteAcc,NoLock,Preserve)
> +      {
> +        TEMP, 32
> +      }
> +
> +      Store(Arg5,TEMP)
> +    } // End of Method(PEWD,6,Serialized)
> +
> +    //
> +    // Name: STDC
> +    // Description: Function to get Standard Capability Register Offset
> +    // Input: Arg0 -> PCIE base address
> +    //        Arg1 -> Bus
> +    //        Arg2 -> Device
> +    //        Arg3 -> Function
> +    //        Arg4 -> Capability ID
> +    // Return: Capability Register Offset data
> +    //
> +    Method(STDC,5,Serialized)
> +    {
> +      ADBG("STDC")
> +
> +      //Check for Referenced device is present or not
> +      Store(PERW(Arg0, Arg1, Arg2, Arg3, 0x00), Local7) //Vendor ID register
> +      If(LEqual(Local7, 0xFFFF))
> +      {
> +        ADBG("Referenced device is not present")
> +        Return(0)
> +      }
> +
> +      Store(PERW(Arg0, Arg1, Arg2, Arg3, 0x06), Local0) //Device Status register
> +      If (LEqual(And(Local0, 16), 0)) //Bit4 - Capabilities List
> +      {
> +        //No Capabilities linked list is available
> +        ADBG("No Capabilities linked list is available")
> +        Return(0)
> +      }
> +
> +      //Local1 is for storing CapabilityID
> +      //Local2 is for storing CapabilityPtr
> +      Store(PERB(Arg0, Arg1, Arg2, Arg3, 0x34), Local2) //CapabilityPtr
> +
> +      While(1)
> +      {
> +        And(Local2, 0xFC, Local2) //Each capability must be DWORD aligned
> +
> +        If(LEqual(Local2, 0)) //A pointer value of 00h is used to indicate the last
> capability in the list
> +        {
> +          ADBG("Capability ID is not found")
> +          Return(0)
> +        }
> +
> +        Store(PERB(Arg0, Arg1, Arg2, Arg3, Local2), Local1) //CapabilityID
> +
> +        If(LEqual(Arg4, Local1)) //CapabilityID match
> +        {
> +          ADBG("Capability ID is found")
> +          ADBG("Capability Offset : ")
> +          ADBG(Local2)
> +          Return(Local2)
> +        }
> +        Store(PERB(Arg0, Arg1, Arg2, Arg3, Add(Local2, 1)), Local2)
> //CapabilityPtr
> +        Return(0)
> +      }
> +    } // End of Method(STDC,5,Serialized)
> +
> +} // End Scope(\_SB)
> +
> --
> 2.16.2.windows.1


  parent reply	other threads:[~2019-08-17  1:17 UTC|newest]

Thread overview: 121+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  1:18   ` Chaganty, Rangasai V
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  6:58   ` Chaganty, Rangasai V
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  7:04   ` Chaganty, Rangasai V
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:10   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-19 18:09   ` Sinha, Ankit
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: " Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:17   ` Chiu, Chasel
2019-08-17 20:08   ` Chaganty, Rangasai V
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:17   ` Chiu, Chasel [this message]
2019-08-17  7:50   ` Chaganty, Rangasai V
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17 20:11   ` Chaganty, Rangasai V
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:17   ` Chiu, Chasel
2019-08-17 20:00   ` Chaganty, Rangasai V
2019-08-19 18:14 ` [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Sinha, Ankit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3C3EFB470A303B4AB093197B6777CCEC50462481@PGSMSX111.gar.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox