summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiewen Yao <jiewen.yao@intel.com>2018-03-26 20:50:41 +0800
committerJiewen Yao <jiewen.yao@intel.com>2018-03-26 20:52:27 +0800
commit62f1e1e58965702030f722dcdf6de58998cf08a1 (patch)
treec9381f7c793a1cb61912e89e0ddfd561d883bf41
parent062cc36cc27bb55c35e0bdd196e9806bc9d79a3e (diff)
downloadedk2-platforms-62f1e1e58965702030f722dcdf6de58998cf08a1.tar.xz
KabylakeOpenBoardPkg: Add TBT support.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Vishal P Adodariya <vishal.p.adodariya@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Gpe.asl13
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c358
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h136
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf66
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3SptPcieTbt.asl410
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl1909
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Acpi/TbtNvs.asl66
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Acpi/TbtNvsAreaDef.h70
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h53
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h47
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h247
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h36
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h114
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h47
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h117
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h48
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h28
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h84
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c167
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf73
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h28
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c321
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf69
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c210
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf62
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h23
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c572
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf48
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c233
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf54
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c216
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf50
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c1615
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h185
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c1771
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf83
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkg.dsc22
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkg.fdf83
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkgConfig.dsc1
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkgPcd.dsc31
-rw-r--r--Platform/Intel/KabylakeOpenBoardPkg/OpenBoardPkg.dec55
41 files changed, 9817 insertions, 4 deletions
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Gpe.asl b/Platform/Intel/KabylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Gpe.asl
index a365882f6d..8433c1fcab 100644
--- a/Platform/Intel/KabylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Gpe.asl
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Gpe.asl
@@ -25,6 +25,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
External(\_SB.PCI0.PEG1.HPME, MethodObj)
External(\_SB.PCI0.PEG2.HPME, MethodObj)
External(\_GPE.AL6F, MethodObj)
+ External(\_SB.THDR, MethodObj)
External(\_GPE.P0L6, MethodObj)
External(\_GPE.P1L6, MethodObj)
External(\_GPE.P2L6, MethodObj)
@@ -34,6 +35,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
External(P0WK)
External(P1WK)
External(P2WK)
+ External(\CPG0)
+ External(\RPS0)
+ External(\RPT0)
External(\_PR.HWPI, IntObj)
External(\_PR.DTSI, IntObj)
@@ -841,5 +845,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\_SB.PCI0.GFX0.GSCI() // Handle the SWSCI
}
}
-
+ //
+ // BIOS Needs to implement appropriate handler based on CIO_PLUG_EVENT GPIO
+ // This is generic 2-tier GPIO handler
+ //
+ Method(_L6F)
+ {
+ \_SB.THDR(\CPG0,\RPS0,\RPT0) // Check for TBT Hotplug Handler event (2-tier GPI GPE event architecture)
+ }
}
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c b/Platform/Intel/KabylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c
new file mode 100644
index 0000000000..38ca4f954f
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c
@@ -0,0 +1,358 @@
+/** @file
+ Pci Hotplug Driver : This file will perform specific PCI-EXPRESS
+ Devics resource configuration.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// 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;
+}
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h
new file mode 100644
index 0000000000..3260af2b15
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h
@@ -0,0 +1,136 @@
+/**@file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PCI_HOT_PLUG_H_
+#define _PCI_HOT_PLUG_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <Base.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <IndustryStandard/Acpi10.h>
+#include <Protocol/PciHotPlugInit.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Guid/HobList.h>
+#include <Library/HobLib.h>
+#include <Protocol/SaPolicy.h>
+
+#define PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE SIGNATURE_32 ('G', 'U', 'L', 'P')
+
+#define ACPI \
+ { \
+ { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \
+ ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (0x0A03), 0 \
+ }
+
+#define PCI(device, function) \
+ { \
+ { HARDWARE_DEVICE_PATH, HW_PCI_DP, { (UINT8) (sizeof (PCI_DEVICE_PATH)), (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) } }, \
+ (UINTN) function, (UINTN) device \
+ }
+
+#define END \
+ { \
+ END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { END_DEVICE_PATH_LENGTH, 0 } \
+ }
+
+#define LPC(eisaid, function) \
+ { \
+ { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \
+ ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (eisaid), function \
+ }
+
+typedef struct PCIE_HOT_PLUG_DEVICE_PATH {
+ ACPI_HID_DEVICE_PATH PciRootBridgeNode;
+ PCI_DEVICE_PATH PciRootPortNode;
+ EFI_DEVICE_PATH_PROTOCOL EndDeviceNode;
+} PCIE_HOT_PLUG_DEVICE_PATH;
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle; // Handle for protocol this driver installs on
+ EFI_PCI_HOT_PLUG_INIT_PROTOCOL HotPlugInitProtocol;
+} PCI_HOT_PLUG_INSTANCE;
+
+/**
+ This procedure returns a list of Root Hot Plug controllers that require
+ initialization during boot process
+
+ @param[in] This The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+ @param[out] HpcCount The number of Root HPCs returned.
+ @param[out] HpcList The list of Root HPCs. HpcCount defines the number of elements in this list.
+
+ @retval EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetRootHpcList (
+ IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This,
+ OUT UINTN *PhpcCount,
+ OUT EFI_HPC_LOCATION **PhpcList
+ );
+
+/**
+ This procedure Initializes one Root Hot Plug Controller
+ This process may casue initialization of its subordinate buses
+
+ @param[in] This The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol.
+ @param[in] HpcDevicePath The Device Path to the HPC that is being initialized.
+ @param[in] HpcPciAddress The address of the Hot Plug Controller function on the PCI bus.
+ @param[in] Event The event that should be signaled when the Hot Plug Controller initialization is complete. Set to NULL if the caller wants to wait until the entire initialization process is complete. The event must be of the type EFI_EVT_SIGNAL.
+ @param[out] HpcState The state of the Hot Plug Controller hardware. The type EFI_Hpc_STATE is defined in section 3.1.
+
+ @retval EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+InitializeRootHpc (
+ IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *PhpcDevicePath,
+ IN UINT64 PhpcPciAddress,
+ IN EFI_EVENT Event, OPTIONAL
+ OUT EFI_HPC_STATE *PhpcState
+ );
+
+/**
+ Returns the resource padding required by the PCI bus that is controlled by the specified Hot Plug Controller.
+
+ @param[in] This The pointer to the instance of the EFI_PCI_HOT_PLUG_INIT protocol. initialized.
+ @param[in] HpcDevicePath The Device Path to the Hot Plug Controller.
+ @param[in] HpcPciAddress The address of the Hot Plug Controller function on the PCI bus.
+ @param[out] HpcState The state of the Hot Plug Controller hardware. The type EFI_HPC_STATE is defined in section 3.1.
+ @param[out] Padding This is the amount of resource padding required by the PCI bus under the control of the specified Hpc. Since the caller does not know the size of this buffer, this buffer is allocated by the callee and freed by the caller.
+ @param[out] Attribute Describes how padding is accounted for.
+
+ @retval EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+GetResourcePadding (
+ IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *PhpcDevicePath,
+ IN UINT64 PhpcPciAddress,
+ OUT EFI_HPC_STATE *PhpcState,
+ OUT VOID **Padding,
+ OUT EFI_HPC_PADDING_ATTRIBUTES *Attributes
+ );
+
+#endif
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf b/Platform/Intel/KabylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf
new file mode 100644
index 0000000000..b444782ffc
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf
@@ -0,0 +1,66 @@
+### @file
+# This module will perform specific PCI-Express devices
+# resource configuration.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[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
+ KabylakeOpenBoardPkg/OpenBoardPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+
+[Sources]
+ PciHotPlug.c
+ PciHotPlug.h
+
+[Protocols]
+ gEfiPciHotPlugInitProtocolGuid ## PRODUCES
+ gSaPolicyProtocolGuid ## CONSUMES
+
+[Guids]
+ gEfiHobListGuid ## CONSUMES
+ gPcieRpConfigGuid ## CONSUMES
+
+[Pcd]
+ gBoardModuleTokenSpaceGuid.PcdPchPcieRootPortHpe
+
+[Depex]
+ gDxeTbtPolicyProtocolGuid
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3SptPcieTbt.asl b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3SptPcieTbt.asl
new file mode 100644
index 0000000000..b54b5a41c3
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3SptPcieTbt.asl
@@ -0,0 +1,410 @@
+/** @file
+ ACPI RTD3 SSDT table for SPT PCIe
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#define PID_ICC 0xDC
+#define R_PCH_PCR_ICC_MSKCKRQ 0x100C ///< Mask Control CLKREQ
+
+External(PCRA,MethodObj)
+External(PCRO,MethodObj)
+External(\MMRP, MethodObj)
+External(\MMTB, MethodObj)
+External(\TRDO, IntObj)
+External(\TRD3, IntObj)
+External(\TBPE, IntObj)
+External(\TOFF, IntObj)
+External(\TBSE, IntObj)
+External(\TBOD, IntObj)
+External(\TBRP, IntObj)
+External(\TBHR, IntObj)
+External(\RTBC, IntObj)
+External(\TBCD, IntObj)
+
+Name(G2SD, 0) // Go2Sx done, set by GO2S, cleaned by _ON
+
+Name(WKEN, 0)
+
+ Method(_S0W, 0)
+ {
+ /// This method returns the lowest D-state supported by PCIe root port during S0 state
+
+ ///- PMEs can be generated from D3hot for ULT
+ Return(4)
+
+ /** @defgroup pcie_s0W PCIE _S0W **/
+ } // End _S0W
+
+ Method (_DSD, 0) {
+ Return (
+ Package () {
+ ToUUID("6211E2C0-58A3-4AF3-90E1-927A4E0C55A4"),
+ Package () {
+ Package (2) {"HotPlugSupportInD3", 1},
+ }
+ }
+ ) // End of Return ()
+ }
+
+ Method(_DSW, 3)
+ {
+ /// This method is used to enable/disable wake from PCIe (WKEN)
+ If (LGreaterEqual(Arg1, 1)) { /// If entering Sx, need to disable WAKE# from generating runtime PME
+ /// Also set 2 to TOFF.
+ Store(0, WKEN)
+ Store (2, TOFF)
+ } Else { /// If Staying in S0
+ If(LAnd(Arg0, Arg2)) ///- Check if Exiting D0 and arming for wake
+ { ///- Set PME
+ Store(1, WKEN)
+ Store (1, TOFF)
+ } Else { ///- Disable runtime PME, either because staying in D0 or disabling wake
+ Store(0, WKEN)
+ Store(0, TOFF)
+ }
+ }
+
+ /** @defgroup pcie_dsw PCIE _DSW **/
+ } // End _DSW
+
+
+ PowerResource(PXP, 0, 0)
+ {
+ /// Define the PowerResource for PCIe slot
+ /// Method: _STA(), _ON(), _OFF()
+ /** @defgroup pcie_pxp PCIE Power Resource **/
+
+ Method(_STA, 0)
+ {
+ Return(PSTA())
+ } /** @defgroup pcie_sta PCIE _STA method **/
+
+ Method(_ON) /// Turn on core power to PCIe Slot
+ {
+ Store(1, TRDO)
+ PON()
+ Store(0, TRDO)
+ } /** @defgroup pcie_on PCIE _ON method **/
+
+ Method(_OFF) /// Turn off core power to PCIe Slot
+ {
+ Store(1, TRD3)
+ POFF()
+ Store(0, TRD3)
+ } // End of Method_OFF
+ } // End PXP
+
+ Method(PSTA, 0)
+ {
+ /// Returns the status of PCIe slot core power
+ // detect power pin status
+ if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) {
+ if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
+ if(LEqual(\_SB.GGOV(DeRefOf(Index(PWRG, 2))),DeRefOf(Index(PWRG, 3)))){
+ Return (1)
+ } Else {
+ Return (0)
+ }
+ } // GPIO mode
+ if(LEqual(DeRefOf(Index(PWRG, 0)),2)) { // IOEX mode
+ if(LEqual(\_SB.PCI0.GEXP.GEPS(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG, 2))),DeRefOf(Index(PWRG, 3)))){
+ Return (1)
+ } Else {
+ Return (0)
+ }
+ } // IOEX mode
+ }
+ // detect reset pin status
+ if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) {
+ if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
+ if(LEqual(\_SB.GGOV(DeRefOf(Index(RSTG, 2))),DeRefOf(Index(RSTG, 3)))){
+ Return (1)
+ } Else {
+ Return (0)
+ }
+ } // GPIO mode
+ if(LEqual(DeRefOf(Index(RSTG, 0)),2)) { // IOEX mode
+ if(LEqual(\_SB.PCI0.GEXP.GEPS(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG, 2))),DeRefOf(Index(RSTG, 3)))){
+ Return (1)
+ } Else {
+ Return (0)
+ }
+ } // IOEX mode
+ }
+ Return (0)
+ } /** @defgroup pcie_sta PCIE _STA method **/
+
+ Method (SXEX, 0, Serialized) {
+
+ Store(\MMTB(TBSE), Local7)
+ OperationRegion(TBDI, SystemMemory, Local7, 0x550)// TBT HR PCICFG MMIO
+ Field(TBDI,DWordAcc, NoLock, Preserve) {
+ DIVI, 32,
+ CMDR, 32,
+ Offset(0x548),
+ TB2P, 32,
+ P2TB, 32
+ }
+
+ Store(100, Local1)
+ Store(0x09, P2TB) // Write SX_EXIT_TBT_CONNECTED to PCIe2TBT
+ While (LGreater(Local1, 0)) {
+
+ Store(Subtract(Local1, 1), Local1)
+ Store(TB2P, Local2)
+ If (LEqual(Local2, 0xFFFFFFFF)) { // Device gone
+ Return()
+ }
+ If (And(Local2, 1)) { // Done
+ break
+ }
+ Sleep(5)
+ }
+ Store(0x0, P2TB) // Write 0 to PCIe2TBT
+
+ // Fast Link bring-up flow
+ Store(500, Local1)
+ While (LGreater(Local1, 0)) {
+ Store(Subtract(Local1, 1), Local1)
+ Store(TB2P, Local2)
+ If (LEqual(Local2, 0xFFFFFFFF)) {// Device gone
+ Return()
+ }
+ If (LNotEqual(DIVI, 0xFFFFFFFF)) {
+ break
+ }
+ Sleep(10)
+ }
+ } // End of Method(SXEX, 0, Serialized)
+
+ Method(PON) /// Turn on core power to PCIe Slot
+ {
+
+ Store(\MMRP(\TBSE), Local7)
+ OperationRegion(L23P,SystemMemory,Local7,0xE4)
+ Field(L23P,WordAcc, NoLock, Preserve)
+ {
+ Offset(0xA4),// PMCSR
+ PSD0, 2, // PowerState
+ Offset(0xE2),// 0xE2, RPPGEN - Root Port Power Gating Enable
+ , 2,
+ L2TE, 1, // 2, L23_Rdy Entry Request (L23ER)
+ L2TR, 1, // 3, L23_Rdy to Detect Transition (L23R2DT)
+ }
+
+ Store(\MMTB(\TBSE), Local6)
+ OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG MMIO
+ Field(TBDI,DWordAcc, NoLock, Preserve) {
+ DIVI, 32,
+ CMDR, 32,
+ Offset(0xA4),
+ TBPS, 2, // PowerState of TBT
+ Offset(0x548),
+ TB2P, 32,
+ P2TB, 32
+ }
+
+ Store(0, TOFF)
+ // Check RTD3 power enable, if already ON, no need to execute sx_exit
+ If (TBPE) {
+ Return()
+ }
+
+ Store(0,G2SD)
+ If (\RTBC) {
+ /// de-assert CLK_REQ MSK
+ if(LNotEqual(DeRefOf(Index(SCLK, 0)),0)) { // if power gating enabled
+ PCRA(PID_ICC,R_PCH_PCR_ICC_MSKCKRQ,Not(DeRefOf(Index(SCLK, 1)))) // And ~SCLK to clear bit
+ }
+ Sleep(\TBCD)
+ }
+
+ /// Turn ON Power for PCIe Slot
+ if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) { // if power gating enabled
+ if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
+ \_SB.SGOV(DeRefOf(Index(PWRG, 2)),DeRefOf(Index(PWRG, 3)))
+ Store(1, TBPE)
+ Sleep(PEP0) /// Sleep for programmable delay
+ }
+ if(LEqual(DeRefOf(Index(PWRG, 0)),2)) { // IOEX mode
+ \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG, 2)),DeRefOf(Index(PWRG, 3)))
+ Store(1, TBPE)
+ Sleep(PEP0) /// Sleep for programmable delay
+ }
+ }
+
+ /// De-Assert Reset Pin
+ if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) { // if reset pin enabled
+ if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
+ \_SB.SGOV(DeRefOf(Index(RSTG, 2)),DeRefOf(Index(RSTG, 3)))
+ }
+ if(LEqual(DeRefOf(Index(RSTG, 0)),2)) { // IOEX mode
+ \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG, 2)),DeRefOf(Index(RSTG, 3)))
+ }
+ }
+
+ /// Clear DLSULPPGE, then set L23_Rdy to Detect Transition (L23R2DT)
+ Store(0, DPGE)
+ Store(1, L2TR)
+ Sleep(16)
+ Store(0, Local0)
+ /// Wait up to 12 ms for transition to Detect
+ While(L2TR) {
+ If(Lgreater(Local0, 4)) // Debug - Wait for 5 ms
+ {
+ Break
+ }
+ Sleep(16)
+ Increment(Local0)
+ }
+ /// Once in Detect, wait up to 124 ms for Link Active (typically happens in under 70ms)
+ /// Worst case per PCIe spec from Detect to Link Active is:
+ /// 24ms in Detect (12+12), 72ms in Polling (24+48), 28ms in Config (24+2+2+2+2)
+ Store(1, DPGE)
+ Store(0, Local0)
+ While(LEqual(LASX,0)) {
+ If(Lgreater(Local0, 8))
+ {
+ Break
+ }
+ Sleep(16)
+ Increment(Local0)
+ }
+ Store(0, LEDM) /// Set PCIEDBG.DMIL1EDM (324[3]) = 0
+
+ // TBT special sleep.
+ Store(PSD0, Local1)
+ Store(0, PSD0)// D0
+ Store(20, Local2) // Poll for TBT, up to 200 ms
+
+ While (LGreater(Local2, 0)) {
+ Store(Subtract(Local2, 1), Local2)
+ Store(TB2P, Local3)
+ If (LNotEqual(Local3, 0xFFFFFFFF)) { // Done
+ break
+ }
+ Sleep(10)
+ }
+
+ If (LLessEqual(Local2, 0)) {
+ }
+ SXEX()
+ Store(Local1, PSD0) // Back to Local1
+ } /** @defgroup pcie_on PCIE _ON method **/
+
+ Method(POFF) { /// Turn off core power to PCIe Slot
+ If (LEqual(TOFF, 0)) {
+ Return()
+ }
+ Store(\MMRP(\TBSE), Local7)
+ OperationRegion(L23P, SystemMemory, Local7, 0xE4)
+ Field(L23P,WordAcc, NoLock, Preserve)
+ {
+ Offset(0xA4),// PMCSR
+ PSD0, 2, // PowerState
+ Offset(0xE2),// 0xE2, RPPGEN - Root Port Power Gating Enable
+ , 2,
+ L2TE, 1, // 2, L23_Rdy Entry Request (L23ER)
+ L2TR, 1, // 3, L23_Rdy to Detect Transition (L23R2DT)
+ }
+
+ Store(\MMTB(TBSE), Local6)
+ OperationRegion(TBDI, SystemMemory, Local6, 0x550)// TBT HR PCICFG MMIO
+ Field(TBDI,DWordAcc, NoLock, Preserve) {
+ DIVI, 32,
+ CMDR, 32,
+ Offset(0xA4),
+ TBPS, 2, // PowerState of TBT
+ Offset(0x548),
+ TB2P, 32,
+ P2TB, 32
+ }
+
+ Store(PSD0, Local1)
+ Store(0, PSD0)// D0
+
+ Store(P2TB, Local3)
+
+ If (Lgreater(TOFF, 1)) {
+ Sleep(10)
+ Store(Local1, PSD0) // Back to Local1
+ Return()
+ }
+ Store(0, TOFF)
+
+ Store(Local1, PSD0) // Back to Local1
+
+ /// Set L23_Rdy Entry Request (L23ER)
+ Store(1, L2TE)
+ Sleep(16)
+ Store(0, Local0)
+ While(L2TE) {
+ If(Lgreater(Local0, 4)) /// Debug - Wait for 5 ms
+ {
+ Break
+ }
+ Sleep(16)
+ Increment(Local0)
+ }
+ Store(1, LEDM) /// PCIEDBG.DMIL1EDM (324[3]) = 1
+
+ /// Assert Reset Pin
+ if(LNotEqual(DeRefOf(Index(RSTG, 0)),0)) { // if reset pin enabled
+ if(LEqual(DeRefOf(Index(RSTG, 0)),1)) { // GPIO mode
+ \_SB.SGOV(DeRefOf(Index(RSTG, 2)),Xor(DeRefOf(Index(RSTG, 3)),1))
+ }
+ if(LEqual(DeRefOf(Index(RSTG, 0)),2)) { // IOEX mode
+ \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(RSTG, 1)),DeRefOf(Index(RSTG, 2)),Xor(DeRefOf(Index(RSTG, 3)),1))
+ }
+ }
+ If (\RTBC) {
+ /// assert CLK_REQ MSK
+ if(LNotEqual(DeRefOf(Index(SCLK, 0)),0)) { // if power gating enabled
+ PCRO(PID_ICC,R_PCH_PCR_ICC_MSKCKRQ,DeRefOf(Index(SCLK, 1))) // Or SCLK to set bit
+ Sleep(16)
+ }
+ }
+
+ /// Power OFF for TBT
+ if(LNotEqual(DeRefOf(Index(PWRG, 0)),0)) { // if power gating enabled
+ if(LEqual(DeRefOf(Index(PWRG, 0)),1)) { // GPIO mode
+ \_SB.SGOV(DeRefOf(Index(PWRG, 2)),Xor(DeRefOf(Index(PWRG, 3)),1))
+ }
+ if(LEqual(DeRefOf(Index(PWRG, 0)),2)) { // IOEX mode
+ \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(PWRG, 1)),DeRefOf(Index(PWRG, 2)),Xor(DeRefOf(Index(PWRG, 3)),1))
+ }
+ }
+
+ Store(0, TBPE)
+
+ Store(1, LDIS) /// Set Link Disable
+ Store(0, LDIS) /// Toggle link disable
+
+ /// enable WAKE
+ If (WKEN) {
+ If (LNotEqual(DeRefOf(Index(WAKG, 0)),0)) { // if power gating enabled
+ If (LEqual(DeRefOf(Index(WAKG, 0)),1)) { // GPIO mode
+ \_SB.SGOV(DeRefOf(Index(WAKG, 2)),DeRefOf(Index(WAKG, 3)))
+ \_SB.SHPO(DeRefOf(Index(WAKG, 2)), 0) // set gpio ownership to ACPI(0=ACPI mode, 1=GPIO mode)
+ }
+ If (LEqual(DeRefOf(Index(WAKG, 0)),2)) { // IOEX mode
+ \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(WAKG, 1)),DeRefOf(Index(WAKG, 2)),DeRefOf(Index(WAKG, 3)))
+ }
+ }
+ }
+ Sleep(\TBOD)
+ /** @defgroup pcie_off PCIE _OFF method **/
+ } // End of Method_OFF
+
+ Name(_PR0, Package(){PXP})
+ Name(_PR3, Package(){PXP})
+
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl
new file mode 100644
index 0000000000..56c27f3a63
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl
@@ -0,0 +1,1909 @@
+/** @file
+ Thunderbolt ACPI methods
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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)
+//
+// SA:RestrictedBegin
+//
+External(\_SB.PCI0.LKEN, MethodObj)
+External(\_SB.PCI0.LKDS, MethodObj)
+//
+// SA:RestrictedEnd
+//
+
+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
+ }
+#ifndef CPU_CFL
+ Case (Package () {4})
+ {
+ Store(0x6, Local0) //Device6-Function0 = 00110.000
+ }
+#endif
+ }
+ } 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
+ }
+#ifndef CPU_CFL
+ Case (4)
+ {
+ Store(0x0, Local0) //Device6-Function0 = 00110.000
+ }
+#endif
+ }
+ } 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)
+ }
+#ifndef CPU_CFL
+ Case (4)
+ {
+ ADBG("Notify PEG3")
+ Notify(\_SB.PCI0.PEG3,0)
+ }
+#endif
+ }
+ }//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.
+// SKL-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 SKL 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)
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Acpi/TbtNvs.asl b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Acpi/TbtNvs.asl
new file mode 100644
index 0000000000..65961e0940
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Acpi/TbtNvs.asl
@@ -0,0 +1,66 @@
+/**@file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+ //
+ // Define TBT NVS Area operation region.
+ //
+
+
+
+ OperationRegion(BNVS,SystemMemory,TNVB,TNVL)
+ Field(BNVS,AnyAcc,Lock,Preserve)
+ { Offset(0), TBSF, 8, // Offset(0), Thunderbolt(TM) SMI Function Number
+ Offset(1), SOHP, 8, // Offset(1), SMI on Hot Plug for TBT devices
+ Offset(2), TWIN, 8, // Offset(2), TbtWin10Support
+ Offset(3), GP5F, 8, // Offset(3), Gpio filter to detect USB Hotplug event
+ Offset(4), NOHP, 8, // Offset(4), Notify on Hot Plug for TBT devices
+ Offset(5), TBSE, 8, // Offset(5), Thunderbolt(TM) Root port selector
+ Offset(6), WKFN, 8, // Offset(6), WAK Finished
+ Offset(7), TBTS, 8, // Offset(7), Thunderbolt(TM) support
+ Offset(8), TARS, 8, // Offset(8), TbtAcpiRemovalSupport
+ Offset(9), FPEN, 32, // Offset(9), TbtFrcPwrEn
+ Offset(13), FPG0, 32, // Offset(13), TbtFrcPwrGpioNo
+ Offset(17), FP0L, 8, // Offset(17), TbtFrcPwrGpioLevel
+ Offset(18), CPG0, 32, // Offset(18), TbtCioPlugEventGpioNo
+ Offset(22), RSG0, 32, // Offset(22), TbtPcieRstGpioNo
+ Offset(26), RS0L, 8, // Offset(26), TbtPcieRstGpioLevel
+ Offset(27), DTCP, 8, // Offset(27), Current Port that has plug event
+ Offset(28), RPS0, 8, // Offset(28), Root port Selected by the User
+ Offset(29), RPT0, 8, // Offset(29), Root port Type
+ Offset(30), RPS1, 8, // Offset(30), Root port Selected by the User
+ Offset(31), RPT1, 8, // Offset(31), Root port Type
+ Offset(32), RPN0, 8, // Offset(32), Root port Enabled by the User
+ Offset(33), RPN1, 8, // Offset(33), Root port Enabled by the User
+ Offset(34), FPG1, 32, // Offset(34), TbtFrcPwrGpioNo
+ Offset(38), FP1L, 8, // Offset(38), TbtFrcPwrGpioLevel
+ Offset(39), CPG1, 32, // Offset(39), TbtCioPlugEventGpioNo
+ Offset(43), RSG1, 32, // Offset(43), TbtPcieRstGpioNo
+ Offset(47), RS1L, 8, // Offset(47), TbtPcieRstGpioLevel
+ Offset(48), CGST, 8, // Offset(48), Set if Single GPIO is used for Multi/Different Controller Hot plug support
+ Offset(49), DTPT, 8, // Offset(49), Root Port type for which SCI Triggered
+ Offset(50), TRWA, 8, // Offset(50), Titan Ridge Osup command
+ Offset(51), ACDC, 8, // Offset(51), TBT Dynamic AcDc L1
+ Offset(52), DT0E, 8, // Offset(52), DTbtController0 is enabled or not.
+ Offset(53), DT1E, 8, // Offset(53), DTbtController1 is enabled or not.
+ Offset(54), TASP, 8, // Offset(54), ASPM setting for all the PCIe device in TBT daisy chain.
+ Offset(55), TL1S, 8, // Offset(55), L1 SubState for for all the PCIe device in TBT daisy chain.
+ Offset(56), TCLK, 8, // Offset(56), CLK REQ for all the PCIe device in TBT daisy chain.
+ Offset(57), TLTR, 8, // Offset(57), LTR for for all the PCIe device in TBT daisy chain.
+ Offset(58), TPTM, 8, // Offset(58), PTM for for all the PCIe device in TBT daisy chain.
+ Offset(59), TWAK, 8, // Offset(59), Send Go2SxNoWake or GoSxWake according to TbtWakeupSupport
+ Offset(60), TBOD, 16, // Offset(60), Rtd3TbtOffDelay TBT RTD3 Off Delay
+ Offset(62), TSXW, 8, // Offset(62), TbtSxWakeSwitchLogicEnable Set True if TBT_WAKE_N will be routed to PCH WakeB at Sx entry point. HW logic is required.
+ Offset(63), RTBT, 8, // Offset(63), Enable Rtd3 support for TBT. Corresponding to Rtd3Tbt in Setup.
+ Offset(64), RTBC, 8, // Offset(64), Enable TBT RTD3 CLKREQ mask.
+ Offset(65), TBCD, 16, // Offset(65), TBT RTD3 CLKREQ mask delay.
+ } \ No newline at end of file
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Acpi/TbtNvsAreaDef.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Acpi/TbtNvsAreaDef.h
new file mode 100644
index 0000000000..583fda5914
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Acpi/TbtNvsAreaDef.h
@@ -0,0 +1,70 @@
+/**@file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+ //
+ // Define TBT NVS Area operation region.
+ //
+
+#ifndef _TBT_NVS_AREA_DEF_H_
+#define _TBT_NVS_AREA_DEF_H_
+
+#pragma pack (push,1)
+typedef struct {
+ UINT8 ThunderboltSmiFunction; ///< Offset 0 Thunderbolt(TM) SMI Function Number
+ UINT8 ThunderboltHotSmi; ///< Offset 1 SMI on Hot Plug for TBT devices
+ UINT8 TbtWin10Support; ///< Offset 2 TbtWin10Support
+ UINT8 TbtGpioFilter; ///< Offset 3 Gpio filter to detect USB Hotplug event
+ UINT8 ThunderboltHotNotify; ///< Offset 4 Notify on Hot Plug for TBT devices
+ UINT8 TbtSelector; ///< Offset 5 Thunderbolt(TM) Root port selector
+ UINT8 WAKFinished; ///< Offset 6 WAK Finished
+ UINT8 DiscreteTbtSupport; ///< Offset 7 Thunderbolt(TM) support
+ UINT8 TbtAcpiRemovalSupport; ///< Offset 8 TbtAcpiRemovalSupport
+ UINT32 TbtFrcPwrEn; ///< Offset 9 TbtFrcPwrEn
+ UINT32 TbtFrcPwrGpioNo0; ///< Offset 13 TbtFrcPwrGpioNo
+ UINT8 TbtFrcPwrGpioLevel0; ///< Offset 17 TbtFrcPwrGpioLevel
+ UINT32 TbtCioPlugEventGpioNo0; ///< Offset 18 TbtCioPlugEventGpioNo
+ UINT32 TbtPcieRstGpioNo0; ///< Offset 22 TbtPcieRstGpioNo
+ UINT8 TbtPcieRstGpioLevel0; ///< Offset 26 TbtPcieRstGpioLevel
+ UINT8 CurrentDiscreteTbtRootPort; ///< Offset 27 Current Port that has plug event
+ UINT8 RootportSelected0; ///< Offset 28 Root port Selected by the User
+ UINT8 RootportSelected0Type; ///< Offset 29 Root port Type
+ UINT8 RootportSelected1; ///< Offset 30 Root port Selected by the User
+ UINT8 RootportSelected1Type; ///< Offset 31 Root port Type
+ UINT8 RootportEnabled0; ///< Offset 32 Root port Enabled by the User
+ UINT8 RootportEnabled1; ///< Offset 33 Root port Enabled by the User
+ UINT32 TbtFrcPwrGpioNo1; ///< Offset 34 TbtFrcPwrGpioNo
+ UINT8 TbtFrcPwrGpioLevel1; ///< Offset 38 TbtFrcPwrGpioLevel
+ UINT32 TbtCioPlugEventGpioNo1; ///< Offset 39 TbtCioPlugEventGpioNo
+ UINT32 TbtPcieRstGpioNo1; ///< Offset 43 TbtPcieRstGpioNo
+ UINT8 TbtPcieRstGpioLevel1; ///< Offset 47 TbtPcieRstGpioLevel
+ UINT8 TBtCommonGpioSupport; ///< Offset 48 Set if Single GPIO is used for Multi/Different Controller Hot plug support
+ UINT8 CurrentDiscreteTbtRootPortType; ///< Offset 49 Root Port type for which SCI Triggered
+ UINT8 TrOsup; ///< Offset 50 Titan Ridge Osup command
+ UINT8 TbtAcDcSwitch; ///< Offset 51 TBT Dynamic AcDc L1
+ UINT8 DTbtControllerEn0; ///< Offset 52 DTbtController0 is enabled or not.
+ UINT8 DTbtControllerEn1; ///< Offset 53 DTbtController1 is enabled or not.
+ UINT8 TbtAspm; ///< Offset 54 ASPM setting for all the PCIe device in TBT daisy chain.
+ UINT8 TbtL1SubStates; ///< Offset 55 L1 SubState for for all the PCIe device in TBT daisy chain.
+ UINT8 TbtSetClkReq; ///< Offset 56 CLK REQ for all the PCIe device in TBT daisy chain.
+ UINT8 TbtLtr; ///< Offset 57 LTR for for all the PCIe device in TBT daisy chain.
+ UINT8 TbtPtm; ///< Offset 58 PTM for for all the PCIe device in TBT daisy chain.
+ UINT8 TbtWakeupSupport; ///< Offset 59 Send Go2SxNoWake or GoSxWake according to TbtWakeupSupport
+ UINT16 Rtd3TbtOffDelay; ///< Offset 60 Rtd3TbtOffDelay TBT RTD3 Off Delay
+ UINT8 TbtSxWakeSwitchLogicEnable; ///< Offset 62 TbtSxWakeSwitchLogicEnable Set True if TBT_WAKE_N will be routed to PCH WakeB at Sx entry point. HW logic is required.
+ UINT8 Rtd3TbtSupport; ///< Offset 63 Enable Rtd3 support for TBT. Corresponding to Rtd3Tbt in Setup.
+ UINT8 Rtd3TbtClkReq; ///< Offset 64 Enable TBT RTD3 CLKREQ mask.
+ UINT16 Rtd3TbtClkReqDelay; ///< Offset 65 TBT RTD3 CLKREQ mask delay.
+} TBT_NVS_AREA;
+
+#pragma pack(pop)
+#endif
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h
new file mode 100644
index 0000000000..9fe16b8a68
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Library/DxeTbtPolicyLib.h
@@ -0,0 +1,53 @@
+/** @file
+ Prototype of the DxeTbtPolicyLib library.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef _DXE_TBT_POLICY_LIB_H_
+#define _DXE_TBT_POLICY_LIB_H_
+
+
+/**
+ Install TBT Policy.
+
+ @param[in] ImageHandle Image handle of this driver.
+
+ @retval EFI_SUCCESS The policy is installed.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallTbtPolicy (
+ IN EFI_HANDLE ImageHandle
+ );
+
+/**
+ Update Tbt Policy Callback.
+
+ @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.
+
+**/
+VOID
+EFIAPI
+UpdateTbtPolicyCallback (
+ VOID
+ );
+
+/**
+ Print DXE TBT Policy
+**/
+VOID
+TbtPrintDxePolicyConfig (
+ VOID
+ );
+#endif // _DXE_TBT_POLICY_LIB_H_
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h
new file mode 100644
index 0000000000..f1ca61ca4e
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Library/PeiTbtPolicyLib.h
@@ -0,0 +1,47 @@
+/** @file
+ Prototype of the PeiTbtPolicyLib library.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef _PEI_TBT_POLICY_LIB_H_
+#define _PEI_TBT_POLICY_LIB_H_
+
+/**
+ Install Tbt Policy
+
+ @retval EFI_SUCCESS The policy is installed.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallPeiTbtPolicy (
+ VOID
+ );
+
+/**
+ Update PEI TBT Policy
+**/
+VOID
+EFIAPI
+UpdatePeiTbtPolicy (
+ VOID
+ );
+
+/**
+ Print PEI TBT Policy
+**/
+VOID
+EFIAPI
+TbtPrintPeiPolicyConfig (
+ VOID
+ );
+#endif // _DXE_TBT_POLICY_LIB_H_
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h
new file mode 100644
index 0000000000..f9338d3bd5
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Library/TbtCommonLib.h
@@ -0,0 +1,247 @@
+/**@file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef _TBT_COMMON_LIB_H_
+#define _TBT_COMMON_LIB_H_
+
+#include <Library/BaseLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/GpioExpanderLib.h>
+
+#define DTBT_CONTROLLER 0x00
+#define DTBT_TYPE_PCH 0x01
+#define DTBT_TYPE_PEG 0x02
+#define TBT2PCIE_DTBT_R 0x548
+#define PCIE2TBT_DTBT_R 0x54C
+
+//
+// Thunderbolt FW OS capability
+//
+#define NO_OS_NATIVE_SUPPORT 0
+#define OS_NATIVE_SUPPORT_ONLY 1
+#define OS_NATIVE_SUPPORT_RTD3 2
+
+#define DTBT_SAVE_STATE_OFFSET BIT0 // Bits 0-3 is for DTBT (only bit 0 is in use)
+/**
+Get Tbt2Pcie Register Offset
+
+@retval Register Register Variable
+**/
+
+#define GET_TBT2PCIE_REGISTER_ADDRESS(Segment, Bus, Device, Function, RegisterAddress) \
+RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, TBT2PCIE_DTBT_R); \
+
+/**
+Get Pcie2Tbt Register Offset
+
+@retval Register Register Variable
+**/
+
+#define GET_PCIE2TBT_REGISTER_ADDRESS(Segment, Bus, Device, Function, RegisterAddress) \
+RegisterAddress = PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCIE2TBT_DTBT_R); \
+
+#define PCIE2TBT_VLD_B BIT0
+#define TBT2PCIE_DON_R BIT0
+#define TBT_MAIL_BOX_DELAY (100*1000)
+#define TBT_5S_TIMEOUT 50
+#define TBT_1S_TIMEOUT 10
+#define TBT_3S_TIMEOUT 30
+
+#define PCIE2TBT_GO2SX (0x02 << 1)
+#define PCIE2TBT_GO2SX_NO_WAKE (0x03 << 1)
+#define PCIE2TBT_SX_EXIT_TBT_CONNECTED (0x04 << 1)
+#define PCIE2TBT_SX_EXIT_NO_TBT_CONNECTED (0x05 << 1)
+#define PCIE2TBT_OS_UP (0x06 << 1)
+#define PCIE2TBT_SET_SECURITY_LEVEL (0x08 << 1)
+#define PCIE2TBT_GET_SECURITY_LEVEL (0x09 << 1)
+#define PCIE2TBT_CM_AUTH_MODE_ENTER (0x10 << 1)
+#define PCIE2TBT_CM_AUTH_MODE_EXIT (0x11 << 1)
+#define PCIE2TBT_BOOT_ON (0x18 << 1)
+#define PCIE2TBT_BOOT_OFF (0x19 << 1)
+#define PCIE2TBT_USB_ON (0x19 << 1)
+#define PCIE2TBT_GET_ENUMERATION_METHOD (0x1A << 1)
+#define PCIE2TBT_SET_ENUMERATION_METHOD (0x1B << 1)
+#define PCIE2TBT_POWER_CYCLE (0x1C << 1)
+#define PCIE2TBT_PREBOOTACL (0x1E << 1)
+#define CONNECT_TOPOLOGY_COMMAND (0x1F << 1)
+
+#define RESET_HR_BIT BIT0
+#define ENUMERATE_HR_BIT BIT1
+#define AUTO 0x0
+
+//
+//Thunder Bolt Device IDs
+//
+
+//
+// Alpine Ridge HR device IDs
+//
+#define AR_HR_2C 0x1576
+#define AR_HR_4C 0x1578
+#define AR_XHC 0x15B5
+#define AR_XHC_4C 0x15B6
+#define AR_HR_LP 0x15C0
+//
+// Alpine Ridge C0 HR device IDs
+//
+#define AR_HR_C0_2C 0x15DA
+#define AR_HR_C0_4C 0x15D3
+//
+// Titan Ridge HR device IDs
+//
+#define TR_HR_2C 0x15E7
+#define TR_HR_4C 0x15EA
+//
+//End of Thunderbolt(TM) Device IDs
+//
+
+typedef struct _DEV_ID {
+ UINT8 Segment;
+ UINT8 Bus;
+ UINT8 Dev;
+ UINT8 Fun;
+} DEV_ID;
+
+//@todo Seems to only be used by Platform/TBT/Smm/TbtSmm.inf
+//@todo should refactor this to only be present in that driver
+//@todo also definitions like this should never be in a .h file anyway
+//@todo this is a quick hack to get things compiling for now
+#ifdef __GNUC__
+#pragma GCC diagnostic warning "-Wunused-variable"
+#endif
+
+/**
+Based on the Security Mode Selection, BIOS drives FORCE_PWR.
+
+@param[in] GpioNumber
+@param[in] Value
+**/
+VOID
+ForceDtbtPower(
+ IN UINT8 GpioAccessType,
+ IN UINT8 Expander,
+ IN UINT32 GpioNumber,
+ IN BOOLEAN Value
+);
+
+/**
+ Get Security Level.
+ @param[in] Bus Bus number for Host Router (DTBT)
+ @param[in] Device Device number for Host Router (DTBT)
+ @param[in] Function Function number for Host Router (DTBT)
+ @param[in] Timeout Time out with 100 ms garnularity
+**/
+UINT8
+GetSecLevel (
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT8 Command,
+ IN UINT32 Timeout
+ );
+
+/**
+ Set Security Level.
+ @param[in] Data Security State
+ @param[in] Bus Bus number for Host Router (DTBT)
+ @param[in] Device Device number for Host Router (DTBT)
+ @param[in] Function Function number for Host Router (DTBT)
+ @param[in] Timeout Time out with 100 ms garnularity
+**/
+BOOLEAN
+SetSecLevel (
+ IN UINT8 Data,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT8 Command,
+ IN UINT32 Timeout
+ );
+
+/**
+Execute TBT Mail Box Command
+
+@param[in] Command TBT Command
+@param[in] Bus Bus number for Host Router (DTBT)
+@param[in] Device Device number for Host Router (DTBT)
+@param[in] Function Function number for Host Router (DTBT)
+@param[in] Timeout Time out with 100 ms garnularity
+@Retval true if command executes succesfully
+**/
+BOOLEAN
+TbtSetPcie2TbtCommand(
+ IN UINT8 Command,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT32 Timeout
+);
+/**
+ Check connected TBT controller is supported or not by DeviceID
+
+ @param[in] DeviceID DeviceID of of TBT controller
+
+
+ @retval TRUE Valid DeviceID
+ @retval FALSE Invalid DeviceID
+**/
+
+BOOLEAN
+IsTbtHostRouter (
+ IN UINT16 DeviceID
+ );
+
+/**
+ Get Pch/Peg Pcie Root Port Device and Function Number for TBT by Root Port physical Number
+
+ @param[in] RpNumber Root port physical number. (0-based)
+ @param[out] RpDev Return corresponding root port device number.
+ @param[out] RpFun Return corresponding root port function number.
+
+ @retval EFI_SUCCESS Root port device and function is retrieved
+**/
+EFI_STATUS
+EFIAPI
+GetDTbtRpDevFun(
+ IN BOOLEAN Type,
+ IN UINTN RpNumber,
+ OUT UINTN *RpDev,
+ OUT UINTN *RpFunc
+ );
+
+/**
+ Internal function to Wait for Tbt2PcieDone Bit.to Set or clear
+ @param[in] CommandOffsetAddress Tbt2Pcie Register Address
+ @param[in] TimeOut Time out with 100 ms garnularity
+ @param[in] Tbt2PcieDone Wait condition (wait for Bit to Clear/Set)
+ @param[out] *Tbt2PcieValue Function Register value
+**/
+BOOLEAN
+InternalWaitforCommandCompletion (
+ IN UINT64 CommandOffsetAddress,
+ IN UINT32 TimeOut,
+ IN BOOLEAN Tbt2PcieDone,
+ OUT UINT32 *Tbt2PcieValue
+ );
+
+VOID
+GetRootporttoSetResourcesforTbt (
+ IN UINTN RpIndex,
+ OUT UINT8 *RsvdExtraBusNum,
+ OUT UINT16 *RsvdPcieMegaMem,
+ OUT UINT8 *PcieMemAddrRngMax,
+ OUT UINT16 *RsvdPciePMegaMem,
+ OUT UINT8 *PciePMemAddrRngMax,
+ OUT BOOLEAN *SetResourceforTbt
+ );
+
+#endif \ No newline at end of file
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h
new file mode 100644
index 0000000000..9b7ff25c55
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Ppi/PeiTbtPolicy.h
@@ -0,0 +1,36 @@
+/** @file
+TBT PEI Policy
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PEI_TBT_POLICY_H_
+#define _PEI_TBT_POLICY_H_
+
+#include <TbtPolicyCommonDefinition.h>
+
+#pragma pack(push, 1)
+
+#define PEI_TBT_POLICY_REVISION 1
+
+/**
+ TBT PEI configuration\n
+ <b>Revision 1</b>:
+ - Initial version.
+**/
+typedef struct _PEI_TBT_POLICY {
+ DTBT_COMMON_CONFIG DTbtCommonConfig; ///< dTbt Common Configuration
+ DTBT_CONTROLLER_CONFIG DTbtControllerConfig; ///< dTbt Controller Configuration
+} PEI_TBT_POLICY;
+
+#pragma pack(pop)
+
+#endif
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h
new file mode 100644
index 0000000000..963a678845
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiDTbtInitLib.h
@@ -0,0 +1,114 @@
+/**@file
+ PEI DTBT Init Dispatch library Header file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef __PEI_DTBT_INIT_LIB_H__
+#define __PEI_DTBT_INIT_LIB_H__
+
+#include <Ppi/PeiTbtPolicy.h>
+
+/**
+ set tPCH25 Timing to 10 ms for DTBT.
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSetTPch25Timing (
+ IN PEI_TBT_POLICY *PeiTbtConfig
+);
+
+/**
+ Do ForcePower for DTBT Controller
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtForcePower (
+ IN PEI_TBT_POLICY *PeiTbtConfig
+);
+
+/**
+ Clear VGA Registers for DTBT.
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtClearVgaRegisters (
+ IN PEI_TBT_POLICY *PeiTbtConfig
+);
+
+/**
+ Exectue Mail box command "Boot On".
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtBootOn (
+ IN PEI_TBT_POLICY *PeiTbtConfig
+);
+
+/**
+ Exectue Mail box command "USB On".
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtUsbOn (
+ IN PEI_TBT_POLICY *PeiTbtConfig
+);
+
+/**
+ Exectue Mail box command "Sx Exit".
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSxExitFlow (
+ IN PEI_TBT_POLICY *PeiTbtConfig
+);
+/**
+ Initialize Thunderbolt(TM)
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval others
+**/
+EFI_STATUS
+EFIAPI
+TbtInit (
+ VOID
+);
+
+#endif \ No newline at end of file
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h
new file mode 100644
index 0000000000..3af3f64377
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Private/Library/PeiTbtCommonInitLib.h
@@ -0,0 +1,47 @@
+/**@file
+ PEI TBT Common Init Dispatch library Header file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef __PEI_TBT_COMMON_INIT_LIB_H__
+#define __PEI_TBT_COMMON_INIT_LIB_H__
+
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/GpioLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TbtCommonLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PchPmcLib.h>
+
+VOID
+TbtSetSxMode(
+IN BOOLEAN Type,
+IN UINT8 Bus,
+IN UINT8 Device,
+IN UINT8 Function,
+IN UINT8 TbtBootOn
+);
+
+VOID
+TbtClearVgaRegisters(
+IN UINTN Segment,
+IN UINTN Bus,
+IN UINTN Device,
+IN UINTN Function
+);
+
+#endif \ No newline at end of file
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h
new file mode 100644
index 0000000000..76f5071d9a
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Protocol/DxeTbtPolicy.h
@@ -0,0 +1,117 @@
+/** @file
+TBT DXE Policy
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _DXE_TBT_POLICY_H_
+#define _DXE_TBT_POLICY_H_
+
+#include <TbtPolicyCommonDefinition.h>
+
+#pragma pack(push, 1)
+
+#define DXE_TBT_POLICY_REVISION 1
+
+//
+// TBT Common Data Structure
+//
+typedef struct _TBT_COMMON_CONFIG{
+ /**
+ TBT Security Level
+ <b>0: SL0 No Security</b>, 1: SL1 User Authorization, 2: SL2 Secure Connect, 3: SL3 Display Port and USB
+ **/
+ UINT32 SecurityMode : 3;
+ /**
+ BIOS W/A for Hot plug of 12V USB devices cause electrical noise on PCH GPIOs
+ <b>0: Disabled</b>, 1: Enabled
+ **/
+ UINT32 Gpio5Filter : 1;
+ /**
+ Send Go2SxNoWake or GoSxWake according to TbtWakeupSupport
+ <b>0: Disabled</b>, 1: Enabled
+ **/
+ UINT32 TbtWakeupSupport : 1;
+ /**
+ SMI TBT enumeration
+ <b>0: Disabled</b>, 1: Enabled
+ **/
+ UINT32 TbtHotSMI : 1;
+ /**
+ Notify PCIe RP after Hot-Plug/Hot-Unplug occurred.
+ <b>0: Disabled</b>, 1: Enabled
+ **/
+ UINT32 TbtHotNotify : 1;
+ /**
+ CLK REQ for all the PCIe device in TBT daisy chain.
+ <b>0: Disabled</b>, 1: Enabled
+ **/
+ UINT32 TbtSetClkReq : 1;
+ /**
+ ASPM setting for all the PCIe device in TBT daisy chain.
+ <b>0: Disabled</b>, 1: L0s, 2: L1, 3: L0sL1
+ **/
+ UINT32 TbtAspm : 2;
+ /**
+ LTR for for all the PCIe device in TBT daisy chain.
+ <b>0: Disabled</b>, 1: Enabled
+ **/
+ UINT32 TbtLtr : 1;
+ /**
+ TBT Dynamic AC/DC L1.
+ <b>0: Disabled</b>, 1: Enabled
+ **/
+ UINT32 TbtAcDcSwitch : 1;
+ /**
+ TBT RTD3 Support.
+ <b>0: Disabled</b>, 1: Enabled
+ **/
+ UINT32 Rtd3Tbt : 1;
+ /**
+ TBT ClkReq for RTD3 Flow.
+ <b>0: Disabled</b>, 1: Enabled
+ **/
+ UINT32 Rtd3TbtClkReq : 1;
+ /**
+ TBT Win10support for Tbt FW execution mode.
+ <b>0: Disabled</b>, 1: Native, 2: Native + RTD3
+ **/
+ UINT32 Win10Support : 2;
+ UINT32 Rsvd0 : 17; ///< Reserved bits
+ UINT16 Rtd3TbtClkReqDelay;
+ UINT16 Rtd3TbtOffDelay;
+} TBT_COMMON_CONFIG;
+
+//
+// dTBT Resource Data Structure
+//
+typedef struct _DTBT_RESOURCE_CONFIG{
+ UINT8 DTbtPcieExtraBusRsvd; ///< Preserve Bus resource for PCIe RP that connect to dTBT Host Router
+ UINT16 DTbtPcieMemRsvd; ///< Preserve MEM resource for PCIe RP that connect to dTBT Host Router
+ UINT8 DTbtPcieMemAddrRngMax; ///< Alignment of Preserve MEM resource for PCIe RP that connect to dTBT Host Router
+ UINT16 DTbtPciePMemRsvd; ///< Preserve PMEM resource for PCIe RP that connect to dTBT Host Router
+ UINT8 DTbtPciePMemAddrRngMax; ///< Alignment of Preserve PMEM resource for PCIe RP that connect to dTBT Host Router
+ UINT8 Reserved[1]; ///< Reserved for DWORD alignment
+} DTBT_RESOURCE_CONFIG;
+
+/**
+ TBT DXE configuration\n
+ <b>Revision 1</b>:
+ - Initial version.
+**/
+typedef struct _DXE_TBT_POLICY_PROTOCOL {
+ TBT_COMMON_CONFIG TbtCommonConfig; ///< Tbt Common Information
+ DTBT_RESOURCE_CONFIG DTbtResourceConfig; ///< dTbt Resource Configuration
+} DXE_TBT_POLICY_PROTOCOL;
+
+#pragma pack(pop)
+
+#endif
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h
new file mode 100644
index 0000000000..c662f162ec
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/Protocol/TbtNvsArea.h
@@ -0,0 +1,48 @@
+/** @file
+ This file defines the TBT NVS Area Protocol.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _TBT_NVS_AREA_H_
+#define _TBT_NVS_AREA_H_
+
+//
+// Platform NVS Area definition
+//
+#include <Acpi\TbtNvsAreaDef.h>
+
+//
+// Includes
+//
+#define TBT_NVS_DEVICE_ENABLE 1
+#define TBT_NVS_DEVICE_DISABLE 0
+
+//
+// Forward reference for pure ANSI compatibility
+//
+typedef struct _TBT_NVS_AREA_PROTOCOL TBT_NVS_AREA_PROTOCOL;
+
+///
+/// Extern the GUID for protocol users.
+///
+extern EFI_GUID gTbtNvsAreaProtocolGuid;
+
+#define TBT_NVS_AREA_REVISION_1 1
+
+//
+// Platform NVS Area Protocol
+//
+typedef struct _TBT_NVS_AREA_PROTOCOL {
+ TBT_NVS_AREA *Area;
+} TBT_NVS_AREA_PROTOCOL;
+
+#endif // _TBT_NVS_AREA_H_
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h
new file mode 100644
index 0000000000..9844935212
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/TbtBoardInfo.h
@@ -0,0 +1,28 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef _TBT_INFO_GUID_H_
+#define _TBT_INFO_GUID_H_
+#include <TbtPolicyCommonDefinition.h>
+
+#pragma pack(1)
+//
+// TBT Info HOB
+//
+typedef struct _TBT_INFO_HOB {
+ EFI_HOB_GUID_TYPE EfiHobGuidType;
+ DTBT_COMMON_CONFIG DTbtCommonConfig; ///< dTbt Common Configuration
+ DTBT_CONTROLLER_CONFIG DTbtControllerConfig; ///< dTbt Controller Configuration
+} TBT_INFO_HOB;
+#pragma pack()
+
+#endif
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h
new file mode 100644
index 0000000000..2033126a25
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Include/TbtPolicyCommonDefinition.h
@@ -0,0 +1,84 @@
+/** @file
+TBT Policy Common definition.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _TBT_POLICY_COMMON_H_
+#define _TBT_POLICY_COMMON_H_
+
+#include <Library/GpioLib.h>
+#include <IndustryStandard/Pci22.h>
+
+#define TYPE_PCIE 0x01
+#define TYPE_PEG 0x02
+
+#pragma pack(push, 1)
+
+//
+// dTBT Force Power GPIO Data Structure
+//
+typedef struct _DTBT_FORCE_POWER_GPIO_CONFIG {
+ UINT8 GpioAccessType; ///< Where the GPIO comes from [a.k.a how to access the GPIO],Where the GPIO comes from. 0: Disabled; 1: PCH, 2: I/O Expander
+ UINT8 Expander; ///< Applicable to GpioAccessType = IoExpander {TCA6424A} type
+ GPIO_PAD GpioPad; ///< GPIO Pad Number
+ BOOLEAN GpioLevel; ///< 0 = Active Low; 1 = Active High
+ UINT8 Reserved[1]; ///< Reserved for DWORD alignment
+} DTBT_FORCE_POWER_GPIO_CONFIG;
+
+//
+// dTBT CIO Plug Event GPIO Data Structure
+//
+typedef struct _DTBT_CIO_PLUG_EVENT_GPIO_CONFIG {
+ GPIO_PAD GpioPad; ///< GPIO Pad Number
+ UINT32 AcpiGpeSignature; ///< AcpiPlatform driver will change the XTBT method to the _Lxx or _Exx that we assign in this item.
+ BOOLEAN AcpiGpeSignaturePorting; ///< 0 = No porting required(for 2-tier GPI GPE event architecture), 1 = Porting required(for 1-tier GPI GPE event architecture)
+ UINT8 Reserved[3]; ///< Reserved for DWORD alignment
+} DTBT_CIO_PLUG_EVENT_GPIO_CONFIG;
+
+//
+// dTBT PCIE Reset GPIO Data Structure
+//
+typedef struct _DTBT_PCIE_RESET_GPIO_CONFIG {
+ GPIO_PAD GpioPad; ///< GPIO Pad Number
+ BOOLEAN GpioLevel; ///< 0 = Active Low; 1 = Active High
+ UINT8 Reserved[3]; ///< Reserved for DWORD alignment
+} DTBT_PCIE_RESET_GPIO_CONFIG;
+
+//
+// dTBT Controller Data Structure
+//
+typedef struct _DTBT_CONTROLLER_CONFIG{
+ UINT8 DTbtControllerEn; ///< Enable/Disable DTbtController.
+ UINT8 Type; ///< 01-Pcie RP, 02- PEG,Reserved. <Specific according to Board Design>
+ UINT8 PcieRpNumber; ///< RP Number/ PEG Port (0,1,2) that connecet to dTBT controller. <Specific according to Board Design>
+ DTBT_FORCE_POWER_GPIO_CONFIG ForcePwrGpio; ///< The GPIO pin that can force dTBT Power On. <Specific according to Board Design>
+ DTBT_CIO_PLUG_EVENT_GPIO_CONFIG CioPlugEventGpio; ///< The GPIO pin that can generate Hot-Plug event. <Specific according to Board Design>
+ DTBT_PCIE_RESET_GPIO_CONFIG PcieRstGpio; ///< The GPIO pin that is use to perform Reset when platform enters to Sx, it is required for platforms where PCI_RST pin connected to Tbt is controlled with GPIO <Specific according to Board Design>
+ UINT8 Reserved[1]; ///< Reserved for DWORD alignment
+} DTBT_CONTROLLER_CONFIG;
+
+//
+// dTBT Controller Data Structure
+//
+typedef struct _DTBT_COMMON_CONFIG{
+ UINT8 TbtBootOn; ///< Send BootOn Mailbox command when TbtBootOn is enabled.
+ UINT8 TbtUsbOn; ///< Send UsbOn Mailbox command when TbtBootOn is enabled.
+ UINT8 Gpio3ForcePwr; ///< Force GPIO to power on or not
+ UINT16 Gpio3ForcePwrDly; ///< The delay time after do ForcePwr
+ BOOLEAN DTbtSharedGpioConfiguration; ///< Multiple DTBT controllers share the same GPIO pin <Specific according to Board Design>
+ BOOLEAN PcieRstSupport; ///< 0 = Not Support, 1 = Supported. it is required for platforms where PCI_RST pin connected to Tbt is controlled with GPIO
+ UINT8 Reserved[1]; ///< Reserved for DWORD alignment
+} DTBT_COMMON_CONFIG;
+
+#pragma pack(pop)
+
+#endif
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c
new file mode 100644
index 0000000000..0e58bc8294
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c
@@ -0,0 +1,167 @@
+/** @file
+ This file is DxeTbtPolicyLib library.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <DxeTbtPolicyLibrary.h>
+#include <TbtBoardInfo.h>
+#include <Protocol/DxeTbtPolicy.h>
+#include <Guid/HobList.h>
+#include <Library/HobLib.h>
+
+
+/**
+Update Tbt Policy Callback
+Need to add PCDs for setup options
+**/
+
+VOID
+EFIAPI
+UpdateTbtPolicyCallback (
+ VOID
+ )
+{
+
+ EFI_STATUS Status;
+ DXE_TBT_POLICY_PROTOCOL *DxeTbtConfig;
+
+ DxeTbtConfig = NULL;
+ Status = EFI_NOT_FOUND;
+ DEBUG ((DEBUG_INFO, "UpdateTbtPolicyCallback\n"));
+
+ Status = gBS->LocateProtocol (
+ &gDxeTbtPolicyProtocolGuid,
+ NULL,
+ (VOID **) &DxeTbtConfig
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, " gDxeTbtPolicyProtocolGuid Not installed!!!\n"));
+ } else {
+ DxeTbtConfig->DTbtResourceConfig.DTbtPcieExtraBusRsvd = PcdGet8 (PcdDTbtPcieExtraBusRsvd);
+ DxeTbtConfig->DTbtResourceConfig.DTbtPcieMemRsvd = PcdGet16 (PcdDTbtPcieMemRsvd);
+ DxeTbtConfig->DTbtResourceConfig.DTbtPcieMemAddrRngMax = PcdGet8 (PcdDTbtPcieMemAddrRngMax);
+ DxeTbtConfig->DTbtResourceConfig.DTbtPciePMemRsvd = PcdGet16 (PcdDTbtPciePMemRsvd);
+ DxeTbtConfig->DTbtResourceConfig.DTbtPciePMemAddrRngMax = PcdGet8 (PcdDTbtPciePMemAddrRngMax);
+
+ DxeTbtConfig->TbtCommonConfig.TbtAspm = PcdGet8 (PcdDTbtAspm);
+ DxeTbtConfig->TbtCommonConfig.TbtHotNotify = PcdGet8 (PcdDTbtHotNotify);
+ DxeTbtConfig->TbtCommonConfig.TbtHotSMI = PcdGet8 (PcdDTbtHotSMI);
+ DxeTbtConfig->TbtCommonConfig.TbtSetClkReq = PcdGet8 (PcdDTbtSetClkReq);
+ DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport = PcdGet8 (PcdDTbtWakeupSupport);
+ DxeTbtConfig->TbtCommonConfig.SecurityMode = PcdGet8 (PcdDTbtSecurityMode);
+
+ DxeTbtConfig->TbtCommonConfig.Gpio5Filter = PcdGet8 (PcdDTbtGpio5Filter);
+ DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch = PcdGet8 (PcdDTbtAcDcSwitch);
+
+ DxeTbtConfig->TbtCommonConfig.Rtd3Tbt = PcdGet8 (PcdRtd3Tbt);
+ DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay = PcdGet16 (PcdRtd3TbtOffDelay);
+ DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq = PcdGet8 (PcdRtd3TbtClkReq);
+ DxeTbtConfig->TbtCommonConfig.Win10Support = PcdGet8 (PcdDTbtWin10Support);
+ }
+
+ return;
+}
+
+/**
+ Print DXE TBT Policy
+**/
+VOID
+TbtPrintDxePolicyConfig (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ DXE_TBT_POLICY_PROTOCOL *DxeTbtConfig;
+
+ DEBUG ((DEBUG_INFO, "TbtPrintDxePolicyConfig Start\n"));
+
+ DxeTbtConfig = NULL;
+ Status = EFI_NOT_FOUND;
+ Status = gBS->LocateProtocol (
+ &gDxeTbtPolicyProtocolGuid,
+ NULL,
+ (VOID **) &DxeTbtConfig
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, " gDxeTbtPolicyProtocolGuid Not installed!!!\n"));
+ }
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Print DTBT Policy
+ //
+ DEBUG ((DEBUG_ERROR, " ========================= DXE TBT POLICY ========================= \n"));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig.DTbtPcieExtraBusRsvd = %x\n", DxeTbtConfig->DTbtResourceConfig.DTbtPcieExtraBusRsvd));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig.DTbtPcieMemRsvd = %x\n", DxeTbtConfig->DTbtResourceConfig.DTbtPcieMemRsvd));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig.DTbtPcieMemAddrRngMax = %x\n", DxeTbtConfig->DTbtResourceConfig.DTbtPcieMemAddrRngMax));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig.DTbtPciePMemRsvd = %x\n", DxeTbtConfig->DTbtResourceConfig.DTbtPciePMemRsvd));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig.DTbtPciePMemAddrRngMax = %x\n", DxeTbtConfig->DTbtResourceConfig.DTbtPciePMemAddrRngMax));
+
+
+ //
+ // Print TBT Common Policy
+ //
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtAspm = %x\n", DxeTbtConfig->TbtCommonConfig.TbtAspm));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtHotNotify = %x\n", DxeTbtConfig->TbtCommonConfig.TbtHotNotify));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtHotSMI = %x\n", DxeTbtConfig->TbtCommonConfig.TbtHotSMI));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtLtr = %x\n", DxeTbtConfig->TbtCommonConfig.TbtLtr));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtSetClkReq = %x\n", DxeTbtConfig->TbtCommonConfig.TbtSetClkReq));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport = %x\n", DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.SecurityMode = %x\n", DxeTbtConfig->TbtCommonConfig.SecurityMode));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Gpio5Filter = %x\n", DxeTbtConfig->TbtCommonConfig.Gpio5Filter));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch = %x\n", DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3Tbt = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3Tbt));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Win10Support = %x\n", DxeTbtConfig->TbtCommonConfig.Win10Support));
+
+ return;
+}
+
+/**
+ Install Tbt Policy
+
+ @param[in] ImageHandle Image handle of this driver.
+
+ @retval EFI_SUCCESS The policy is installed.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallTbtPolicy (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ DXE_TBT_POLICY_PROTOCOL *DxeTbtPolicy;
+
+ DEBUG ((DEBUG_INFO, "Install DXE TBT Policy\n"));
+
+ DxeTbtPolicy = NULL;
+ //Alloc memory for DxeTbtPolicy
+ DxeTbtPolicy = (DXE_TBT_POLICY_PROTOCOL *) AllocateZeroPool (sizeof (DXE_TBT_POLICY_PROTOCOL));
+ if (DxeTbtPolicy == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gDxeTbtPolicyProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ DxeTbtPolicy
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Install Tbt Secure Boot List protocol failed\n"));
+ }
+ return Status;
+}
+
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
new file mode 100644
index 0000000000..38f30d1f11
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
@@ -0,0 +1,73 @@
+## @file
+# Component description file for Tbt functionality
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeTbtPolicyLib
+FILE_GUID = 28ABF346-4E52-4BD3-b1FF-63BA7563C9D4
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxeTbtPolicyLib
+
+
+[LibraryClasses]
+BaseMemoryLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+PostCodeLib
+HobLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ KabylakeOpenBoardPkg/OpenBoardPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+gBoardModuleTokenSpaceGuid.PcdDTbtSecurityMode ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtGpio5Filter ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtAspm ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3Tbt ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtWin10Support ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReqDelay ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtOffDelay ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieExtraBusRsvd ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemRsvd ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieRpNumber ## CONSUMES
+
+
+[Sources]
+DxeTbtPolicyLib.c
+
+
+[Guids]
+gEfiEndOfDxeEventGroupGuid
+#gSetupVariableGuid
+gTbtInfoHobGuid
+
+[Protocols]
+gDxeTbtPolicyProtocolGuid
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h
new file mode 100644
index 0000000000..e0f749ec53
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLibrary.h
@@ -0,0 +1,28 @@
+/** @file
+ Header file for the DxeTBTPolicy library.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef _DXE_TBT_POLICY_LIBRARY_H_
+#define _DXE_TBT_POLICY_LIBRARY_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <ConfigBlock.h>
+#include <Library/ConfigBlockLib.h>
+#include <Guid/EventGroup.h>
+
+#endif // _DXE_TBT_POLICY_LIBRARY_H_
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c
new file mode 100644
index 0000000000..4f2690ca56
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c
@@ -0,0 +1,321 @@
+/** @file
+ PeiTbtInit library implementition with empty functions.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/TbtCommonLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/GpioLib.h>
+
+
+/**
+ Selects the proper TBT Root port to assign resources
+ based on the user input value
+
+ @param[in] SetupData Pointer to Setup data
+
+ @retval TbtSelectorChosen Rootport number.
+**/
+VOID
+GetRootporttoSetResourcesforTbt (
+ IN UINTN RpIndex,
+ OUT UINT8 *RsvdExtraBusNum,
+ OUT UINT16 *RsvdPcieMegaMem,
+ OUT UINT8 *PcieMemAddrRngMax,
+ OUT UINT16 *RsvdPciePMegaMem,
+ OUT UINT8 *PciePMemAddrRngMax,
+ OUT BOOLEAN *SetResourceforTbt
+ )
+{
+ UINTN TbtRpNumber;
+ TbtRpNumber = (UINTN) PcdGet8 (PcdDTbtPcieRpNumber);
+
+ if (RpIndex == (TbtRpNumber - 1)) {
+ *RsvdExtraBusNum = PcdGet8 (PcdDTbtPcieExtraBusRsvd);
+ *RsvdPcieMegaMem = PcdGet16 (PcdDTbtPcieMemRsvd);
+ *PcieMemAddrRngMax = PcdGet8 (PcdDTbtPcieMemAddrRngMax);
+ *RsvdPciePMegaMem = PcdGet16 (PcdDTbtPciePMemRsvd);
+ *PciePMemAddrRngMax = PcdGet8 (PcdDTbtPciePMemAddrRngMax);
+ *SetResourceforTbt = TRUE;
+ }
+ else {
+ *SetResourceforTbt = FALSE;
+ }
+ }
+
+/**
+ Internal function to Wait for Tbt2PcieDone Bit.to Set or clear
+ @param[in] CommandOffsetAddress Tbt2Pcie Register Address
+ @param[in] TimeOut Time out with 100 ms garnularity
+ @param[in] Tbt2PcieDone Wait condition (wait for Bit to Clear/Set)
+ @param[out] *Tbt2PcieValue Function Register value
+**/
+BOOLEAN
+InternalWaitforCommandCompletion(
+ IN UINT64 CommandOffsetAddress,
+ IN UINT32 TimeOut,
+ IN BOOLEAN Tbt2PcieDone,
+ OUT UINT32 *Tbt2PcieValue
+ )
+{
+ BOOLEAN ReturnFlag;
+ UINT32 Tbt2PcieCheck;
+
+ ReturnFlag = FALSE;
+ while (TimeOut-- > 0) {
+ *Tbt2PcieValue = PciSegmentRead32 (CommandOffsetAddress);
+
+ if (0xFFFFFFFF == *Tbt2PcieValue ) {
+ //
+ // Device is not here return now
+ //
+ ReturnFlag = FALSE;
+ break;
+ }
+
+ if(Tbt2PcieDone) {
+ Tbt2PcieCheck = *Tbt2PcieValue & TBT2PCIE_DON_R;
+ } else {
+ Tbt2PcieCheck = !(*Tbt2PcieValue & TBT2PCIE_DON_R);
+ }
+
+ if (Tbt2PcieCheck) {
+ ReturnFlag = TRUE;
+ break;
+ }
+
+ MicroSecondDelay(TBT_MAIL_BOX_DELAY);
+ }
+ return ReturnFlag;
+}
+/**
+ Get Security Level.
+ @param[in] Bus Bus number Host Router (DTBT)
+ @param[in] Device Device number for Host Router (DTBT)
+ @param[in] Function Function number for Host Router (DTBT)
+ @param[in] Command Command for Host Router (DTBT)
+ @param[in] Timeout Time out with 100 ms garnularity
+**/
+UINT8
+GetSecLevel (
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT8 Command,
+ IN UINT32 Timeout
+ )
+{
+ UINT64 Pcie2Tbt;
+ UINT64 Tbt2Pcie;
+ UINT32 RegisterValue;
+ UINT8 ReturnFlag;
+
+ ReturnFlag = 0xFF;
+
+ DEBUG ((DEBUG_INFO, "GetSecLevel() \n"));
+
+ GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+ GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+ PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
+
+ if(InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue)) {
+ ReturnFlag = (UINT8) (0xFF & (RegisterValue >> 8));
+ }
+
+ PciSegmentWrite32 (Pcie2Tbt, 0);
+
+ InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE, &RegisterValue);
+ DEBUG ((DEBUG_INFO, "Security Level configured to %x \n", ReturnFlag));
+
+ return ReturnFlag;
+}
+
+/**
+ Set Security Level.
+ @param[in] Data Security State
+ @param[in] Bus Bus number for Host Router (DTBT)
+ @param[in] Device Device number for Host Router (DTBT)
+ @param[in] Function Function number for Host Router (DTBT)
+ @param[in] Command Command for Host Router (DTBT)
+ @param[in] Timeout Time out with 100 ms garnularity
+**/
+BOOLEAN
+SetSecLevel (
+ IN UINT8 Data,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT8 Command,
+ IN UINT32 Timeout
+ )
+{
+ UINT64 Pcie2Tbt;
+ UINT64 Tbt2Pcie;
+ UINT32 RegisterValue;
+ BOOLEAN ReturnFlag;
+
+ ReturnFlag = FALSE;
+
+ DEBUG ((DEBUG_INFO, "SetSecLevel() \n"));
+
+ GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+ GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+ PciSegmentWrite32 (Pcie2Tbt, (Data << 8) | Command | PCIE2TBT_VLD_B);
+
+ ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
+ DEBUG ((DEBUG_INFO, "RegisterValue %x \n", RegisterValue));
+ PciSegmentWrite32 (Pcie2Tbt, 0);
+
+ InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE, &RegisterValue);
+ DEBUG ((DEBUG_INFO, "Return value %x \n", ReturnFlag));
+ return ReturnFlag;
+}
+
+/**
+Based on the Security Mode Selection, BIOS drives FORCE_PWR.
+
+@param[in] GpioNumber
+@param[in] Value
+**/
+VOID
+ForceDtbtPower(
+ IN UINT8 GpioAccessType,
+ IN UINT8 Expander,
+ IN UINT32 GpioNumber,
+ IN BOOLEAN Value
+)
+{
+ if (GpioAccessType == 0x01) {
+ // PCH
+ GpioSetOutputValue (GpioNumber, (UINT32)Value);
+ } else if (GpioAccessType == 0x02) {
+ // IoExpander {TCA6424A}
+ GpioExpSetOutput (Expander, (UINT8)GpioNumber, (UINT8)Value);
+ }
+}
+
+/**
+Execute TBT Mail Box Command
+
+@param[in] Command TBT Command
+@param[in] Bus Bus number for Host Router (DTBT)
+@param[in] Device Device number for Host Router (DTBT)
+@param[in] Function Function number for Host Router (DTBT)
+@param[in] Timeout Time out with 100 ms garnularity
+@Retval true if command executes succesfully
+**/
+BOOLEAN
+TbtSetPcie2TbtCommand(
+ IN UINT8 Command,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT32 Timeout
+)
+{
+ UINT64 Pcie2Tbt;
+ UINT64 Tbt2Pcie;
+ UINT32 RegisterValue;
+ BOOLEAN ReturnFlag;
+
+ GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+ GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+ PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
+
+ ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
+
+ PciSegmentWrite32(Pcie2Tbt, 0);
+
+ return ReturnFlag;
+}
+/**
+ Get Pch/Peg Pcie Root Port Device and Function Number for TBT by Root Port physical Number
+
+ @param[in] RpNumber Root port physical number. (0-based)
+ @param[out] RpDev Return corresponding root port device number.
+ @param[out] RpFun Return corresponding root port function number.
+
+ @retval EFI_SUCCESS Root port device and function is retrieved
+ @retval EFI_INVALID_PARAMETER If Invalid Root Port Number or TYPE is Passed
+**/
+EFI_STATUS
+EFIAPI
+GetDTbtRpDevFun (
+ IN BOOLEAN Type,
+ IN UINTN RpNumber,
+ OUT UINTN *RpDev,
+ OUT UINTN *RpFunc
+ )
+{
+ EFI_STATUS Status;
+ UINTN TbtRpDev;
+ UINTN TbtRpFunc;
+
+ Status = EFI_INVALID_PARAMETER; // Update the Status to EFI_SUCCESS if valid input found.
+ //
+ // CNL PCH-H can support up to 24 root ports. PEG0,PEG1 and PEG2 will be
+ // with device number 0x1 and Function number 0,1 and 2 respectively.
+ //
+ if (Type == DTBT_TYPE_PEG)
+ {
+ //
+ // PEG Rootport
+ //
+ if (RpNumber <= 2) {
+ *RpDev = 0x01;
+ *RpFunc = RpNumber;
+ Status = EFI_SUCCESS;
+ }
+ }
+ if (Type == DTBT_TYPE_PCH)
+ {
+ //
+ // PCH Rootport
+ //
+ if (RpNumber <= 23) {
+ Status = GetPchPcieRpDevFun (RpNumber, &TbtRpDev, &TbtRpFunc);
+ *RpDev = TbtRpDev;
+ *RpFunc = TbtRpFunc;
+ }
+ }
+
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+BOOLEAN
+IsTbtHostRouter (
+ IN UINT16 DeviceID
+ )
+{
+ switch (DeviceID) {
+ case AR_HR_2C:
+ case AR_HR_4C:
+ case AR_HR_LP:
+ case AR_HR_C0_2C:
+ case AR_HR_C0_4C:
+ case TR_HR_2C:
+ case TR_HR_4C:
+ return TRUE;
+ }
+
+ return FALSE;
+} // IsTbtHostRouter
+
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
new file mode 100644
index 0000000000..ec8a31421e
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
@@ -0,0 +1,69 @@
+### @file
+# Component information file for Tbt common library
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = TbtCommonLib
+ FILE_GUID = 5F03614E-CB56-40B1-9989-A09E25BBA294
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = TbtCommonLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[LibraryClasses]
+ DebugLib
+ PchPcieRpLib
+ PciSegmentLib
+ TimerLib
+ BaseLib
+ GpioLib
+ GpioExpanderLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ KabylakeOpenBoardPkg/OpenBoardPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gBoardModuleTokenSpaceGuid.PcdDTbtSecurityMode ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtGpio5Filter ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtAspm ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3Tbt ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtWin10Support ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReqDelay ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtOffDelay ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieExtraBusRsvd ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemRsvd ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieRpNumber
+
+[Sources]
+ TbtCommonLib.c
+
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c
new file mode 100644
index 0000000000..d0e3229db5
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c
@@ -0,0 +1,210 @@
+/** @file
+ This file is PeiTbtPolicyLib library.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Library/PeiServicesLib.h>
+#include <Library/GpioLib.h>
+#include <PiPei.h>
+#include <PeiTbtPolicyLibrary.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <Base.h>
+#include <GpioConfig.h>
+
+/**
+ Update PEI TBT Policy Callback
+**/
+VOID
+EFIAPI
+UpdatePeiTbtPolicy (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ PEI_TBT_POLICY *PeiTbtConfig;
+
+ PeiTbtConfig = NULL;
+ Status = EFI_NOT_FOUND;
+
+ DEBUG ((DEBUG_INFO, "UpdatePeiTbtPolicy \n"));
+
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (VOID **) &VariableServices
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PeiServicesLocatePpi (
+ &gPeiTbtPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &PeiTbtConfig
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+ }
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update DTBT Policy
+ //
+ PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn = PcdGet8 (PcdDTbtControllerEn);
+ if (PcdGet8 (PcdDTbtControllerType) == TYPE_PEG)
+ {
+ PeiTbtConfig-> DTbtControllerConfig.Type = (UINT8) TYPE_PEG;
+ PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber = 1; // PEG RP 1 (Function no. 0)
+ }
+ else {
+ PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber = PcdGet8 (PcdDTbtPcieRpNumber);
+ PeiTbtConfig-> DTbtControllerConfig.Type = PcdGet8 (PcdDTbtControllerType);
+ }
+ PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad = (GPIO_PAD) PcdGet32 (PcdDTbtCioPlugEventGpioPad);
+ if (GpioCheckFor2Tier(PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad)) {
+ PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = 0;
+ PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = SIGNATURE_32('X', 'T', 'B', 'T');
+ }
+ else {
+ PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = 1;
+ //
+ // Update Signature based on platform GPIO.
+ //
+ PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = SIGNATURE_32('X', 'T', 'B', 'T');
+ }
+ PeiTbtConfig->DTbtCommonConfig.TbtBootOn = PcdGet8 (PcdDTbtBootOn);
+ PeiTbtConfig->DTbtCommonConfig.TbtUsbOn = PcdGet8 (PcdDTbtUsbOn);
+ PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr = PcdGet8 (PcdDTbtGpio3ForcePwr);
+ PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly = PcdGet16 (PcdDTbtGpio3ForcePwrDly);
+
+ return;
+}
+
+/**
+ Print PEI TBT Policy
+**/
+VOID
+EFIAPI
+TbtPrintPeiPolicyConfig (
+ VOID
+ )
+{
+ DEBUG_CODE_BEGIN ();
+ EFI_STATUS Status;
+ PEI_TBT_POLICY *PeiTbtConfig;
+
+ PeiTbtConfig = NULL;
+ Status = EFI_NOT_FOUND;
+ DEBUG ((DEBUG_INFO, "TbtPrintPolicyConfig Start\n"));
+
+ Status = PeiServicesLocatePpi (
+ &gPeiTbtPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &PeiTbtConfig
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+ }
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Print DTBT Policy
+ //
+ DEBUG ((DEBUG_INFO, "\n------------------------ TBT Policy (PEI) Print BEGIN -----------------\n"));
+ DEBUG ((DEBUG_INFO, "Revision : 0x%x\n", PEI_TBT_POLICY_REVISION));
+ DEBUG ((DEBUG_INFO, "------------------------ PEI_TBT_CONFIG -----------------\n"));
+ DEBUG ((DEBUG_INFO, " Revision : %d\n", PEI_TBT_POLICY_REVISION));
+
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.DTbtControllerEn = %x\n", PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.Type = %x\n", PeiTbtConfig-> DTbtControllerConfig.Type));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.PcieRpNumber = %x\n", PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.ForcePwrGpio.GpioPad = %x\n", PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.ForcePwrGpio.GpioLevel = %x\n", PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.PcieRstGpio.GpioPad = %x\n", PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioPad));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.PcieRstGpio.GpioLevel = %x\n", PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioLevel));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad = %x\n", PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.GpioPad));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = %x\n", PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = %x\n", PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting));
+
+
+ //
+ // Print DTBT Common Policy
+ //
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.TbtBootOn = %x\n", PeiTbtConfig->DTbtCommonConfig.TbtBootOn));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.TbtUsbOn = %x\n", PeiTbtConfig->DTbtCommonConfig.TbtUsbOn));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr = %x\n", PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly = %x\n", PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration = %x\n", PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.PcieRstSupport = %x\n", PeiTbtConfig->DTbtCommonConfig.PcieRstSupport));
+
+ DEBUG ((DEBUG_INFO, "\n------------------------ TBT Policy (PEI) Print END -----------------\n"));
+ DEBUG_CODE_END ();
+
+ return;
+}
+
+/**
+ Install Tbt Policy
+
+ @retval EFI_SUCCESS The policy is installed.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallPeiTbtPolicy (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *PeiTbtPolicyPpiDesc;
+ PEI_TBT_POLICY *PeiTbtConfig;
+
+ DEBUG ((DEBUG_INFO, "Install PEI TBT Policy\n"));
+
+ PeiTbtConfig = NULL;
+
+ //
+ // Allocate memory for PeiTbtPolicyPpiDesc
+ //
+ PeiTbtPolicyPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+ ASSERT (PeiTbtPolicyPpiDesc != NULL);
+ if (PeiTbtPolicyPpiDesc == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Allocate memory and initialize all default to zero for PeiTbtPolicy
+ //
+ PeiTbtConfig = (PEI_TBT_POLICY *) AllocateZeroPool (sizeof (PEI_TBT_POLICY));
+ ASSERT (PeiTbtConfig != NULL);
+ if (PeiTbtConfig == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize PPI
+ //
+ PeiTbtPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ PeiTbtPolicyPpiDesc->Guid = &gPeiTbtPolicyPpiGuid;
+ PeiTbtPolicyPpiDesc->Ppi = PeiTbtConfig;
+
+ Status = PeiServicesInstallPpi (PeiTbtPolicyPpiDesc);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Install PEI TBT Policy failed\n"));
+ }
+ return Status;
+}
+
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
new file mode 100644
index 0000000000..fa88e97b8f
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
@@ -0,0 +1,62 @@
+## @file
+# Component description file for Tbt policy
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiTbtPolicyLib
+FILE_GUID = 4A95FDBB-2535-49eb-9A79-D56D24257106
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PeiTbtPolicyLib
+
+
+[LibraryClasses]
+BaseMemoryLib
+PeiServicesLib
+PeiServicesTablePointerLib
+MemoryAllocationLib
+DebugLib
+PostCodeLib
+HobLib
+GpioLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ KabylakeOpenBoardPkg/OpenBoardPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+ IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Pcd]
+gBoardModuleTokenSpaceGuid.PcdDTbtControllerEn ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtControllerType ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieRpNumber ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtBootOn ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtUsbOn ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtGpio3ForcePwr ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtGpio3ForcePwrDly ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad ## CONSUMES
+
+[Sources]
+PeiTbtPolicyLib.c
+
+[Guids]
+gTbtInfoHobGuid
+
+[Ppis]
+gEfiPeiReadOnlyVariable2PpiGuid
+gPeiTbtPolicyPpiGuid
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h
new file mode 100644
index 0000000000..16ac667b1c
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLibrary.h
@@ -0,0 +1,23 @@
+/** @file
+ Header file for the PeiTBTPolicy library.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef _PEI_TBT_POLICY_LIBRARY_H_
+#define _PEI_TBT_POLICY_LIBRARY_H_
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#endif // _PEI_TBT_POLICY_LIBRARY_H_
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c
new file mode 100644
index 0000000000..4521bff957
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c
@@ -0,0 +1,572 @@
+/**@file
+ Thunderbolt(TM) Pei Library
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklLp.h>
+#include <GpioPinsSklH.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/MmPciLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/GpioExpanderLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+
+#include <Base.h>
+#include <Library/TbtCommonLib.h>
+#include <TbtBoardInfo.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PeiTbtPolicyLib.h>
+#include <Library/PchPmcLib.h>
+#include <Private/Library/PeiDTbtInitLib.h>
+
+/**
+Is host router (For dTBT) or End Point (For iTBT) present before sleep
+
+@param[in] ControllerType - DTBT_CONTROLLER or ITBT_CONTROLLER
+@param[in] Controller - Controller begin offset of CMOS
+
+@Retval TRUE There is a TBT HostRouter presented before sleep
+@Retval FALSE There is no TBT HostRouter presented before sleep
+
+BOOLEAN
+IsHostRouterPresentBeforeSleep(
+IN UINT8 ControllerType,
+IN UINT8 Controller
+)
+{
+ UINT8 SavedState;
+
+ SavedState = (UINT8)GetTbtHostRouterStatus();
+ if (ControllerType == DTBT_CONTROLLER){
+ return ((SavedState & (DTBT_SAVE_STATE_OFFSET << Controller)) == (DTBT_SAVE_STATE_OFFSET << Controller));
+ } else {
+ if (ControllerType == ITBT_CONTROLLER) {
+ return ((SavedState & (ITBT_SAVE_STATE_OFFSET << Controller)) == (ITBT_SAVE_STATE_OFFSET << Controller));
+ }
+ }
+ return 0;
+}
+**/
+
+/**
+Execute TBT PCIE2TBT_SX_EXIT_TBT_CONNECTED Mail Box Command for S4 mode with PreBootAclEnable
+
+@param[in] Bus Bus number for Host Router (DTBT)
+@param[in] Device Device number for Host Router (DTBT)
+@param[in] Function Function number for Host Router (DTBT)
+@param[in] Timeout Time out with 100 ms garnularity
+@Retval true if command executes succesfully
+**/
+BOOLEAN
+TbtSetPcie2TbtSxExitCommandWithPreBootAclEnable(
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT32 Timeout
+)
+{
+ UINT64 Pcie2Tbt;
+ UINT64 Tbt2Pcie;
+ UINT32 RegisterValue;
+ BOOLEAN ReturnFlag;
+ UINT32 Command;
+
+ GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+ GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+// If PreBootAcl is Enable, we need to enable DATA bit while sending SX EXIT MAIL BOX Command
+ Command = (1 << 8) | PCIE2TBT_SX_EXIT_TBT_CONNECTED;
+ PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
+
+ ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
+
+ PciSegmentWrite32(Pcie2Tbt, 0);
+
+ return ReturnFlag;
+}
+
+/**
+Set the Sleep Mode if the HR is up.
+@param[in] Bus Bus number for Host Router (DTBT)
+@param[in] Device Device number for Host Router (DTBT)
+@param[in] Function Function number for Host Router (DTBT)
+**/
+VOID
+TbtSetSxMode(
+IN UINT8 Bus,
+IN UINT8 Device,
+IN UINT8 Function,
+IN UINT8 TbtBootOn
+)
+{
+ UINT64 TbtUsDevId;
+ UINT64 Tbt2Pcie;
+ UINT32 RegVal;
+ UINT32 MaxLoopCount;
+ UINTN Delay;
+ UINT8 RetCode;
+ EFI_BOOT_MODE BootMode;
+ EFI_STATUS Status;
+
+ TbtUsDevId = PCI_SEGMENT_LIB_ADDRESS(0, Bus, Device, Function, 0);
+ GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+
+ MaxLoopCount = TBT_5S_TIMEOUT; // Wait 5 sec
+ Delay = 100 * 1000;
+ RetCode = 0x62;
+
+ Status = PeiServicesGetBootMode(&BootMode);
+ ASSERT_EFI_ERROR(Status);
+
+ if ((BootMode == BOOT_ON_S4_RESUME) && (TbtBootOn == 2)) {
+ MaxLoopCount = TBT_3S_TIMEOUT;
+ if (!TbtSetPcie2TbtSxExitCommandWithPreBootAclEnable(Bus, Device, Function, MaxLoopCount)) {
+ //
+ // Nothing to wait, HR is not responsive
+ //
+ return;
+ }
+ }
+ else {
+ if (!TbtSetPcie2TbtCommand(PCIE2TBT_SX_EXIT_TBT_CONNECTED, Bus, Device, Function, MaxLoopCount)) {
+ //
+ // Nothing to wait, HR is not responsive
+ //
+ return;
+ }
+ }
+
+ DEBUG((DEBUG_INFO, "Wait for Dev ID != 0xFF\n"));
+
+ while (MaxLoopCount-- > 0) {
+ //
+ // Check what HR still here
+ //
+ RegVal = PciSegmentRead32(Tbt2Pcie);
+ if (0xFFFFFFFF == RegVal) {
+ RetCode = 0x6F;
+ break;
+ }
+ //
+ // Check completion of TBT link
+ //
+ RegVal = PciSegmentRead32(TbtUsDevId);
+ if (0xFFFFFFFF != RegVal) {
+ RetCode = 0x61;
+ break;
+ }
+
+ MicroSecondDelay(Delay);
+ }
+
+ DEBUG((DEBUG_INFO, "Return code = 0x%x\n", RetCode));
+}
+/**
+ set tPCH25 Timing to 10 ms for DTBT.
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSetTPch25Timing (
+ IN PEI_TBT_POLICY *PeiTbtConfig
+)
+{
+ DEBUG ((DEBUG_INFO, "DTbtSetTPch25Timing call Inside\n"));
+ UINT32 PchPwrmBase;
+
+ //
+ //During boot, reboot and wake tPCH25 Timing should be set to 10 ms
+ //
+ PchPwrmBaseGet (&PchPwrmBase);
+ MmioOr32 (
+ (UINTN) (PchPwrmBase + R_PCH_PWRM_CFG),
+ (BIT0 | BIT1)
+ );
+
+ DEBUG((DEBUG_INFO, "DTbtSetTPch25Timing call Return\n"));
+ return EFI_SUCCESS;
+}
+
+/**
+ Do ForcePower for DTBT Controller
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtForcePower (
+ IN PEI_TBT_POLICY *PeiTbtConfig
+)
+{
+
+ DEBUG ((DEBUG_INFO, "DTbtForcePower call Inside\n"));
+
+ if (PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr) {
+ DEBUG((DEBUG_INFO, "ForcePwrGpio.GpioPad = %x \n", PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad));
+ ForceDtbtPower(PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioAccessType,PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.Expander, PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad, PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel);
+ DEBUG((DEBUG_INFO, "ForceDtbtPower asserted \n"));
+ MicroSecondDelay(PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly * 1000);
+ DEBUG((DEBUG_INFO, "Delay after ForceDtbtPower = 0x%x ms \n", PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly));
+ }
+
+ DEBUG ((DEBUG_INFO, "DTbtForcePower call Return\n"));
+ return EFI_SUCCESS;
+}
+
+/**
+ Clear VGA Registers for DTBT.
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtClearVgaRegisters (
+ IN PEI_TBT_POLICY *PeiTbtConfig
+)
+{
+ UINTN RpDev;
+ UINTN RpFunc;
+ EFI_STATUS Status;
+ UINT64 BridngeBaseAddress;
+ UINT16 Data16;
+
+ DEBUG ((DEBUG_INFO, "DTbtClearVgaRegisters call Inside\n"));
+
+ Status = EFI_SUCCESS;
+
+ Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+ ASSERT_EFI_ERROR(Status);
+ //
+ // VGA Enable and VGA 16-bit decode registers of Bridge control register of Root port where
+ // Host router resides should be cleaned
+ //
+
+ BridngeBaseAddress = PCI_SEGMENT_LIB_ADDRESS(0, 0, (UINT32)RpDev, (UINT32)RpFunc, 0);
+ Data16 = PciSegmentRead16(BridngeBaseAddress + PCI_BRIDGE_CONTROL_REGISTER_OFFSET);
+ Data16 &= (~(EFI_PCI_BRIDGE_CONTROL_VGA | EFI_PCI_BRIDGE_CONTROL_VGA_16));
+ PciSegmentWrite16(BridngeBaseAddress + PCI_BRIDGE_CONTROL_REGISTER_OFFSET, Data16);
+
+ DEBUG ((DEBUG_INFO, "DTbtClearVgaRegisters call Return\n"));
+ return Status;
+}
+
+/**
+ Exectue Mail box command "Boot On".
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtBootOn(
+ IN PEI_TBT_POLICY *PeiTbtConfig
+)
+{
+ EFI_STATUS Status;
+ UINT32 OrgBusNumberConfiguration;
+ UINTN RpDev;
+ UINTN RpFunc;
+
+ DEBUG((DEBUG_INFO, "DTbtBootOn call Inside\n"));
+
+ Status = EFI_SUCCESS;
+
+ Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+ ASSERT_EFI_ERROR(Status);
+ OrgBusNumberConfiguration = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
+ //
+ // Set Sec/Sub buses to 0xF0
+ //
+ PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
+ //
+ //When Thunderbolt(TM) boot [TbtBootOn] is enabled in bios setup we need to do the below:
+ //Bios should send "Boot On" message through PCIE2TBT register
+ //The Boot On command as described above would include the command and acknowledge from FW (with the default timeout in BIOS),
+ //once the Boot On command is completed it is guaranteed that the AlpineRidge(AR) device is there and the PCI tunneling was done by FW,
+ //next step from BIOS is enumeration using SMI
+ //
+
+ if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn > 0) {
+ //
+ // Exectue Mail box command "Boot On / Pre-Boot ACL"
+ //
+ //Command may be executed only during boot/reboot and not during Sx exit flow
+ if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 1) {
+ if (!TbtSetPcie2TbtCommand(PCIE2TBT_BOOT_ON, 0xF0, 0, 0, TBT_5S_TIMEOUT)) {
+ //
+ // Nothing to wait, HR is not responsive
+ //
+ DEBUG((DEBUG_INFO, "<TbtPei> DTbtBootOn - Boot On message sent failed \n"));
+ }
+ }
+ if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 2) {
+ if (!TbtSetPcie2TbtCommand(PCIE2TBT_PREBOOTACL, 0xF0, 0, 0, TBT_3S_TIMEOUT)) {
+ //
+ // Nothing to wait, HR is not responsive
+ //
+ DEBUG((DEBUG_INFO, "<TbtPei> DTbtBootOn - Pre-Boot ACL message sent failed \n"));
+ }
+ }
+ }
+ //
+ // Reset Sec/Sub buses to original value
+ //
+ PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), OrgBusNumberConfiguration);
+
+ DEBUG((DEBUG_INFO, "DTbtBootOn call Return\n"));
+ return Status;
+}
+
+/**
+ Exectue Mail box command "USB On".
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtUsbOn(
+ IN PEI_TBT_POLICY *PeiTbtConfig
+)
+{
+ EFI_STATUS Status;
+ UINTN RpDev;
+ UINTN RpFunc;
+ UINT32 OrgBusNumberConfiguration;
+ UINT64 TbtBaseAddress;
+ UINT32 MaxWaitIter;
+ UINT32 RegVal;
+ EFI_BOOT_MODE BootMode;
+
+ DEBUG((DEBUG_INFO, "DTbtUsbOn call Inside\n"));
+
+ Status = EFI_SUCCESS;
+
+ Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+ ASSERT_EFI_ERROR(Status);
+ OrgBusNumberConfiguration = PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
+ //
+ // Set Sec/Sub buses to 0xF0
+ //
+ PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
+
+ //
+ //When Thunderbolt(TM) Usb boot [TbtUsbOn] is enabled in bios setup we need to do the below:
+ //Bios should send "Usb On" message through PCIE2TBT register
+ //The Usb On command as described above would include the command and acknowledge from FW (with the default timeout in BIOS),
+ //once the Usb On command is completed it is guaranteed that the AlpineRidge(AR) device is there and the PCI tunneling was done by FW,
+ //next step from BIOS is enumeration using SMI
+ //
+ if (PeiTbtConfig->DTbtCommonConfig.TbtUsbOn) {
+ if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn > 0) {
+ MaxWaitIter = 50; // Wait 5 sec
+ TbtBaseAddress = PCI_SEGMENT_LIB_ADDRESS(0, 0xF0, 0, 0, 0);
+ //
+ // Driver clears the PCIe2TBT Valid bit to support two consicutive mailbox commands
+ //
+ PciSegmentWrite32(TbtBaseAddress + PCIE2TBT_DTBT_R, 0);
+ DEBUG((DEBUG_INFO, "TbtBaseAddress + PCIE2TBT_DTBT_R = 0x%lx \n", TbtBaseAddress + PCIE2TBT_DTBT_R));
+ while (MaxWaitIter-- > 0) {
+ RegVal = PciSegmentRead32(TbtBaseAddress + TBT2PCIE_DTBT_R);
+ if (0xFFFFFFFF == RegVal) {
+ //
+ // Device is not here return now
+ //
+ DEBUG((DEBUG_INFO, "TBT device is not present \n"));
+ break;
+ }
+
+ if (!(RegVal & TBT2PCIE_DON_R)) {
+ break;
+ }
+ MicroSecondDelay(100 * 1000);
+ }
+ }
+
+ Status = PeiServicesGetBootMode(&BootMode);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Exectue Mail box command "Usb On"
+ //
+ //Command may be executed only during boot/reboot and not during S3 exit flow
+ //In case of S4 Exit send USB ON cmd only if Host Router was inactive/not present during S4 entry
+ if ((BootMode == BOOT_ON_S4_RESUME) ) {
+ // USB_ON cmd not required
+ } else {
+ if (!TbtSetPcie2TbtCommand(PCIE2TBT_USB_ON, 0xF0, 0, 0, TBT_5S_TIMEOUT)) {
+ //
+ // Nothing to wait, HR is not responsive
+ //
+ DEBUG((DEBUG_INFO, "<TbtPei> TbtBootSupport - Usb On message sent failed \n"));
+ }
+ }
+ }
+ //
+ // Reset Sec/Sub buses to original value
+ //
+ PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), OrgBusNumberConfiguration);
+
+ DEBUG((DEBUG_INFO, "DTbtUsbOn call return\n"));
+ return Status;
+}
+
+/**
+ Exectue Mail box command "Sx Exit".
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSxExitFlow(
+ IN PEI_TBT_POLICY *PeiTbtConfig
+)
+{
+ EFI_STATUS Status;
+ UINT32 OrgBusNumberConfiguration;
+ UINTN RpDev;
+ UINTN RpFunc;
+ UINT32 Count;
+
+ DEBUG((DEBUG_INFO, "DTbtSxExitFlow call Inside\n"));
+
+ Status = EFI_SUCCESS;
+ Count = 0;
+
+ Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+ ASSERT_EFI_ERROR(Status);
+ OrgBusNumberConfiguration = PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
+ //
+ // Set Sec/Sub buses to 0xF0
+ //
+ PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
+
+ if ( (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 2)) {
+ //
+ // WA: When system with TBT 3.1 device, resume SX system need to wait device ready. In document that maximum time out should be 500ms.
+ //
+ while (PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS(0, 0xf0, 0x0, 0x0, 0x08)) == 0xffffffff) { //End Device will be with Device Number 0x0, Function Number 0x0.
+ MicroSecondDelay(STALL_ONE_MICRO_SECOND * 1000); // 1000usec
+ Count++;
+ if (Count > 10000) { //Allowing Max Delay of 10 sec for CFL-S board.
+ break;
+ }
+ }
+
+ //
+ // Upon wake, if BIOS saved pre-Sx Host Router state as active (system went to sleep with
+ // attached devices), BIOS should:
+ // 1. Execute "Sx_Exit_TBT_Connected" mailbox command.
+ // 2. If procedure above returns true, BIOS should perform "wait for fast link bring-up" loop
+ // 3. Continue regular wake flow.
+ //
+ //
+ // Exectue Mail box command and perform "wait for fast link bring-up" loop
+ //
+ TbtSetSxMode(0xF0, 0, 0, PeiTbtConfig->DTbtCommonConfig.TbtBootOn);
+ }
+ //
+ // Reset Sec/Sub buses to original value
+ //
+ PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), OrgBusNumberConfiguration);
+
+ DEBUG((DEBUG_INFO, "DTbtSxExitFlow call Return\n"));
+ return Status;
+}
+
+
+/**
+ Initialize Thunderbolt(TM)
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval others
+**/
+EFI_STATUS
+EFIAPI
+TbtInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ PEI_TBT_POLICY *PeiTbtConfig;
+
+ //
+ // Get the TBT Policy
+ //
+ Status = PeiServicesLocatePpi (
+ &gPeiTbtPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &PeiTbtConfig
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+ }
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Exectue Mail box command "Boot On"
+ //
+ Status = DTbtBootOn (PeiTbtConfig);
+ //
+ // Exectue Mail box command "Usb On"
+ //
+ Status = DTbtUsbOn (PeiTbtConfig);
+ //
+ //During boot, reboot and wake (bits [1:0]) of PCH PM_CFG register should be
+ //set to 11b - 10 ms (default value is 0b - 10 us)
+ //
+ Status = DTbtSetTPch25Timing (PeiTbtConfig);
+ //
+ // Configure Tbt Force Power
+ //
+ Status = DTbtForcePower (PeiTbtConfig);
+ //
+ // VGA Enable and VGA 16-bit decode registers of Bridge control register of Root port where
+ // Host router resides should be cleaned
+ //
+ Status = DTbtClearVgaRegisters (PeiTbtConfig);
+ //
+ // Upon wake, if BIOS saved pre-Sx Host Router state as active (system went to sleep with
+ // attached devices), BIOS should:
+ // 1. Execute "Sx_Exit_TBT_Connected" mailbox command.
+ // 2. If procedure above returns true, BIOS should perform "wait for fast link bring-up" loop
+ // 3. Continue regular wake flow.
+ //
+ Status = DTbtSxExitFlow (PeiTbtConfig);
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
new file mode 100644
index 0000000000..83a0f57535
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
@@ -0,0 +1,48 @@
+### @file
+# Component description file for PEI DTBT Init library.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PeiDTbtInitLib
+ FILE_GUID = 06768A8D-8152-403f-83C1-59584FD2B438
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = PeiDTbtInitLib
+
+[LibraryClasses]
+ PeiServicesLib
+ DebugLib
+ PcdLib
+ TbtCommonLib
+ PciSegmentLib
+ PeiTbtPolicyLib
+ PchPmcLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ KabylakeOpenBoardPkg/OpenBoardPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+
+[Ppis]
+ gPeiTbtPolicyPpiGuid ## CONSUMES
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## CONSUMES
+ #gClientCommonModuleTokenSpaceGuid.PcdTbtSupport ## PRODUCES
+
+[Sources]
+ PeiDTbtInitLib.c
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c
new file mode 100644
index 0000000000..cfe38d8018
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c
@@ -0,0 +1,233 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/TbtCommonLib.h>
+#include <Library/DxeTbtPolicyLib.h>
+#include <TbtBoardInfo.h>
+#include <Protocol/DxeTbtPolicy.h>
+#include <Protocol/TbtNvsArea.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/PcdLib.h>
+#include <Library/AslUpdateLib.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_NVS_AREA_PROTOCOL mTbtNvsAreaProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED TBT_INFO_HOB *gTbtInfoHob = NULL;
+
+/**
+ TBT NVS Area Initialize
+
+**/
+
+VOID
+TbtNvsAreaInit (
+ IN VOID **mTbtNvsAreaPtr
+ )
+{
+ UINTN Pages;
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_STATUS Status;
+ TBT_NVS_AREA_PROTOCOL *TbtNvsAreaProtocol;
+ DXE_TBT_POLICY_PROTOCOL *DxeTbtConfig;
+
+ DEBUG ((DEBUG_INFO, "TbtNvsAreaInit Start\n"));
+ Status = gBS->LocateProtocol (
+ &gDxeTbtPolicyProtocolGuid,
+ NULL,
+ (VOID **) &DxeTbtConfig
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Pages = EFI_SIZE_TO_PAGES (sizeof (TBT_NVS_AREA));
+ Address = 0xffffffff; // allocate address below 4G.
+
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiACPIMemoryNVS,
+ Pages,
+ &Address
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ *mTbtNvsAreaPtr = (VOID *) (UINTN) Address;
+ SetMem (*mTbtNvsAreaPtr, sizeof (TBT_NVS_AREA), 0);
+
+ //
+ // TBTNvsAreaProtocol default value init here
+ //
+ TbtNvsAreaProtocol = (TBT_NVS_AREA_PROTOCOL *) &Address;
+
+ //
+ // Initialize default values
+ //
+ TbtNvsAreaProtocol->Area->WAKFinished = 0;
+ TbtNvsAreaProtocol->Area->DiscreteTbtSupport = ((gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn == 1 ) ? TRUE : FALSE);
+ TbtNvsAreaProtocol->Area->TbtAcpiRemovalSupport = 0;
+ TbtNvsAreaProtocol->Area->TbtGpioFilter = (UINT8) DxeTbtConfig->TbtCommonConfig.Gpio5Filter;
+// TbtNvsAreaProtocol->Area->TrOsup = (UINT8) DxeTbtConfig->TbtCommonConfig.TrA0OsupWa;
+ TbtNvsAreaProtocol->Area->TbtFrcPwrEn = gTbtInfoHob->DTbtCommonConfig.Gpio3ForcePwr;
+ TbtNvsAreaProtocol->Area->TbtAspm = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtAspm;
+// TbtNvsAreaProtocol->Area->TbtL1SubStates = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtL1SubStates;
+ TbtNvsAreaProtocol->Area->TbtSetClkReq = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtSetClkReq;
+ TbtNvsAreaProtocol->Area->TbtLtr = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtLtr;
+// TbtNvsAreaProtocol->Area->TbtPtm = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtPtm;
+ TbtNvsAreaProtocol->Area->TbtWakeupSupport = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport;
+ TbtNvsAreaProtocol->Area->TbtAcDcSwitch = (UINT8) DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch;
+ TbtNvsAreaProtocol->Area->Rtd3TbtSupport = (UINT8) DxeTbtConfig->TbtCommonConfig.Rtd3Tbt; // TBT RTD3 Enable.
+ TbtNvsAreaProtocol->Area->Rtd3TbtOffDelay = (UINT16) DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay; // TBT RTD3 Off delay in ms.
+ TbtNvsAreaProtocol->Area->Rtd3TbtClkReq = (UINT8) DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq; // TBT RTD3 ClkReq Mask Enable.
+ TbtNvsAreaProtocol->Area->Rtd3TbtClkReqDelay = (UINT16) DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay; // TBT RTD3 ClkReq mask delay in ms.
+ TbtNvsAreaProtocol->Area->TbtWin10Support = (UINT8) DxeTbtConfig->TbtCommonConfig.Win10Support; // TBT FW Execution Mode
+
+ //
+ // DTBT Controller 1
+ //
+ TbtNvsAreaProtocol->Area->DTbtControllerEn0 = gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn;
+ TbtNvsAreaProtocol->Area->RootportSelected0 = gTbtInfoHob-> DTbtControllerConfig.PcieRpNumber;
+ TbtNvsAreaProtocol->Area->RootportSelected0Type = gTbtInfoHob-> DTbtControllerConfig.Type;
+ TbtNvsAreaProtocol->Area->RootportEnabled0 = gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn;
+ TbtNvsAreaProtocol->Area->TbtFrcPwrGpioNo0 = gTbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioPad;
+ TbtNvsAreaProtocol->Area->TbtFrcPwrGpioLevel0 = gTbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioLevel;
+ TbtNvsAreaProtocol->Area->TbtCioPlugEventGpioNo0 = gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.GpioPad;
+ TbtNvsAreaProtocol->Area->TbtPcieRstGpioNo0 = gTbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioPad;
+ TbtNvsAreaProtocol->Area->TbtPcieRstGpioLevel0 = gTbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioLevel;
+
+ TbtNvsAreaProtocol->Area->TBtCommonGpioSupport = gTbtInfoHob->DTbtCommonConfig.DTbtSharedGpioConfiguration;
+
+ DEBUG ((DEBUG_INFO, "TbtNvsAreaInit End\n"));
+}
+
+/**
+ This function gets registered as a callback to patch TBT ASL code
+
+ @param[in] Event - A pointer to the Event that triggered the callback.
+ @param[in] Context - A pointer to private data registered with the callback function.
+ can we put this also in read me
+**/
+VOID
+EFIAPI
+TbtAcpiEndOfDxeCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Address;
+ UINT16 Length;
+ UINT32 Signature;
+
+ Status = InitializeAslUpdateLib ();
+ ASSERT_EFI_ERROR (Status);
+
+ Address = (UINT32) (UINTN) mTbtNvsAreaProtocol.Area;
+ Length = (UINT16) sizeof (TBT_NVS_AREA);
+ DEBUG ((DEBUG_INFO, "Patch TBT NvsAreaAddress: TBT NVS Address %x Length %x\n", Address, Length));
+ Status = UpdateNameAslCode (SIGNATURE_32 ('T','N','V','B'), &Address, sizeof (Address));
+ ASSERT_EFI_ERROR (Status);
+ Status = UpdateNameAslCode (SIGNATURE_32 ('T','N','V','L'), &Length, sizeof (Length));
+ ASSERT_EFI_ERROR (Status);
+
+ if (gTbtInfoHob != NULL) {
+ if (gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn == 1) {
+ if (gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting == TRUE) {
+ DEBUG ((DEBUG_INFO, "Patch ATBT Method Name\n"));
+ Signature = gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature;
+ Status = UpdateNameAslCode (SIGNATURE_32 ('A','T','B','T'), &Signature, sizeof (Signature));
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ }
+
+ return;
+}
+
+/**
+ Initialize Thunderbolt(TM) SSDT ACPI tables
+
+ @retval EFI_SUCCESS ACPI tables are initialized successfully
+ @retval EFI_NOT_FOUND ACPI tables not found
+**/
+
+EFI_STATUS
+EFIAPI
+TbtDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ // EFI_EVENT EndOfDxeEvent;
+
+ DEBUG ((DEBUG_INFO, "TbtDxeEntryPoint \n"));
+
+ //
+ // Get TBT INFO HOB
+ //
+ gTbtInfoHob = (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid);
+ if (gTbtInfoHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+ InstallTbtPolicy (ImageHandle);
+ //
+ // Update DXE TBT Policy
+ //
+ UpdateTbtPolicyCallback ();
+
+ //
+ // Print DXE TBT Policy
+ //
+ TbtPrintDxePolicyConfig ();
+
+ //
+ // Initialize Tbt Nvs Area
+ //
+ TbtNvsAreaInit ((VOID **) &mTbtNvsAreaProtocol.Area);
+
+
+ //
+ // [ACPI] Thunderbolt ACPI table
+ //
+
+
+ Handle = NULL;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gTbtNvsAreaProtocolGuid,
+ &mTbtNvsAreaProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register an end of DXE event for TBT ACPI to do some patch can be put as description
+ //
+ /**
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ TbtAcpiEndOfDxeCallback,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+**/
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
new file mode 100644
index 0000000000..86f51191d1
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
@@ -0,0 +1,54 @@
+### @file
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[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
+ KabylakeOpenBoardPkg/OpenBoardPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+
+[Sources]
+ TbtDxe.c
+
+[Protocols]
+ gTbtNvsAreaProtocolGuid ## CONSUMES
+ gDxeTbtPolicyProtocolGuid
+
+[Guids]
+ gTbtInfoHobGuid ## CONSUMES
+
+[Depex]
+ gEfiVariableWriteArchProtocolGuid AND
+ gEfiVariableArchProtocolGuid \ No newline at end of file
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c
new file mode 100644
index 0000000000..a9a022844d
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c
@@ -0,0 +1,216 @@
+/** @file
+ Source code file for TBT Init PEI module
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/IoLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PeiTbtPolicyLib.h>
+#include <Ppi/SiPolicy.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <Ppi/EndOfPeiPhase.h>
+#include <TbtBoardInfo.h>
+#include <Private/Library/PeiDTbtInitLib.h>
+/*
+/**
+ This function Update and Print PEI TBT Policy after TbtPolicyBoardInitDone
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval others
+**/
+
+
+/**
+ This function pass PEI TBT Policy to Hob at the end of PEI
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval others
+**/
+
+
+EFI_STATUS
+EFIAPI
+PassTbtPolicyToHob (
+VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ TBT_INFO_HOB *TbtInfoHob;
+ PEI_TBT_POLICY *PeiTbtConfig;
+
+ DEBUG ((DEBUG_INFO, "PassTbtPolicyToHob\n"));
+
+ Status = PeiServicesGetBootMode (&BootMode);
+ ASSERT_EFI_ERROR (Status);
+ if (BootMode == BOOT_ON_S3_RESUME ) {
+ return EFI_SUCCESS;
+ }
+
+ Status = PeiServicesLocatePpi (
+ &gPeiTbtPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &PeiTbtConfig
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+ }
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Create HOB for TBT Data
+ //
+ Status = PeiServicesCreateHob (
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof (TBT_INFO_HOB),
+ (VOID **) &TbtInfoHob
+ );
+ DEBUG ((DEBUG_INFO, "TbtInfoHob Created \n"));
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize the TBT INFO HOB data.
+ //
+ TbtInfoHob->EfiHobGuidType.Name = gTbtInfoHobGuid;
+
+ //
+ // Update DTBT Policy
+ //
+ TbtInfoHob-> DTbtControllerConfig.DTbtControllerEn = PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn;
+ TbtInfoHob-> DTbtControllerConfig.Type = PeiTbtConfig-> DTbtControllerConfig.Type;
+ TbtInfoHob-> DTbtControllerConfig.PcieRpNumber = PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber;
+ TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioPad = PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad;
+ TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioLevel = PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel;
+ TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.GpioPad = PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.GpioPad;
+ TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature;
+ TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting;
+ TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioPad = PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioPad;
+ TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioLevel = PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioLevel;
+
+ TbtInfoHob->DTbtCommonConfig.TbtBootOn = PeiTbtConfig->DTbtCommonConfig.TbtBootOn;
+ TbtInfoHob->DTbtCommonConfig.TbtUsbOn = PeiTbtConfig->DTbtCommonConfig.TbtUsbOn;
+ TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwr = PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr;
+ TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwrDly = PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly;
+ TbtInfoHob->DTbtCommonConfig.DTbtSharedGpioConfiguration = PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration;
+ TbtInfoHob->DTbtCommonConfig.PcieRstSupport = PeiTbtConfig->DTbtCommonConfig.PcieRstSupport;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function handles TbtInit task at the end of PEI
+
+ @param[in] PeiServices Pointer to PEI Services Table.
+ @param[in] NotifyDesc Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi Pointer to the PPI data associated with this function.
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval others
+**/
+
+EFI_STATUS
+EFIAPI
+TbtInitEndOfPei (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN DTbtExisted;
+ PEI_TBT_POLICY *PeiTbtConfig;
+
+ DEBUG ((DEBUG_INFO, "TbtInitEndOfPei Entry\n"));
+
+ Status = EFI_SUCCESS;
+ PeiTbtConfig = NULL;
+ DTbtExisted = FALSE;
+
+ Status = PeiServicesLocatePpi (
+ &gPeiTbtPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &PeiTbtConfig
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+ }
+ ASSERT_EFI_ERROR (Status);
+
+ if (PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn == 1) {
+ DTbtExisted = TRUE;
+ }
+
+ if (DTbtExisted == TRUE) {
+ //
+ // Call Init function
+ //
+ Status = TbtInit ();
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ TBT Init PEI module entry point
+
+ @param[in] FileHandle Not used.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database
+**/
+EFI_STATUS
+EFIAPI
+TbtInitEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "TBT PEI EntryPoint\n"));
+
+ //
+ // Install PEI TBT Policy
+ //
+ Status = InstallPeiTbtPolicy ();
+ ASSERT_EFI_ERROR (Status);
+
+
+ UpdatePeiTbtPolicy ();
+
+ TbtPrintPeiPolicyConfig ();
+ //
+ // Performing PassTbtPolicyToHob and TbtInitEndOfPei
+ //
+ Status = PassTbtPolicyToHob ();
+
+ Status = TbtInitEndOfPei ();
+
+ return Status;
+}
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
new file mode 100644
index 0000000000..fdf85cbd67
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
@@ -0,0 +1,50 @@
+### @file
+# Component information file for the TBT Init PEI module.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[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
+ KabylakeOpenBoardPkg/OpenBoardPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+
+[Sources]
+ PeiTbtInit.c
+
+[Guids]
+ gTbtInfoHobGuid ## CONSUMES
+
+[Ppis]
+ gEfiEndOfPeiSignalPpiGuid ## CONSUMES
+ gPeiTbtPolicyBoardInitDonePpiGuid ## CONSUMES
+
+[Depex]
+ gEfiPeiMemoryDiscoveredPpiGuid \ No newline at end of file
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c
new file mode 100644
index 0000000000..5280f9e1c8
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c
@@ -0,0 +1,1615 @@
+/**@file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TbtSmiHandler.h"
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/SmmVariable.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/PciSegmentLib.h>
+#define MEM_PER_SLOT (DEF_RES_MEM_PER_DEV << 4)
+#define PMEM_PER_SLOT (DEF_RES_PMEM_PER_DEV << 4)
+#define IO_PER_SLOT (DEF_RES_IO_PER_DEV << 2)
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN gDeviceBaseAddress;
+//
+//US(X:0:0), DS(X+1:3:0),DS(X+1:4:0),DS(X+1:5:0),DS(X+1:6:0)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED BRDG_CONFIG HrConfigs[MAX_CFG_PORTS];
+
+extern UINT8 gCurrentDiscreteTbtRootPort;
+extern UINT8 gCurrentDiscreteTbtRootPortType;
+
+BOOLEAN isLegacyDevice = FALSE;
+STATIC UINT8 TbtSegment = 0;
+
+STATIC
+VOID
+PortInfoInit (
+ IN OUT PORT_INFO *PortInfo
+ )
+{
+ PortInfo->BusNumLimit = 4;
+}
+
+STATIC
+VOID
+UnsetVesc (
+ IN UINT8 Bus,
+ IN UINT8 Dev,
+ IN UINT8 Fun
+ )
+{
+ UINT8 Dbus;
+ UINT32 Data32;
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+
+ //
+ // Check for abcence of DS bridge
+ //
+ if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+ return;
+ }
+
+ //
+ // Unset vesc_reg2[23] bit (to have an option to access below DS)
+ //
+ Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
+ Data32 &= 0xFF7FFFFF;
+ PciSegmentWrite32(gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
+ //
+ // Go to Device behind DS
+ //
+ Dbus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+ DEBUG((DEBUG_INFO, "Dbus = %d\n",Dbus));
+ //
+ // Check if there is something behind this Downstream Port (Up or Ep)
+ // If there nothing behind Downstream Port Set vesc_reg2[23] bit -> this will flush all future MemWr
+ //
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Dbus, 0x00, 0x00, 0);
+ if(0xFFFF == PciSegmentRead16(gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET))
+ {
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+ Data32 = PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2);
+ Data32 |= 0x00800000;
+ PciSegmentWrite32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32);
+ }
+}// Unset_VESC_REG2
+
+STATIC
+UINT16
+MemPerSlot (
+ IN UINT16 CurrentUsage
+ )
+{
+ if (CurrentUsage == 0) {
+ return 0;
+ }
+
+ if (CurrentUsage <= 16) {
+ return 16;
+ }
+
+ if (CurrentUsage <= 64) {
+ return 64;
+ }
+
+ if (CurrentUsage <= 128) {
+ return 128;
+ }
+
+ if (CurrentUsage <= 256) {
+ return 256;
+ }
+
+ if (CurrentUsage <= 512) {
+ return 512;
+ }
+
+ if (CurrentUsage <= 1024) {
+ return 1024;
+ }
+
+ return CurrentUsage;
+} // MemPerSlot
+
+STATIC
+UINT64
+PMemPerSlot (
+ IN UINT64 CurrentUsage
+ )
+{
+ if (CurrentUsage == 0) {
+ return 0;
+ }
+
+ if (CurrentUsage <= 1024ULL) {
+ return 1024ULL;
+ }
+
+ if (CurrentUsage <= 4096ULL) {
+ return 4096ULL;
+ }
+
+ return CurrentUsage;
+} // PMemPerSlot
+
+STATIC
+VOID
+SetPhyPortResources (
+ IN UINT8 Bus,
+ IN UINT8 Dev,
+ IN UINT8 SubBus,
+ IN INT8 Depth,
+ IN PORT_INFO *CurrentPi,
+ IN OUT PORT_INFO *PortInfo
+ )
+{
+ UINT8 Cmd;
+ UINT16 DeltaMem;
+ UINT64 DeltaPMem;
+
+ Cmd = CMD_BUS_MASTER;
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, 0x00, 0);
+
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+
+ DeltaMem = PortInfo->MemBase - CurrentPi->MemBase;
+ if (isLegacyDevice) {
+ if (Depth >= 0 && (DeltaMem < MEM_PER_SLOT)) {
+ PortInfo->MemBase += MEM_PER_SLOT - DeltaMem;
+ }
+ } else {
+ if (DeltaMem < MemPerSlot (DeltaMem)) {
+ PortInfo->MemBase += MemPerSlot (DeltaMem) - DeltaMem;
+ }
+ }
+
+ if (PortInfo->MemBase > CurrentPi->MemBase && (PortInfo->MemBase - 0x10) <= PortInfo->MemLimit) {
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), CurrentPi->MemBase);
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), PortInfo->MemBase - 0x10);
+ Cmd |= CMD_BM_MEM;
+ } else {
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
+ PortInfo->MemBase = CurrentPi->MemBase;
+ }
+
+ DeltaPMem = PortInfo->PMemBase64 - CurrentPi->PMemBase64;
+ if (isLegacyDevice) {
+ if ((Depth >= 0) && ((UINTN)DeltaPMem < (UINTN)PMEM_PER_SLOT)) {
+ PortInfo->PMemBase64 += PMEM_PER_SLOT - DeltaPMem;
+ }
+ } else {
+ if (DeltaPMem < PMemPerSlot (DeltaPMem)) {
+ PortInfo->PMemBase64 += PMemPerSlot (DeltaPMem) - DeltaPMem;
+ }
+ }
+
+ if (PortInfo->PMemBase64 > CurrentPi->PMemBase64 && (PortInfo->PMemBase64 - 0x10) <= PortInfo->PMemLimit64) {
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (CurrentPi->PMemBase64 & 0xFFFF));
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) ((PortInfo->PMemBase64 - 0x10) & 0xFFFF));
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (CurrentPi->PMemBase64 >> 16));
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) ((PortInfo->PMemBase64 - 0x10) >> 16));
+ Cmd |= CMD_BM_MEM;
+ } else {
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), 0);
+ PortInfo->PMemBase64 = CurrentPi->PMemBase64;
+ }
+
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+} // SetPhyPortResources
+
+STATIC
+UINT32
+SaveSetGetRestoreBar (
+ IN UINTN Bar
+ )
+{
+ UINT32 BarReq;
+ UINT32 OrigBar;
+
+ OrigBar = PciSegmentRead32(Bar); // Save BAR
+ PciSegmentWrite32(Bar, 0xFFFFFFFF); // Set BAR
+ BarReq = PciSegmentRead32(Bar); // Get BAR
+ PciSegmentWrite32(Bar, OrigBar); // Restore BAR
+
+ return BarReq;
+} // SaveSetGetRestoreBar
+
+STATIC
+VOID
+SetIoBar (
+ IN UINTN BAR,
+ IN UINT32 BarReq,
+ IN OUT UINT8 *Cmd,
+ IN OUT IO_REGS *IoReg
+ )
+{
+ UINT16 Alignment;
+ UINT16 Size;
+ UINT16 NewBase;
+
+ Alignment = ~(BarReq & 0xFFFC);
+ Size = Alignment + 1;
+
+ if (IoReg->Base > IoReg->Limit || !Size) {
+ return ;
+
+ }
+
+ NewBase = BAR_ALIGN (IoReg->Base, Alignment);
+ if (NewBase > IoReg->Limit || NewBase + Size - 1 > IoReg->Limit) {
+ return ;
+
+ }
+ PciSegmentWrite16(BAR, NewBase);
+ IoReg->Base = NewBase + Size; // Advance to new position
+ *Cmd |= CMD_BM_IO; // Set Io Space Enable
+} // SetIoBar
+
+STATIC
+VOID
+SetMemBar (
+ IN UINTN BAR,
+ IN UINT32 BarReq,
+ IN OUT UINT8 *Cmd,
+ IN OUT MEM_REGS *MemReg
+ )
+{
+ UINT32 Alignment;
+ UINT32 Size;
+ UINT32 NewBase;
+
+ Alignment = ~(BarReq & 0xFFFFFFF0);
+ Size = Alignment + 1;
+
+ if (MemReg->Base > MemReg->Limit || !Size) {
+ return ;
+
+ }
+
+ NewBase = BAR_ALIGN (MemReg->Base, Alignment);
+ if (NewBase > MemReg->Limit || NewBase + Size - 1 > MemReg->Limit) {
+ return ;
+
+ }
+
+ PciSegmentWrite32(BAR, NewBase);
+ MemReg->Base = NewBase + Size; // Advance to new position
+ *Cmd |= CMD_BM_MEM; // Set Memory Space Enable
+} // SetMemBar
+
+STATIC
+VOID
+SetPMem64Bar (
+ IN UINTN BAR,
+ IN BOOLEAN IsMaxBar,
+ IN UINT32 BarReq,
+ IN OUT UINT8 *Cmd,
+ IN OUT PMEM_REGS *MemReg
+ )
+{
+ UINT32 Alignment;
+ UINT32 Size;
+ UINT64 NewBase;
+
+ Alignment = ~(BarReq & 0xFFFFFFF0);
+ Size = Alignment + 1;
+
+ if (MemReg->Base64 > MemReg->Limit64 || !Size) {
+ return ;
+ }
+
+ NewBase = BAR_ALIGN (MemReg->Base64, Alignment);
+ if (NewBase > MemReg->Limit64 || NewBase + Size - 1 > MemReg->Limit64) {
+ return ;
+ }
+ PciSegmentWrite32(BAR, (UINT32)(NewBase & 0xFFFFFFFF));
+ if (!IsMaxBar) {
+ BAR++;
+ PciSegmentWrite32(BAR, (UINT32)(NewBase >> 32));
+ }
+ MemReg->Base64 = NewBase + Size; // Advance to new position
+ *Cmd |= CMD_BM_MEM; // Set Memory Space Enable
+} // SetPMem64Bar
+
+STATIC
+VOID
+SetDevResources (
+ IN UINT8 Bus,
+ IN UINT8 Dev,
+ IN UINT8 MaxFun, // PCI_MAX_FUNC for devices, 1 for bridge
+ IN UINT8 MaxBar, // PCI_BAR5 for devices, PCI_BAR1 for bridge
+ IN OUT PORT_INFO *PortInfo
+ )
+{
+ UINT8 Fun;
+ UINT8 Reg;
+ UINT32 BarReq;
+ IO_REGS Io;
+ MEM_REGS Mem;
+ PMEM_REGS PMem;
+ UINT8 Cmd;
+
+ Io.Base = PortInfo->IoBase << 8;
+ Io.Limit = (PortInfo->IoLimit << 8) | 0xFF;
+ Mem.Base = PortInfo->MemBase << 16;
+ Mem.Limit = (PortInfo->MemLimit << 16) | 0xFFFF;
+ PMem.Base64 = PortInfo->PMemBase64 << 16;
+ PMem.Limit64 = (PortInfo->PMemLimit64 << 16) | 0xFFFF;
+
+ for (Fun = 0; Fun < MaxFun; ++Fun) {
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun, 0);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BUS_MASTER);
+ Cmd = PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET);
+ if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+ continue;
+
+ }
+
+ for (Reg = PCI_BASE_ADDRESSREG_OFFSET; Reg <= MaxBar; Reg += 4) {
+ BarReq = SaveSetGetRestoreBar(gDeviceBaseAddress + Reg); // Perform BAR sizing
+
+ if (BarReq & BIT0) {
+ //
+ // I/O BAR
+ //
+ SetIoBar (
+ (gDeviceBaseAddress + Reg),
+ BarReq,
+ &Cmd,
+ &Io
+ );
+ continue;
+ }
+
+ if (BarReq & BIT3) {
+ //
+ // P-Memory BAR
+ //
+ SetPMem64Bar ((gDeviceBaseAddress + Reg), MaxBar == Reg, BarReq, &Cmd, &PMem);
+ } else {
+ SetMemBar ((gDeviceBaseAddress + Reg), BarReq, &Cmd, &Mem);
+ }
+
+ if (BIT2 == (BarReq & (BIT2 | BIT1))) {
+ //
+ // Base address is 64 bits wide
+ //
+ Reg += 4;
+ if (!(BarReq & BIT3)) {
+ //
+ // 64-bit memory bar
+ //
+ PciSegmentWrite32 (gDeviceBaseAddress + Reg, 0);
+ }
+ }
+ }
+
+ if (Cmd & BIT1) {
+ //
+ // If device uses I/O and MEM mapping use only MEM mepping
+ //
+ Cmd &= ~BIT0;
+ }
+
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+ }
+ //
+ // Update PortInfo if any changes
+ //
+ if (Io.Base > ((UINT32) PortInfo->IoBase << 8)) {
+ PortInfo->IoBase = (UINT8) (BAR_ALIGN (Io.Base, 0xFFF) >> 8);
+ }
+
+ if (Mem.Base > ((UINT32) PortInfo->MemBase << 16)) {
+ PortInfo->MemBase = (UINT16) (BAR_ALIGN (Mem.Base, 0xFFFFF) >> 16);
+ }
+
+ if (PMem.Base64 > (PortInfo->PMemBase64 << 16)) {
+ PortInfo->PMemBase64 = (BAR_ALIGN (PMem.Base64, 0xFFFFF) >> 16);
+ }
+} // SetDevResources
+
+STATIC
+VOID
+InitARHRConfigs(
+ IN HR_CONFIG *Hr_Config,
+ IN UINT8 BusNumLimit,
+ IN OUT BRDG_RES_CONFIG* HrResConf
+)
+{
+ UINT8 i,j;
+
+ //
+ // DS port for USB device
+ //
+ HrConfigs[AR_DS_PORT2].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+ HrConfigs[AR_DS_PORT2].DevId.Dev = 2;
+ HrConfigs[AR_DS_PORT2].DevId.Fun = 0;
+ HrConfigs[AR_DS_PORT2].PBus = HrConfigs[AR_DS_PORT2].DevId.Bus;
+ HrConfigs[AR_DS_PORT2].SBus = HrConfigs[AR_DS_PORT2].PBus + 1;
+ HrConfigs[AR_DS_PORT2].SubBus = HrConfigs[AR_DS_PORT2].PBus + 1;
+ //
+ // CIO port
+ //
+ HrConfigs[AR_DS_PORT1].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+ HrConfigs[AR_DS_PORT1].DevId.Dev = 1;
+ HrConfigs[AR_DS_PORT1].DevId.Fun = 0;
+ HrConfigs[AR_DS_PORT1].PBus = HrConfigs[AR_DS_PORT1].DevId.Bus;
+ HrConfigs[AR_DS_PORT1].SBus = HrConfigs[HR_DS_PORT0].SubBus + 1;
+ HrConfigs[AR_DS_PORT1].SubBus = BusNumLimit;
+
+ switch(Hr_Config->DeviceId)
+ {
+ //
+ // HR with 1 DS and 1 USB
+ //
+ case AR_HR_2C:
+ case AR_HR_LP:
+ case AR_HR_C0_2C:
+ case TR_HR_2C:
+ Hr_Config->MinDSNumber = HrConfigs[AR_DS_PORT1].DevId.Dev;
+ Hr_Config->MaxDSNumber = HrConfigs[AR_DS_PORT2].DevId.Dev;
+ Hr_Config->BridgeLoops = 4;
+ break;
+ //
+ // HR with 2 DS and 1 USB
+ //
+ case AR_HR_4C:
+ case TR_HR_4C:
+ case AR_HR_C0_4C:
+ Hr_Config->MinDSNumber = 1;
+ Hr_Config->MaxDSNumber = 4;
+ Hr_Config->BridgeLoops = 6;
+ for(j = 2, i = Hr_Config->MinDSNumber; j < count(HrConfigs) && i <= Hr_Config->MaxDSNumber; ++j, ++i)
+ {
+ HrConfigs[j].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+ HrConfigs[j].DevId.Dev = i;
+ HrConfigs[j].DevId.Fun = 0;
+ HrConfigs[j].PBus = HrConfigs[j].DevId.Bus;
+ HrConfigs[j].Res.Cls = DEF_CACHE_LINE_SIZE;
+ }
+ break;
+ }
+}//InitARHRConfigs
+
+
+STATIC
+VOID
+InitCommonHRConfigs (
+ IN HR_CONFIG *Hr_Config,
+ IN UINT8 BusNumLimit,
+ IN OUT BRDG_RES_CONFIG *HrResConf
+ )
+{
+ UINT8 i;
+
+ UINT8 j;
+ for(i = 0; i < count(HrConfigs); ++i) {
+ HrConfigs[i].IsDSBridge = TRUE;
+ }
+ //
+ // US(HRBus:0:0)
+ //
+ HrConfigs[HR_US_PORT].DevId.Bus = Hr_Config->HRBus;
+ HrConfigs[HR_US_PORT].DevId.Dev = 0;
+ HrConfigs[HR_US_PORT].DevId.Fun = 0;
+ HrConfigs[HR_US_PORT].Res = *HrResConf;
+ HrConfigs[HR_US_PORT].Res.IoBase = 0xF1;
+ HrConfigs[HR_US_PORT].Res.IoLimit = 0x01;
+ HrConfigs[HR_US_PORT].PBus = HrConfigs[HR_US_PORT].DevId.Bus;
+ HrConfigs[HR_US_PORT].SBus = HrConfigs[HR_US_PORT].PBus + 1;
+ HrConfigs[HR_US_PORT].SubBus = BusNumLimit;
+ HrConfigs[HR_US_PORT].IsDSBridge = FALSE;
+
+ //
+ // HIA resides here
+ //
+ HrConfigs[HR_DS_PORT0].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+ HrConfigs[HR_DS_PORT0].DevId.Dev = 0;
+ HrConfigs[HR_DS_PORT0].DevId.Fun = 0;
+ HrConfigs[HR_DS_PORT0].Res = NOT_IN_USE_BRIDGE;
+ HrConfigs[HR_DS_PORT0].Res.MemBase = HrResConf->MemLimit;
+ HrConfigs[HR_DS_PORT0].Res.MemLimit = HrResConf->MemLimit;
+ HrResConf->MemLimit -= 0x10; //This 1 MB chunk will be used by HIA
+ HrConfigs[HR_DS_PORT0].Res.Cmd = CMD_BM_MEM;
+ HrConfigs[HR_DS_PORT0].Res.Cls = DEF_CACHE_LINE_SIZE;
+ HrConfigs[HR_DS_PORT0].PBus = HrConfigs[HR_DS_PORT0].DevId.Bus;
+ HrConfigs[HR_DS_PORT0].SBus = HrConfigs[HR_DS_PORT0].PBus + 1;
+ HrConfigs[HR_DS_PORT0].SubBus = HrConfigs[HR_DS_PORT0].PBus + 1;
+
+ switch (Hr_Config->DeviceId) {
+ //
+ // Alpine Ridge
+ //
+ case AR_HR_2C:
+ case AR_HR_C0_2C:
+ case AR_HR_LP:
+ case AR_HR_4C:
+ case AR_HR_C0_4C:
+ //
+ // Titan Ridge
+ //
+ case TR_HR_2C:
+ case TR_HR_4C:
+ InitARHRConfigs(Hr_Config, BusNumLimit, HrResConf);
+ break;
+
+ default:
+ //
+ // DS(HRBus+2:3-6:0)
+ //
+ Hr_Config->MinDSNumber = 3;
+ Hr_Config->MaxDSNumber = 6;
+ Hr_Config->BridgeLoops = count (HrConfigs);
+
+ for (j = 2, i = Hr_Config->MinDSNumber; j < count (HrConfigs) && i <= Hr_Config->MaxDSNumber; ++j, ++i) {
+ HrConfigs[j].DevId.Bus = HrConfigs[HR_US_PORT].DevId.Bus + 1;
+ HrConfigs[j].DevId.Dev = i;
+ HrConfigs[j].DevId.Fun = 0;
+ HrConfigs[j].PBus = HrConfigs[j].DevId.Bus;
+ HrConfigs[j].Res.Cls = DEF_CACHE_LINE_SIZE;
+ }
+ }
+} // InitCommonHRConfigs
+
+STATIC
+VOID
+InitHRDSPort_Disable (
+ IN UINT8 id,
+ IN OUT BRDG_CONFIG *BrdgConf
+ )
+{
+ HrConfigs[id].Res = NOT_IN_USE_BRIDGE;
+ HrConfigs[id].SBus = BrdgConf->SBus;
+ HrConfigs[id].SubBus = BrdgConf->SBus;
+
+ BrdgConf->SBus++;
+} // InitHRDSPort_Disable
+
+//AR only
+
+STATIC
+VOID
+InitARDSPort_1Port(
+ IN OUT BRDG_CONFIG* BrdgConf
+)
+{
+ UINT16 MemBase = BrdgConf->Res.MemBase & 0xFFF0;
+ UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
+ UINT8 BusRange = BrdgConf->SubBus - BrdgConf->PBus - 2;
+
+ HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
+ HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
+ HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
+ HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
+ HrConfigs[AR_DS_PORT1].Res.MemLimit = BrdgConf->Res.MemLimit - 1;
+ HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
+ HrConfigs[AR_DS_PORT1].Res.PMemLimit64 = BrdgConf->Res.PMemLimit64;
+ HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
+ HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
+
+ BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
+
+ HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
+ HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
+ HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
+ HrConfigs[AR_DS_PORT2].Res.MemBase = BrdgConf->Res.MemLimit;
+ HrConfigs[AR_DS_PORT2].Res.MemLimit = BrdgConf->Res.MemLimit;
+ HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
+ HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
+
+ BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
+}//InitARDSPort_1Port
+
+STATIC
+VOID
+InitARDSPort_2Port(
+ IN OUT BRDG_CONFIG* BrdgConf
+)
+{
+ UINT16 MemBase = BrdgConf->Res.MemBase & 0xFFF0;
+ UINT64 PMemBase64 = BrdgConf->Res.PMemBase64 & ~0xFULL;
+ UINT8 BusRange = BrdgConf->SubBus - BrdgConf->PBus - 3;
+
+ // Busses are split between ports 1 and 4
+ BusRange /= 2;
+
+ HrConfigs[AR_DS_PORT1].Res = NOT_IN_USE_BRIDGE;
+ HrConfigs[AR_DS_PORT1].Res.Cls = DEF_CACHE_LINE_SIZE;
+ HrConfigs[AR_DS_PORT1].Res.Cmd = CMD_BM_MEM;
+ HrConfigs[AR_DS_PORT1].Res.MemBase = MemBase;
+ HrConfigs[AR_DS_PORT1].Res.MemLimit = MemBase + 0x17F0 - 1;
+ HrConfigs[AR_DS_PORT1].Res.PMemBase64 = PMemBase64;
+ HrConfigs[AR_DS_PORT1].Res.PMemLimit64 = PMemBase64 + 0x2000 - 1;
+ HrConfigs[AR_DS_PORT1].SBus = BrdgConf->SBus;
+ HrConfigs[AR_DS_PORT1].SubBus = BrdgConf->SBus + BusRange;
+
+ BrdgConf->SBus = HrConfigs[AR_DS_PORT1].SubBus + 1;
+
+ HrConfigs[AR_DS_PORT2].Res = NOT_IN_USE_BRIDGE;
+ HrConfigs[AR_DS_PORT2].Res.Cls = DEF_CACHE_LINE_SIZE;
+ HrConfigs[AR_DS_PORT2].Res.Cmd = CMD_BM_MEM;
+ HrConfigs[AR_DS_PORT2].Res.MemBase = MemBase + 0x17F0;
+ HrConfigs[AR_DS_PORT2].Res.MemLimit = MemBase + 0x1800 - 1;
+ HrConfigs[AR_DS_PORT2].SBus = BrdgConf->SBus;
+ HrConfigs[AR_DS_PORT2].SubBus = BrdgConf->SBus;
+
+ BrdgConf->SBus = HrConfigs[AR_DS_PORT2].SubBus + 1;
+
+
+ HrConfigs[AR_DS_PORT4].Res = NOT_IN_USE_BRIDGE;
+ HrConfigs[AR_DS_PORT4].Res.Cls = DEF_CACHE_LINE_SIZE;
+ HrConfigs[AR_DS_PORT4].Res.Cmd = CMD_BM_MEM;
+ HrConfigs[AR_DS_PORT4].Res.MemBase = MemBase + 0x1800;
+ HrConfigs[AR_DS_PORT4].Res.MemLimit = BrdgConf->Res.MemLimit;
+ HrConfigs[AR_DS_PORT4].Res.PMemBase64 = PMemBase64 + 0x2000;
+ HrConfigs[AR_DS_PORT4].Res.PMemLimit64 = BrdgConf->Res.PMemLimit64;
+ HrConfigs[AR_DS_PORT4].SBus = BrdgConf->SBus;
+ HrConfigs[AR_DS_PORT4].SubBus = BrdgConf->SubBus;
+
+ BrdgConf->SBus = HrConfigs[AR_DS_PORT4].SubBus + 1;
+}//InitARDSPort_2Port
+
+
+STATIC
+BOOLEAN
+CheckLimits (
+ IN BOOLEAN Is2PortDev,
+ IN BRDG_RES_CONFIG *HrResConf,
+ IN UINT8 BusRange
+ )
+{
+ UINT16 MemBase;
+ UINT16 MemLimit;
+ UINT64 PMemBase64;
+ UINT64 PMemLimit64;
+
+ MemBase = HrResConf->MemBase & 0xFFF0;
+ MemLimit = HrResConf->MemLimit & 0xFFF0;
+ PMemBase64 = HrResConf->PMemBase64 & 0xFFF0;
+ PMemLimit64 = HrResConf->PMemLimit64 & 0xFFF0;
+ //
+ // Check memoty alignment
+ //
+ if (MemBase & 0x3FF) {
+ DEBUG((DEBUG_INFO, "M alig\n"));
+ return FALSE;
+ }
+
+ if (PMemBase64 & 0xFFF) {
+ DEBUG((DEBUG_INFO, "PM alig\n"));
+ return FALSE;
+ }
+
+ if (Is2PortDev) {
+ //
+ // Check mem size
+ //
+ if (MemLimit + 0x10 - MemBase < 0x2E00) {
+ DEBUG((DEBUG_INFO, "M size\n"));
+ return FALSE;
+ }
+ //
+ // Check P-mem size
+ //
+ if (PMemLimit64 + 0x10 - PMemBase64 < 0x4A00) {
+ DEBUG((DEBUG_INFO, "PM size\n"));
+ return FALSE;
+ }
+ //
+ // Check bus range
+ //
+ if (BusRange < 106) {
+ DEBUG((DEBUG_INFO, "Bus range\n"));
+ return FALSE;
+ }
+ } else {
+ //
+ // Check mem size
+ //
+ if (MemLimit + 0x10 - MemBase < 0x1600) {
+ DEBUG((DEBUG_INFO, "M size\n"));
+ return FALSE;
+ }
+ //
+ // Check P-mem size
+ //
+ if (PMemLimit64 + 0x10 - PMemBase64 < 0x2200) {
+ DEBUG((DEBUG_INFO, "PM size\n"));
+ return FALSE;
+ }
+ //
+ // Check bus range
+ //
+ if (BusRange < 56) {
+ DEBUG((DEBUG_INFO, "Bus range\n"));
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+} // CheckLimits
+
+STATIC
+BOOLEAN
+InitHRResConfigs (
+ IN OUT HR_CONFIG *Hr_Config,
+ IN UINT8 BusNumLimit,
+ IN OUT BRDG_RES_CONFIG*HrResConf
+ )
+{
+ BRDG_CONFIG BrdgConf = { { 0 } };
+
+ InitCommonHRConfigs (Hr_Config, BusNumLimit, HrResConf);
+ BrdgConf.PBus = Hr_Config->HRBus + 2;// Take into account busses
+ BrdgConf.SBus = Hr_Config->HRBus + 3;// for US and DS of HIA
+ BrdgConf.SubBus = BusNumLimit;
+ BrdgConf.Res = *HrResConf;
+ while (TRUE) {
+ switch (Hr_Config->DeviceId) {
+ case AR_HR_4C:
+ case TR_HR_4C:
+ case AR_HR_C0_4C:
+ //
+ // 2 Port host
+ //
+ if (CheckLimits (TRUE, HrResConf, BusNumLimit - Hr_Config->HRBus)) {
+
+
+ InitARDSPort_2Port(&BrdgConf);
+ DEBUG((DEBUG_INFO, "AR2\n"));
+
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ // AR only
+ case AR_HR_2C: // 1 port host
+ case AR_HR_C0_2C:
+ case AR_HR_LP:
+ case TR_HR_2C:
+ DEBUG((DEBUG_INFO, "AR1\n"));
+ InitARDSPort_1Port(&BrdgConf);
+ return TRUE;
+
+ default:
+ InitHRDSPort_Disable (HR_DS_PORT3, &BrdgConf);
+ InitHRDSPort_Disable (HR_DS_PORT4, &BrdgConf);
+ InitHRDSPort_Disable (HR_DS_PORT5, &BrdgConf);
+ InitHRDSPort_Disable (HR_DS_PORT6, &BrdgConf);
+ return FALSE;
+ }
+ }
+} // InitHRResConfigs
+
+STATIC
+BOOLEAN
+InitializeHostRouter (
+ OUT HR_CONFIG *Hr_Config,
+ IN UINTN RpSegment,
+ IN UINTN RpBus,
+ IN UINTN RpDevice,
+ IN UINTN RpFunction
+ )
+{
+ UINT8 BusNumLimit;
+ BRDG_RES_CONFIG HrResConf = { 0 };
+ UINT8 i;
+ BOOLEAN Ret;
+
+ Ret = TRUE;
+
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
+ Hr_Config->HRBus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (RpSegment, Hr_Config->HRBus, 0x00, 0x00, 0);
+ Hr_Config->DeviceId = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+ if (!(IsTbtHostRouter (Hr_Config->DeviceId))) {
+ return FALSE;
+ }
+ TbtSegment = (UINT8)RpSegment;
+
+ HrResConf.Cmd = CMD_BM_MEM;
+ HrResConf.Cls = DEF_CACHE_LINE_SIZE;
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDevice, RpFunction, 0);
+ HrResConf.IoBase = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
+ HrResConf.IoLimit = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
+ HrResConf.MemBase = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
+ HrResConf.MemLimit = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
+ HrResConf.PMemBase64 = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase));
+ HrResConf.PMemLimit64 = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit));
+ HrResConf.PMemBase64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
+ HrResConf.PMemLimit64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
+ BusNumLimit = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+
+ Ret = InitHRResConfigs (Hr_Config, BusNumLimit, &HrResConf);
+
+ for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
+ UINT8 Bus;
+ UINT8 Dev;
+ UINT8 Fun;
+ Bus = HrConfigs[i].DevId.Bus;
+ Dev = HrConfigs[i].DevId.Dev;
+ Fun = HrConfigs[i].DevId.Fun;
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, HrConfigs[i].Res.Cls);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, HrConfigs[i].PBus);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, HrConfigs[i].SBus);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, HrConfigs[i].SubBus);
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), HrConfigs[i].Res.MemBase);
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), HrConfigs[i].Res.MemLimit);
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (HrConfigs[i].Res.PMemBase64 & 0xFFFF));
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) (HrConfigs[i].Res.PMemLimit64 & 0xFFFF));
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (HrConfigs[i].Res.PMemBase64 >> 16));
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) (HrConfigs[i].Res.PMemLimit64 >> 16));
+ PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), HrConfigs[i].Res.IoBase);
+ PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit), HrConfigs[i].Res.IoLimit);
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16), 0x00000000);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, HrConfigs[i].Res.Cmd);
+ }
+ if (Hr_Config->DeviceId == AR_HR_2C || Hr_Config->DeviceId == AR_HR_4C || Hr_Config->DeviceId == AR_HR_LP) {
+ for (i = 0; i < Hr_Config->BridgeLoops; ++i) {
+ if(HrConfigs[i].IsDSBridge) {
+ UnsetVesc(HrConfigs[i].DevId.Bus, HrConfigs[i].DevId.Dev, HrConfigs[i].DevId.Fun);
+ }
+ }
+ }
+
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,(Hr_Config->HRBus + 2), 0x00, 0x00, 0);
+ PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4), HrConfigs[HR_DS_PORT0].Res.MemLimit << 16);
+ PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), (HrConfigs[HR_DS_PORT0].Res.MemLimit + 0x4) << 16);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BM_MEM);
+ return Ret;
+} // InitializeHostRouter
+STATIC
+UINT8
+ConfigureSlot (
+ IN UINT8 Bus,
+ IN UINT8 MAX_DEVICE,
+ IN INT8 Depth,
+ IN BOOLEAN ArPcie,
+ IN OUT PORT_INFO *PortInfo
+ )
+{
+ UINT8 Device;
+ UINT8 SBus;
+ UINT8 UsedBusNumbers;
+ UINT8 RetBusNum;
+ PORT_INFO CurrentSlot;
+
+ RetBusNum = 0;
+
+ for (Device = 0; Device < MAX_DEVICE; Device++) {
+ //
+ // Continue if device is absent
+ //
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, 0x00, 0);
+ if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+ continue;
+
+ }
+
+ if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress + (PCI_CLASSCODE_OFFSET + 1))) {
+ SetDevResources (
+ Bus,
+ Device,
+ PCI_MAX_FUNC,
+ PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4),
+ PortInfo
+ );
+ continue;
+ }
+ //
+ // Else Bridge
+ //
+ CopyMem (&CurrentSlot, PortInfo, sizeof (PORT_INFO));
+
+ ++RetBusNum; // UP Bridge
+ SBus = Bus + RetBusNum; // DS Bridge
+
+ if (SBus + 1 >= PortInfo->BusNumLimit) {
+ continue;
+
+ }
+
+ SetDevResources (Bus, Device, 1, PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), PortInfo);
+
+ //
+ // Init UP Bridge to reach DS Bridge
+ //
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BM_MEM);
+
+ if(ArPcie) {
+ UnsetVesc(Bus, Device, 0x00);
+ }
+
+ UsedBusNumbers = ConfigureSlot(SBus, PCI_MAX_DEVICE + 1, -1, FALSE, PortInfo);
+ RetBusNum += UsedBusNumbers;
+
+ SetPhyPortResources (
+ Bus,
+ Device,
+ SBus + UsedBusNumbers,
+ Depth,
+ &CurrentSlot,
+ PortInfo
+ );
+ }
+ //
+ // for (Device = 0; Device <= PCI_MAX_DEVICE; Device++)
+ //
+ return RetBusNum;
+} // ConfigureSlot
+
+STATIC
+VOID
+SetCioPortResources (
+ IN UINT8 Bus,
+ IN UINT8 Dev,
+ IN UINT8 SBus,
+ IN UINT8 SubBus,
+ IN PORT_INFO *portInfoBeforeChange,
+ IN OUT PORT_INFO *PortInfo
+ )
+{
+ UINT8 Cmd;
+ Cmd = CMD_BUS_MASTER;
+
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, 0x00, 0);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, SBus);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, SubBus);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+
+ if (PortInfo->IoBase <= PortInfo->IoLimit) {
+ PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), PortInfo->IoBase);
+ PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit), PortInfo->IoLimit);
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16), 0x00000000);
+ Cmd |= CMD_BM_IO;
+ } else {
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), DISBL_IO_REG1C);
+ }
+
+ if (PortInfo->MemBase <= PortInfo->MemLimit) {
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), PortInfo->MemBase);
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit), PortInfo->MemLimit);
+ Cmd |= CMD_BM_MEM;
+ } else {
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
+ }
+
+ if (PortInfo->PMemBase64 <= PortInfo->PMemLimit64) {
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), (UINT16) (PortInfo->PMemBase64 & 0xFFFF));
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit), (UINT16) (PortInfo->PMemLimit64 & 0xFFFF));
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), (UINT32) (PortInfo->PMemBase64 >> 16));
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), (UINT32) (PortInfo->PMemLimit64 >> 16));
+ Cmd |= CMD_BM_MEM;
+ } else {
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32), 0);
+ }
+
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+} // SetCioPortResources
+
+STATIC
+VOID
+SetSlotsAsUnused (
+ IN UINT8 Bus,
+ IN UINT8 MaxSlotNum,
+ IN UINT8 CioSlot,
+ IN OUT PORT_INFO *PortInfo
+ )
+{
+ UINT8 Slot;
+ for (Slot = MaxSlotNum; Slot > CioSlot; --Slot) {
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Slot, 0x00, 0);
+ if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+ continue;
+ }
+
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CACHE_LINE_SIZE);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, Bus);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, PortInfo->BusNumLimit);
+ PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase), DISBL_IO_REG1C);
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase), DISBL_MEM32_REG20);
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase), DISBL_PMEM_REG24);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BUS_MASTER);
+ PortInfo->BusNumLimit--;
+ }
+} // SetSlotsAsUnused
+
+STATIC
+UINT16
+FindVendorSpecificHeader(
+ IN UINT8 Bus
+)
+{
+ PCI_EXP_EXT_HDR *ExtHdr;
+ UINT32 ExtHdrValue;
+ UINT16 ExtendedRegister;
+
+ ExtHdr = (PCI_EXP_EXT_HDR*) &ExtHdrValue;
+ ExtendedRegister = 0x100;
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
+ while (ExtendedRegister) {
+ ExtHdrValue = PciSegmentRead32 (gDeviceBaseAddress + ExtendedRegister);
+ if (ExtHdr->CapabilityId == 0xFFFF) {
+ return 0x0000; // No Vendor-Specific Extended Capability header
+ }
+
+ if (PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID == ExtHdr->CapabilityId) {
+ return ExtendedRegister;
+ }
+
+ ExtendedRegister = (UINT16) ExtHdr->NextCapabilityOffset;
+ }
+ return 0x0000; // No Vendor-Specific Extended Capability header
+}
+
+STATIC
+UINT8
+FindSsid_SsvidHeader (
+ IN UINT8 Bus
+ )
+{
+ UINT8 CapHeaderId;
+ UINT8 CapHeaderOffset;
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
+ CapHeaderOffset = PciSegmentRead8 (gDeviceBaseAddress + PCI_CAPBILITY_POINTER_OFFSET);
+
+ while (CapHeaderOffset != 0) {
+ CapHeaderId = PciSegmentRead8 (gDeviceBaseAddress + CapHeaderOffset);
+
+ if (CapHeaderId == PCIE_CAP_ID_SSID_SSVID) {
+ return CapHeaderOffset;
+ }
+
+ CapHeaderOffset = PciSegmentRead8 (gDeviceBaseAddress + CapHeaderOffset + 1);
+ }
+
+ DEBUG((DEBUG_INFO, "SID0\n"));
+ return 0;
+} // FindSsid_SsvidHeader
+
+STATIC
+BOOLEAN
+GetCioSlotByDevId (
+ IN UINT8 Bus,
+ OUT UINT8 *CioSlot,
+ OUT UINT8 *MaxSlotNum,
+ OUT BOOLEAN *ArPcie
+ )
+{
+ UINT16 VSECRegister;
+ BRDG_CIO_MAP_REG BridgMap;
+ UINT32 BitScanRes;
+ UINT16 DevId;
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, 0x00, 0x00, 0);
+ DevId = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+
+ //
+ // Init out params in case device is not recognised
+ //
+ *CioSlot = 4;
+ *MaxSlotNum = 7;
+ *ArPcie = FALSE;
+
+ switch (DevId) {
+ //
+ // For known device IDs
+ //
+ case 0x1578:
+ *ArPcie = TRUE;
+ }
+
+ switch (DevId) {
+ //
+ // For known device IDs
+ //
+ case 0x1513:
+ case 0x151A:
+ case 0x151B:
+ case 0x1547:
+ case 0x1548:
+ return TRUE; // Just return
+ case 0x1549:
+ return FALSE; // Just return
+ }
+
+ VSECRegister = FindVendorSpecificHeader(Bus);
+ if (!VSECRegister) {
+ return TRUE; // Just return
+ }
+ //
+ // Go to Bridge/CIO map register
+ //
+ VSECRegister += 0x18;
+ BridgMap.AB_REG = PciSegmentRead32(gDeviceBaseAddress + VSECRegister);
+ //
+ // Check for range
+ //
+ if (BridgMap.Bits.NumOfDSPorts < 1 || BridgMap.Bits.NumOfDSPorts > 27) {
+ return TRUE;
+ //
+ // Not a valid register
+ //
+ }
+ //
+ // Set OUT params
+ //
+ *MaxSlotNum = (UINT8) BridgMap.Bits.NumOfDSPorts;
+
+#ifdef _MSC_VER
+ if(!_BitScanForward(&BitScanRes, BridgMap.Bits.CioPortMap)) { // No DS bridge which is CIO port
+ return FALSE;
+ }
+#else
+#ifdef __GNUC__
+ if (BridgMap.Bits.CioPortMap == 0) {
+ return FALSE;
+ }
+ BitScanRes = __builtin_ctz (BridgMap.Bits.CioPortMap);
+#else
+#error Unsupported Compiler
+#endif
+#endif
+
+ *CioSlot = (UINT8)BitScanRes;
+ return TRUE;
+} // GetCioSlotByDevId
+
+#define TBT_LEGACY_SUB_SYS_ID 0x11112222
+
+STATIC
+BOOLEAN
+IsLegacyDevice (
+ IN UINT8 Bus
+ )
+{
+ UINT32 Sid;
+ UINT8 SidRegister;
+ UINT16 DevId;
+
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x00, 0);
+ DevId = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+ switch (DevId) {
+ //
+ // For known device IDs
+ //
+ case 0x1513:
+ case 0x151A:
+ case 0x151B:
+ DEBUG((DEBUG_INFO, "Legacy "));
+ DEBUG((DEBUG_INFO, "DevId = %d\n",DevId));
+ return TRUE;
+ //
+ // Legacy device by Device Id
+ //
+ }
+
+ SidRegister = FindSsid_SsvidHeader(Bus);
+
+ if (!SidRegister) {
+ return TRUE; // May be absent for legacy devices
+ }
+ //
+ // Go to register
+ //
+ SidRegister += 0x4;
+ Sid = PciSegmentRead32(gDeviceBaseAddress + SidRegister);
+ DEBUG((DEBUG_INFO, "SID"));
+ DEBUG((DEBUG_INFO, " = %d\n", Sid));
+
+return TBT_LEGACY_SUB_SYS_ID == Sid || 0 == Sid;
+} // IsLegacyDevice
+
+STATIC
+VOID
+UnsetVescEp(
+ IN UINT8 Bus,
+ IN UINT8 MaxSlotNum
+ )
+{
+ UINT8 i;
+
+ for (i = 0; i <= MaxSlotNum; ++i)
+ {
+ UnsetVesc(Bus, i, 0);
+ }
+}// Unset_VESC_REG2_EP
+
+STATIC
+BOOLEAN
+ConfigureEP (
+ IN INT8 Depth,
+ IN OUT UINT8 *Bus,
+ IN OUT PORT_INFO *PortInfo
+ )
+{
+ UINT8 SBus;
+ UINT8 CioSlot;
+ UINT8 MaxSlotNum;
+ BOOLEAN ArPcie;
+ UINT8 MaxPHYSlots;
+ UINT8 UsedBusNumbers;
+ UINT8 cmd;
+ BOOLEAN CioSlotPresent;
+ BOOLEAN Continue;
+ PORT_INFO PortInfoOrg;
+ UINT8 CioBus;
+
+ CioSlot = 4;
+ MaxSlotNum = 7;
+ CopyMem (&PortInfoOrg, PortInfo, sizeof (PORT_INFO));
+
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, *Bus, 0x00, 0x00, 0);
+ cmd = PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET);
+ // AR ONLY
+ // Endpoint on CIO slot, but not a bridge device
+ if (P2P_BRIDGE != PciSegmentRead16 (gDeviceBaseAddress + (PCI_CLASSCODE_OFFSET + 1))) {
+ DEBUG((DEBUG_INFO, "UEP\n"));
+ // Check whether EP already configured by examining CMD register
+ if(cmd & CMD_BUS_MASTER) // Yes, no need to touch this EP
+ {
+ DEBUG((DEBUG_INFO, "BMF\n"));
+ return FALSE;
+ }
+ // Configure it as regular PCIe device
+ ConfigureSlot(*Bus, PCI_MAX_DEVICE + 1, -1, FALSE, PortInfo);
+
+ return FALSE;
+ }
+
+ //
+ // Based on Device ID assign Cio slot and max number of PHY slots to scan
+ //
+ CioSlotPresent = GetCioSlotByDevId(*Bus, &CioSlot, &MaxSlotNum, &ArPcie);
+ MaxPHYSlots = MaxSlotNum;
+ //
+ // Check whether EP already configured by examining CMD register
+ //
+
+ if (cmd & CMD_BUS_MASTER) {
+ //
+ // Yes no need to touch this EP, just move to next one in chain
+ //
+ CioBus = *Bus + 1;
+ if(ArPcie){
+ UnsetVescEp(CioBus, MaxSlotNum);
+ }
+ if (!CioSlotPresent) {
+ //
+ // Cio slot is not present in EP, just return FALSE
+ //
+ DEBUG((DEBUG_INFO, "BMF\n"));
+ return FALSE;
+ }
+ //
+ // Take all resources from Cio slot and return
+ //
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,CioBus, CioSlot, 0x00, 0);
+ PortInfo->BusNumLimit = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+ PortInfo->IoBase = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase));
+ PortInfo->IoLimit = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit));
+ PortInfo->MemBase = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase));
+ PortInfo->MemLimit = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit));
+ PortInfo->PMemBase64 = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
+ PortInfo->PMemLimit64 = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
+ PortInfo->PMemBase64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
+ PortInfo->PMemLimit64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
+ PortInfo->PMemLimit64 |= 0xF;
+ //
+ // Jump to next EP
+ //
+ *Bus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+ //
+ // Should we continue?
+ //
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus, 0x00, 0x00, 0);
+ Continue = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+ return Continue;
+ }
+ //
+ // Set is legacy dvice
+ //
+ isLegacyDevice = IsLegacyDevice (*Bus);
+
+ SetCioPortResources (
+ *Bus,
+ 0, // Assign all available resources to US port of EP
+ *Bus + 1,
+ PortInfo->BusNumLimit,
+ 0,
+ PortInfo
+ );
+
+ SBus = *Bus + 1;// Jump to DS port
+
+ if (CioSlotPresent) {
+ MaxPHYSlots = CioSlot;
+ }
+
+ UsedBusNumbers = ConfigureSlot(SBus, MaxPHYSlots, Depth, ArPcie, PortInfo);
+ if (!CioSlotPresent) {
+ return FALSE;
+ //
+ // Stop resource assignment on this chain
+ //
+ }
+ //
+ // Set rest of slots us unused
+ //
+ SetSlotsAsUnused (SBus, MaxSlotNum, CioSlot, PortInfo);
+
+ SetCioPortResources (
+ SBus,
+ CioSlot,
+ SBus + UsedBusNumbers + 1,
+ PortInfo->BusNumLimit,
+ &PortInfoOrg,
+ PortInfo
+ );
+ *Bus = SBus + UsedBusNumbers + 1;// Go to next EP
+ if(ArPcie) {
+ UnsetVesc(SBus, CioSlot, 0x00);
+ }
+ if (*Bus > PortInfo->BusNumLimit - 2) {
+ //
+ // In case of bus numbers are exhausted stop enumeration
+ //
+ return FALSE;
+ }
+ //
+ // Check whether we should continue on this chain
+ //
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus, 0x00, 0x00, 0);
+ Continue = 0xFFFF != PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+ return Continue;
+} // ConfigureEP
+
+STATIC
+VOID
+GetPortResources (
+ IN UINT8 Bus,
+ IN UINT8 Dev,
+ IN UINT8 Fun,
+ IN OUT PORT_INFO *PortInfo
+ )
+{
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+ PortInfo->BusNumLimit = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+ PortInfo->IoBase = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase)) & 0xF0;
+ PortInfo->IoLimit = PciSegmentRead8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit)) & 0xF0;
+ PortInfo->MemBase = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase)) & 0xFFF0;
+ PortInfo->MemLimit = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit)) & 0xFFF0;
+ PortInfo->PMemBase64 = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0;
+ PortInfo->PMemLimit64 = PciSegmentRead16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0;
+ PortInfo->PMemBase64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16;
+ PortInfo->PMemLimit64 |= (UINT64)(PciSegmentRead32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16;
+ PortInfo->IoLimit |= 0xF;
+ PortInfo->MemLimit |= 0xF;
+ PortInfo->PMemLimit64 |= 0xF;
+} // GetPortResources
+
+STATIC
+VOID
+ConfigurePort (
+ IN UINT8 Bus,
+ IN UINT8 Dev,
+ IN UINT8 Fun,
+ IN OUT PORT_INFO *PortInfo
+ )
+{
+ INT8 i;
+ UINT8 USBusNum;
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+ USBusNum = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment, USBusNum, 0x00, 0x00, 0);
+ if (0xFFFF == PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET)) {
+ //
+ // Nothing to do if TBT device is not connected
+ //
+ return ;
+ }
+
+ GetPortResources(Bus, Dev, Fun, PortInfo);// Take reserved resources from DS port
+ //
+ // Assign resources to EPs
+ //
+ for (i = 0; i < MAX_TBT_DEPTH; ++i) {
+ PortInfo->ConfedEP++;
+ if (!ConfigureEP (i, &USBusNum, PortInfo)) {
+ return ;
+ }
+ }
+} // ConfigurePort
+
+VOID
+ThunderboltCallback (
+ IN UINT8 Type
+ )
+{
+ PORT_INFO PortInfoOrg = { 0 };
+ HR_CONFIG HrConfig = { 0 };
+ UINT8 i;
+ UINTN Segment = 0;
+ UINTN Bus = 0;
+ UINTN Device;
+ UINTN Function;
+
+ DEBUG((DEBUG_INFO, "ThunderboltCallback.Entry\n"));
+
+ DEBUG((DEBUG_INFO, "PortInfo Initialization\n"));
+ PortInfoInit (&PortInfoOrg);
+ if(Type == DTBT_CONTROLLER) {
+ if (gCurrentDiscreteTbtRootPort == 0) {
+ DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
+ return;
+ }
+ GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType, gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
+ DEBUG((DEBUG_INFO, "InitializeHostRouter. \n"));
+ if (!InitializeHostRouter (&HrConfig, Segment, Bus, Device, Function)) {
+ return ;
+ }
+ //
+ // Configure DS ports
+ //
+ for (i = HrConfig.MinDSNumber; i <= HrConfig.MaxDSNumber; ++i) {
+ DEBUG((DEBUG_INFO, "ConfigurePort. \n"));
+ ConfigurePort (HrConfig.HRBus + 1, i,0, &PortInfoOrg);
+ }
+
+ DEBUG((DEBUG_INFO, "EndOfThunderboltCallback.\n"));
+ EndOfThunderboltCallback (Segment, Bus, Device, Function);
+
+ }
+ DEBUG((DEBUG_INFO, "ThunderboltCallback.Exit\n"));
+} // ThunderboltCallback
+
+VOID
+DisablePCIDevicesAndBridges (
+ IN UINT8 MinBus,
+ IN UINT8 MaxBus
+ )
+{
+ UINT8 Bus;
+ UINT8 Dev;
+ UINT8 Fun;
+ UINT8 RegVal;
+ //
+ // Disable PCI device First, and then Disable PCI Bridge
+ //
+ for (Bus = MaxBus; Bus > MinBus; --Bus) {
+ for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+ for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+ if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress + PCI_VENDOR_ID_OFFSET)) {
+ if (Fun == 0) {
+ break;
+
+ }
+
+ continue;
+ }
+
+ RegVal = PciSegmentRead8 (gDeviceBaseAddress + PCI_HEADER_TYPE_OFFSET);
+ if (HEADER_TYPE_DEVICE == (RegVal & 1)) {
+ //
+ // ******** Disable PCI Device ********
+ // BIT0 I/O Space Enabled BIT1 Memory Space Enabled
+ // BIT2 Bus Master Enabled BIT4 Memory Write and Invalidation Enable
+ //
+ PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
+ PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX0 * 4), 0);
+ PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX1 * 4), 0);
+ PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX2 * 4), 0);
+ PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX3 * 4), 0);
+ PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX4 * 4), 0);
+ PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PCI_BAR_IDX5 * 4), 0);
+ }
+ }
+ }
+ }
+ //
+ // now no more PCI dev on another side of PCI Bridge can safty disable PCI Bridge
+ //
+ for (Bus = MaxBus; Bus > MinBus; --Bus) {
+ for (Dev = 0; Dev <= PCI_MAX_DEVICE; ++Dev) {
+ for (Fun = 0; Fun <= PCI_MAX_FUNC; ++Fun) {
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun, 0);
+ if (INVALID_PCI_DEVICE == PciSegmentRead32 (gDeviceBaseAddress + PCI_VENDOR_ID_OFFSET)) {
+ if (Fun == 0) {
+ break;
+ }
+
+ continue;
+ }
+
+ RegVal = PciSegmentRead8 (gDeviceBaseAddress + PCI_HEADER_TYPE_OFFSET);
+ if (HEADER_TYPE_PCI_TO_PCI_BRIDGE == (RegVal & BIT0)) {
+ PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, (UINT8)~(BIT0 | BIT1 | BIT2 | BIT4));
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET, 0);
+ PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 0);
+ PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32), 0);
+ }
+ } // for ( Fun .. )
+ } // for ( Dev ... )
+ } // for ( Bus ... )
+} // DisablePCIDevicesAndBridges
+
+VOID
+TbtDisablePCIDevicesAndBridges (
+ IN UINT8 Type
+ )
+{
+ UINTN Segment = 0;
+ UINTN Bus = 0;
+ UINTN Device;
+ UINTN Function;
+ UINT8 MinBus;
+ UINT8 MaxBus;
+ UINT16 DeviceId;
+
+ MinBus = 1;
+ if(Type == DTBT_CONTROLLER) {
+ //
+ // for(Dev = 0; Dev < 8; ++Dev)
+ // {
+ // PciOr8(PCI_LIB_ADDRESS(2, Dev, 0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0x40);
+ // gBS->Stall(2000); // 2msec
+ // PciAnd8(PCI_LIB_ADDRESS(2, Dev, 0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET), 0xBF);
+ // }
+ // gBS->Stall(200 * 1000); // 200 msec
+ //
+ if (gCurrentDiscreteTbtRootPort == 0) {
+ DEBUG((DEBUG_ERROR, "Invalid RP Input\n"));
+ return;
+ }
+ GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType, gCurrentDiscreteTbtRootPort - 1, &Device, &Function);
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, 0);
+ MinBus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+ MaxBus = PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+ gDeviceBaseAddress = PCI_SEGMENT_LIB_ADDRESS (Segment, MinBus, 0x00, 0x00, 0);
+ DeviceId = PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_OFFSET);
+ if (!(IsTbtHostRouter (DeviceId))) {
+ return;
+ }
+ TbtSegment = (UINT8)Segment;
+ MinBus++;
+ //
+ // @todo : Move this out when we dont have Loop for ITBT
+ //
+ DisablePCIDevicesAndBridges(MinBus, MaxBus);
+
+ }
+} // DisablePCIDevicesAndBridges
+
+
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h
new file mode 100644
index 0000000000..22f6aeeb7f
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.h
@@ -0,0 +1,185 @@
+/**@file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef _TBT_SMI_HANDLER_H_
+#define _TBT_SMI_HANDLER_H_
+
+#include <Library/TbtCommonLib.h>
+#include <Library/IoLib.h>
+#include <IndustryStandard/Pci.h>
+
+#ifdef PROGRESS_CODE
+#undef PROGRESS_CODE
+#endif
+
+#define MAX_TBT_DEPTH 6
+
+#define P2P_BRIDGE (((PCI_CLASS_BRIDGE) << 8) | (PCI_CLASS_BRIDGE_P2P))
+
+#define BAR_ALIGN(v, a) ((((v) - 1) | (a)) + 1)
+
+#define CMD_BUS_MASTER BIT2
+#define CMD_BM_IO (CMD_BUS_MASTER | BIT0)
+#define CMD_BM_MEM (CMD_BUS_MASTER | BIT1)
+#define CMD_BM_MEM_IO (CMD_BUS_MASTER | BIT1 | BIT0)
+
+#define DEF_CACHE_LINE_SIZE 0x20
+#define DEF_RES_IO_PER_DEV 4
+#define DEF_RES_MEM_PER_DEV 32
+#define DEF_RES_PMEM_PER_DEV 32
+
+#define DOCK_BUSSES 8
+
+#define DISBL_IO_REG1C 0x01F1
+#define DISBL_MEM32_REG20 0x0000FFF0
+#define DISBL_PMEM_REG24 0x0001FFF1
+
+#define count(x) (sizeof (x) / sizeof ((x)[0]))
+
+#define PCIE_CAP_ID_SSID_SSVID 0x0D
+#define INVALID_PCI_DEVICE 0xFFFFFFFF
+#define PCI_TBT_VESC_REG2 0x510
+
+typedef struct _PortInfo {
+ UINT8 IoBase;
+ UINT8 IoLimit;
+ UINT16 MemBase;
+ UINT16 MemLimit;
+ UINT64 PMemBase64;
+ UINT64 PMemLimit64;
+ UINT8 BusNumLimit;
+ UINT8 ConfedEP;
+} PORT_INFO;
+
+typedef struct _MEM_REGS {
+ UINT32 Base;
+ UINT32 Limit;
+} MEM_REGS;
+
+typedef struct _PMEM_REGS {
+ UINT64 Base64;
+ UINT64 Limit64;
+} PMEM_REGS;
+
+typedef struct _IO_REGS {
+ UINT16 Base;
+ UINT16 Limit;
+} IO_REGS;
+
+typedef struct _BRDG_RES_CONFIG {
+ UINT8 Cmd;
+ UINT8 Cls;
+ UINT8 IoBase;
+ UINT8 IoLimit;
+ UINT16 MemBase;
+ UINT16 MemLimit;
+ UINT64 PMemBase64;
+ UINT64 PMemLimit64;
+} BRDG_RES_CONFIG;
+
+typedef struct _BRDG_CONFIG {
+ DEV_ID DevId;
+ UINT8 PBus;
+ UINT8 SBus;
+ UINT8 SubBus;
+ BOOLEAN IsDSBridge;
+ BRDG_RES_CONFIG Res;
+} BRDG_CONFIG;
+
+enum {
+ HR_US_PORT,
+ HR_DS_PORT0,
+ HR_DS_PORT3,
+ HR_DS_PORT4,
+ HR_DS_PORT5,
+ HR_DS_PORT6,
+ MAX_CFG_PORTS
+};
+
+enum {
+ HR_DS_PORT1 = HR_DS_PORT3
+};
+
+//
+// Alpine Ridge
+//
+enum {
+ AR_DS_PORT1 = HR_DS_PORT3,
+ AR_DS_PORT2,
+ AR_DS_PORT3,
+ AR_DS_PORT4
+};
+
+typedef struct _HR_CONFIG {
+ UINT16 DeviceId;
+ UINT8 HRBus;
+ UINT8 MinDSNumber;
+ UINT8 MaxDSNumber;
+ UINT8 BridgeLoops;
+} HR_CONFIG;
+
+STATIC const BRDG_RES_CONFIG NOT_IN_USE_BRIDGE = {
+ CMD_BUS_MASTER,
+ 0,
+ DISBL_IO_REG1C & 0xFF,
+ DISBL_IO_REG1C >> 8,
+ DISBL_MEM32_REG20 & 0xFFFF,
+ DISBL_MEM32_REG20 >> 16,
+ DISBL_PMEM_REG24 & 0xFFFF,
+ DISBL_PMEM_REG24 >> 16
+};
+
+typedef union _BRDG_CIO_MAP_REG {
+ UINT32 AB_REG;
+ struct {
+ UINT32 NumOfDSPorts : 5;
+ UINT32 CioPortMap : 27;
+ } Bits;
+} BRDG_CIO_MAP_REG;
+
+//
+// Functions
+//
+VOID
+ThunderboltCallback (
+ IN UINT8 Type
+ );
+
+VOID
+TbtDisablePCIDevicesAndBridges (
+ IN UINT8 Type
+ );
+
+VOID
+EndOfThunderboltCallback(
+ IN UINTN RpSegment,
+ IN UINTN RpBus,
+ IN UINTN RpDevice,
+ IN UINTN RpFunction
+);
+
+VOID
+ConfigureTbtAspm(
+ IN UINT8 Type,
+ IN UINT16 Aspm
+);
+
+UINT8
+PcieFindCapId (
+ IN UINT8 Segment,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT8 CapId
+ );
+
+#endif
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c
new file mode 100644
index 0000000000..f2abfb0db9
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c
@@ -0,0 +1,1771 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// 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
+} \ No newline at end of file
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf
new file mode 100644
index 0000000000..31ecb9767a
--- /dev/null
+++ b/Platform/Intel/KabylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf
@@ -0,0 +1,83 @@
+### @file
+# Component information file for the ThunderBolt Smm module.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[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
+ KabylakeOpenBoardPkg/OpenBoardPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+ gBoardModuleTokenSpaceGuid.PcdSwSmiDTbtEnumerate ## CONSUMES
+ gSiPkgTokenSpaceGuid.PcdPciExpressRegionLength ## CONSUMES
+
+[FixedPcd]
+ gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress ## CONSUMES
+
+[Sources]
+ TbtSmiHandler.h
+ TbtSmiHandler.c
+ TbtSmm.c
+
+[Protocols]
+ gTbtNvsAreaProtocolGuid ## CONSUMES
+ gEfiSmmSxDispatch2ProtocolGuid ## CONSUMES
+ gEfiSmmSwDispatch2ProtocolGuid ## CONSUMES
+ gEfiSmmVariableProtocolGuid ## CONSUMES
+ gDxeTbtPolicyProtocolGuid
+
+[Guids]
+ gTbtInfoHobGuid ## CONSUMES
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## CONSUMES
+
+[Depex]
+ gEfiSmmBase2ProtocolGuid AND
+ gEfiSmmSxDispatch2ProtocolGuid AND
+ gEfiSmmSwDispatch2ProtocolGuid AND
+ gEfiGlobalNvsAreaProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid AND
+ gEfiVariableArchProtocolGuid AND
+ gEfiSmmVariableProtocolGuid
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkg.dsc b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkg.dsc
index 139ce8c057..6dd6234a63 100644
--- a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkg.dsc
+++ b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkg.dsc
@@ -107,6 +107,11 @@
BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/BoardInitLibNull/BoardInitLibNull.inf
TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLibNull/TestPointCheckLibNull.inf
+# Tbt
+!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+ TbtCommonLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
+ DxeTbtPolicyLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
+!endif
#
# Silicon Init Package
#
@@ -124,6 +129,11 @@
MultiBoardInitSupportLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/PeiMultiBoardInitSupportLib.inf
BoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/MultiBoardInitSupportLib/PeiMultiBoardInitSupportLib.inf
+# Tbt
+!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+ PeiTbtPolicyLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
+ PeiDTbtInitLib|$(PLATFORM_BOARD_PACKAGE)/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
+!endif
#
# Silicon Init Package
#
@@ -232,6 +242,11 @@
IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf
IntelSiliconPkg/Feature/VTd/PlatformVTdInfoSamplePei/PlatformVTdInfoSamplePei.inf
+# Tbt
+!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+ $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
+!endif
+
[Components.X64]
#
@@ -254,6 +269,13 @@
#
!include $(PLATFORM_SI_PACKAGE)/SiPkgDxe.dsc
+# Tbt
+!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+ $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Smm/TbtSmm.inf
+ $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
+ $(PLATFORM_BOARD_PACKAGE)/Features/PciHotPlug/PciHotPlug.inf
+!endif
+
#
# Platform
#
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkg.fdf b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkg.fdf
index 3d2ef2b4aa..574d2b7878 100644
--- a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkg.fdf
+++ b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkg.fdf
@@ -600,7 +600,74 @@ FILE FV_IMAGE = C83522D9-80A1-4D95-8C25-3F1370497406 {
SECTION FV_IMAGE = FvSecurityLate
}
}
-
+
+[FV.FvAdvancedPreMem]
+FvAlignment = 16
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+FvNameGuid = 6053D78A-457E-4490-A237-31D0FBE2F305
+
+!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+INF $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf
+!endif
+
+[FV.FvAdvancedPostMem]
+FvAlignment = 16
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+FvNameGuid = BE3DF86F-E464-44A3-83F7-0D27E6B88C27
+
+[FV.FvAdvancedLate]
+FvAlignment = 16
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+FvNameGuid = 11F6E304-43F9-4B2F-90AB-B8FFEAD6205D
+
+!if gBoardModuleTokenSpaceGuid.PcdTbtEnable == TRUE
+INF $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Dxe/TbtDxe.inf
+INF $(PLATFORM_BOARD_PACKAGE)/Features/PciHotPlug/PciHotPlug.inf
+INF $(PLATFORM_BOARD_PACKAGE)/Features/Tbt/TbtInit/Smm/TbtSmm.inf
+!endif
+
[FV.FvAdvanced]
BlockSize = $(FLASH_BLOCK_SIZE)
FvAlignment = 16
@@ -621,6 +688,20 @@ READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = TRUE
FvNameGuid = B23E7388-9953-45C7-9201-0473DDE5487A
+FILE FV_IMAGE = 35E7406A-5842-4F2B-BC62-19022C12AF74 {
+ SECTION FV_IMAGE = FvAdvancedPreMem
+ }
+
+FILE FV_IMAGE = F5DCB34F-27EA-48AC-9406-C894F6D587CA {
+ SECTION FV_IMAGE = FvAdvancedPostMem
+ }
+
+FILE FV_IMAGE = 5248467B-B87B-4E74-AC02-398AF4BCB712 {
+ SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+ SECTION FV_IMAGE = FvAdvancedLate
+ }
+ }
+
################################################################################
#
# Rules are use with the [FV] section's module INF type to define
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkgConfig.dsc b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkgConfig.dsc
index d566967b86..600a3288ae 100644
--- a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkgConfig.dsc
+++ b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkgConfig.dsc
@@ -52,6 +52,7 @@
gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable|TRUE
!endif
+ gBoardModuleTokenSpaceGuid.PcdTbtEnable|TRUE
#
# More fine granularity control below:
#
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkgPcd.dsc b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkgPcd.dsc
index 36274af337..92b9ad8bcf 100644
--- a/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkgPcd.dsc
+++ b/Platform/Intel/KabylakeOpenBoardPkg/KabylakeRvp3/OpenBoardPkgPcd.dsc
@@ -249,4 +249,35 @@ gSiPkgTokenSpaceGuid.PcdTsegSize|0x800000
gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap|0
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2HashMask|0x0000001F
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy|1
+
+# Tbt
+gBoardModuleTokenSpaceGuid.PcdDTbtControllerEn | 0x1
+gBoardModuleTokenSpaceGuid.PcdDTbtControllerType | 0x1
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieRpNumber | 0x1
+gBoardModuleTokenSpaceGuid.PcdDTbtGpioAccessType | 0x2
+gBoardModuleTokenSpaceGuid.PcdExpander | 0x0
+gBoardModuleTokenSpaceGuid.PcdDTbtGpioLevel | 0x1
+gBoardModuleTokenSpaceGuid.PcdDTbtForcepowerGpioPad | 13
+gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad | 0x02010011
+gBoardModuleTokenSpaceGuid.PcdDTbtAcpiGpeSignature | 0
+gBoardModuleTokenSpaceGuid.PcdDTbtAcpiGpeSignaturePorting | 0
+gBoardModuleTokenSpaceGuid.PcdDTbtSecurityMode | 0x1
+#gBoardModuleTokenSpaceGuid.PcdDTbtGpio5Filter | 0x0
+gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport | 0x0
+gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI | 0x1
+gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify | 0x1
+gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq| 0x1
+gBoardModuleTokenSpaceGuid.PcdDTbtAspm | 0x0
+gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch | 0x0
+gBoardModuleTokenSpaceGuid.PcdRtd3Tbt | 0x1
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq | 0x1
+gBoardModuleTokenSpaceGuid.PcdDTbtWin10Support | 0x0
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReqDelay | 0x0
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtOffDelay | 5000
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieExtraBusRsvd | 56
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemRsvd | 100
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax | 26
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd | 100
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax | 28
+gBoardModuleTokenSpaceGuid.PcdPchPcieRootPortHpe| 0x00000001
diff --git a/Platform/Intel/KabylakeOpenBoardPkg/OpenBoardPkg.dec b/Platform/Intel/KabylakeOpenBoardPkg/OpenBoardPkg.dec
index ddd7c47bc8..d0fdb109f1 100644
--- a/Platform/Intel/KabylakeOpenBoardPkg/OpenBoardPkg.dec
+++ b/Platform/Intel/KabylakeOpenBoardPkg/OpenBoardPkg.dec
@@ -27,6 +27,7 @@ PACKAGE_GUID = 0A8BA6E8-C8AC-4AC1-87AC-52772FA6AE5E
[Includes]
Include
KabylakeRvp3\Include
+Features\Tbt\Include
[Guids]
@@ -34,9 +35,18 @@ gBoardModuleTokenSpaceGuid = {0x72d1fff7, 0xa42a, 0x4219, {0xb9, 0x9
gTianoLogoGuid = {0x7BB28B99, 0x61BB, 0x11D5, {0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}
+gTbtInfoHobGuid = {0x74a81eaa, 0x033c, 0x4783, {0xbe, 0x2b, 0x84, 0x85, 0x74, 0xa6, 0x97, 0xb7}}
+
+gPlatformModuleTokenSpaceGuid = {0x69d13bf0, 0xaf91, 0x4d96, {0xaa, 0x9f, 0x21, 0x84, 0xc5, 0xce, 0x3b, 0xc0}}
+
+
[Protocols]
+gTbtNvsAreaProtocolGuid = {0x4d6a54d1, 0xcd56, 0x47f3, {0x93, 0x6e, 0x7e, 0x51, 0xd9, 0x31, 0x15, 0x4f}}
+gDxeTbtPolicyProtocolGuid = {0x196bf9e3, 0x20d7, 0x4b7b, {0x89, 0xf9, 0x31, 0xc2, 0x72, 0x08, 0xc9, 0xb9}}
[Ppis]
+gPeiTbtPolicyPpiGuid = {0xd7e7e1e6, 0xcbec, 0x4f5f, {0xae, 0xd3, 0xfd, 0xc0, 0xa8, 0xb0, 0x7e, 0x25}}
+gPeiTbtPolicyBoardInitDonePpiGuid = {0x970f9c60, 0x8547, 0x49d7, { 0xa4, 0xb, 0x1e, 0xc4, 0xbc, 0x4e, 0xe8, 0x9b}}
[LibraryClasses]
@@ -56,8 +66,8 @@ gBoardModuleTokenSpaceGuid.PcdSioBaseAddress|0x0680|UINT16|0x9000001D
gBoardModuleTokenSpaceGuid.PcdLpcSioIndexDefaultPort|0x164E|UINT16|0x90000021
gBoardModuleTokenSpaceGuid.PcdLpcSioDataDefaultPort|0x164F|UINT16|0x90000022
-
-
+## Tbt SW_SMI_DTBT_ENUMERATEgSetupVariableGuid
+gBoardModuleTokenSpaceGuid.PcdSwSmiDTbtEnumerate|0xF7|UINT8|0x000000110
gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition|0x01|UINT8|0x90000015
@@ -231,6 +241,45 @@ gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort7|0|UINT8|0x000000E6
gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort8|0|UINT8|0x000000E7
gBoardModuleTokenSpaceGuid.PcdUsb30OverCurrentPinPort9|0|UINT8|0x000000E8
+# TBT
+gBoardModuleTokenSpaceGuid.PcdDTbtBootOn |0|UINT8|0x000000E9
+gBoardModuleTokenSpaceGuid.PcdDTbtUsbOn |0|UINT8|0x000000EA
+gBoardModuleTokenSpaceGuid.PcdDTbtGpio3ForcePwr |0|UINT8|0x000000EB
+gBoardModuleTokenSpaceGuid.PcdDTbtGpio3ForcePwrDly |0|UINT16|0x000000ED
+gBoardModuleTokenSpaceGuid.PcdDTbtControllerEn |0|UINT8|0x000000EE
+gBoardModuleTokenSpaceGuid.PcdDTbtControllerType |0|UINT8|0x000000EF
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieRpNumber |0|UINT8|0x000000F0
+gBoardModuleTokenSpaceGuid.PcdDTbtGpioAccessType |0|UINT8|0x000000F1
+gBoardModuleTokenSpaceGuid.PcdExpander |0|UINT8|0x000000F2
+gBoardModuleTokenSpaceGuid.PcdDTbtGpioLevel |0|BOOLEAN|0x000000F3
+gBoardModuleTokenSpaceGuid.PcdDTbtForcepowerGpioPad |0|UINT32|0x000000F4
+gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad |0|UINT32|0x000000F5
+gBoardModuleTokenSpaceGuid.PcdDTbtAcpiGpeSignature |0|UINT32|0x000000F6
+gBoardModuleTokenSpaceGuid.PcdDTbtAcpiGpeSignaturePorting |0|BOOLEAN|0x000000F7
+gBoardModuleTokenSpaceGuid.PcdDTbtSecurityMode |0|UINT8|0x000000F8
+gBoardModuleTokenSpaceGuid.PcdDTbtGpio5Filter |0|UINT8|0x000000F9
+gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport |0|UINT8|0x000000FA
+gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI |0|UINT8|0x000000FB
+gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify |0|UINT8|0x000000FC
+gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq|0|UINT8|0x000000FD
+gBoardModuleTokenSpaceGuid.PcdDTbtAspm |0|UINT8|0x000000FE
+gBoardModuleTokenSpaceGuid.PcdDTbtLtr | 0 | UINT8| 0x00000116
+gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch |0|UINT8|0x000000FF
+gBoardModuleTokenSpaceGuid.PcdRtd3Tbt |0|UINT8|0x00000100
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq |0|UINT8|0x0000010A
+gBoardModuleTokenSpaceGuid.PcdDTbtWin10Support |0|UINT8|0x000000102
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReqDelay |0|UINT16|0x00000103
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtOffDelay |0|UINT16|0x00000104
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieExtraBusRsvd |0|UINT8|0x00000105
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemRsvd |0|UINT16|0x00000106
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax |0|UINT8|0x00000107
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd |0|UINT16|0x00000108
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax |0|UINT8|0x00000109
+gBoardModuleTokenSpaceGuid.PcdPchPcieRootPortHpe|0|UINT32|0x00000117
+
+
+
+
# UCMC GPIO Table
gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTable|0|UINT32|0x000000111
gBoardModuleTokenSpaceGuid.PcdBoardUcmcGpioTableSize|0|UINT16|0x000000112
@@ -267,3 +316,5 @@ gBoardModuleTokenSpaceGuid.PcdIoExpanderPresent|FALSE|BOOLEAN|0x000000EC
gBoardModuleTokenSpaceGuid.PcdIntelGopEnable |TRUE|BOOLEAN|0xF0000062
gBoardModuleTokenSpaceGuid.PcdMultiBoardSupport |TRUE|BOOLEAN|0xF0000000
+
+ gBoardModuleTokenSpaceGuid.PcdTbtEnable |FALSE|BOOLEAN|0x000000115