From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.120; helo=mga04.intel.com; envelope-from=michael.a.kubacki@intel.com; receiver=edk2-devel@lists.01.org Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id B52D7211C385B for ; Wed, 30 Jan 2019 22:12:19 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 30 Jan 2019 22:12:18 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,543,1539673200"; d="scan'208";a="134651725" Received: from makuback-desk1.amr.corp.intel.com ([10.9.70.181]) by orsmga001.jf.intel.com with ESMTP; 30 Jan 2019 22:12:17 -0800 From: Michael Kubacki To: edk2-devel@lists.01.org Cc: Hao Wu , Liming Gao , Jiewen Yao , Michael D Kinney Date: Wed, 30 Jan 2019 22:11:15 -0800 Message-Id: <20190131061117.36916-6-michael.a.kubacki@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 In-Reply-To: <20190131061117.36916-1-michael.a.kubacki@intel.com> References: <20190131061117.36916-1-michael.a.kubacki@intel.com> Subject: [edk2-platforms/devel-MinPlatform][PATCH v4 5/7] ClevoOpenBoardPkg: Add modules X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 31 Jan 2019 06:12:20 -0000 Based on KabylakeOpenBoardPkg from the following branch: https://github.com/tianocore/edk2-platforms/tree/devel-MinPlatform Modules shared across Clevo board instances. * BoardAcpiDxe - Performs DXE board ACPI initialization. * PciHotPlug - Performs PCI-e resource configuration. * PeiTbtInit - Initializes Thunderbolt policy in PEI. * TbtDxe - Performs Thunderbolt initialization in DXE. * TbtSmm - Performs Thunderbolt initialization in SMM. Cc: Hao Wu Cc: Liming Gao Cc: Jiewen Yao Cc: Michael D Kinney Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kubacki --- .../Acpi/BoardAcpiDxe/BoardAcpiDxe.inf | 75 + .../Features/PciHotPlug/PciHotPlug.inf | 65 + .../Features/Tbt/TbtInit/Dxe/TbtDxe.inf | 55 + .../Features/Tbt/TbtInit/Pei/PeiTbtInit.inf | 50 + .../Features/Tbt/TbtInit/Smm/TbtSmm.inf | 83 + .../Acpi/BoardAcpiDxe/AcpiGnvsInit.c | 101 ++ .../Acpi/BoardAcpiDxe/BoardAcpiDxe.c | 313 ++++ .../Acpi/BoardAcpiDxe/UpdateDsdt.c | 782 ++++++++ .../Features/PciHotPlug/PciHotPlug.c | 357 ++++ .../Features/Tbt/TbtInit/Dxe/TbtDxe.c | 234 +++ .../Features/Tbt/TbtInit/Pei/PeiTbtInit.c | 199 ++ .../Features/Tbt/TbtInit/Smm/TbtSmiHandler.c | 1616 +++++++++++++++++ .../Features/Tbt/TbtInit/Smm/TbtSmm.c | 1770 ++++++++++++++++++ .../Acpi/BoardAcpiDxe/Dsdt/ALS.ASL | 43 + .../Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl | 27 + .../Acpi/BoardAcpiDxe/Dsdt/CPU.asl | 252 +++ .../Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL | 127 ++ .../Acpi/BoardAcpiDxe/Dsdt/Gpe.asl | 856 +++++++++ .../Acpi/BoardAcpiDxe/Dsdt/Itss.asl | 39 + .../Acpi/BoardAcpiDxe/Dsdt/LPC_DEV.ASL | 205 +++ .../Acpi/BoardAcpiDxe/Dsdt/LpcB.asl | 94 + .../Acpi/BoardAcpiDxe/Dsdt/PCI_DRC.ASL | 122 ++ .../Acpi/BoardAcpiDxe/Dsdt/PciTree.asl | 312 ++++ .../Acpi/BoardAcpiDxe/Dsdt/Platform.asl | 1135 ++++++++++++ .../Acpi/BoardAcpiDxe/Dsdt/PlatformGnvs.asl | 14 + .../Acpi/BoardAcpiDxe/Dsdt/Video.asl | 33 + .../Features/Tbt/AcpiTables/Rtd3SptPcieTbt.asl | 409 +++++ .../Features/Tbt/AcpiTables/Tbt.asl | 1908 ++++++++++++++++++++ .../Features/Tbt/Include/Acpi/TbtNvs.asl | 62 + .../ClevoOpenBoardPkg/Include/Acpi/GlobalNvs.asl | 120 ++ 30 files changed, 11458 insertions(+) create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/UpdateDsdt.c create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/ALS.ASL create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/CPU.asl create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Gpe.asl create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Itss.asl create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/LPC_DEV.ASL create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/LpcB.asl create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PCI_DRC.ASL create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PlatformGnvs.asl create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Video.asl create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3SptPcieTbt.asl create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Include/Acpi/TbtNvs.asl create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Include/Acpi/GlobalNvs.asl diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf new file mode 100644 index 0000000000..e02a1b5587 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf @@ -0,0 +1,75 @@ +### @file +# Component information file for board ACPI initialization. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# 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 = 0x00010005 + BASE_NAME = BoardAcpiDxe + FILE_GUID = E269E77D-6163-4F5D-8E59-21EAF114D307 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = InstallAcpiBoard + +[Sources.common] + BoardAcpiDxe.c + AcpiGnvsInit.c + UpdateDsdt.c + Dsdt/DSDT.ASL + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + MinPlatformPkg/MinPlatformPkg.dec + PcAtChipsetPkg/PcAtChipsetPkg.dec + ClevoOpenBoardPkg/OpenBoardPkg.dec + KabylakeSiliconPkg/SiPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + DebugLib + IoLib + PcdLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + BaseMemoryLib + HobLib + AslUpdateLib + BoardAcpiTableLib + +[Protocols] + gEfiAcpiTableProtocolGuid ## CONSUMES + gEfiFirmwareVolume2ProtocolGuid ## CONSUMES + gEfiMpServiceProtocolGuid ## CONSUMES + gEfiGlobalNvsAreaProtocolGuid + +[Pcd] + gBoardModuleTokenSpaceGuid.PcdAcpiGnvsAddress + + gBoardModuleTokenSpaceGuid.PcdAcpiSleepState + gBoardModuleTokenSpaceGuid.PcdAcpiHibernate + gBoardModuleTokenSpaceGuid.PcdLowPowerS0Idle + gBoardModuleTokenSpaceGuid.PcdDisableActiveTripPoints + gBoardModuleTokenSpaceGuid.PcdDisablePassiveTripPoints + gBoardModuleTokenSpaceGuid.PcdDisableCriticalTripPoints + +[Depex] + gEfiAcpiTableProtocolGuid AND + gEfiFirmwareVolume2ProtocolGuid AND + gEfiPciRootBridgeIoProtocolGuid AND + gEfiVariableArchProtocolGuid AND + gEfiVariableWriteArchProtocolGuid + + diff --git a/Platform/Intel/ClevoOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf b/Platform/Intel/ClevoOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf new file mode 100644 index 0000000000..a1ca0ec072 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf @@ -0,0 +1,65 @@ +### @file +# Performs specific PCI-EXPRESS device resource configuration. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# 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 + ClevoOpenBoardPkg/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/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf new file mode 100644 index 0000000000..f9afa7c2cd --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf @@ -0,0 +1,55 @@ +### @file +# Thunderbolt initialization in DXE. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# 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 + ClevoOpenBoardPkg/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/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf new file mode 100644 index 0000000000..4a7a28a69b --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.inf @@ -0,0 +1,50 @@ +### @file +# Thunderbolt initialization in PEI. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# 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 + ClevoOpenBoardPkg/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/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf new file mode 100644 index 0000000000..97322f3d57 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf @@ -0,0 +1,83 @@ +### @file +# Thunderbolt SMM initialization module. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# 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 + ClevoOpenBoardPkg/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/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c new file mode 100644 index 0000000000..fc2657476d --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c @@ -0,0 +1,101 @@ +/** @file + Acpi Gnvs Init Library. + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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 +#include +#include +#include +#include +#include + +#include +#include +#include + +/** +@brief + Global NVS initialize. + + @param[in] GlobalNvs - Pointer of Global NVS area + + @retval EFI_SUCCESS - Allocate Global NVS completed. + @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for GNVS. +**/ +EFI_STATUS +EFIAPI +AcpiGnvsInit ( + IN OUT VOID **GlobalNvs + ) +{ + UINTN Pages; + EFI_PHYSICAL_ADDRESS Address; + EFI_STATUS Status; + EFI_GLOBAL_NVS_AREA_PROTOCOL *GNVS; + EFI_MP_SERVICES_PROTOCOL *MpService; + UINTN NumberOfCPUs; + UINTN NumberOfEnabledCPUs; + + Pages = EFI_SIZE_TO_PAGES (sizeof (EFI_GLOBAL_NVS_AREA)); + Address = 0xffffffff; // allocate address below 4G. + + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + Pages, + &Address + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR(Status)) { + return Status; + } + + // + // Locate the MP services protocol + // Find the MP Protocol. This is an MP platform, so MP protocol must be there. + // + Status = gBS->LocateProtocol ( + &gEfiMpServiceProtocolGuid, + NULL, + (VOID **) &MpService + ); + ASSERT_EFI_ERROR (Status); + + // + // Determine the number of processors + // + MpService->GetNumberOfProcessors ( + MpService, + &NumberOfCPUs, + &NumberOfEnabledCPUs + ); + + *GlobalNvs = (VOID *) (UINTN) Address; + SetMem (*GlobalNvs, sizeof (EFI_GLOBAL_NVS_AREA), 0); + + // + // GNVS default value init here... + // + GNVS = (EFI_GLOBAL_NVS_AREA_PROTOCOL *) &Address; + + GNVS->Area->ThreadCount = (UINT8)NumberOfEnabledCPUs; + + // + // Miscellaneous + // + GNVS->Area->PL1LimitCS = 0; + GNVS->Area->PL1LimitCSValue = 4500; + + return EFI_SUCCESS; +} + diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c new file mode 100644 index 0000000000..d0a2f4bc84 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c @@ -0,0 +1,313 @@ +/** @file + Board ACPI DXE initialization. + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea; + +/** +@brief + Global NVS initialize. + + @param[in] GlobalNvs - Pointer of Global NVS area + + @retval EFI_SUCCESS - Allocate Global NVS completed. + @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for GNVS. +**/ +EFI_STATUS +EFIAPI +AcpiGnvsInit ( + IN OUT VOID **GlobalNvs + ); + +VOID +UpdateDsdt ( + IN VOID *Table + ); + +// +// Function implementations +// + +/** + Locate the first instance of a protocol. If the protocol requested is an + FV protocol, then it will return the first FV that contains the ACPI table + storage file. + + @param[in] Protocol The protocol to find. + @param[in] Instance Return pointer to the first instance of the protocol. + @param[in] Type TRUE if the desired protocol is a FV protocol. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND The protocol could not be located. + @retval EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol. +**/ +EFI_STATUS +LocateSupportProtocol ( + IN EFI_GUID *Protocol, + IN EFI_GUID *gEfiAcpiMultiTableStorageGuid, + OUT VOID **Instance, + IN BOOLEAN Type + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + EFI_FV_FILETYPE FileType; + UINT32 FvStatus; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINTN Size; + UINTN Index; + + // + // Locate protocol. + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + Protocol, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + // + // Defined errors at this time are not found and out of resources. + // + return Status; + } + + // + // Looking for FV with ACPI storage file + // + for (Index = 0; Index < NumberOfHandles; Index++) { + + // + // Get the protocol on this handle + // This should not fail because of LocateHandleBuffer + // + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + Protocol, + Instance + ); + ASSERT_EFI_ERROR (Status); + + if (!Type) { + + // + // Not looking for the FV protocol, so find the first instance of the + // protocol. There should not be any errors because our handle buffer + // should always contain at least one or LocateHandleBuffer would have + // returned not found. + // + break; + } + + // + // See if it has the ACPI storage file + // + Size = 0; + FvStatus = 0; + Status = ((EFI_FIRMWARE_VOLUME2_PROTOCOL *) (*Instance))->ReadFile ( + *Instance, + gEfiAcpiMultiTableStorageGuid, + NULL, + &Size, + &FileType, + &Attributes, + &FvStatus + ); + + // + // If we found it, then we are done + // + if (Status == EFI_SUCCESS) { + break; + } + } + + // + // Our exit status is determined by the success of the previous operations + // If the protocol was found, Instance already points to it. + // + // + // Free any allocated buffers + // + FreePool (HandleBuffer); + + return Status; +} + +EFI_STATUS +PublishAcpiTablesFromFv ( + IN EFI_GUID *gEfiAcpiMultiTableStorageGuid + ) +{ + EFI_STATUS Status; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; + EFI_ACPI_COMMON_HEADER *CurrentTable; + UINT32 FvStatus; + UINTN Size; + EFI_ACPI_TABLE_VERSION Version; + UINTN TableHandle; + INTN Instance; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + + Instance = 0; + TableHandle = 0; + CurrentTable = NULL; + FwVol = NULL; + + // + // Find the AcpiSupport protocol + // + Status = LocateSupportProtocol ( + &gEfiAcpiTableProtocolGuid, + gEfiAcpiMultiTableStorageGuid, + (VOID **) &AcpiTable, + FALSE + ); + ASSERT_EFI_ERROR (Status); + + // + // Locate the firmware volume protocol + // + Status = LocateSupportProtocol ( + &gEfiFirmwareVolume2ProtocolGuid, + gEfiAcpiMultiTableStorageGuid, + (VOID **) &FwVol, + TRUE + ); + + // + // Read tables from the storage file. + // + + while (Status == EFI_SUCCESS) { + Status = FwVol->ReadSection ( + FwVol, + gEfiAcpiMultiTableStorageGuid, + EFI_SECTION_RAW, + Instance, + (VOID **) &CurrentTable, + &Size, + &FvStatus + ); + + if (!EFI_ERROR (Status)) { + + // + // Perform any table specific updates. + // + if (CurrentTable->Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) { + UpdateDsdt (CurrentTable); + } + BoardUpdateAcpiTable (CurrentTable, &Version); + + // + // Add the table + // + TableHandle = 0; + + if (Version != EFI_ACPI_TABLE_VERSION_NONE) { + Status = AcpiTable->InstallAcpiTable ( + AcpiTable, + CurrentTable, + CurrentTable->Length, + &TableHandle + ); + } + + ASSERT_EFI_ERROR (Status); + + // + // Increment the instance + // + Instance++; + CurrentTable = NULL; + } + } + + // + // Finished + // + return EFI_SUCCESS; +} + +/** + ACPI Platform driver installation function. + + @param[in] ImageHandle Handle for this drivers loaded image protocol. + @param[in] SystemTable EFI system table. + + @retval EFI_SUCCESS The driver installed without error. + @retval EFI_ABORTED The driver encountered an error and could not complete installation of + the ACPI tables. + +**/ +EFI_STATUS +EFIAPI +InstallAcpiBoard ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + AcpiGnvsInit((VOID **) &mGlobalNvsArea.Area); + + // + // This PCD set must be done before PublishAcpiTablesFromFv. + // The PCD data will be used there. + // + PcdSet64S (PcdAcpiGnvsAddress, (UINT64)(UINTN)mGlobalNvsArea.Area); + + // + // Platform ACPI Tables + // + PublishAcpiTablesFromFv (&gEfiCallerIdGuid); + + // + // This protocol publish must be done after PublishAcpiTablesFromFv. + // The NVS data is be updated there. + // + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiGlobalNvsAreaProtocolGuid, + &mGlobalNvsArea, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/UpdateDsdt.c b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/UpdateDsdt.c new file mode 100644 index 0000000000..832c64cd00 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/UpdateDsdt.c @@ -0,0 +1,782 @@ +/** @file + Performs board DSDT ACPI table updates. + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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 +#include +#include +#include +#include +#include + +#include +extern GLOBAL_REMOVE_IF_UNREFERENCED EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea; + +VOID +UpdateDsdt ( + IN VOID *Table + ) +{ + UINT8 *CurrPtr; + UINT8 *TmpDsdtPointer; + UINT8 *DsdtPointer; + UINT32 *Signature; + UINT8 *Operation; + UINT32 *Address; + UINT8 *Value; + UINT16 *Size; + BOOLEAN EnterDock = FALSE; + + UINT8 MaximumDsdtPointLength; + + MaximumDsdtPointLength = 20; + + // + // Fix up the AML code in the DSDT affected by end user options. + // Fix up the following ASL Code: + // (1) ACPI Global NVS Memory Base and Size. + // (2) ACPI Graphics NVS Memory Base and Size. + // (3) SMBus I/O Base. + // (4) Thermal Management Methods. + // + // + // Loop through the ASL looking for values that we must fix up. + // + CurrPtr = (UINT8 *) Table; + for (DsdtPointer = CurrPtr; + DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); + DsdtPointer++ + ) { + Signature = (UINT32 *) DsdtPointer; + switch (*Signature) { + // + // GNVS operation region + // + case (SIGNATURE_32 ('G', 'N', 'V', 'S')): + // + // Conditional match. For Region Objects, the Operator will always be the + // byte immediately before the specific name. Therefore, subtract 1 to check + // the Operator. + // + Operation = DsdtPointer - 1; + if (*Operation == AML_EXT_REGION_OP) { + Address = (UINT32 *) (DsdtPointer + 6); + *Address = (UINT32) (UINTN) mGlobalNvsArea.Area; + Size = (UINT16 *) (DsdtPointer + 11); + *Size = sizeof (EFI_GLOBAL_NVS_AREA); + } + break; + + // + // _AC0 method + // + case (SIGNATURE_32 ('_', 'A', 'C', '0')): + // + // Conditional match. _AC0 is >63 and <4095 bytes, so the package length is 2 bytes. + // Therefore, subtract 3 to check the Operator. + // + Operation = DsdtPointer - 3; + if (*Operation == AML_METHOD_OP) { + // + // Check if we want _AC0 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'C', '0'); + } + } + break; + + // + // _AL0 method + // + case (SIGNATURE_32 ('_', 'A', 'L', '0')): + // + // Conditional match. For Name Objects, the Operator will always be the byte + // immediately before the specific name. Therefore, subtract 1 to check the + // Operator. + // + Operation = DsdtPointer - 1; + if (*Operation == AML_NAME_OP) { + + // + // Check if we want _AL0 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'L', '0'); + } + } + break; + + // + // _AC1 method + // + case (SIGNATURE_32 ('_', 'A', 'C', '1')): + // + // Conditional match. _AC1 is < 63 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 2; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _AC1 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'C', '1'); + } + } + break; + + // + // _AL1 method + // + case (SIGNATURE_32 ('_', 'A', 'L', '1')): + // + // Conditional match. For Name Objects, the Operator will always be the byte + // immediately before the specific name. Therefore, subtract 1 to check the + // Operator. + // + Operation = DsdtPointer - 1; + if (*Operation == AML_NAME_OP) { + + // + // Check if we want _AL1 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'L', '1'); + } + } + break; + + // + // _AC2 method + // + case (SIGNATURE_32 ('_', 'A', 'C', '2')): + // + // Conditional match. _AC2 is < 63 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 2; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _AC2 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'C', '2'); + } + } + break; + + // + // _AL2 method + // + case (SIGNATURE_32 ('_', 'A', 'L', '2')): + // + // Conditional match. For Name Objects, the Operator will always be the byte + // immediately before the specific name. Therefore, subtract 1 to check the + // Operator. + // + Operation = DsdtPointer - 1; + if (*Operation == AML_NAME_OP) { + + // + // Check if we want _AL2 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'L', '2'); + } + } + break; + + // + // _AC3 method + // + case (SIGNATURE_32 ('_', 'A', 'C', '3')): + // + // Conditional match. _AC3 is < 63 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 2; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _AC3 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'C', '3'); + } + } + break; + + // + // _AL3 method + // + case (SIGNATURE_32 ('_', 'A', 'L', '3')): + // + // Conditional match. For Name Objects, the Operator will always be the byte + // immediately before the specific name. Therefore, subtract 1 to check the + // Operator. + // + Operation = DsdtPointer - 1; + if (*Operation == AML_NAME_OP) { + + // + // Check if we want _AL3 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'L', '3'); + } + } + break; + + // + // _AC4 method + // + case (SIGNATURE_32 ('_', 'A', 'C', '4')): + // + // Conditional match. _AC4 is < 63 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 2; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _AC4 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'C', '4'); + } + } + break; + + // + // _AL4 method + // + case (SIGNATURE_32 ('_', 'A', 'L', '4')): + // + // Conditional match. For Name Objects, the Operator will always be the byte + // immediately before the specific name. Therefore, subtract 1 to check the + // Operator. + // + Operation = DsdtPointer - 1; + if (*Operation == AML_NAME_OP) { + + // + // Check if we want _AL4 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'L', '4'); + } + } + break; + + // + // _AC5 method + // + case (SIGNATURE_32 ('_', 'A', 'C', '5')): + // + // Conditional match. _AC5 is < 63 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 2; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _AC5 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'C', '5'); + } + } + break; + + // + // _AL5 method + // + case (SIGNATURE_32 ('_', 'A', 'L', '5')): + // + // Conditional match. For Name Objects, the Operator will always be the byte + // immediately before the specific name. Therefore, subtract 1 to check the + // Operator. + // + Operation = DsdtPointer - 1; + if (*Operation == AML_NAME_OP) { + + // + // Check if we want _AL5 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'L', '5'); + } + } + break; + + // + // _AC6 method + // + case (SIGNATURE_32 ('_', 'A', 'C', '6')): + // + // Conditional match. _AC6 is < 63 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 2; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _AC6 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'C', '6'); + } + } + break; + + // + // _AL6 method + // + case (SIGNATURE_32 ('_', 'A', 'L', '6')): + // + // Conditional match. For Name Objects, the Operator will always be the byte + // immediately before the specific name. Therefore, subtract 1 to check the + // Operator. + // + Operation = DsdtPointer - 1; + if (*Operation == AML_NAME_OP) { + + // + // Check if we want _AL6 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'L', '6'); + } + } + break; + + // + // _AC7 method + // + case (SIGNATURE_32 ('_', 'A', 'C', '7')): + // + // Conditional match. _AC7 is < 63 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 2; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _AC7 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'C', '7'); + } + } + break; + + // + // _AL7 method + // + case (SIGNATURE_32 ('_', 'A', 'L', '7')): + // + // Conditional match. For Name Objects, the Operator will always be the byte + // immediately before the specific name. Therefore, subtract 1 to check the + // Operator. + // + Operation = DsdtPointer - 1; + if (*Operation == AML_NAME_OP) { + + // + // Check if we want _AL7 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'L', '7'); + } + } + break; + + // + // _AC8 method + // + case (SIGNATURE_32 ('_', 'A', 'C', '8')): + // + // Conditional match. _AC8 is < 63 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 2; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _AC8 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'C', '8'); + } + } + break; + + // + // _AL8 method + // + case (SIGNATURE_32 ('_', 'A', 'L', '8')): + // + // Conditional match. For Name Objects, the Operator will always be the byte + // immediately before the specific name. Therefore, subtract 1 to check the + // Operator. + // + Operation = DsdtPointer - 1; + if (*Operation == AML_NAME_OP) { + + // + // Check if we want _AL8 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'L', '8'); + } + } + break; + + // + // _AC9 method + // + case (SIGNATURE_32 ('_', 'A', 'C', '9')): + // + // Conditional match. _AC9 is < 63 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 2; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _AC9 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'C', '9'); + } + } + break; + + // + // _AL9 method + // + case (SIGNATURE_32 ('_', 'A', 'L', '9')): + // + // Conditional match. For Name Objects, the Operator will always be the byte + // immediately before the specific name. Therefore, subtract 1 to check the + // Operator. + // + Operation = DsdtPointer - 1; + if (*Operation == AML_NAME_OP) { + + // + // Check if we want _AL9 enabled + // + if (PcdGet8 (PcdDisableActiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'A', 'L', '9'); + } + } + break; + + // + // _PSL method + // + case (SIGNATURE_32 ('_', 'P', 'S', 'L')): + // + // Conditional match. _PSL is < 256 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 3; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _PSL enabled + // + if (PcdGet8 (PcdDisablePassiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'P', 'S', 'L'); + } + } + break; + + // + // _PSV method + // + case (SIGNATURE_32 ('_', 'P', 'S', 'V')): + // + // Conditional match. _PSV is < 256 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 3; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _PSV enabled + // + if (PcdGet8 (PcdDisablePassiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'P', 'S', 'V'); + } + } + break; + + // + // _CRT method + // + case (SIGNATURE_32 ('_', 'C', 'R', 'T')): + // + // Conditional match. _CRT is < 256 bytes, so the package length is 1 byte. + // Subtract 3 to check the Operator for CRB, subract 2 for Harris Beach. + // + Operation = DsdtPointer - 3; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _CRT enabled + // + if (PcdGet8 (PcdDisableCriticalTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'C', 'R', 'T'); + } + } + break; + + // + // _TC1 method + // + case (SIGNATURE_32 ('_', 'T', 'C', '1')): + // + // Conditional match. _TC1 is < 256 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 2; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _TC1 enabled + // + if (PcdGet8 (PcdDisablePassiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'T', 'C', '1'); + } + } + break; + + // + // _TC2 method + // + case (SIGNATURE_32 ('_', 'T', 'C', '2')): + // + // Conditional match. _TC2 is < 256 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 2; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _TC2 enabled + // + if (PcdGet8 (PcdDisablePassiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'T', 'C', '2'); + } + } + break; + + // + // _TSP method + // + case (SIGNATURE_32 ('_', 'T', 'S', 'P')): + // + // Conditional match. _TSP is < 256 bytes, so the package length is 1 byte. + // Therefore, subtract 2 to check the Operator. + // + Operation = DsdtPointer - 2; + if (*Operation == AML_METHOD_OP) { + + // + // Check if we want _TSP enabled + // + if (PcdGet8 (PcdDisablePassiveTripPoints) == 0) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'T', 'S', 'P'); + } + } + break; + + // + // Update SS3 Name with Setup value + // + case (SIGNATURE_32 ('S', 'S', '3', '_')): + Operation = DsdtPointer - 1; + if (*Operation == AML_NAME_OP) { + Value = (UINT8 *) DsdtPointer + 4; + *Value = PcdGet8 (PcdAcpiSleepState); + } + break; + // + // Update SS4 Name with Setup value + // + case (SIGNATURE_32 ('S', 'S', '4', '_')): + Operation = DsdtPointer - 1; + if (*Operation == AML_NAME_OP) { + Value = (UINT8 *) DsdtPointer + 4; + *Value = PcdGet8 (PcdAcpiHibernate); + } + break; + // + // _EJ0 method + // + case (SIGNATURE_32 ('_', 'E', 'J', '0')): + if (PcdGet8 (PcdLowPowerS0Idle)) { + // + // Remove _EJ0 for SOC + // + if (*(DsdtPointer-3) == AML_METHOD_OP) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'E', 'J', '0'); + EnterDock = TRUE; + } + } + break; + // + // _STA method for Device (\_SB.PCI0.DOCK) + // + case (SIGNATURE_32 ('_', 'S', 'T', 'A')): + if (PcdGet8 (PcdLowPowerS0Idle)) { + // + // Remove _STA in (\_SB.PCI0.DOCK) for SOC + // + if ((*(DsdtPointer-3) == AML_METHOD_OP) && (EnterDock)) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'S', 'T', 'A'); + EnterDock = FALSE; + } + } + break; + // + // _UPC method for Device (\_SB.PCI0.XHC.RHUB) + // + case (SIGNATURE_32('H', 'S', '1', '3')): + for (TmpDsdtPointer = DsdtPointer; + TmpDsdtPointer <= DsdtPointer + MaximumDsdtPointLength; + TmpDsdtPointer++){ + Signature = (UINT32 *) TmpDsdtPointer; + switch (*Signature) { + case(SIGNATURE_32('U', 'P', 'C', 'P')): + Value = (UINT8 *)((UINT32 *)TmpDsdtPointer + 2); + break; + default: + // + // Do nothing. + // + break; + } + } + break; + + + // + // _DCK method + // + case (SIGNATURE_32 ('_', 'D', 'C', 'K')): + if (PcdGet8 (PcdLowPowerS0Idle)) { + // + // Remove _DCK for SOC + // + if (*(DsdtPointer-3) == AML_METHOD_OP) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'D', 'C', 'K'); + } + } + break; + + // + // mask _DEP from CPU's scope if CS disabled. + // + case (SIGNATURE_32 ('P', 'R', '0', '0')): + case (SIGNATURE_32 ('P', 'R', '0', '1')): + case (SIGNATURE_32 ('P', 'R', '0', '2')): + case (SIGNATURE_32 ('P', 'R', '0', '3')): + case (SIGNATURE_32 ('P', 'R', '0', '4')): + case (SIGNATURE_32 ('P', 'R', '0', '5')): + case (SIGNATURE_32 ('P', 'R', '0', '6')): + case (SIGNATURE_32 ('P', 'R', '0', '7')): + case (SIGNATURE_32 ('P', 'R', '0', '8')): + case (SIGNATURE_32 ('P', 'R', '0', '9')): + case (SIGNATURE_32 ('P', 'R', '1', '0')): + case (SIGNATURE_32 ('P', 'R', '1', '1')): + case (SIGNATURE_32 ('P', 'R', '1', '2')): + case (SIGNATURE_32 ('P', 'R', '1', '3')): + case (SIGNATURE_32 ('P', 'R', '1', '4')): + case (SIGNATURE_32 ('P', 'R', '1', '5')): + + if (PcdGet8 (PcdLowPowerS0Idle) == 0) { + for (TmpDsdtPointer = DsdtPointer; TmpDsdtPointer <= DsdtPointer + MaximumDsdtPointLength; TmpDsdtPointer++){ + Signature = (UINT32 *) TmpDsdtPointer; + switch (*Signature) { + case(SIGNATURE_32('_', 'D', 'E', 'P')): + *(UINT8 *) TmpDsdtPointer = 'X'; + break; + default: + // + // Do nothing. + // + break; + } + } + } + break; + + // + // _EDL name + // + case (SIGNATURE_32 ('_', 'E', 'D', 'L')): + if (PcdGet8 (PcdLowPowerS0Idle)) { + // + // Remove _EDL for SOC + // + if (*(DsdtPointer-1) == AML_NAME_OP) { + Signature = (UINT32 *) DsdtPointer; + *Signature = SIGNATURE_32 ('X', 'E', 'D', 'L'); + } + } + break; + + default: + // + // Do nothing. + // + break; + } + } +} + diff --git a/Platform/Intel/ClevoOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c b/Platform/Intel/ClevoOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c new file mode 100644 index 0000000000..a9e616ffa4 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c @@ -0,0 +1,357 @@ +/** @file + Performs specific PCI-EXPRESS device resource configuration. + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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 +#include +#include +#include + +#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/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c new file mode 100644 index 0000000000..69162f10bf --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c @@ -0,0 +1,234 @@ +/** @file + Thunderbolt initialization in DXE. + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c new file mode 100644 index 0000000000..5c792bf3b9 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit.c @@ -0,0 +1,199 @@ +/** @file + Thunderbolt initialization in PEI. + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + 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/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c new file mode 100644 index 0000000000..28de0dc793 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHandler.c @@ -0,0 +1,1616 @@ +/**@file + Thunderbolt SMI handler. + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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 +#include +#include +#include +#include +#include +#include +#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/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c new file mode 100644 index 0000000000..09e107a146 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c @@ -0,0 +1,1770 @@ +/** @file + Thunderbolt initialization in SMM. + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "TbtSmiHandler.h" +#include +#include +#include +#include +#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/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/ALS.ASL b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/ALS.ASL new file mode 100644 index 0000000000..87b7448f95 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/ALS.ASL @@ -0,0 +1,43 @@ +/** @file + ACPI DSDT table + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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. + +**/ + +Device(ALSD) +{ + Name(_HID,"ACPI0008") + + Method(_STA,0) + { + If(LEqual(ALSE,2)) + { + Return(0x000B) // ALS Enabled. Don't show it in UI. + } + + Return(0x0000) // ALS Disabled. Hide it. + } + + Method(_ALI) + { + Return (Or(ShiftLeft(LHIH,8),LLOW)) + } + + Name(_ALR, Package() + { + Package() {70, 0}, + Package() {73, 10}, + Package() {85, 80}, + Package() {100, 300}, + Package() {150, 1000} + }) + +} diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl new file mode 100644 index 0000000000..ef0f3a9ded --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl @@ -0,0 +1,27 @@ +/** @file + ACPI DSDT table + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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. + +**/ + + + +/////////////////////////////////////////////////////////////////////////////////// +//Values are set like this to have ASL compiler reserve enough space for objects +/////////////////////////////////////////////////////////////////////////////////// +// +// Available Sleep states +// +Name(SS1,0) +Name(SS2,0) +Name(SS3,1) +Name(SS4,1) + diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/CPU.asl b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/CPU.asl new file mode 100644 index 0000000000..b229284192 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/CPU.asl @@ -0,0 +1,252 @@ +/** @file + ACPI DSDT table + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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. + +**/ + +Scope(\_PR) +{ + Processor(PR00, // Unique name for Processor 0. + 1, // Unique ID for Processor 0. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR01, // Unique name for Processor 1. + 2, // Unique ID for Processor 1. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR02, // Unique name for Processor 2. + 3, // Unique ID for Processor 2. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR03, // Unique name for Processor 3. + 4, // Unique ID for Processor 3. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR04, // Unique name for Processor 4. + 5, // Unique ID for Processor 4. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR05, // Unique name for Processor 5. + 6, // Unique ID for Processor 5. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR06, // Unique name for Processor 6. + 7, // Unique ID for Processor 6. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR07, // Unique name for Processor 7. + 8, // Unique ID for Processor 7. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR08, // Unique name for Processor 8. + 9, // Unique ID for Processor 8. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR09, // Unique name for Processor 9. + 10, // Unique ID for Processor 9. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR10, // Unique name for Processor 10. + 11, // Unique ID for Processor 10. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR11, // Unique name for Processor 11. + 12, // Unique ID for Processor 11. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR12, // Unique name for Processor 12. + 13, // Unique ID for Processor 12. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR13, // Unique name for Processor 13. + 14, // Unique ID for Processor 13. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR14, // Unique name for Processor 14. + 15, // Unique ID for Processor 14. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} + + Processor(PR15, // Unique name for Processor 15. + 16, // Unique ID for Processor 15. + 0x1810, // P_BLK address = ACPIBASE + 10h. + 6) // P_BLK length = 6 bytes. + {} +} // End Scope(\_PR) + +// +// _CPC (Continuous Performance Control) Package declaration +// Package +// { +// NumEntries, // Integer +// Revision, // Integer +// HighestPerformance, // Generic Register Descriptor +// NominalPerformance, // Generic Register Descriptor +// LowestNonlinearPerformance, // Generic Register Descriptor +// LowestPerformance, // Generic Register Descriptor +// GuaranteedPerformanceRegister, // Generic Register Descriptor +// DesiredPerformanceRegister, // Generic Register Descriptor +// MinimumPerformanceRegister, // Generic Register Descriptor +// MaximumPerformanceRegister, // Generic Register Descriptor +// PerformanceReductionToleranceRegister,// Generic Register Descriptor +// TimeWindowRegister, // Generic Register Descriptor +// CounterWraparoundTime, // Generic Register Descriptor +// NominalCounterRegister, // Generic Register Descriptor +// DeliveredCounterRegister, // Generic Register Descriptor +// PerformanceLimitedRegister, // Generic Register Descriptor +// EnableRegister // Generic Register Descriptor +// } +// +Scope(\_PR.PR00) +{ + Name(CPC2, Package() + { + 21, // Number of entries + 02, // Revision + // + // Describe processor capabilities + // + ResourceTemplate() {Register(FFixedHW, 8, 0, 0x771, 4)}, // HighestPerformance + ResourceTemplate() {Register(FFixedHW, 8, 8, 0xCE, 4)}, // Nominal Performance - Maximum Non Turbo Ratio + ResourceTemplate() {Register(FFixedHW, 8, 16, 0x771, 4)},//Lowest nonlinear Performance + ResourceTemplate() {Register(FFixedHW, 8, 24, 0x771, 4)}, // LowestPerformance + ResourceTemplate() {Register(FFixedHW, 8, 8, 0x0771, 4)}, // Guaranteed Performance + ResourceTemplate() {Register(FFixedHW, 8, 16, 0x0774, 4)}, // Desired PerformanceRegister + ResourceTemplate() {Register(FFixedHW, 8, 0, 0x774, 4)}, // Minimum PerformanceRegister + ResourceTemplate() {Register(FFixedHW, 8, 8, 0x774, 4)}, // Maximum PerformanceRegister + ResourceTemplate() {Register(SystemMemory, 0, 0, 0, 0)}, // Performance ReductionToleranceRegister (Null) + ResourceTemplate() {Register(SystemMemory, 0, 0, 0, 0)}, // Time window register(Null) + ResourceTemplate() {Register(SystemMemory, 0, 0, 0, 0)}, // Counter wrap around time(Null) + ResourceTemplate() {Register(FFixedHW, 64, 0, 0xE7, 4)}, // Reference counter register (PPERF) + ResourceTemplate() {Register(FFixedHW, 64, 0, 0xE8, 4)}, // Delivered counter register (APERF) + ResourceTemplate() {Register(FFixedHW, 2, 1, 0x777, 4)}, // Performance limited register + ResourceTemplate() {Register(FFixedHW, 1, 0, 0x770, 4)}, // Enable register + 1, // Autonomous selection enable register (Exclusively autonomous) + ResourceTemplate() {Register(FFixedHW, 10, 32, 0x774, 4)}, // Autonomous activity window register + ResourceTemplate() {Register(FFixedHW, 8, 24, 0x774, 4)}, // Autonomous energy performance preference register + 0 // Reference performance (not supported) + }) + + Name(CPOC, Package() + { + 21, // Number of entries + 02, // Revision + // + // Describe processor capabilities + // + 255, // HighestPerformance + ResourceTemplate() {Register(FFixedHW, 8, 8, 0xCE, 4)}, // Nominal Performance - Maximum Non Turbo Ratio + ResourceTemplate() {Register(FFixedHW, 8, 16, 0x771, 4)},//Lowest nonlinear Performance + ResourceTemplate() {Register(FFixedHW, 8, 24, 0x771, 4)}, // LowestPerformance + ResourceTemplate() {Register(FFixedHW, 8, 8, 0x0771, 4)}, // Guaranteed Performance + ResourceTemplate() {Register(FFixedHW, 8, 16, 0x0774, 4)}, // Desired PerformanceRegister + ResourceTemplate() {Register(FFixedHW, 8, 0, 0x774, 4)}, // Minimum PerformanceRegister + ResourceTemplate() {Register(FFixedHW, 8, 8, 0x774, 4)}, // Maximum PerformanceRegister + ResourceTemplate() {Register(SystemMemory, 0, 0, 0, 0)}, // Performance ReductionToleranceRegister (Null) + ResourceTemplate() {Register(SystemMemory, 0, 0, 0, 0)}, // Time window register(Null) + ResourceTemplate() {Register(SystemMemory, 0, 0, 0, 0)}, // Counter wrap around time(Null) + ResourceTemplate() {Register(FFixedHW, 64, 0, 0xE7, 4)}, // Reference counter register (PPERF) + ResourceTemplate() {Register(FFixedHW, 64, 0, 0xE8, 4)}, // Delivered counter register (APERF) + ResourceTemplate() {Register(FFixedHW, 2, 1, 0x777, 4)}, // Performance limited register + ResourceTemplate() {Register(FFixedHW, 1, 0, 0x770, 4)}, // Enable register + 1, // Autonomous selection enable register (Exclusively autonomous) + ResourceTemplate() {Register(FFixedHW, 10, 32, 0x774, 4)}, // Autonomous activity window register + ResourceTemplate() {Register(FFixedHW, 8, 24, 0x774, 4)}, // Autonomous energy performance preference register + 0 // Reference performance (not supported) + }) + +}// end Scope(\_PR.PR00) + +#ifndef SPS_SUPPORT // SPS is using Processor Aggregator Device different way +Scope(\_SB) +{ + // The Processor Aggregator Device provides a control point that enables the platform to perform + // specific processor configuration and control that applies to all processors in the platform. + Device (PAGD) + { + Name (_HID, "ACPI000C") // Processor Aggregator Device + + // _STA (Status) + // + // This object returns the current status of a device. + // + // Arguments: (0) + // None + // Return Value: + // An Integer containing a device status bitmap: + // Bit 0 - Set if the device is present. + // Bit 1 - Set if the device is enabled and decoding its resources. + // Bit 2 - Set if the device should be shown in the UI. + // Bit 3 - Set if the device is functioning properly (cleared if device failed its diagnostics). + // Bit 4 - Set if the battery is present. + // Bits 5-31 - Reserved (must be cleared). + // + Method(_STA) + { + If(\_OSI("Processor Aggregator Device")){ + Return (0x0F) // Processor Aggregator Device is supported by this OS. + } Else { + Return (0) // No support in this OS. + } + } + + + // _PUR (Processor Utilization Request) + // + // The _PUR object is an optional object that may be declared under the Processor Aggregator Device + // and provides a means for the platform to indicate to OSPM the number of logical processors + // to be idled. OSPM evaluates the _PUR object as a result of the processing of a Notify event + // on the Processor Aggregator device object of type 0x80. + // + // Arguments: (0) + // None + // Return Value: + // Package + // + Name (_PUR, Package() // Requests a number of logical processors to be placed in an idle state. + { + 1, // RevisionID, Integer: Current value is 1 + 0 // NumProcessors, Integer + }) + + } // end Device(PAGD) +}// end Scope(\_SB) +#endif // ndef SPS_SUPPORT + diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL new file mode 100644 index 0000000000..3adf6996e3 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL @@ -0,0 +1,127 @@ +/** @file + ACPI DSDT table + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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. + +**/ + +DefinitionBlock ( + "DSDT.aml", + "DSDT", + 0x02, // DSDT revision. + // A Revision field value greater than or equal to 2 signifies that integers + // declared within the Definition Block are to be evaluated as 64-bit values + "INTEL", // OEM ID (6 byte string) + "SKL ",// OEM table ID (8 byte string) + 0x0 // OEM version of DSDT table (4 byte Integer) +) + +// BEGIN OF ASL SCOPE +{ + External(LHIH) + External(LLOW) + External(IGDS) + External(LIDS) + External(BRTL) + External(ALSE) + External(GSMI) + External(\_SB.PCI0.GFX0.ALSI) + External(\_SB.PCI0.GFX0.CDCK) + External(\_SB.PCI0.GFX0.CBLV) + External(\_SB.PCI0.GFX0.GSSE) + External(\_SB.PCI0.PEG0, DeviceObj) + External(\_SB.PCI0.PEG0.PEGP, DeviceObj) + External(\_SB.PCI0.PEG1, DeviceObj) + External(\_SB.PCI0.PEG2, DeviceObj) + External(\_SB.PCI0.GFX0.DD1F, DeviceObj) + External(\_SB.PCI0.GFX0.GDCK, MethodObj) + External(\_SB.PCI0.GFX0.GHDS, MethodObj) + External(\_SB.PCI0.GFX0.AINT, MethodObj) + External(\_SB.PCI0.GFX0.GLID, MethodObj) + External(\_SB.PCI0.GFX0.GSCI, MethodObj) + External(\_PR.PR00._PSS, MethodObj) + External(\_PR.PR00.LPSS, PkgObj) + External(\_PR.PR00.TPSS, PkgObj) + External(\_PR.PR00._PPC, MethodObj) + External(\_PR.CPPC, IntObj) + External(\_TZ.TZ00, DeviceObj) + External(\_TZ.TZ01, DeviceObj) + External(\_TZ.ETMD, IntObj) + External(\_TZ.FN00._OFF, MethodObj) + // Miscellaneous services enabled in Project + Include ("AMLUPD.asl") + Include ("Acpi/GlobalNvs.asl") + Include ("PciTree.asl") + + if(LEqual(ECR1,1)){ + Scope(\_SB.PCI0) { + // + // PCI-specific method's GUID + // + Name(PCIG, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D")) + // + // PCI's _DSM - an attempt at modular _DSM implementation + // When writing your own _DSM function that needs to include PCI-specific methods, do this: + // + // Method(_YOUR_DSM,4){ + // if(Lequal(Arg0,PCIG)) { return(PCID(Arg0,Arg1,Arg2,Arg3)) } + // ...continue your _DSM by checking different GUIDs... + // else { return(0) } + // } + // + Method(PCID, 4, Serialized) { + If(LEqual(Arg0, PCIG)) { // PCIE capabilities UUID + If(LGreaterEqual(Arg1,3)) { // revision at least 3 + If(LEqual(Arg2,0)) { Return (Buffer(2){0x01,0x03}) } // function 0: list of supported functions + If(LEqual(Arg2,8)) { Return (1) } // function 8: Avoiding Power-On Reset Delay Duplication on Sx Resume + If(LEqual(Arg2,9)) { Return (Package(5){50000,Ones,Ones,50000,Ones}) } // function 9: Specifying Device Readiness Durations + } + } + return (Buffer(1){0}) + } + }//scope + }//if + + Scope(\_SB.PCI0) { + //PciCheck, Arg0=UUID, returns true if support for 'PCI delays optimization ECR' is enabled and the UUID is correct + Method(PCIC,1,Serialized) { + If(LEqual(ECR1,1)) { + If(LEqual(Arg0, PCIG)) { + return (1) + } + } + return (0) + } + } + + Include ("Pch.asl") // Not in this package. Refer to the PCH Reference Code accordingly + Include ("LpcB.asl") + Include ("Platform.asl") + Include ("CPU.asl") + Include ("PCI_DRC.ASL") + Include ("Video.asl") + Include ("PlatformGnvs.asl") + Include ("Gpe.asl") + + Name(\_S0, Package(4){0x0,0x0,0,0}) // mandatory System state + if(SS1) { Name(\_S1, Package(4){0x1,0x0,0,0})} + if(SS3) { Name(\_S3, Package(4){0x5,0x0,0,0})} + if(SS4) { Name(\_S4, Package(4){0x6,0x0,0,0})} + Name(\_S5, Package(4){0x7,0x0,0,0}) // mandatory System state + + Method(PTS, 1) { // METHOD CALLED FROM _PTS PRIOR TO ENTER ANY SLEEP STATE + If(Arg0) // entering any sleep state + { + } + } + Method(WAK, 1) { // METHOD CALLED FROM _WAK RIGHT AFTER WAKE UP + } +}// End of ASL File + diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Gpe.asl b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Gpe.asl new file mode 100644 index 0000000000..0218b893d1 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Gpe.asl @@ -0,0 +1,856 @@ +/** @file + ACPI DSDT table + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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. + +**/ + + // General Purpose Events. This Scope handles the Run-time and + // Wake-time SCIs. The specific method called will be determined by + // the _Lxx value, where xx equals the bit location in the General + // Purpose Event register(s). + + + External(D1F0) + External(D1F1) + External(D1F2) + External(\_SB.PCI0.PEG0.HPME, MethodObj) + 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) + External(SGGP) + External(P1GP) + External(P2GP) + External(P0WK) + External(P1WK) + External(P2WK) + External(\CPG0) + External(\RPS0) + External(\RPT0) + External(\_PR.HWPI, IntObj) + External(\_PR.DTSI, IntObj) + + Scope(\_GPE) + { + // Note: + // Originally, the two GPE methods below are automatically generated, but, for ASL code restructuring, + // disabled the automatic generation and declare the ASL code here. + // + + // + // This PME event (PCH's GPE 69h) is received on one or more of the PCI Express* ports or + // an assert PMEGPE message received via DMI + // + Method(_L69, 0, serialized) { + \_SB.PCI0.RP01.HPME() + \_SB.PCI0.RP02.HPME() + \_SB.PCI0.RP03.HPME() + \_SB.PCI0.RP04.HPME() + \_SB.PCI0.RP05.HPME() + \_SB.PCI0.RP06.HPME() + \_SB.PCI0.RP07.HPME() + \_SB.PCI0.RP08.HPME() + \_SB.PCI0.RP09.HPME() + \_SB.PCI0.RP10.HPME() + \_SB.PCI0.RP11.HPME() + \_SB.PCI0.RP12.HPME() + \_SB.PCI0.RP13.HPME() + \_SB.PCI0.RP14.HPME() + \_SB.PCI0.RP15.HPME() + \_SB.PCI0.RP16.HPME() + \_SB.PCI0.RP17.HPME() + \_SB.PCI0.RP18.HPME() + \_SB.PCI0.RP19.HPME() + \_SB.PCI0.RP20.HPME() + \_SB.PCI0.RP21.HPME() + \_SB.PCI0.RP22.HPME() + \_SB.PCI0.RP23.HPME() + \_SB.PCI0.RP24.HPME() + + If(LEqual(D1F0,1)) + { + \_SB.PCI0.PEG0.HPME() + Notify(\_SB.PCI0.PEG0, 0x02) + Notify(\_SB.PCI0.PEG0.PEGP, 0x02) + } + + If(LEqual(D1F1,1)) + { + \_SB.PCI0.PEG1.HPME() + Notify(\_SB.PCI0.PEG1, 0x02) + } + + If(LEqual(D1F2,1)) + { + \_SB.PCI0.PEG2.HPME() + Notify(\_SB.PCI0.PEG2, 0x02) + } + } + + // PCI Express Hot-Plug caused the wake event. + + Method(_L61) + { + Add(L01C,1,L01C) // Increment L01 Entry Count. + + P8XH(0,0x01) // Output information to Port 80h. + P8XH(1,L01C) + + + // Check Root Port 1 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP01.VDID,0xFFFFFFFF),\_SB.PCI0.RP01.HPSX)) + { + // Delay for 100ms to meet the timing requirements + // of the PCI Express Base Specification, Revision + // 1.0A, Section 6.6 ("...software must wait at + // least 100ms from the end of reset of one or more + // device before it is permitted to issue + // Configuration Requests to those devices"). + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x1),LNotEqual(TBS1,0x1)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP01.PDCX) + { + // Clear all status bits first. + + Store(1,\_SB.PCI0.RP01.PDCX) + Store(1,\_SB.PCI0.RP01.HPSX) + + // + // PCH BIOS Spec Update Rev 1.03, Section 8.9 PCI Express* Hot-Plug BIOS Support + // In addition, BIOS should intercept Presence Detect Changed interrupt, enable L0s on + // hot plug and disable L0s on hot unplug. BIOS should also make sure the L0s is + // disabled on empty slots prior booting to OS. + // + If(LNot(\_SB.PCI0.RP01.PDSX)) { + // The PCI Express slot is empty, so disable L0s on hot unplug + // + Store(0,\_SB.PCI0.RP01.L0SE) + + } + + // Perform proper notification + // to the OS. + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x1),LNotEqual(TBS1,0x1)))) { + Notify(\_SB.PCI0.RP01,0) + } + } + Else + { + // False event. Clear Hot-Plug Status + // then exit. + + Store(1,\_SB.PCI0.RP01.HPSX) + } + } + + // Check Root Port 2 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP02.VDID,0xFFFFFFFF),\_SB.PCI0.RP02.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x2),LNotEqual(TBS1,0x2)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP02.PDCX) + { + Store(1,\_SB.PCI0.RP02.PDCX) + Store(1,\_SB.PCI0.RP02.HPSX) + + If(LNot(\_SB.PCI0.RP02.PDSX)) { + Store(0,\_SB.PCI0.RP02.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x2),LNotEqual(TBS1,0x2)))) { + Notify(\_SB.PCI0.RP02,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP02.HPSX) + } + } + + // Check Root Port 3 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP03.VDID,0xFFFFFFFF),\_SB.PCI0.RP03.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x3),LNotEqual(TBS1,0x3)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP03.PDCX) + { + Store(1,\_SB.PCI0.RP03.PDCX) + Store(1,\_SB.PCI0.RP03.HPSX) + + If(LNot(\_SB.PCI0.RP03.PDSX)) { + Store(0,\_SB.PCI0.RP03.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x3),LNotEqual(TBS1,0x3)))) { + Notify(\_SB.PCI0.RP03,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP03.HPSX) + } + } + + // Check Root Port 4 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP04.VDID,0xFFFFFFFF),\_SB.PCI0.RP04.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x4),LNotEqual(TBS1,0x4)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP04.PDCX) + { + Store(1,\_SB.PCI0.RP04.PDCX) + Store(1,\_SB.PCI0.RP04.HPSX) + + If(LNot(\_SB.PCI0.RP04.PDSX)) { + Store(0,\_SB.PCI0.RP04.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x4),LNotEqual(TBS1,0x4)))) { + Notify(\_SB.PCI0.RP04,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP04.HPSX) + } + } + + // Check Root Port 5 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP05.VDID,0xFFFFFFFF),\_SB.PCI0.RP05.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x5),LNotEqual(TBS1,0x5)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP05.PDCX) + { + Store(1,\_SB.PCI0.RP05.PDCX) + Store(1,\_SB.PCI0.RP05.HPSX) + + If(LNot(\_SB.PCI0.RP05.PDSX)) { + Store(0,\_SB.PCI0.RP05.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x5),LNotEqual(TBS1,0x5)))) { + Notify(\_SB.PCI0.RP05,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP05.HPSX) + } + } + + // Check Root Port 6 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP06.VDID,0xFFFFFFFF),\_SB.PCI0.RP06.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x6),LNotEqual(TBS1,0x6)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP06.PDCX) + { + Store(1,\_SB.PCI0.RP06.PDCX) + Store(1,\_SB.PCI0.RP06.HPSX) + + If(LNot(\_SB.PCI0.RP06.PDSX)) { + Store(0,\_SB.PCI0.RP06.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x6),LNotEqual(TBS1,0x6)))) { + Notify(\_SB.PCI0.RP06,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP06.HPSX) + } + } + + // Check Root Port 7 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP07.VDID,0xFFFFFFFF),\_SB.PCI0.RP07.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x7),LNotEqual(TBS1,0x7)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP07.PDCX) + { + Store(1,\_SB.PCI0.RP07.PDCX) + Store(1,\_SB.PCI0.RP07.HPSX) + + If(LNot(\_SB.PCI0.RP07.PDSX)) { + Store(0,\_SB.PCI0.RP07.L0SE) + } + + } + Else + { + Store(1,\_SB.PCI0.RP07.HPSX) + } + } + + // Check Root Port 8 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP08.VDID,0xFFFFFFFF),\_SB.PCI0.RP08.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x8),LNotEqual(TBS1,0x8)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP08.PDCX) + { + Store(1,\_SB.PCI0.RP08.PDCX) + Store(1,\_SB.PCI0.RP08.HPSX) + + If(LNot(\_SB.PCI0.RP08.PDSX)) { + Store(0,\_SB.PCI0.RP08.L0SE) + } + + } + Else + { + Store(1,\_SB.PCI0.RP08.HPSX) + } + } + + // Check Root Port 9 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP09.VDID,0xFFFFFFFF),\_SB.PCI0.RP09.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x9),LNotEqual(TBS1,0x9)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP09.PDCX) + { + Store(1,\_SB.PCI0.RP09.PDCX) + Store(1,\_SB.PCI0.RP09.HPSX) + + If(LNot(\_SB.PCI0.RP09.PDSX)) { + Store(0,\_SB.PCI0.RP09.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x9),LNotEqual(TBS1,0x9)))) { + Notify(\_SB.PCI0.RP09,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP09.HPSX) + } + } + + // Check Root Port 10 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP10.VDID,0xFFFFFFFF),\_SB.PCI0.RP10.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0xA),LNotEqual(TBS1,0xA)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP10.PDCX) + { + Store(1,\_SB.PCI0.RP10.PDCX) + Store(1,\_SB.PCI0.RP10.HPSX) + + If(LNot(\_SB.PCI0.RP10.PDSX)) { + Store(0,\_SB.PCI0.RP10.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0xA),LNotEqual(TBS1,0xA)))) { + Notify(\_SB.PCI0.RP10,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP10.HPSX) + } + } + + // Check Root Port 11 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP11.VDID,0xFFFFFFFF),\_SB.PCI0.RP11.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0xB),LNotEqual(TBS1,0xB)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP11.PDCX) + { + Store(1,\_SB.PCI0.RP11.PDCX) + Store(1,\_SB.PCI0.RP11.HPSX) + + If(LNot(\_SB.PCI0.RP11.PDSX)) { + Store(0,\_SB.PCI0.RP11.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0xB),LNotEqual(TBS1,0xB)))) { + Notify(\_SB.PCI0.RP11,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP11.HPSX) + } + } + + // Check Root Port 12 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP12.VDID,0xFFFFFFFF),\_SB.PCI0.RP12.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0xC),LNotEqual(TBS1,0xC)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP12.PDCX) + { + Store(1,\_SB.PCI0.RP12.PDCX) + Store(1,\_SB.PCI0.RP12.HPSX) + + If(LNot(\_SB.PCI0.RP12.PDSX)) { + Store(0,\_SB.PCI0.RP12.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0xC),LNotEqual(TBS1,0xC)))) { + Notify(\_SB.PCI0.RP12,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP12.HPSX) + } + } + + // Check Root Port 13 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP13.VDID,0xFFFFFFFF),\_SB.PCI0.RP13.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0xD),LNotEqual(TBS1,0xD)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP13.PDCX) + { + Store(1,\_SB.PCI0.RP13.PDCX) + Store(1,\_SB.PCI0.RP13.HPSX) + + If(LNot(\_SB.PCI0.RP13.PDSX)) { + Store(0,\_SB.PCI0.RP13.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0xD),LNotEqual(TBS1,0xD)))) { + Notify(\_SB.PCI0.RP13,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP13.HPSX) + } + } + + // Check Root Port 14 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP14.VDID,0xFFFFFFFF),\_SB.PCI0.RP14.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0xE),LNotEqual(TBS1,0xE)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP14.PDCX) + { + Store(1,\_SB.PCI0.RP14.PDCX) + Store(1,\_SB.PCI0.RP14.HPSX) + + If(LNot(\_SB.PCI0.RP14.PDSX)) { + Store(0,\_SB.PCI0.RP14.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0xE),LNotEqual(TBS1,0xE)))) { + Notify(\_SB.PCI0.RP14,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP14.HPSX) + } + } + + // Check Root Port 15 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP15.VDID,0xFFFFFFFF),\_SB.PCI0.RP15.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0xF),LNotEqual(TBS1,0xF)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP15.PDCX) + { + Store(1,\_SB.PCI0.RP15.PDCX) + Store(1,\_SB.PCI0.RP15.HPSX) + + If(LNot(\_SB.PCI0.RP15.PDSX)) { + Store(0,\_SB.PCI0.RP15.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0xF),LNotEqual(TBS1,0xF)))) { + Notify(\_SB.PCI0.RP15,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP15.HPSX) + } + } + + // Check Root Port 16 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP16.VDID,0xFFFFFFFF),\_SB.PCI0.RP16.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x10),LNotEqual(TBS1,0x10)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP16.PDCX) + { + Store(1,\_SB.PCI0.RP16.PDCX) + Store(1,\_SB.PCI0.RP16.HPSX) + + If(LNot(\_SB.PCI0.RP16.PDSX)) { + Store(0,\_SB.PCI0.RP16.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x10),LNotEqual(TBS1,0x10)))) { + Notify(\_SB.PCI0.RP16,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP16.HPSX) + } + } + + // Check Root Port 17 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP17.VDID,0xFFFFFFFF),\_SB.PCI0.RP17.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x11),LNotEqual(TBS1,0x11)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP17.PDCX) + { + Store(1,\_SB.PCI0.RP17.PDCX) + Store(1,\_SB.PCI0.RP17.HPSX) + + If(LNot(\_SB.PCI0.RP17.PDSX)) { + Store(0,\_SB.PCI0.RP17.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x11),LNotEqual(TBS1,0x11)))) { + Notify(\_SB.PCI0.RP17,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP17.HPSX) + } + } + + // Check Root Port 18 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP18.VDID,0xFFFFFFFF),\_SB.PCI0.RP18.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x12),LNotEqual(TBS1,0x12)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP18.PDCX) + { + Store(1,\_SB.PCI0.RP18.PDCX) + Store(1,\_SB.PCI0.RP18.HPSX) + + If(LNot(\_SB.PCI0.RP18.PDSX)) { + Store(0,\_SB.PCI0.RP18.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x12),LNotEqual(TBS1,0x12)))) { + Notify(\_SB.PCI0.RP18,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP18.HPSX) + } + } + + // Check Root Port 19 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP19.VDID,0xFFFFFFFF),\_SB.PCI0.RP19.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x13),LNotEqual(TBS1,0x13)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP19.PDCX) + { + Store(1,\_SB.PCI0.RP19.PDCX) + Store(1,\_SB.PCI0.RP19.HPSX) + + If(LNot(\_SB.PCI0.RP19.PDSX)) { + Store(0,\_SB.PCI0.RP19.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x13),LNotEqual(TBS1,0x13)))) { + Notify(\_SB.PCI0.RP19,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP19.HPSX) + } + } + + // Check Root Port 20 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP20.VDID,0xFFFFFFFF),\_SB.PCI0.RP20.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x14),LNotEqual(TBS1,0x14)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP20.PDCX) + { + Store(1,\_SB.PCI0.RP20.PDCX) + Store(1,\_SB.PCI0.RP20.HPSX) + + If(LNot(\_SB.PCI0.RP20.PDSX)) { + Store(0,\_SB.PCI0.RP20.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x14),LNotEqual(TBS1,0x14)))) { + Notify(\_SB.PCI0.RP20,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP20.HPSX) + } + } + + // Check Root Port 21 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP21.VDID,0xFFFFFFFF),\_SB.PCI0.RP21.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x21),LNotEqual(TBS1,0x21)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP21.PDCX) + { + Store(1,\_SB.PCI0.RP21.PDCX) + Store(1,\_SB.PCI0.RP21.HPSX) + + If(LNot(\_SB.PCI0.RP21.PDSX)) { + Store(0,\_SB.PCI0.RP21.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x21),LNotEqual(TBS1,0x21)))) { + Notify(\_SB.PCI0.RP21,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP21.HPSX) + } + } + + // Check Root Port 22 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP22.VDID,0xFFFFFFFF),\_SB.PCI0.RP22.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x22),LNotEqual(TBS1,0x22)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP22.PDCX) + { + Store(1,\_SB.PCI0.RP22.PDCX) + Store(1,\_SB.PCI0.RP22.HPSX) + + If(LNot(\_SB.PCI0.RP22.PDSX)) { + Store(0,\_SB.PCI0.RP22.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x22),LNotEqual(TBS1,0x22)))) { + Notify(\_SB.PCI0.RP22,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP22.HPSX) + } + } + + // Check Root Port 23 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP23.VDID,0xFFFFFFFF),\_SB.PCI0.RP23.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x23),LNotEqual(TBS1,0x23)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP23.PDCX) + { + Store(1,\_SB.PCI0.RP23.PDCX) + Store(1,\_SB.PCI0.RP23.HPSX) + + If(LNot(\_SB.PCI0.RP23.PDSX)) { + Store(0,\_SB.PCI0.RP23.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x23),LNotEqual(TBS1,0x23)))) { + Notify(\_SB.PCI0.RP23,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP23.HPSX) + } + } + + // Check Root Port 24 for a Hot Plug Event if the Port is + // enabled. + + If(LAnd(LNotEqual(\_SB.PCI0.RP24.VDID,0xFFFFFFFF),\_SB.PCI0.RP24.HPSX)) + { + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x24),LNotEqual(TBS1,0x24)))) { + Sleep(100) + } + + If(\_SB.PCI0.RP24.PDCX) + { + Store(1,\_SB.PCI0.RP24.PDCX) + Store(1,\_SB.PCI0.RP24.HPSX) + + If(LNot(\_SB.PCI0.RP24.PDSX)) { + Store(0,\_SB.PCI0.RP24.L0SE) + } + + If(LOr(LNotEqual(TBTS, 0x01),LOr(LNotEqual(TBSE,0x24),LNotEqual(TBS1,0x24)))) { + Notify(\_SB.PCI0.RP24,0) + } + } + Else + { + Store(1,\_SB.PCI0.RP24.HPSX) + } + } + } + + // + // Software GPE caused the event. + // + Method(_L62) + { + // Clear GPE status bit. + Store(0,GPEC) + + // + // Handle DTS Thermal SCI Event. + // + If(CondRefOf(\_PR.DTSE)){ + If(LGreaterEqual(\_PR.DTSE, 0x01)){ + If(LEqual(\_PR.DTSI, 1)){ + Notify(\_TZ.TZ00,0x80) + Notify(\_TZ.TZ01,0x80) + /// + /// Clear HWP interrupt status + /// + Store(0,\_PR.DTSI) + } + } + } + /// + /// Handle HWP SCI event + /// + External(\_GPE.HLVT, MethodObj) + If(LEqual(\_PR.HWPI, 1)){ + If(CondRefOf(\_GPE.HLVT)){ + \_GPE.HLVT() + } + /// + /// Clear HWP interrupt status + /// + Store(0,\_PR.HWPI) + } + } + + // IGD OpRegion SCI event (see IGD OpRegion/Software SCI BIOS SPEC). + + Method(_L66) + { + If(LAnd(\_SB.PCI0.GFX0.GSSE, LNot(GSMI))) // Graphics software SCI event? + { + \_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/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Itss.asl b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Itss.asl new file mode 100644 index 0000000000..73b3de105e --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Itss.asl @@ -0,0 +1,39 @@ +/** @file + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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. + +**/ + + +// ITSS +// Define the needed ITSS registers used by ASL on Interrupt +// mapping. + +scope(\_SB){ + OperationRegion(ITSS, SystemMemory, 0xfdc43100, 0x208) + Field(ITSS, ByteAcc, NoLock, Preserve) + { + PARC, 8, + PBRC, 8, + PCRC, 8, + PDRC, 8, + PERC, 8, + PFRC, 8, + PGRC, 8, + PHRC, 8, + Offset(0x200), // Offset 3300h ITSSPRC - ITSS Power Reduction Control + , 1, + , 1, + SCGE, 1, // ITSSPRC[2]: 8254 Static Clock Gating Enable (8254CGE) + + } +} + + diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/LPC_DEV.ASL b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/LPC_DEV.ASL new file mode 100644 index 0000000000..816f83ba3d --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/LPC_DEV.ASL @@ -0,0 +1,205 @@ +/** @file + ACPI DSDT table + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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. + +**/ + +Device(FWHD) // Firmware Hub Device +{ + Name(_HID,EISAID("INT0800")) + + Name(_CRS,ResourceTemplate() + { + Memory32Fixed(ReadOnly,0xFF000000,0x1000000) + }) +} + + +Device(HPET) // High Performance Event Timer +{ + Name(_HID,EISAID("PNP0103")) + Name(_UID, 0) + + Name(BUF0,ResourceTemplate() + { + Memory32Fixed(ReadWrite,0xFED00000,0x400,FED0) + }) + + Method(_STA,0) + { + // Show this Device only if the OS is WINXP or beyond. + If(HPTE) + { + Return(0x000F) // Enabled, do Display. + } + + Return(0x0000) // Return Nothing. + } + + Method(_CRS,0,Serialized) + { + If(HPTE) + { + // Check if HPETimer Base should be modified. + CreateDwordField(BUF0,^FED0._BAS,HPT0) + Store(HPTB,HPT0) + } + + Return(BUF0) + } +} + +Device(IPIC) // 8259 PIC +{ + Name(_HID,EISAID("PNP0000")) + + Name(_CRS,ResourceTemplate() + { + IO(Decode16,0x20,0x20,0x01,0x02) + IO(Decode16,0x24,0x24,0x01,0x02) + IO(Decode16,0x28,0x28,0x01,0x02) + IO(Decode16,0x2C,0x2C,0x01,0x02) + IO(Decode16,0x30,0x30,0x01,0x02) + IO(Decode16,0x34,0x34,0x01,0x02) + IO(Decode16,0x38,0x38,0x01,0x02) + IO(Decode16,0x3C,0x3C,0x01,0x02) + IO(Decode16,0xA0,0xA0,0x01,0x02) + IO(Decode16,0xA4,0xA4,0x01,0x02) + IO(Decode16,0xA8,0xA8,0x01,0x02) + IO(Decode16,0xAC,0xAC,0x01,0x02) + IO(Decode16,0xB0,0xB0,0x01,0x02) + IO(Decode16,0xB4,0xB4,0x01,0x02) + IO(Decode16,0xB8,0xB8,0x01,0x02) + IO(Decode16,0xBC,0xBC,0x01,0x02) + IO(Decode16,0x4D0,0x4D0,0x01,0x02) + IRQNoFlags() {2} + }) +} + + +Device(MATH) // Math Co-Processor +{ + Name(_HID,EISAID("PNP0C04")) + + Name(_CRS,ResourceTemplate() + { + IO(Decode16,0xF0,0xF0,0x01,0x01) + IRQNoFlags() {13} + }) + + // + // Report device present for LPT-H. + // + Method (_STA, 0x0, NotSerialized) + { + If(LEqual(PCHV(), SPTH)) { + Return(0x1F) + } else { + Return(0x0) + } + } +} + + +Device(LDRC) // LPC Device Resource Consumption +{ + Name(_HID,EISAID("PNP0C02")) + + Name(_UID,2) + + Name(_CRS,ResourceTemplate() // This is for Cougar Point + { + IO(Decode16,0x2E,0x2E,0x1,0x02) // SIO Access. + IO(Decode16,0x4E,0x4E,0x1,0x02) // LPC Slot Access. + IO(Decode16,0x61,0x61,0x1,0x1) // NMI Status. + IO(Decode16,0x63,0x63,0x1,0x1) // Processor I/F. + IO(Decode16,0x65,0x65,0x1,0x1) // Processor I/F. + IO(Decode16,0x67,0x67,0x1,0x1) // Processor I/F. + IO(Decode16,0x70,0x70,0x1,0x1) // NMI Enable. + IO(Decode16,0x80,0x80,0x1,0x1) // Port 80h. + IO(Decode16,0x92,0x92,0x1,0x1) // Processor I/F. + IO(Decode16,0xB2,0xB2,0x01,0x02) // Software SMI. + IO(Decode16,0x680,0x680,0x1,0x20) // 32 Byte I/O. + IO(Decode16,0xFFFF,0xFFFF,0x1,0x1) // ACPI IO Trap. + IO(Decode16,0xFFFF,0xFFFF,0x1,0x1) // DTS IO Trap. + IO(Decode16,0xFFFF,0xFFFF,0x1,0x1) // HotKey IO Trap. + + IO(Decode16, 0x1800,0x1800,0x1,0xFF) // PCH ACPI Base + + IO(Decode16,0x164e,0x164e,0x1,0x02) // 16 Byte I/O. + }) +} + +Device(LDR2) // LPC Device Resource Consumption for PCH GPIO +{ + Name(_HID,EISAID("PNP0C02")) + + Name(_UID, "LPC_DEV") + + // LPT-H GPIO resource map + Name(_CRS,ResourceTemplate() + { + IO(Decode16, 0x800,0x800,0x1,0x80) // PCH GPIO Base. + }) + + Method(_STA, 0, NotSerialized) + { + If(LEqual(PCHV(), SPTH)) { + Return(0xF) + } else { + Return(0) + } + } +} + +Device(RTC) // RTC +{ + Name(_HID,EISAID("PNP0B00")) + + Name(_CRS,ResourceTemplate() + { + IO(Decode16,0x70,0x70,0x01,0x08) + IRQNoFlags() {8} + }) +} + +Device(TIMR) // 8254 Timer +{ + Name(_HID,EISAID("PNP0100")) + + Name(_CRS,ResourceTemplate() + { + IO(Decode16,0x40,0x40,0x01,0x04) + IO(Decode16,0x50,0x50,0x10,0x04) + IRQNoFlags() {0} + }) +} + +Device(CWDT) +{ + Name(_HID,EISAID("INT3F0D")) + Name(_CID,EISAID("PNP0C02")) + Name(BUF0,ResourceTemplate() + { + IO(Decode16, 0x1854, 0x1854, 0x4, 0x4) // PMBS 0x1800 + Offset 0x54 + } + ) + + Method(_STA,0,Serialized) + { + Return(0x0F) + } + + Method(_CRS,0,Serialized) + { + Return(BUF0) + } +} diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/LpcB.asl b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/LpcB.asl new file mode 100644 index 0000000000..29b026a571 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/LpcB.asl @@ -0,0 +1,94 @@ +/** @file + ACPI DSDT table + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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. + +**/ + + +// LPC Bridge - Device 31, Function 0 +scope (\_SB.PCI0.LPCB) { + Include ("LPC_DEV.ASL") + + // Define the KBC_COMMAND_REG-64, KBC_DATA_REG-60 Registers as an ACPI Operating + // Region. These registers will be used to skip kbd mouse + // resource settings if not present. + OperationRegion(PKBS, SystemIO, 0x60, 0x05) + Field(PKBS, ByteAcc, Lock, Preserve) + { + PKBD, 8, + , 8, + , 8, + , 8, + PKBC, 8 + } + Device(PS2K) // PS2 Keyboard + { + Name(_HID,"MSFT0001") + Name(_CID,EISAID("PNP0303")) + + Method(_STA) + { + If (P2MK) //Ps2 Keyboard and Mouse Enable + { + Return(0x000F) + } + Return(0x0000) + } + + Name(_CRS,ResourceTemplate() + { + IO(Decode16,0x60,0x60,0x01,0x01) + IO(Decode16,0x64,0x64,0x01,0x01) + IRQ(Edge,ActiveHigh,Exclusive){0x01} + }) + + Name(_PRS, ResourceTemplate(){ + StartDependentFn(0, 0) { + FixedIO(0x60,0x01) + FixedIO(0x64,0x01) + IRQNoFlags(){1} + } + EndDependentFn() + }) + + } + + Device(PS2M) // PS/2 Mouse + { + Name(_HID,"MSFT0003") + Name(_CID,EISAID("PNP0F03")) + + Method(_STA) + { + If (P2ME) //Ps2 Mouse Enable + { + If (P2MK) //Ps2 Keyboard and Mouse Enable + { + Return(0x000F) + } + } + Return(0x0000) + } + + Name(_CRS,ResourceTemplate() + { + IRQ(Edge,ActiveHigh,Exclusive){0x0C} + }) + + Name(_PRS, ResourceTemplate(){ + StartDependentFn(0, 0) { + IRQNoFlags(){12} + } + EndDependentFn() + }) + } + +} diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PCI_DRC.ASL b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PCI_DRC.ASL new file mode 100644 index 0000000000..4304e07275 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PCI_DRC.ASL @@ -0,0 +1,122 @@ +/** @file + ACPI DSDT table + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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. + +**/ + + +Scope (\_SB.PCI0){ + + Device(PDRC) + { + // + // PCI Device Resource Consumption + // + + Name(_HID,EISAID("PNP0C02")) + + Name(_UID,1) + + Name(BUF0,ResourceTemplate() + { + // + // MCH BAR _BAS will be updated in _CRS below according to B0:D0:F0:Reg.48h + // + Memory32Fixed(ReadWrite,0,0x08000,MCHB) + // + // DMI BAR _BAS will be updated in _CRS below according to B0:D0:F0:Reg.68h + // + Memory32Fixed(ReadWrite,0,0x01000,DMIB) + // + // EP BAR _BAS will be updated in _CRS below according to B0:D0:F0:Reg.40h + // + Memory32Fixed(ReadWrite,0,0x01000,EGPB) + // + // PCI Express BAR _BAS and _LEN will be updated in _CRS below according to B0:D0:F0:Reg.60h + // + Memory32Fixed(ReadWrite,0,0,PCIX) + + // + // MISC ICH TTT base address reserved for the TxT module use. Check if the hard code meets the real configuration. + // If not, dynamically update it like the _CRS method below. + // + Memory32Fixed(ReadWrite,0xFED20000,0x20000) + + // + // VTD engine memory range. Check if the hard code meets the real configuration. + // If not, dynamically update it like the _CRS method below. + // + Memory32Fixed(ReadOnly, 0xFED90000, 0x00004000) + + // + // MISC ICH. Check if the hard code meets the real configuration. + // If not, dynamically update it like the _CRS method below. + // + Memory32Fixed(ReadWrite,0xFED45000,0x4B000,TPMM) + + // + // FLASH range + // + Memory32Fixed (ReadOnly, 0xFF000000, 0x1000000, FIOH) //16MB as per IOH spec + + // + // Local APIC range(0xFEE0_0000 to 0xFEEF_FFFF) + // + Memory32Fixed (ReadOnly, 0xFEE00000, 0x100000, LIOH) + + // + // Sx handler reserved MMIO + // + Memory32Fixed (ReadWrite, 0, 0, SXRE) + + // + // Reserve HPET address decode range + // + Memory32Fixed (ReadWrite, 0, 0, HPET) + + }) + + + Method(_CRS,0,Serialized) + { + + CreateDwordField(BUF0,^MCHB._BAS,MBR0) + Store(\_SB.PCI0.GMHB(), MBR0) + + CreateDwordField(BUF0,^DMIB._BAS,DBR0) + Store(\_SB.PCI0.GDMB(), DBR0) + + CreateDwordField(BUF0,^EGPB._BAS,EBR0) + Store(\_SB.PCI0.GEPB(), EBR0) + + CreateDwordField(BUF0,^PCIX._BAS,XBR0) + Store(\_SB.PCI0.GPCB(), XBR0) + + CreateDwordField(BUF0,^PCIX._LEN,XSZ0) + Store(\_SB.PCI0.GPCL(), XSZ0) + + CreateDwordField(BUF0,^SXRE._BAS,SXRA) + Store(SXRB, SXRA) + CreateDwordField(BUF0,^SXRE._LEN,SXRL) + Store(SXRS, SXRL) + + // HPET device claims the resource in LPC_DEV.ASL. + If(LNOT(HPTE)){ + CreateDwordField(BUF0,^HPET._BAS,HBAS) + CreateDwordField(BUF0,^HPET._LEN,HLEN) + Store(HPTB, HBAS) + Store(0x400, HLEN) + } + + Return(BUF0) + } + } //end of PDRC +} // end of SB diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl new file mode 100644 index 0000000000..3bc988f619 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl @@ -0,0 +1,312 @@ +/** @file + ACPI DSDT table + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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. + +**/ + +Scope(\_SB) { + Name(PR00, Package(){ +// PCI Bridge +// D31: cAVS, SMBus, GbE, Nothpeak + Package(){0x001FFFFF, 0, LNKA, 0 }, + Package(){0x001FFFFF, 1, LNKB, 0 }, + Package(){0x001FFFFF, 2, LNKC, 0 }, + Package(){0x001FFFFF, 3, LNKD, 0 }, +// D30: SerialIo and SCS - can't use PIC +// D29: PCI Express Port 9-16 + Package(){0x001DFFFF, 0, LNKA, 0 }, + Package(){0x001DFFFF, 1, LNKB, 0 }, + Package(){0x001DFFFF, 2, LNKC, 0 }, + Package(){0x001DFFFF, 3, LNKD, 0 }, +// D28: PCI Express Port 1-8 + Package(){0x001CFFFF, 0, LNKA, 0 }, + Package(){0x001CFFFF, 1, LNKB, 0 }, + Package(){0x001CFFFF, 2, LNKC, 0 }, + Package(){0x001CFFFF, 3, LNKD, 0 }, +// D27: PCI Express Port 17-20 + Package(){0x001BFFFF, 0, LNKA, 0 }, + Package(){0x001BFFFF, 1, LNKB, 0 }, + Package(){0x001BFFFF, 2, LNKC, 0 }, + Package(){0x001BFFFF, 3, LNKD, 0 }, +// D25: SerialIo - can't use PIC +// D23: SATA controller + Package(){0x0017FFFF, 0, LNKA, 0 }, +// D22: CSME (HECI, IDE-R, Keyboard and Text redirection + Package(){0x0016FFFF, 0, LNKA, 0 }, + Package(){0x0016FFFF, 1, LNKB, 0 }, + Package(){0x0016FFFF, 2, LNKC, 0 }, + Package(){0x0016FFFF, 3, LNKD, 0 }, +// D21: SerialIo - can't use PIC +// D20: xHCI, Thermal Subsystem, Camera IO Host Controller + Package(){0x0014FFFF, 0, LNKA, 0 }, + Package(){0x0014FFFF, 1, LNKB, 0 }, + Package(){0x0014FFFF, 2, LNKC, 0 }, + Package(){0x0014FFFF, 3, LNKD, 0 }, +// D19: Integrated Sensor Hub - can't use PIC + +// Host Bridge +// P.E.G. Root Port D1F0 + Package(){0x0001FFFF, 0, LNKA, 0 }, + Package(){0x0001FFFF, 1, LNKB, 0 }, + Package(){0x0001FFFF, 2, LNKC, 0 }, + Package(){0x0001FFFF, 3, LNKD, 0 }, +// P.E.G. Root Port D1F1 +// P.E.G. Root Port D1F2 +// SA IGFX Device + Package(){0x0002FFFF, 0, LNKA, 0 }, +// SA Thermal Device + Package(){0x0004FFFF, 0, LNKA, 0 }, +// SA SkyCam Device + Package(){0x0005FFFF, 0, LNKA, 0 }, +// SA GMM Device + Package(){0x0008FFFF, 0, LNKA, 0 }, + }) + Name(AR00, Package(){ +// PCI Bridge +// D31: cAVS, SMBus, GbE, Nothpeak + Package(){0x001FFFFF, 0, 0, 16 }, + Package(){0x001FFFFF, 1, 0, 17 }, + Package(){0x001FFFFF, 2, 0, 18 }, + Package(){0x001FFFFF, 3, 0, 19 }, +// D30: SerialIo and SCS + Package(){0x001EFFFF, 0, 0, 20 }, + Package(){0x001EFFFF, 1, 0, 21 }, + Package(){0x001EFFFF, 2, 0, 22 }, + Package(){0x001EFFFF, 3, 0, 23 }, +// D29: PCI Express Port 9-16 + Package(){0x001DFFFF, 0, 0, 16 }, + Package(){0x001DFFFF, 1, 0, 17 }, + Package(){0x001DFFFF, 2, 0, 18 }, + Package(){0x001DFFFF, 3, 0, 19 }, +// D28: PCI Express Port 1-8 + Package(){0x001CFFFF, 0, 0, 16 }, + Package(){0x001CFFFF, 1, 0, 17 }, + Package(){0x001CFFFF, 2, 0, 18 }, + Package(){0x001CFFFF, 3, 0, 19 }, +// D27: PCI Express Port 17-20 + Package(){0x001BFFFF, 0, 0, 16 }, + Package(){0x001BFFFF, 1, 0, 17 }, + Package(){0x001BFFFF, 2, 0, 18 }, + Package(){0x001BFFFF, 3, 0, 19 }, +// D25: SerialIo + Package(){0x0019FFFF, 0, 0, 32 }, + Package(){0x0019FFFF, 1, 0, 33 }, + Package(){0x0019FFFF, 2, 0, 34 }, +// D23: SATA controller + Package(){0x0017FFFF, 0, 0, 16 }, +// D22: CSME (HECI, IDE-R, Keyboard and Text redirection + Package(){0x0016FFFF, 0, 0, 16 }, + Package(){0x0016FFFF, 1, 0, 17 }, + Package(){0x0016FFFF, 2, 0, 18 }, + Package(){0x0016FFFF, 3, 0, 19 }, +// D21: SerialIo + Package(){0x0015FFFF, 0, 0, 16 }, + Package(){0x0015FFFF, 1, 0, 17 }, + Package(){0x0015FFFF, 2, 0, 18 }, + Package(){0x0015FFFF, 3, 0, 19 }, +// D20: xHCI, OTG, Thermal Subsystem, Camera IO Host Controller + Package(){0x0014FFFF, 0, 0, 16 }, + Package(){0x0014FFFF, 1, 0, 17 }, + Package(){0x0014FFFF, 2, 0, 18 }, + Package(){0x0014FFFF, 3, 0, 19 }, +// D19: Integrated Sensor Hub + Package(){0x0013FFFF, 0, 0, 20 }, + +// Host Bridge +// P.E.G. Root Port D1F0 + Package(){0x0001FFFF, 0, 0, 16 }, + Package(){0x0001FFFF, 1, 0, 17 }, + Package(){0x0001FFFF, 2, 0, 18 }, + Package(){0x0001FFFF, 3, 0, 19 }, +// P.E.G. Root Port D1F1 +// P.E.G. Root Port D1F2 +// SA IGFX Device + Package(){0x0002FFFF, 0, 0, 16 }, +// SA Thermal Device + Package(){0x0004FFFF, 0, 0, 16 }, +// SA SkyCam Device + Package(){0x0005FFFF, 0, 0, 16 }, +// SA GMM Device + Package(){0x0008FFFF, 0, 0, 16 }, + }) + Name(PR04, Package(){ + Package(){0x0000FFFF, 0, LNKA, 0 }, + Package(){0x0000FFFF, 1, LNKB, 0 }, + Package(){0x0000FFFF, 2, LNKC, 0 }, + Package(){0x0000FFFF, 3, LNKD, 0 }, + }) + Name(AR04, Package(){ + Package(){0x0000FFFF, 0, 0, 16 }, + Package(){0x0000FFFF, 1, 0, 17 }, + Package(){0x0000FFFF, 2, 0, 18 }, + Package(){0x0000FFFF, 3, 0, 19 }, + }) + Name(PR05, Package(){ + Package(){0x0000FFFF, 0, LNKB, 0 }, + Package(){0x0000FFFF, 1, LNKC, 0 }, + Package(){0x0000FFFF, 2, LNKD, 0 }, + Package(){0x0000FFFF, 3, LNKA, 0 }, + }) + Name(AR05, Package(){ + Package(){0x0000FFFF, 0, 0, 17 }, + Package(){0x0000FFFF, 1, 0, 18 }, + Package(){0x0000FFFF, 2, 0, 19 }, + Package(){0x0000FFFF, 3, 0, 16 }, + }) + Name(PR06, Package(){ + Package(){0x0000FFFF, 0, LNKC, 0 }, + Package(){0x0000FFFF, 1, LNKD, 0 }, + Package(){0x0000FFFF, 2, LNKA, 0 }, + Package(){0x0000FFFF, 3, LNKB, 0 }, + }) + Name(AR06, Package(){ + Package(){0x0000FFFF, 0, 0, 18 }, + Package(){0x0000FFFF, 1, 0, 19 }, + Package(){0x0000FFFF, 2, 0, 16 }, + Package(){0x0000FFFF, 3, 0, 17 }, + }) + Name(PR07, Package(){ + Package(){0x0000FFFF, 0, LNKD, 0 }, + Package(){0x0000FFFF, 1, LNKA, 0 }, + Package(){0x0000FFFF, 2, LNKB, 0 }, + Package(){0x0000FFFF, 3, LNKC, 0 }, + }) + Name(AR07, Package(){ + Package(){0x0000FFFF, 0, 0, 19 }, + Package(){0x0000FFFF, 1, 0, 16 }, + Package(){0x0000FFFF, 2, 0, 17 }, + Package(){0x0000FFFF, 3, 0, 18 }, + }) + Name(PR08, Package(){ + Package(){0x0000FFFF, 0, LNKA, 0 }, + Package(){0x0000FFFF, 1, LNKB, 0 }, + Package(){0x0000FFFF, 2, LNKC, 0 }, + Package(){0x0000FFFF, 3, LNKD, 0 }, + }) + Name(AR08, Package(){ + Package(){0x0000FFFF, 0, 0, 16 }, + Package(){0x0000FFFF, 1, 0, 17 }, + Package(){0x0000FFFF, 2, 0, 18 }, + Package(){0x0000FFFF, 3, 0, 19 }, + }) + Name(PR09, Package(){ + Package(){0x0000FFFF, 0, LNKB, 0 }, + Package(){0x0000FFFF, 1, LNKC, 0 }, + Package(){0x0000FFFF, 2, LNKD, 0 }, + Package(){0x0000FFFF, 3, LNKA, 0 }, + }) + Name(AR09, Package(){ + Package(){0x0000FFFF, 0, 0, 17 }, + Package(){0x0000FFFF, 1, 0, 18 }, + Package(){0x0000FFFF, 2, 0, 19 }, + Package(){0x0000FFFF, 3, 0, 16 }, + }) + Name(PR0E, Package(){ + Package(){0x0000FFFF, 0, LNKC, 0 }, + Package(){0x0000FFFF, 1, LNKD, 0 }, + Package(){0x0000FFFF, 2, LNKA, 0 }, + Package(){0x0000FFFF, 3, LNKB, 0 }, + }) + Name(AR0E, Package(){ + Package(){0x0000FFFF, 0, 0, 18 }, + Package(){0x0000FFFF, 1, 0, 19 }, + Package(){0x0000FFFF, 2, 0, 16 }, + Package(){0x0000FFFF, 3, 0, 17 }, + }) + Name(PR0F, Package(){ + Package(){0x0000FFFF, 0, LNKD, 0 }, + Package(){0x0000FFFF, 1, LNKA, 0 }, + Package(){0x0000FFFF, 2, LNKB, 0 }, + Package(){0x0000FFFF, 3, LNKC, 0 }, + }) + Name(AR0F, Package(){ + Package(){0x0000FFFF, 0, 0, 19 }, + Package(){0x0000FFFF, 1, 0, 16 }, + Package(){0x0000FFFF, 2, 0, 17 }, + Package(){0x0000FFFF, 3, 0, 18 }, + }) + Name(PR02, Package(){ + Package(){0x0000FFFF, 0, LNKA, 0 }, + Package(){0x0000FFFF, 1, LNKB, 0 }, + Package(){0x0000FFFF, 2, LNKC, 0 }, + Package(){0x0000FFFF, 3, LNKD, 0 }, + }) + Name(AR02, Package(){ +// P.E.G. Port Slot x16 + Package(){0x0000FFFF, 0, 0, 16 }, + Package(){0x0000FFFF, 1, 0, 17 }, + Package(){0x0000FFFF, 2, 0, 18 }, + Package(){0x0000FFFF, 3, 0, 19 }, + }) + Name(PR0A, Package(){ +// P.E.G. Port Slot x8 + Package(){0x0000FFFF, 0, LNKB, 0 }, + Package(){0x0000FFFF, 1, LNKC, 0 }, + Package(){0x0000FFFF, 2, LNKD, 0 }, + Package(){0x0000FFFF, 3, LNKA, 0 }, + }) + Name(AR0A, Package(){ +// P.E.G. Port Slot x8 + Package(){0x0000FFFF, 0, 0, 17 }, + Package(){0x0000FFFF, 1, 0, 18 }, + Package(){0x0000FFFF, 2, 0, 19 }, + Package(){0x0000FFFF, 3, 0, 16 }, + }) + Name(PR0B, Package(){ +// P.E.G. Port Slot x4 + Package(){0x0000FFFF, 0, LNKC, 0 }, + Package(){0x0000FFFF, 1, LNKD, 0 }, + Package(){0x0000FFFF, 2, LNKA, 0 }, + Package(){0x0000FFFF, 3, LNKB, 0 }, + }) + Name(AR0B, Package(){ +// P.E.G. Port Slot x4 + Package(){0x0000FFFF, 0, 0, 18 }, + Package(){0x0000FFFF, 1, 0, 19 }, + Package(){0x0000FFFF, 2, 0, 16 }, + Package(){0x0000FFFF, 3, 0, 17 }, + }) +//--------------------------------------------------------------------------- +// List of IRQ resource buffers compatible with _PRS return format. +//--------------------------------------------------------------------------- +// Naming legend: +// RSxy, PRSy - name of the IRQ resource buffer to be returned by _PRS, "xy" - last two characters of IRQ Link name. +// Note. PRSy name is generated if IRQ Link name starts from "LNK". +// HLxy , LLxy - reference names, can be used to access bit mask of available IRQs. HL and LL stand for active High(Low) Level triggered Irq model. +//--------------------------------------------------------------------------- + Name(PRSA, ResourceTemplate(){ // Link name: LNKA + IRQ(Level, ActiveLow, Shared, LLKA) {3,4,5,6,10,11,12,14,15} + }) + Alias(PRSA,PRSB) // Link name: LNKB + Alias(PRSA,PRSC) // Link name: LNKC + Alias(PRSA,PRSD) // Link name: LNKD + Alias(PRSA,PRSE) // Link name: LNKE + Alias(PRSA,PRSF) // Link name: LNKF + Alias(PRSA,PRSG) // Link name: LNKG + Alias(PRSA,PRSH) // Link name: LNKH +//--------------------------------------------------------------------------- +// Begin PCI tree object scope +//--------------------------------------------------------------------------- + Device(PCI0) { // PCI Bridge "Host Bridge" + Name(_HID, EISAID("PNP0A08")) // Indicates PCI Express/PCI-X Mode2 host hierarchy + Name(_CID, EISAID("PNP0A03")) // To support legacy OS that doesn't understand the new HID + Name(_ADR, 0x00000000) + Method(^BN00, 0){ return(0x0000) } // Returns default Bus number for Peer PCI busses. Name can be overriden with control method placed directly under Device scope + Method(_BBN, 0){ return(BN00()) } // Bus number, optional for the Root PCI Bus + Name(_UID, 0x0000) // Unique Bus ID, optional + Method(_PRT,0) { + If(PICM) {Return(AR00)} // APIC mode + Return (PR00) // PIC Mode + } // end _PRT + + Include("HostBus.asl") + } // end PCI0 Bridge "Host Bridge" +} // end _SB scope diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl new file mode 100644 index 0000000000..90f873c8bd --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl @@ -0,0 +1,1135 @@ +/** @file + ACPI DSDT table + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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 TRAP_TYPE_DTS 0x02 +#define TRAP_TYPE_IGD 0x03 +#define TRAP_TYPE_BGD 0x04 // BIOS Guard + +// Define the following External variables to prevent a WARNING when +// using ASL.EXE and an ERROR when using IASL.EXE. + +External(\PC00, IntObj) // PR00 _PDC Flags +External(\PC01) +External(\PC02) +External(\PC03) +External(\PC04) +External(\PC05) +External(\PC06) +External(\PC07) +External(\PC08) +External(\PC09) +External(\PC10) +External(\PC11) +External(\PC12) +External(\PC13) +External(\PC14) +External(\PC15) +External(\_PR.CFGD) +External(\SGMD) + +// +// DTS externals +// +External(\_PR.DTSF) +External(\_PR.DTSE) +External(\_PR.TRPD) +External(\_PR.TRPF) +External(\_PR.DSAE) +// +// SGX +// +External(\_PR.EPCS) +External(\_PR.EMNA) +External(\_PR.ELNG) + +External(\_SB.PCI0.GFX0.TCHE) // Technology enabled indicator +External(\_SB.PCI0.GFX0.STAT) // State Indicator + +External(\_SB.TPM.PTS, MethodObj) +External(\_SB.PCI0.PAUD.PUAM, MethodObj) //PUAM - PowerResource User Absent Mode +External(\_SB.PCI0.XHC.DUAM, MethodObj) //DUAM - Device User Absent Mode for XHCI controller +External(\_SB.PCI0.I2C4.GEXP.INVC, MethodObj) + +External(\_SB.PCI0.GFX0.IUEH, MethodObj) + +#define CONVERTIBLE_BUTTON 6 +#define DOCK_INDICATOR 7 + +Name(ECUP, 1) // EC State indicator: 1- Normal Mode 0- Low Power Mode +Mutex(EHLD, 0) // EC Hold indicator: 0- No one accessing the EC Power State 1- Someone else is accessing the EC Power State + + + +External(TBTD, MethodObj) +External(TBTF, MethodObj) +External(MMRP, MethodObj) +External(MMTB, MethodObj) +External(TBFF, MethodObj) +External(FFTB, MethodObj) +External(SXTB, MethodObj) + + +// Interrupt specific registers +include("Itss.asl") + +// Create a Global MUTEX. + +Mutex(MUTX,0) + +// OS Up mutex +Mutex(OSUM, 0) +// _WAK Finished Event +Event(WFEV) + +// Define Port 80 as an ACPI Operating Region to use for debugging. Please +// note that the Intel CRBs have the ability to ouput an entire DWord to +// Port 80h for debugging purposes, so the model implemented here may not be +// able to be used on OEM Designs. + +OperationRegion(PRT0,SystemIO,0x80,4) +Field(PRT0,DwordAcc,Lock,Preserve) +{ + P80H, 32 +} + +// Port 80h Update: +// Update 8 bits of the 32-bit Port 80h. +// +// Arguments: +// Arg0: 0 = Write Port 80h, Bits 7:0 Only. +// 1 = Write Port 80h, Bits 15:8 Only. +// 2 = Write Port 80h, Bits 23:16 Only. +// 3 = Write Port 80h, Bits 31:24 Only. +// Arg1: 8-bit Value to write +// +// Return Value: +// None + +Method(D8XH,2,Serialized) +{ + If(LEqual(Arg0,0)) // Write Port 80h, Bits 7:0. + { + Store(Or(And(P80D,0xFFFFFF00),Arg1),P80D) + } + + If(LEqual(Arg0,1)) // Write Port 80h, Bits 15:8. + { + Store(Or(And(P80D,0xFFFF00FF),ShiftLeft(Arg1,8)),P80D) + } + + If(LEqual(Arg0,2)) // Write Port 80h, Bits 23:16. + { + Store(Or(And(P80D,0xFF00FFFF),ShiftLeft(Arg1,16)),P80D) + } + + If(LEqual(Arg0,3)) // Write Port 80h, Bits 31:24. + { + Store(Or(And(P80D,0x00FFFFFF),ShiftLeft(Arg1,24)),P80D) + } + + Store(P80D,P80H) +} + +// Debug Port 80h Update: +// If Acpidebug is enabled only then call D8XH to update 8 bits of the 32-bit Port 80h. +// +// Arguments: +// Arg0: 0 = Write Port 80h, Bits 7:0 Only. +// 1 = Write Port 80h, Bits 15:8 Only. +// 2 = Write Port 80h, Bits 23:16 Only. +// 3 = Write Port 80h, Bits 31:24 Only. +// Arg1: 8-bit Value to write +// +// Return Value: +// None +Method(P8XH,2,Serialized) +{ + // If ACPI debug is enabled, then display post codes on Port 80h + If(CondRefOf(MDBG)) {// Check if ACPI Debug SSDT is loaded + D8XH(Arg0,Arg1) + } +} + +Method(ADBG,1,Serialized) +{ + Return(0) +} + +// +// Define SW SMI port as an ACPI Operating Region to use for generate SW SMI. +// +OperationRegion(SPRT,SystemIO, 0xB2,2) +Field (SPRT, ByteAcc, Lock, Preserve) { + SSMP, 8 +} + +// The _PIC Control Method is optional for ACPI design. It allows the +// OS to inform the ASL code which interrupt controller is being used, +// the 8259 or APIC. The reference code in this document will address +// PCI IRQ Routing and resource allocation for both cases. +// +// The values passed into _PIC are: +// 0 = 8259 +// 1 = IOAPIC + +Method(\_PIC,1) +{ + Store(Arg0,GPIC) + Store(Arg0,PICM) +} + +// Prepare to Sleep. The hook is called when the OS is about to +// enter a sleep state. The argument passed is the numeric value of +// the Sx state. + +Method(_PTS,1) +{ + Store(0,P80D) // Zero out the entire Port 80h DWord. + D8XH(0,Arg0) // Output Sleep State to Port 80h, Byte 0. + + ADBG(Concatenate("_PTS=",ToHexString(Arg0))) + + + // If code is executed, Wake from RI# via Serial Modem will be + // enabled. If code is not executed, COM Port Debugging throughout + // all Sx states will be enabled. + + If(LEqual(Arg0,3)) + { + // + // Disable update DTS temperature and threshold value in every SMI + // + If(CondRefOf(\_PR.DTSE)){ + If(LAnd(\_PR.DTSE, LGreater(TCNT, 1))) + { + TRAP(TRAP_TYPE_DTS,30) + } + } + } + + + // Generate a SW SMI trap to save some NVRAM data back to CMOS. + + // Don't enable IGD OpRegion support yet. + // TRAP(1, 81) + // + // Call TPM.PTS + // + If(CondRefOf(\_SB.TPM.PTS)) + { + // + // Call TPM PTS method + // + \_SB.TPM.PTS (Arg0) + } + +} + +// Wake. This hook is called when the OS is about to wake from a +// sleep state. The argument passed is the numeric value of the +// sleep state the system is waking from. + +Method(_WAK,1,Serialized) +{ + D8XH(1,0xAB) // Beginning of _WAK. + + ADBG("_WAK") + + // + // Only set 8254 CG if Low Power S0 Idle Capability is enabled + // + If (LEqual(S0ID, One)) { + // + // Set ITSSPRC.8254CGE: Offset 3300h ITSSPRC[2] + // + Store(0x01, \_SB.SCGE) + } + + If(NEXP) + { + // Reinitialize the Native PCI Express after resume + + If(And(OSCC,0x02)) + { + \_SB.PCI0.NHPG() + } + If(And(OSCC,0x04)) // PME control granted? + { + \_SB.PCI0.NPME() + } + } + + + If(LOr(LEqual(Arg0,3), LEqual(Arg0,4))) // If S3 or S4 Resume + { + + // Check to send Convertible/Dock state changes upon resume from Sx. + If(And(GBSX,0x40)) + { + \_SB.PCI0.GFX0.IUEH(6) + + // + // Do the same thing for Virtul Button device. + // Toggle Bit3 of PB1E(Slate/Notebook status) + // + Xor(PB1E, 0x08, PB1E) + + } + + If(And(GBSX,0x80)) + { + \_SB.PCI0.GFX0.IUEH(7) + + // + // Do the same thing for Virtul Button device. + // Toggle Bit4 of PB1E (Dock/Undock status) + // + Xor(PB1E, 0x10, PB1E) + + } + + + If(CondRefOf(\_PR.DTSE)){ + If(LAnd(\_PR.DTSE, LGreater(TCNT, 1))) + { + TRAP(TRAP_TYPE_DTS, 20) + } + } + + + // For PCI Express Express Cards, it is possible a device was + // either inserted or removed during an Sx State. The problem + // is that no wake event will occur for a given warm insertion + // or removal, so the OS will not become aware of any change. + // To get around this, re-enumerate all Express Card slots. + // + // If the Root Port is enabled, it may be assumed to be hot-pluggable. + + If(LNotEqual(\_SB.PCI0.RP01.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP01,0) + } + + If(LNotEqual(\_SB.PCI0.RP02.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP02,0) + } + + If(LNotEqual(\_SB.PCI0.RP03.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP03,0) + } + + If(LNotEqual(\_SB.PCI0.RP04.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP04,0) + } + + If(LNotEqual(\_SB.PCI0.RP05.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP05,0) + } + + If(LNotEqual(\_SB.PCI0.RP06.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP06,0) + } + + If(LNotEqual(\_SB.PCI0.RP07.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP07,0) + } + + If(LNotEqual(\_SB.PCI0.RP08.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP08,0) + } + + If(LNotEqual(\_SB.PCI0.RP09.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP09,0) + } + + If(LNotEqual(\_SB.PCI0.RP10.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP10,0) + } + + If(LNotEqual(\_SB.PCI0.RP11.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP11,0) + } + + If(LNotEqual(\_SB.PCI0.RP12.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP12,0) + } + + If(LNotEqual(\_SB.PCI0.RP13.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP13,0) + } + + If(LNotEqual(\_SB.PCI0.RP14.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP14,0) + } + + If(LNotEqual(\_SB.PCI0.RP15.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP15,0) + } + + If(LNotEqual(\_SB.PCI0.RP16.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP16,0) + } + + If(LNotEqual(\_SB.PCI0.RP17.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP17,0) + } + + If(LNotEqual(\_SB.PCI0.RP18.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP18,0) + } + + If(LNotEqual(\_SB.PCI0.RP19.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP19,0) + } + + If(LNotEqual(\_SB.PCI0.RP20.VDID,0xFFFFFFFF)) + { + Notify (\_SB.PCI0.RP20,0) + } + } + + + Return(Package(){0,0}) +} + +// Get Buffer: +// This method will take a buffer passed into the method and +// create then return a smaller buffer based on the pointer +// and size parameters passed in. +// +// Arguments: +// Arg0: Pointer to start of new Buffer in passed in Buffer. +// Arg1: Size of Buffer to create. +// Arg2: Original Buffer +// +// Return Value: +// Newly created buffer. + +Method(GETB,3,Serialized) +{ + Multiply(Arg0,8,Local0) // Convert Index. + Multiply(Arg1,8,Local1) // Convert Size. + CreateField(Arg2,Local0,Local1,TBF3) // Create Buffer. + + Return(TBF3) // Return Buffer. +} + +// Power Notification: +// Perform all needed OS notifications during a +// Power Switch. +// +// Arguments: +// None +// +// Return Value: +// None + +Method(PNOT,0,Serialized) +{ + // + // If MP enabled and driver support is present, notify all + // processors. + // + If(LGreater(TCNT, 1)) + { + If(And(\PC00,0x0008)){ + Notify(\_PR.PR00,0x80) // Eval PR00 _PPC. + } + If(And(\PC01,0x0008)){ + Notify(\_PR.PR01,0x80) // Eval PR01 _PPC. + } + If(And(\PC02,0x0008)){ + Notify(\_PR.PR02,0x80) // Eval PR02 _PPC. + } + If(And(\PC03,0x0008)){ + Notify(\_PR.PR03,0x80) // Eval PR03 _PPC. + } + If(And(\PC04,0x0008)){ + Notify(\_PR.PR04,0x80) // Eval PR04 _PPC. + } + If(And(\PC05,0x0008)){ + Notify(\_PR.PR05,0x80) // Eval PR05 _PPC. + } + If(And(\PC06,0x0008)){ + Notify(\_PR.PR06,0x80) // Eval PR06 _PPC. + } + If(And(\PC07,0x0008)){ + Notify(\_PR.PR07,0x80) // Eval PR07 _PPC. + } + If(And(\PC08,0x0008)){ + Notify(\_PR.PR08,0x80) // Eval PR08 _PPC. + } + If(And(\PC09,0x0008)){ + Notify(\_PR.PR09,0x80) // Eval PR09 _PPC. + } + If(And(\PC10,0x0008)){ + Notify(\_PR.PR10,0x80) // Eval PR10 _PPC. + } + If(And(\PC11,0x0008)){ + Notify(\_PR.PR11,0x80) // Eval PR11 _PPC. + } + If(And(\PC12,0x0008)){ + Notify(\_PR.PR12,0x80) // Eval PR12 _PPC. + } + If(And(\PC13,0x0008)){ + Notify(\_PR.PR13,0x80) // Eval PR13 _PPC. + } + If(And(\PC14,0x0008)){ + Notify(\_PR.PR14,0x80) // Eval PR14 _PPC. + } + If(And(\PC15,0x0008)){ + Notify(\_PR.PR15,0x80) // Eval PR15 _PPC. + } + }Else{ + Notify(\_PR.PR00,0x80) // Eval _PPC. + } + + If(LGreater(TCNT, 1)){ + If(LAnd(And(\PC00,0x0008),And(\PC00,0x0010))){ + Notify(\_PR.PR00,0x81) // Eval PR00 _CST. + } + If(LAnd(And(\PC01,0x0008),And(\PC01,0x0010))){ + Notify(\_PR.PR01,0x81) // Eval PR01 _CST. + } + If(LAnd(And(\PC02,0x0008),And(\PC02,0x0010))){ + Notify(\_PR.PR02,0x81) // Eval PR02 _CST. + } + If(LAnd(And(\PC03,0x0008),And(\PC03,0x0010))){ + Notify(\_PR.PR03,0x81) // Eval PR03 _CST. + } + If(LAnd(And(\PC04,0x0008),And(\PC04,0x0010))){ + Notify(\_PR.PR04,0x81) // Eval PR04 _CST. + } + If(LAnd(And(\PC05,0x0008),And(\PC05,0x0010))){ + Notify(\_PR.PR05,0x81) // Eval PR05 _CST. + } + If(LAnd(And(\PC06,0x0008),And(\PC06,0x0010))){ + Notify(\_PR.PR06,0x81) // Eval PR06 _CST. + } + If(LAnd(And(\PC07,0x0008),And(\PC07,0x0010))){ + Notify(\_PR.PR07,0x81) // Eval PR07 _CST. + } + If(LAnd(And(\PC08,0x0008),And(\PC08,0x0010))){ + Notify(\_PR.PR08,0x81) // Eval PR08 _CST. + } + If(LAnd(And(\PC09,0x0008),And(\PC09,0x0010))){ + Notify(\_PR.PR09,0x81) // Eval PR09 _CST. + } + If(LAnd(And(\PC10,0x0008),And(\PC10,0x0010))){ + Notify(\_PR.PR10,0x81) // Eval PR10 _CST. + } + If(LAnd(And(\PC11,0x0008),And(\PC11,0x0010))){ + Notify(\_PR.PR11,0x81) // Eval PR11 _CST. + } + If(LAnd(And(\PC12,0x0008),And(\PC12,0x0010))){ + Notify(\_PR.PR12,0x81) // Eval PR12 _CST. + } + If(LAnd(And(\PC13,0x0008),And(\PC13,0x0010))){ + Notify(\_PR.PR13,0x81) // Eval PR13 _CST. + } + If(LAnd(And(\PC14,0x0008),And(\PC14,0x0010))){ + Notify(\_PR.PR14,0x81) // Eval PR14 _CST. + } + If(LAnd(And(\PC15,0x0008),And(\PC15,0x0010))){ + Notify(\_PR.PR15,0x81) // Eval PR15 _CST. + } + } Else { + Notify(\_PR.PR00,0x81) // Eval _CST. + } + + +} // end of Method(PNOT) + +// +// Memory window to the CTDP registers starting at MCHBAR+5000h. +// + OperationRegion (MBAR, SystemMemory, Add(\_SB.PCI0.GMHB(),0x5000), 0x1000) + Field (MBAR, ByteAcc, NoLock, Preserve) + { + Offset (0x938), // PACKAGE_POWER_SKU_UNIT (MCHBAR+0x5938) + PWRU, 4, // Power Units [3:0] unit value is calculated by 1 W / Power(2,PWR_UNIT). The default value of 0011b corresponds to 1/8 W. + Offset (0x9A0), // TURBO_POWER_LIMIT1 (MCHBAR+0x59A0) + PPL1, 15, // PKG_PWR_LIM_1 [14:0] + PL1E,1, // PKG_PWR_LIM1_EN [15] + CLP1,1, // Package Clamping Limitation 1 + } +Name(CLMP, 0) // save the clamp bit +Name(PLEN,0) // save the power limit enable bit +Name(PLSV,0x8000) // save value of PL1 upon entering CS +Name(CSEM, 0) //semaphore to avoid multiple calls to SPL1. SPL1/RPL1 must always be called in pairs, like push/pop off a stack +// +// SPL1 (Set PL1 to 4.5 watts with clamp bit set) +// Per Legacy Thermal management CS requirements, we would like to set the PL1 limit when entering CS to 4.5W with clamp bit set via MMIO. +// This can be done in the ACPI object which gets called by graphics driver during CS Entry. +// Likewise, during CS exit, the BIOS must reset the PL1 value to the previous value prior to CS entry and reset the clamp bit. +// +// Arguments: +// None +// +// Return Value: +// None +Method(SPL1,0,Serialized) +{ + Name(PPUU,0) // units + If (LEqual(CSEM, 1)) + { + Return() // we have already been called, must have CS exit before calling again + } + Store(1, CSEM) // record first call + + Store (PPL1, PLSV) // save PL1 value upon entering CS + Store (PL1E, PLEN) // save PL1 Enable bit upon entering CS + Store (CLP1, CLMP) // save PL1 Clamp bit upon entering CS + + If (LEqual(PWRU,0)) { // use PACKAGE_POWER_SKU_UNIT - Power Units[3:0] + Store(1,PPUU) + } Else { + ShiftLeft(Decrement(PWRU),2,PPUU) // get units + } + + Multiply(PLVL,PPUU,Local0) // convert SETUP value to power units in milli-watts + Divide(Local0,1000,,Local1) // convert SETUP value to power units in watts + Store(Local1, PPL1) // copy value to PL1 + Store(1, PL1E) // set Enable bit + Store(1, CLP1) // set Clamp bit +} +// +// RPL1 (Restore the PL1 register to the values prior to CS entry) +// +// Arguments: +// None +// +// Return Value: +// None +Method(RPL1,0,Serialized) +{ + Store (PLSV, PPL1) // restore value of PL1 upon exiting CS + Store(PLEN, PL1E) // restore the PL1 enable bit + Store(CLMP, CLP1) // restore the PL1 Clamp bit + Store(0, CSEM) // restore semaphore +} + +Name(UAMS, 0) // User Absent Mode state, Zero - User Present; non-Zero - User not present +Name(GLCK, 0) // a spin lock to avoid multi execution of GUAM +// GUAM - Global User Absent Mode +// Run when a change to User Absent mode is made, e.g. screen/display on/off events. +// Any device that needs notifications of these events includes its own UAMN Control Method. +// +// Arguments: +// Power State: +// 00h = On +// 01h = Standby +// other value = do nothing & return +// +// Return Value: +// None +// +Method(GUAM,1,Serialized) +{ + Switch(ToInteger(Arg0)) + { + Case(0) // exit CS + { + If(LEqual(GLCK, 1)){ + store(0, GLCK) + + P8XH(0, 0xE1) + P8XH(1, 0xAB) + ADBG("Exit Resiliency") + + // @Todo: Exit EC Low Power Mode here + + + If(PSCP){ + // if P-state Capping s enabled + If (CondRefOf(\_PR.PR00._PPC)) + { + Store(Zero, \_PR.CPPC) + PNOT() + } + } + If(PLCS){ + RPL1() // restore PL1 to pre-CS value upon exiting CS + } + } // end GLCK=1 + } // end case(0) + + Case(1) // enter CS + { + If(LEqual(GLCK, 0)){ + store(1, GLCK) + + P8XH(0, 0xE0) + P8XH(1, 00) + ADBG("Enter Resiliency") + + //@Todo: Enter EC Low Power Mode here + + + If(PSCP){ + // if P-state Capping is enabled + If (LAnd(CondRefOf(\_PR.PR00._PSS), CondRefOf(\_PR.PR00._PPC))) + { + If(And(\PC00,0x0400)) + { + Subtract(SizeOf(\_PR.PR00.TPSS), One, \_PR.CPPC) + } Else { + Subtract(SizeOf(\_PR.PR00.LPSS), One, \_PR.CPPC) + } + PNOT() + } + } + If(PLCS){ + SPL1() // set PL1 to low value upon CS entry + } + } // end GLCK=0 + } // end case(1) + Default{ + Return() // do nothing + } + } // end switch(arg0) + + Store(LAnd(Arg0, LNot(PWRS)), UAMS) // UAMS: User Absent Mode state, Zero - User Present; non-Zero - User not present + P_CS() // Powergating during CS + +} // end method GUAM() + +// Power CS Powergated Devices: +// Method to enable/disable power during CS +Method(P_CS,0,Serialized) +{ + // NOTE: Do not turn ON Touch devices from here. Touch does not have PUAM + If(CondRefOf(\_SB.PCI0.PAUD.PUAM)){ // Notify Codec(HD-A/ADSP) + \_SB.PCI0.PAUD.PUAM() + } + // Adding back USB powergating (ONLY for Win8) until RTD3 walkup port setup implementation is complete */ + If(LEqual(OSYS,2012)){ // ONLY for Win8 OS + If(CondRefOf(\_SB.PCI0.XHC.DUAM)){ // Notify USB port- RVP + \_SB.PCI0.XHC.DUAM() + } + } + // TODO: Add calls to UAMN methods for + // * USB controller(s) + // * Embedded Controller + // * Sensor devices + // * Audio DSP? + // * Any other devices dependent on User Absent mode for power controls +} + +// SMI I/O Trap: +// Generate a Mutex protected SMI I/O Trap. +// +// Arguments: +// Arg0: I/O Trap type. +// 2 - For DTS +// 3 - For IGD +// 4 - For BIOS Guard Tools +// Arg1: SMI I/O Trap Function to call. +// +// Return Value: +// SMI I/O Trap Return value. +// 0 = Success. Non-zero = Failure. + +Scope(\) +{ + // + // The IO address in this ACPI Operating Region will be updated during POST. + // This address range is used as a HotKey I/O Trap SMI so that ASL and SMI can + // communicate when needed. + // + OperationRegion(IO_H,SystemIO,0x1000,0x4) + Field(IO_H,ByteAcc,NoLock,Preserve) { + TRPH, 8 + } +} + +Method(TRAP,2,Serialized) +{ + Store(Arg1,SMIF) // Store SMI Function. + + If(LEqual(Arg0,TRAP_TYPE_DTS)) // Is DTS IO Trap? + { + Store(Arg1,\_PR.DTSF) // Store the function number global NVS + Store(0,\_PR.TRPD) // Generate IO Trap. + Return(\_PR.DTSF) // Return status from SMI handler + } + + If(LEqual(Arg0,TRAP_TYPE_IGD)) // Is IGD IO Trap? + { + Store(0,TRPH) // Generate IO Trap. + } + + If(LEqual(Arg0,TRAP_TYPE_BGD)) // Is BIOS Guard TOOLS IO Trap? + { + Store(0,\_PR.TRPF) // Generate IO Trap + } + + Return(SMIF) // Return SMIF. 0 = Success. +} + +// Note: Only add the indicator device needed by the platform. + +// +// System Bus +// +Scope(\_SB.PCI0) +{ + + Method(_INI,0, Serialized) + { + + // Determine the OS and store the value, where: + // + // OSYS = 1000 = Linux. + // OSYS = 2000 = WIN2000. + // OSYS = 2001 = WINXP, RTM or SP1. + // OSYS = 2002 = WINXP SP2. + // OSYS = 2006 = Vista. + // OSYS = 2009 = Windows 7 and Windows Server 2008 R2. + // OSYS = 2012 = Windows 8 and Windows Server 2012. + // OSYS = 2013 = Windows Blue. + // + // Assume Windows 2000 at a minimum. + + Store(2000,OSYS) + + // Check for a specific OS which supports _OSI. + + If(CondRefOf(\_OSI)) + { + If(\_OSI("Linux")) + { + Store(1000,OSYS) + } + + If(\_OSI("Windows 2001")) // Windows XP + { + Store(2001,OSYS) + } + + If(\_OSI("Windows 2001 SP1")) //Windows XP SP1 + { + Store(2001,OSYS) + } + + If(\_OSI("Windows 2001 SP2")) //Windows XP SP2 + { + Store(2002,OSYS) + } + + If (\_OSI( "Windows 2001.1")) //Windows Server 2003 + { + Store(2003,OSYS) + } + + If(\_OSI("Windows 2006")) //Windows Vista + { + Store(2006,OSYS) + } + + If(\_OSI("Windows 2009")) //Windows 7 and Windows Server 2008 R2 + { + Store(2009,OSYS) + } + + If(\_OSI("Windows 2012")) //Windows 8 and Windows Server 2012 + { + Store(2012,OSYS) + } + + If(\_OSI("Windows 2013")) //Windows 8.1 and Windows Server 2012 R2 + { + Store(2013,OSYS) + } + + If(\_OSI("Windows 2015")) //Windows 10 + { + Store(2015,OSYS) + } + } + + // + // Set DTS NVS data means in OS ACPI mode enabled insteads of GlobalNvs OperatingSystem (OSYS) + // + If(CondRefOf(\_PR.DTSE)){ + If(LGreaterEqual(\_PR.DTSE, 0x01)){ + Store(0x01, \_PR.DSAE) + } + } + + } + + Method(NHPG,0,Serialized) + { + Store(0,^RP01.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP02.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP03.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP04.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP05.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP06.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP07.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP08.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP09.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP10.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP11.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP12.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP13.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP14.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP15.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP16.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP17.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP18.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP19.HPEX) // clear the hot plug SCI enable bit + Store(0,^RP20.HPEX) // clear the hot plug SCI enable bit + + Store(1,^RP01.HPSX) // clear the hot plug SCI status bit + Store(1,^RP02.HPSX) // clear the hot plug SCI status bit + Store(1,^RP03.HPSX) // clear the hot plug SCI status bit + Store(1,^RP04.HPSX) // clear the hot plug SCI status bit + Store(1,^RP05.HPSX) // clear the hot plug SCI status bit + Store(1,^RP06.HPSX) // clear the hot plug SCI status bit + Store(1,^RP07.HPSX) // clear the hot plug SCI status bit + Store(1,^RP08.HPSX) // clear the hot plug SCI status bit + Store(1,^RP09.HPSX) // clear the hot plug SCI status bit + Store(1,^RP10.HPSX) // clear the hot plug SCI status bit + Store(1,^RP11.HPSX) // clear the hot plug SCI status bit + Store(1,^RP12.HPSX) // clear the hot plug SCI status bit + Store(1,^RP13.HPSX) // clear the hot plug SCI status bit + Store(1,^RP14.HPSX) // clear the hot plug SCI status bit + Store(1,^RP15.HPSX) // clear the hot plug SCI status bit + Store(1,^RP16.HPSX) // clear the hot plug SCI status bit + Store(1,^RP17.HPSX) // clear the hot plug SCI status bit + Store(1,^RP18.HPSX) // clear the hot plug SCI status bit + Store(1,^RP19.HPSX) // clear the hot plug SCI status bit + Store(1,^RP20.HPSX) // clear the hot plug SCI status bit + } + + Method(NPME,0,Serialized) + { + Store(0,^RP01.PMEX) // clear the PME SCI enable bit + Store(0,^RP02.PMEX) // clear the PME SCI enable bit + Store(0,^RP03.PMEX) // clear the PME SCI enable bit + Store(0,^RP04.PMEX) // clear the PME SCI enable bit + Store(0,^RP05.PMEX) // clear the PME SCI enable bit + Store(0,^RP06.PMEX) // clear the PME SCI enable bit + Store(0,^RP07.PMEX) // clear the PME SCI enable bit + Store(0,^RP08.PMEX) // clear the PME SCI enable bit + Store(0,^RP09.PMEX) // clear the PME SCI enable bit + Store(0,^RP10.PMEX) // clear the PME SCI enable bit + Store(0,^RP11.PMEX) // clear the PME SCI enable bit + Store(0,^RP12.PMEX) // clear the PME SCI enable bit + Store(0,^RP13.PMEX) // clear the PME SCI enable bit + Store(0,^RP14.PMEX) // clear the PME SCI enable bit + Store(0,^RP15.PMEX) // clear the PME SCI enable bit + Store(0,^RP16.PMEX) // clear the PME SCI enable bit + Store(0,^RP17.PMEX) // clear the PME SCI enable bit + Store(0,^RP18.PMEX) // clear the PME SCI enable bit + Store(0,^RP19.PMEX) // clear the PME SCI enable bit + Store(0,^RP20.PMEX) // clear the PME SCI enable bit + + Store(1,^RP01.PMSX) // clear the PME SCI status bit + Store(1,^RP02.PMSX) // clear the PME SCI status bit + Store(1,^RP03.PMSX) // clear the PME SCI status bit + Store(1,^RP04.PMSX) // clear the PME SCI status bit + Store(1,^RP05.PMSX) // clear the PME SCI status bit + Store(1,^RP06.PMSX) // clear the PME SCI enable bit + Store(1,^RP07.PMSX) // clear the PME SCI status bit + Store(1,^RP08.PMSX) // clear the PME SCI status bit + Store(1,^RP09.PMSX) // clear the PME SCI status bit + Store(1,^RP10.PMSX) // clear the PME SCI status bit + Store(1,^RP11.PMSX) // clear the PME SCI status bit + Store(1,^RP12.PMSX) // clear the PME SCI status bit + Store(1,^RP13.PMSX) // clear the PME SCI status bit + Store(1,^RP14.PMSX) // clear the PME SCI status bit + Store(1,^RP15.PMSX) // clear the PME SCI status bit + Store(1,^RP16.PMSX) // clear the PME SCI status bit + Store(1,^RP17.PMSX) // clear the PME SCI status bit + Store(1,^RP18.PMSX) // clear the PME SCI status bit + Store(1,^RP19.PMSX) // clear the PME SCI status bit + Store(1,^RP20.PMSX) // clear the PME SCI status bit + } +} + +Scope (\) +{ + // + // Global Name, returns current Interrupt controller mode; + // updated from _PIC control method + // + Name(PICM, 0) + + // + // Procedure: GPRW + // + // Description: Generic Wake up Control Method ("Big brother") + // to detect the Max Sleep State available in ASL Name scope + // and Return the Package compatible with _PRW format. + // Input: Arg0 = bit offset within GPE register space device event will be triggered to. + // Arg1 = Max Sleep state, device can resume the System from. + // If Arg1 = 0, Update Arg1 with Max _Sx state enabled in the System. + // Output: _PRW package + // + Name(PRWP, Package(){Zero, Zero}) // _PRW Package + + Method(GPRW, 2) + { + Store(Arg0, Index(PRWP, 0)) // copy GPE# + // + // SS1-SS4 - enabled in BIOS Setup Sleep states + // + Store(ShiftLeft(SS1,1),Local0) // S1 ? + Or(Local0,ShiftLeft(SS2,2),Local0) // S2 ? + Or(Local0,ShiftLeft(SS3,3),Local0) // S3 ? + Or(Local0,ShiftLeft(SS4,4),Local0) // S4 ? + // + // Local0 has a bit mask of enabled Sx(1 based) + // bit mask of enabled in BIOS Setup Sleep states(1 based) + // + If(And(ShiftLeft(1, Arg1), Local0)) + { + // + // Requested wake up value (Arg1) is present in Sx list of available Sleep states + // + Store(Arg1, Index(PRWP, 1)) // copy Sx# + } + Else + { + // + // Not available -> match Wake up value to the higher Sx state + // + ShiftRight(Local0, 1, Local0) + // If(LOr(LEqual(OSFL, 1), LEqual(OSFL, 2))) { // ??? Win9x + // FindSetLeftBit(Local0, Index(PRWP,1)) // Arg1 == Max Sx + // } Else { // ??? Win2k / XP + FindSetLeftBit(Local0, Index(PRWP,1)) // Arg1 == Min Sx + // } + } + + Return(PRWP) + } +} + + +Scope (\_SB) +{ + Name(OSCI, 0) // \_SB._OSC DWORD2 input + Name(OSCO, 0) // \_SB._OSC DWORD2 output + Name(OSCP, 0) // \_SB._OSC CAPABILITIES + // _OSC (Operating System Capabilities) + // _OSC under \_SB scope is used to convey platform wide OSPM capabilities. + // For a complete description of _OSC ACPI Control Method, refer to ACPI 5.0 + // specification, section 6.2.10. + // Arguments: (4) + // Arg0 - A Buffer containing the UUID "0811B06E-4A27-44F9-8D60-3CBBC22E7B48" + // Arg1 - An Integer containing the Revision ID of the buffer format + // Arg2 - An Integer containing a count of entries in Arg3 + // Arg3 - A Buffer containing a list of DWORD capabilities + // Return Value: + // A Buffer containing the list of capabilities + // + Method(_OSC,4,Serialized) + { + // + // Point to Status DWORD in the Arg3 buffer (STATUS) + // + CreateDWordField(Arg3, 0, STS0) + // + // Point to Caps DWORDs of the Arg3 buffer (CAPABILITIES) + // + CreateDwordField(Arg3, 4, CAP0) + + + // + // Only set 8254 CG if Low Power S0 Idle Capability is enabled + // + If (LEqual(S0ID, One)) { + // + // Set ITSSPRC.8254CGE: Offset 3300h ITSSPRC[2] + // + Store(0x01, \_SB.SCGE) + } + + // + // Check UUID + // + If(LEqual(Arg0,ToUUID("0811B06E-4A27-44F9-8D60-3CBBC22E7B48"))) + { + // + // Check Revision + // + If(LEqual(Arg1,One)) + { + Store(CAP0, OSCP) + If(And(CAP0,0x04)) // Check _PR3 Support(BIT2) + { + Store(0x04, OSCO) + If(LNotEqual(And(SGMD,0x0F),2)) // Check Switchable/Hybrid graphics is not enabled in bios setup [SgModeMuxless]? + { + If(LEqual(RTD3,0)) // Is RTD3 support disabled in Bios Setup? + { + // RTD3 is disabled via BIOS Setup. + And(CAP0, 0x3B, CAP0) // Clear _PR3 capability + Or(STS0, 0x10, STS0) // Indicate capability bit is cleared + } + } + } + } Else{ + And(STS0,0xFFFFFF00,STS0) + Or(STS0,0xA, STS0) // Unrecognised Revision and report OSC failure + } + } Else { + And(STS0,0xFFFFFF00,STS0) + Or (STS0,0x6, STS0) // Unrecognised UUID and report OSC failure + } + + Return(Arg3) + } // End _OSC + +} // End of Scope(\_SB) + +// +// CS Wake up event support +// +Scope (\_SB) +{ + // Define Sleep button to put the system in sleep + Device (SLPB) + { + Name (_HID, EISAID ("PNP0C0E")) + Name (_STA, 0x0B) + // Bit0 - the device is present: Yes. + // Bit1 - the device is enabled and decoding its resources: Yes. + // Bit2 - the device should be shown in the UI: No. + // Bit3 - the device is functioning properly: Yes. + // Bit4 - the battery is present: N/A + } +} // End of Scope(\_SB) diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PlatformGnvs.asl b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PlatformGnvs.asl new file mode 100644 index 0000000000..97e54bdccf --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PlatformGnvs.asl @@ -0,0 +1,14 @@ +/** @file + ACPI DSDT table + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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. + +**/ + diff --git a/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Video.asl b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Video.asl new file mode 100644 index 0000000000..002a377d83 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Video.asl @@ -0,0 +1,33 @@ +/** @file + ACPI DSDT table + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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. + +**/ + +External(DIDX) + +// Brightness Notification: +// Generate a brightness related notification +// to the LFP if its populated. +// +// Arguments: +// Arg0: Notification value. +// +// Return Value: +// None + +Method(BRTN,1,Serialized) +{ + If(LEqual(And(DIDX,0x0F00),0x400)) + { + Notify(\_SB.PCI0.GFX0.DD1F,Arg0) + } +} diff --git a/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3SptPcieTbt.asl b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3SptPcieTbt.asl new file mode 100644 index 0000000000..35544fb0a2 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3SptPcieTbt.asl @@ -0,0 +1,409 @@ +/** @file + ACPI RTD3 SSDT table for SPT PCIe + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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/ClevoOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl new file mode 100644 index 0000000000..c8226a5549 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl @@ -0,0 +1,1908 @@ +/** @file + Thunderbolt ACPI methods + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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/ClevoOpenBoardPkg/Features/Tbt/Include/Acpi/TbtNvs.asl b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Include/Acpi/TbtNvs.asl new file mode 100644 index 0000000000..7ec419d42a --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Include/Acpi/TbtNvs.asl @@ -0,0 +1,62 @@ +/**@file + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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/ClevoOpenBoardPkg/Include/Acpi/GlobalNvs.asl b/Platform/Intel/ClevoOpenBoardPkg/Include/Acpi/GlobalNvs.asl new file mode 100644 index 0000000000..651708ea70 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Include/Acpi/GlobalNvs.asl @@ -0,0 +1,120 @@ +/** @file + ACPI DSDT table + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+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 a Global region of ACPI NVS Region that may be used for any + // type of implementation. The starting offset and size will be fixed + // up by the System BIOS during POST. Note that the Size must be a word + // in size to be fixed up correctly. + + + + + OperationRegion(GNVS,SystemMemory,0xFFFF0000,0xAA55) + Field(GNVS,AnyAcc,Lock,Preserve) + { + // + // Miscellaneous Dynamic Registers: + // + Offset(0), OSYS, 16, // Offset(0), Operating System + Offset(2), SMIF, 8, // Offset(2), SMI Function Call (ASL to SMI via I/O Trap) + Offset(3), P80D, 32, // Offset(3), Port 80 Debug Port Value + Offset(7), PWRS, 8, // Offset(7), Power State (AC Mode = 1) + // + // Thermal Policy Registers: + // + Offset(8), DTSE, 8, // Offset(8), Digital Thermal Sensor Enable + Offset(9), DTSF, 8, // Offset(9), DTS SMI Function Call + // + // CPU Identification Registers: + // + Offset(10), APIC, 8, // Offset(10), APIC Enabled by SBIOS (APIC Enabled = 1) + Offset(11), TCNT, 8, // Offset(11), Number of Enabled Threads + // + // PCIe Hot Plug + // + Offset(12), OSCC, 8, // Offset(12), PCIE OSC Control + Offset(13), NEXP, 8, // Offset(13), Native PCIE Setup Value + // + // Global Variables + // + Offset(14), DSEN, 8, // Offset(14), _DOS Display Support Flag. + Offset(15), GPIC, 8, // Offset(15), Global IOAPIC/8259 Interrupt Mode Flag. + Offset(16), L01C, 8, // Offset(16), Global L01 Counter. + Offset(17), LTR1, 8, // Offset(17), Latency Tolerance Reporting Enable + Offset(18), LTR2, 8, // Offset(18), Latency Tolerance Reporting Enable + Offset(19), LTR3, 8, // Offset(19), Latency Tolerance Reporting Enable + Offset(20), LTR4, 8, // Offset(20), Latency Tolerance Reporting Enable + Offset(21), LTR5, 8, // Offset(21), Latency Tolerance Reporting Enable + Offset(22), LTR6, 8, // Offset(22), Latency Tolerance Reporting Enable + Offset(23), LTR7, 8, // Offset(23), Latency Tolerance Reporting Enable + Offset(24), LTR8, 8, // Offset(24), Latency Tolerance Reporting Enable + Offset(25), LTR9, 8, // Offset(25), Latency Tolerance Reporting Enable + Offset(26), LTRA, 8, // Offset(26), Latency Tolerance Reporting Enable + Offset(27), LTRB, 8, // Offset(27), Latency Tolerance Reporting Enable + Offset(28), LTRC, 8, // Offset(28), Latency Tolerance Reporting Enable + Offset(29), LTRD, 8, // Offset(29), Latency Tolerance Reporting Enable + Offset(30), LTRE, 8, // Offset(30), Latency Tolerance Reporting Enable + Offset(31), LTRF, 8, // Offset(31), Latency Tolerance Reporting Enable + Offset(32), LTRG, 8, // Offset(32), Latency Tolerance Reporting Enable + Offset(33), LTRH, 8, // Offset(33), Latency Tolerance Reporting Enable + Offset(34), LTRI, 8, // Offset(34), Latency Tolerance Reporting Enable + Offset(35), LTRJ, 8, // Offset(35), Latency Tolerance Reporting Enable + Offset(36), LTRK, 8, // Offset(36), Latency Tolerance Reporting Enable + Offset(37), LTRL, 8, // Offset(37), Latency Tolerance Reporting Enable + Offset(38), LTRM, 8, // Offset(38), Latency Tolerance Reporting Enable + Offset(39), LTRN, 8, // Offset(39), Latency Tolerance Reporting Enable + Offset(40), LTRO, 8, // Offset(40), Latency Tolerance Reporting Enable + Offset(41), OBF1, 8, // Offset(41), Optimized Buffer Flush and Fill + Offset(42), OBF2, 8, // Offset(42), Optimized Buffer Flush and Fill + Offset(43), OBF3, 8, // Offset(43), Optimized Buffer Flush and Fill + Offset(44), OBF4, 8, // Offset(44), Optimized Buffer Flush and Fill + Offset(45), OBF5, 8, // Offset(45), Optimized Buffer Flush and Fill + Offset(46), OBF6, 8, // Offset(46), Optimized Buffer Flush and Fill + Offset(47), OBF7, 8, // Offset(47), Optimized Buffer Flush and Fill + Offset(48), OBF8, 8, // Offset(48), Optimized Buffer Flush and Fill + Offset(49), OBF9, 8, // Offset(49), Optimized Buffer Flush and Fill + Offset(50), OBFA, 8, // Offset(50), Optimized Buffer Flush and Fill + Offset(51), OBFB, 8, // Offset(51), Optimized Buffer Flush and Fill + Offset(52), OBFC, 8, // Offset(52), Optimized Buffer Flush and Fill + Offset(53), OBFD, 8, // Offset(53), Optimized Buffer Flush and Fill + Offset(54), OBFE, 8, // Offset(54), Optimized Buffer Flush and Fill + Offset(55), OBFF, 8, // Offset(55), Optimized Buffer Flush and Fill + Offset(56), OBFG, 8, // Offset(56), Optimized Buffer Flush and Fill + Offset(57), OBFH, 8, // Offset(57), Optimized Buffer Flush and Fill + Offset(58), OBFI, 8, // Offset(58), Optimized Buffer Flush and Fill + Offset(59), OBFJ, 8, // Offset(59), Optimized Buffer Flush and Fill + Offset(60), OBFK, 8, // Offset(60), Optimized Buffer Flush and Fill + Offset(61), OBFL, 8, // Offset(61), Optimized Buffer Flush and Fill + Offset(62), OBFM, 8, // Offset(62), Optimized Buffer Flush and Fill + Offset(63), OBFN, 8, // Offset(63), Optimized Buffer Flush and Fill + Offset(64), OBFO, 8, // Offset(64), Optimized Buffer Flush and Fill + Offset(65), RTD3, 8, // Offset(65), Runtime D3 support. + Offset(66), S0ID, 8, // Offset(66), Low Power S0 Idle Enable + Offset(67), GBSX, 8, // Offset(67), Virtual GPIO button Notify Sleep State Change + Offset(68), PSCP, 8, // Offset(68), P-state Capping + Offset(69), P2ME, 8, // Offset(69), Ps2 Mouse Enable + Offset(70), P2MK, 8, // Offset(70), Ps2 Keyboard and Mouse Enable + // + // Driver Mode + // + Offset(71), GIRQ, 32, // Offset(71), GPIO IRQ + Offset(75), PLCS, 8, // Offset(75), set PL1 limit when entering CS + Offset(76), PLVL, 16, // Offset(76), PL1 limit value + Offset(78), PB1E, 8, // Offset(78), 10sec Power button support + Offset(79), ECR1, 8, // Offset(79), Pci Delay Optimization Ecr + Offset(80), TBTS, 8, // Offset(80), Thunderbolt(TM) support + Offset(81), TNAT, 8, // Offset(81), TbtNativeOsHotPlug + Offset(82), TBSE, 8, // Offset(82), Thunderbolt(TM) Root port selector + Offset(83), TBS1, 8, // Offset(83), Thunderbolt(TM) Root port selector + } -- 2.16.2.windows.1