Browse Source

CometlakeOpenBoardPkg: Add modules

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2280

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.
* BiosInfo - Provides the BIOS informations in PEI.

Signed-off-by: Kathappan Esakkithevar <kathappan.esakkithevar@intel.com>
Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Deepika Kethi Reddy <deepika.kethi.reddy@intel.com>
Cc: Prince Agyeman <prince.agyeman@intel.com>
Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>
Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
Reviewed-by: Sai Chaganty <rangasai.v.chaganty@intel.com>
Kathappan Esakkithevar 4 years ago
parent
commit
65ca075e9d
38 changed files with 10112 additions and 0 deletions
  1. 96 0
      Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c
  2. 290 0
      Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c
  3. 73 0
      Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf
  4. 20 0
      Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl
  5. 37 0
      Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL
  6. 516 0
      Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl
  7. 309 0
      Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl
  8. 76 0
      Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl
  9. 93 0
      Platform/Intel/CometlakeOpenBoardPkg/BiosInfo/BiosInfo.c
  10. 49 0
      Platform/Intel/CometlakeOpenBoardPkg/BiosInfo/BiosInfo.inf
  11. 353 0
      Platform/Intel/CometlakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c
  12. 130 0
      Platform/Intel/CometlakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h
  13. 63 0
      Platform/Intel/CometlakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf
  14. 405 0
      Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl
  15. 1877 0
      Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl
  16. 228 0
      Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c
  17. 51 0
      Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
  18. 211 0
      Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c
  19. 47 0
      Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
  20. 1609 0
      Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c
  21. 180 0
      Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h
  22. 1765 0
      Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c
  23. 80 0
      Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf
  24. 608 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c
  25. 32 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h
  26. 46 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c
  27. 38 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h
  28. 174 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c
  29. 41 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h
  30. 55 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c
  31. 52 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h
  32. 88 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.c
  33. 45 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h
  34. 176 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf
  35. 60 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c
  36. 56 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h
  37. 46 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c
  38. 37 0
      Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h

+ 96 - 0
Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c

@@ -0,0 +1,96 @@
+/** @file
+  Acpi Gnvs Init Library.
+
+
+  Copyright (c) 2020, 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;
+}
+
+

+ 290 - 0
Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c

@@ -0,0 +1,290 @@
+/** @file
+  ACPI Platform Driver
+
+
+  Copyright (c) 2020, 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;
+}
+

+ 73 - 0
Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf

@@ -0,0 +1,73 @@
+## @file
+#  Component information file for AcpiPlatform module
+#
+#
+#  Copyright (c) 2020, 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
+  CometlakeOpenBoardPkg/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]
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdAcpiGnvsAddress
+
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdAcpiSleepState
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdAcpiHibernate
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdLowPowerS0Idle
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdDisableActiveTripPoints
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdDisablePassiveTripPoints
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdDisableCriticalTripPoints
+  gMinPlatformPkgTokenSpaceGuid.PcdPciReservedMemBase
+  gMinPlatformPkgTokenSpaceGuid.PcdPciReservedMemLimit
+
+[Depex]
+  gEfiAcpiTableProtocolGuid           AND
+  gEfiFirmwareVolume2ProtocolGuid     AND
+  gEfiPciRootBridgeIoProtocolGuid     AND
+  gEfiVariableArchProtocolGuid        AND
+  gEfiVariableWriteArchProtocolGuid
+
+
+

+ 20 - 0
Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl

@@ -0,0 +1,20 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2020, 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)
+
+

+ 37 - 0
Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL

@@ -0,0 +1,37 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2020, 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)
+  "CML     ",// 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
+
+

+ 516 - 0
Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.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) 2020, 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,NonCacheable,
+    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,NonCacheable,
+    ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02)
+
+  //
+  // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF )
+  //
+  DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable,
+    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.
+  //
+  Add (Subtract (FixedPcdGet32(PcdPciReservedMemLimit),FixedPcdGet32(PcdPciReservedMemBase)), 1, M1LN)
+  Store (FixedPcdGet32(PcdPciReservedMemBase), M1MN)
+  Store (FixedPcdGet32(PcdPciReservedMemLimit), 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)
+}
+

+ 309 - 0
Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl

@@ -0,0 +1,309 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2020, 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
+

+ 76 - 0
Platform/Intel/CometlakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl

@@ -0,0 +1,76 @@
+/** @file
+  ACPI DSDT table
+
+
+  Copyright (c) 2020, 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)
+}
+

+ 93 - 0
Platform/Intel/CometlakeOpenBoardPkg/BiosInfo/BiosInfo.c

@@ -0,0 +1,93 @@
+/** @file
+  Driver for BIOS Info support.
+
+  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+#include <Guid/BiosInfo.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <IndustryStandard/FirmwareInterfaceTable.h>
+
+#define INDEXPORT_TO_ADDRESS(x)             (x)
+#define DATAPORT_TO_ADDRESS(x)              ((x) << 16)
+#define PORTWIDTH_TO_ADDRESS(x)             ((x) << 32)
+#define PORTBITNUMBER_TO_ADDRESS(x)         ((x) << 40)
+#define PORTINDEXNUMBER_TO_ADDRESS(x)       ((x) << 48)
+
+//
+// Internal
+//
+#pragma pack (1)
+
+typedef struct {
+  BIOS_INFO_HEADER  Header;
+  BIOS_INFO_STRUCT  Entry[1];
+} BIOS_INFO;
+#pragma pack ()
+
+GLOBAL_REMOVE_IF_UNREFERENCED BIOS_INFO  mBiosInfo = {
+  {
+    BIOS_INFO_SIGNATURE,
+    1,
+    0,
+  },
+  {
+    {
+      FIT_TYPE_01_MICROCODE,
+      BIOS_INFO_STRUCT_ATTRIBUTE_MICROCODE_WHOLE_REGION,
+      0x0100,
+      FixedPcdGet32 (PcdFlashMicrocodeFvSize),
+      FixedPcdGet32 (PcdFlashMicrocodeFvBase)
+    }
+  }
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR  mBiosInfoPpiList = {
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+  &gBiosInfoGuid,
+  &mBiosInfo
+};
+
+/**
+  Installs BiosInfo Ppi and builds BiosInfo HOB .
+
+  @param  FileHandle  Handle of the file being invoked.
+  @param  PeiServices Describes the list of possible PEI Services.
+
+  @retval EFI_SUCCESS   Install the BiosInfo Ppi and HOB successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosInfoEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS  Status;
+  VOID        *HobData;
+
+  //
+  // Install PPI, so that other PEI module can add dependency.
+  //
+  Status = PeiServicesInstallPpi (&mBiosInfoPpiList);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Build hob, so that DXE module can also get the data.
+  //
+  HobData = BuildGuidHob (&gBiosInfoGuid, sizeof (mBiosInfo));
+  ASSERT (HobData != NULL);
+  if (HobData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  CopyMem (HobData, &mBiosInfo, sizeof (mBiosInfo));
+
+  return EFI_SUCCESS;
+}

+ 49 - 0
Platform/Intel/CometlakeOpenBoardPkg/BiosInfo/BiosInfo.inf

@@ -0,0 +1,49 @@
+### @file
+#  Module Information description file for BIOS Info Driver
+#
+#  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+###
+
+[Defines]
+  INF_VERSION                    = 0x00010017
+  BASE_NAME                      = BiosInfo
+  FILE_GUID                      = A842B2D2-5C88-44E9-A9E2-4830F26662B7
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  ENTRY_POINT                    = BiosInfoEntryPoint
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES IA32 X64
+#
+
+[LibraryClasses]
+  PeimEntryPoint
+  PeiServicesLib
+  HobLib
+  BaseMemoryLib
+  DebugLib
+  PcdLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  CometLakeFspBinPkg/CometLake1/CometLakeFspBinPkg.dec
+  BoardModulePkg/BoardModulePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+
+[Pcd]
+  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase                    ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize                    ## CONSUMES
+
+[Sources]
+  BiosInfo.c
+
+[Guids]
+  gBiosInfoGuid                                 ## PRODUCES
+
+[Depex]
+  TRUE

+ 353 - 0
Platform/Intel/CometlakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c

@@ -0,0 +1,353 @@
+/** @file
+  Pci Hotplug Driver : This file will perform specific PCI-EXPRESS
+  Devics resource configuration.
+
+
+  Copyright (c) 2020, 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 ,&RsvdTbtPciePMegaMem ,&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;
+}
+

+ 130 - 0
Platform/Intel/CometlakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h

@@ -0,0 +1,130 @@
+/** @file
+
+  Copyright (c) 2020, 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
+

+ 63 - 0
Platform/Intel/CometlakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf

@@ -0,0 +1,63 @@
+## @file
+# This module will perform specific PCI-Express devices
+# resource configuration.
+#
+#
+#  Copyright (c) 2020, 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
+  CometlakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Sources]
+  PciHotPlug.c
+  PciHotPlug.h
+
+[Protocols]
+  gEfiPciHotPlugInitProtocolGuid                ## PRODUCES
+  gSaPolicyProtocolGuid                         ## CONSUMES
+
+[Guids]
+  gEfiHobListGuid                               ## CONSUMES
+  gPcieRpConfigGuid                  ## CONSUMES
+
+[Pcd]
+
+[Depex]
+  gDxeTbtPolicyProtocolGuid
+

+ 405 - 0
Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt.asl

@@ -0,0 +1,405 @@
+/** @file
+  ACPI RTD3 SSDT table for SPT PCIe
+
+
+  Copyright (c) 2020, 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})
+
+

+ 1877 - 0
Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl

@@ -0,0 +1,1877 @@
+/** @file
+ Thunderbolt ACPI methods
+
+
+  Copyright (c) 2020, 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)
+

+ 228 - 0
Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c

@@ -0,0 +1,228 @@
+/** @file
+
+  Copyright (c) 2020, 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;
+}
+

+ 51 - 0
Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf

@@ -0,0 +1,51 @@
+## @file
+#
+#
+#  Copyright (c) 2020, 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
+  CometlakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  TbtDxe.c
+
+[Protocols]
+  gTbtNvsAreaProtocolGuid                       ## CONSUMES
+  gDxeTbtPolicyProtocolGuid
+
+[Guids]
+  gTbtInfoHobGuid                               ## CONSUMES
+
+[Depex]
+  gEfiVariableWriteArchProtocolGuid   AND
+  gEfiVariableArchProtocolGuid
+

+ 211 - 0
Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c

@@ -0,0 +1,211 @@
+/** @file
+  Source code file for TBT Init PEI module
+
+
+  Copyright (c) 2020, 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;
+}
+

+ 47 - 0
Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf

@@ -0,0 +1,47 @@
+## @file
+# Component information file for the TBT Init PEI module.
+#
+#
+#  Copyright (c) 2020, 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
+  CometlakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+  PeiTbtInit.c
+
+[Guids]
+  gTbtInfoHobGuid                               ## CONSUMES
+
+[Ppis]
+  gEfiEndOfPeiSignalPpiGuid                     ## CONSUMES
+  gPeiTbtPolicyBoardInitDonePpiGuid             ## CONSUMES
+
+[Depex]
+  gEfiPeiMemoryDiscoveredPpiGuid
+

+ 1609 - 0
Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c

@@ -0,0 +1,1609 @@
+/** @file
+
+  Copyright (c) 2020, 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
+
+
+

+ 180 - 0
Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h

@@ -0,0 +1,180 @@
+/** @file
+
+  Copyright (c) 2020, 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
+

+ 1765 - 0
Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c

@@ -0,0 +1,1765 @@
+/** @file
+
+`  Copyright (c) 2020, 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
+}
+

+ 80 - 0
Platform/Intel/CometlakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf

@@ -0,0 +1,80 @@
+## @file
+# Component information file for the ThunderBolt Smm module.
+#
+#
+#  Copyright (c) 2020, 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
+  CometlakeOpenBoardPkg/OpenBoardPkg.dec
+  CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+  #gCometlakeOpenBoardPkgTokenSpaceGuid.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
+

+ 608 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c

@@ -0,0 +1,608 @@
+/** @file
+  Source code for the board configuration init function in DXE init phase.
+
+
+  Copyright (c) 2020, 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 BoardIdCometLakeULpddr3Rvp:
+      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 BoardIdCometLakeULpddr3Rvp:
+      if ((TbtInfoHob != NULL) && (TbtInfoHob->DTbtControllerConfig[0].DTbtControllerEn == 1)) {
+        PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_', 'c', 'm', 'u', 't', '3'));
+      } else {
+        PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_', 'c', 'm', 'u', 'l', '3'));
+      }
+      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 BoardIdCometLakeULpddr3Rvp:
+      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 BoardIdCometLakeULpddr3Rvp:
+      PcdSet32S (PcdBtIrqGpio,    GPIO_CNL_LP_GPP_C11);
+      PcdSet32S (PcdBtRfKillGpio, GPIO_CNL_LP_GPP_B4);
+      break;
+    default:
+      break;
+  }
+
+  //
+  // Board Specific Init
+  //
+  switch (BoardId) {
+    case BoardIdCometLakeULpddr3Rvp:
+      PcdSetBoolS(PcdCmlURtd3TableEnable, 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;
+
+  //
+  // Enable EC SMI# for SMI
+  //
+  switch (BoardId) {
+    case BoardIdCometLakeULpddr3Rvp:
+      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 == BoardIdCometLakeULpddr3Rvp) {
+    PcdSetBoolS (PcdDetectPs2KbOnCmdAck, TRUE);
+  } else {
+    PcdSetBoolS (PcdDetectPs2KbOnCmdAck,  FALSE);
+  }
+
+  switch (BoardId) {
+    default:
+      PcdSetBoolS (PcdSpdAddressOverride, FALSE);
+      break;
+  }
+
+  //
+  // DDISelection
+  //
+  switch (BoardId) {
+    case BoardIdCometLakeULpddr3Rvp:
+      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 BoardIdCometLakeULpddr3Rvp:
+      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 BoardIdCometLakeULpddr3Rvp:
+      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 BoardIdCometLakeULpddr3Rvp:
+      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 BoardIdCometLakeULpddr3Rvp:
+      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 BoardIdCometLakeULpddr3Rvp:
+      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 BoardIdCometLakeULpddr3Rvp:
+      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 BoardIdCometLakeULpddr3Rvp:
+      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 BoardIdCometLakeULpddr3Rvp:
+      PcdSet32S (PcdPmPowerButtonGpioPin, (UINT32) GPIO_CNL_LP_GPD3);
+      break;
+    default:
+      PcdSet32S (PcdPmPowerButtonGpioPin, 0x00);
+      break;
+  }
+
+  //
+  // Acpi Enable All Button Support
+  //
+  switch (BoardId) {
+    case BoardIdCometLakeULpddr3Rvp:
+      PcdSetBoolS (PcdAcpiEnableAllButtonSupport, TRUE);
+      break;
+    default:
+      PcdSetBoolS (PcdAcpiEnableAllButtonSupport, FALSE);
+      break;
+  }
+
+  //
+  // Acpi Hid Driver Button Support
+  //
+  switch (BoardId) {
+    case BoardIdCometLakeULpddr3Rvp:
+      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 BoardIdCometLakeULpddr3Rvp:
+      //
+      // 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 = BoardIdCometLakeULpddr3Rvp;
+
+  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;
+}
+

+ 32 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h

@@ -0,0 +1,32 @@
+/** @file
+ Header file for board Init function for DXE Init phase.
+
+
+  Copyright (c) 2020, 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_
+

+ 46 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.c

@@ -0,0 +1,46 @@
+/** @file
+  This file is SampleCode for Intel Silicon DXE Platform Policy initialzation.
+
+
+  Copyright (c) 2020, 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;
+}
+

+ 38 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitDxe.h

@@ -0,0 +1,38 @@
+/** @file
+  Header file for the SiliconPolicyInitDxe Driver.
+
+
+  Copyright (c) 2020, 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
+

+ 174 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.c

@@ -0,0 +1,174 @@
+/** @file
+  This file initialises and Installs GopPolicy Protocol.
+
+
+  Copyright (c) 2020, 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;
+}
+

+ 41 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitDxe.h

@@ -0,0 +1,41 @@
+/** @file
+Header file for the GopPolicyInitDxe Driver.
+
+
+  Copyright (c) 2020, 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
+

+ 55 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.c

@@ -0,0 +1,55 @@
+/** @file
+  This file is SampleCode for PCH DXE Policy initialization.
+
+
+  Copyright (c) 2020, 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;
+}
+

+ 52 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitDxe.h

@@ -0,0 +1,52 @@
+/** @file
+  Header file for the PchPolicyInitDxe Driver.
+
+
+  Copyright (c) 2020, 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
+

+ 88 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.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) 2020, 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;
+
+}
+

+ 45 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.h

@@ -0,0 +1,45 @@
+/** @file
+  Header file for the PolicyInitDxe Driver.
+
+
+  Copyright (c) 2020, 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
+

+ 176 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.inf

@@ -0,0 +1,176 @@
+## @file
+# Module Information file for the PolicyInit DXE driver.
+#
+#
+#  Copyright (c) 2020, 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
+  CometlakeOpenBoardPkg/OpenBoardPkg.dec
+  IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress                     ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase                          ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize                          ## CONSUMES
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdIntelGopEnable
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdPlatformFlavor
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdPlatformType
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdEcPresent
+  gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdTbtEnable
+  gSiPkgTokenSpaceGuid.PcdCpuSmmMsrSaveStateEnable                      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable                   ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmUseDelayIndication                      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmUseBlockIndication                      ## CONSUMES
+  gSiPkgTokenSpaceGuid.PcdCpuSmmUseSmmEnableIndication                  ## CONSUMES
+
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdVirtualButtonVolumeUpSupport
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdVirtualButtonVolumeDownSupport
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdVirtualButtonHomeButtonSupport
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdVirtualButtonRotationLockSupport
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdSlateModeSwitchSupport
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdAcDcAutoSwitchSupport
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdPmPowerButtonGpioPin
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdAcpiEnableAllButtonSupport
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdAcpiHidDriverButtonSupport
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdTsOnDimmTemperature
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdBatteryPresent
+
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCSupport
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCEcLess
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdEcHotKeyF3Support
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdEcHotKeyF4Support
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdEcHotKeyF5Support
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdEcHotKeyF6Support
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdEcHotKeyF7Support
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdEcHotKeyF8Support
+
+  #
+  # PSS Board Configuration.
+  #
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdPssReadSN
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdPssI2cBusNumber
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdPssI2cSlaveAddress
+
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdXhciAcpiTableSignature
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdPreferredPmProfile
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdFingerPrintSleepGpio
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdFingerPrintIrqGpio
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdGnssResetGpio
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdTouchpadIrqGpio
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdTouchpanelIrqGpio
+
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdHdaI2sCodecIrqGpio
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdHdaI2sCodecI2cBusNumber
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdBleUsbPortNumber
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdEcSmiGpio
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdEcLowPowerExitGpio
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdHidI2cIntPad
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdDetectPs2KbOnCmdAck
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdSpdAddressOverride
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdDDISelection
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdGfxCrbDetectGpio
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCPort1
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCPort1Pch
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbCPort1Proterties
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCPort2
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCPort2Pch
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbCPort2Proterties
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCPort3
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCPort3Pch
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbCPort3Proterties
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCPort4
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCPort4Pch
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbCPort4Proterties
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCPort5
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCPort5Pch
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbCPort5Proterties
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCPort6
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbTypeCPort6Pch
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdUsbCPort6Proterties
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdMipiCam0LinkUsed
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdMipiCam1LinkUsed
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdMipiCam2LinkUsed
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdMipiCam3LinkUsed
+  gPlatformModuleTokenSpaceGuid.PcdH8S2113Present
+  gPlatformModuleTokenSpaceGuid.PcdNat87393Present
+  gPlatformModuleTokenSpaceGuid.PcdNct677FPresent
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdConvertableDockSupport
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdSmcRuntimeSciPin
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdRealBattery1Control
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdRealBattery2Control
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdDimmPopulationError
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdBtIrqGpio
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdBtRfKillGpio
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdCmlURtd3TableEnable
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdTypeCPortsSupported
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdMipiCamSensor
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdH8S2113SIO
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdNCT6776FCOM
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdNCT6776FSIO
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdNCT6776FHWMON
+  gCometlakeOpenBoardPkgTokenSpaceGuid.PcdGpioTier2WakeEnable
+  gCometlakeOpenBoardPkgTokenSpaceGuid.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
+

+ 60 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.c

@@ -0,0 +1,60 @@
+/** @file
+  This file is SampleCode for SA DXE Policy initialization.
+
+
+  Copyright (c) 2020, 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;
+}
+

+ 56 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDxe.h

@@ -0,0 +1,56 @@
+/** @file
+  Header file for the SaPolicyInitDxe Driver.
+
+
+  Copyright (c) 2020, 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
+

+ 46 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.c

@@ -0,0 +1,46 @@
+/** @file
+  This file is SampleCode for Intel Silicon DXE Platform Policy initialzation.
+
+
+  Copyright (c) 2020, 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;
+}
+

+ 37 - 0
Platform/Intel/CometlakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyInitDxe.h

@@ -0,0 +1,37 @@
+/** @file
+  Header file for the SiliconPolicyInitDxe Driver.
+
+
+  Copyright (c) 2020, 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
+