From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.151, mailfrom: rangasai.v.chaganty@intel.com) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by groups.io with SMTP; Sat, 17 Aug 2019 00:50:12 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Aug 2019 00:50:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,396,1559545200"; d="scan'208";a="185114216" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by FMSMGA003.fm.intel.com with ESMTP; 17 Aug 2019 00:50:11 -0700 Received: from fmsmsx113.amr.corp.intel.com (10.18.116.7) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.439.0; Sat, 17 Aug 2019 00:50:11 -0700 Received: from fmsmsx104.amr.corp.intel.com ([169.254.3.2]) by FMSMSX113.amr.corp.intel.com ([169.254.13.127]) with mapi id 14.03.0439.000; Sat, 17 Aug 2019 00:50:10 -0700 From: "Chaganty, Rangasai V" To: "Kubacki, Michael A" , "devel@edk2.groups.io" CC: "Chiu, Chasel" , "Gao, Liming" , "Desimone, Nathaniel L" , "Kinney, Michael D" , "Sinha, Ankit" Subject: Re: [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Thread-Topic: [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Thread-Index: AQHVVJEdqTZq/H0oQUCY4Qlei25siKb+92xQ Date: Sat, 17 Aug 2019 07:50:10 +0000 Message-ID: References: <20190817001603.30632-1-michael.a.kubacki@intel.com> <20190817001603.30632-36-michael.a.kubacki@intel.com> In-Reply-To: <20190817001603.30632-36-michael.a.kubacki@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiNzdiMDcxNWUtYzhkNC00OWM5LWEwYWYtODg2NDkyNmM2YzVjIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiV2FnK1lKaDBNNnNHa21zTnp5T1EzOHRaV0d3VlZrR3Q3WWdwOTU2S09xM1hwZWdVT0dKdjNjWWUzQUlobWNSQSJ9 x-ctpclassification: CTP_NT x-originating-ip: [10.1.200.108] MIME-Version: 1.0 Return-Path: rangasai.v.chaganty@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Sai Chaganty -----Original Message----- From: Kubacki, Michael A=20 Sent: Friday, August 16, 2019 5:16 PM To: devel@edk2.groups.io Cc: Chaganty, Rangasai V ; Chiu, Chasel ; Gao, Liming ; Desimone, Nathanie= l L ; Kinney, Michael D ; Sinha, Ankit Subject: [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modu= les REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D2083 Modules shared across board instances. * BoardAcpiDxe - Performs DXE board ACPI initialization. * PciHotPlug - Performs PCI-e resource configuration. * PeiTbtInit - Initializes Thunderbolt policy in PEI. * PolicyInitDxe - Initializes policy in DXE. * TbtDxe - Performs Thunderbolt initialization in DXE. * TbtSmm - Performs Thunderbolt initialization in SMM. Cc: Sai Chaganty Cc: Chasel Chiu Cc: Liming Gao Cc: Nate DeSimone Cc: Michael D Kinney Cc: Ankit Sinha Signed-off-by: Michael Kubacki --- Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.inf = | 71 + Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.inf = | 62 + Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.inf= | 51 + Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit= .inf | 47 + Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.inf= | 80 + Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.= inf | 176 ++ Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.h = | 130 ++ Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHand= ler.h | 180 ++ Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.h= | 32 + Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitD= xe.h | 38 + Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitD= xe.h | 41 + Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitD= xe.h | 52 + Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.= h | 45 + Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDx= e.h | 56 + Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyI= nitDxe.h | 37 + Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit.c = | 96 + Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe.c = | 290 +++ Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug.c = | 353 ++++ Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDxe.c = | 228 +++ Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTbtInit= .c | 211 +++ Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmiHand= ler.c | 1609 +++++++++++++++++ Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSmm.c = | 1765 ++++++++++++++++++ Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimerLib.c= | 394 ++++ Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInitLib.c= | 612 +++++++ Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicyInitD= xe.c | 46 + Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicyInitD= xe.c | 174 ++ Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicyInitD= xe.c | 55 + Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyInitDxe.= c | 88 + Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyInitDx= e.c | 60 + Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPolicyI= nitDxe.c | 46 + Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.asl = | 20 + Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.ASL = | 37 + Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus.asl = | 516 ++++++ Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree.asl = | 309 ++++ Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platform.asl= | 76 + Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3PcieTbt= .asl | 405 +++++ Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.asl = | 1877 ++++++++++++++++++++ 37 files changed, 10365 insertions(+) diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Board= AcpiDxe.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Boar= dAcpiDxe.inf new file mode 100644 index 0000000000..2bbc3cb9e2 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe= .inf @@ -0,0 +1,71 @@ +## @file +# Component information file for AcpiPlatform module +# +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D BoardAcpiDxe + FILE_GUID =3D E269E77D-6163-4F5D-8E59-21EAF114D307 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D InstallAcpiBoard + +[Sources.common] + BoardAcpiDxe.c + AcpiGnvsInit.c + Dsdt/DSDT.ASL + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + MinPlatformPkg/MinPlatformPkg.dec + PcAtChipsetPkg/PcAtChipsetPkg.dec + WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec + CoffeelakeSiliconPkg/SiPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + DebugLib + IoLib + PcdLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + BaseMemoryLib + HobLib + AslUpdateLib + BoardAcpiTableLib + +[Protocols] + gEfiAcpiTableProtocolGuid ## CONSUMES + gEfiFirmwareVolume2ProtocolGuid ## CONSUMES + gEfiMpServiceProtocolGuid ## CONSUMES + gEfiGlobalNvsAreaProtocolGuid + +[Pcd] + gBoardModuleTokenSpaceGuid.PcdAcpiGnvsAddress + + gBoardModuleTokenSpaceGuid.PcdAcpiSleepState + gBoardModuleTokenSpaceGuid.PcdAcpiHibernate + gBoardModuleTokenSpaceGuid.PcdLowPowerS0Idle + gBoardModuleTokenSpaceGuid.PcdDisableActiveTripPoints + gBoardModuleTokenSpaceGuid.PcdDisablePassiveTripPoints + gBoardModuleTokenSpaceGuid.PcdDisableCriticalTripPoints + +[Depex] + gEfiAcpiTableProtocolGuid AND + gEfiFirmwareVolume2ProtocolGuid AND + gEfiPciRootBridgeIoProtocolGuid AND + gEfiVariableArchProtocolGuid AND + gEfiVariableWriteArchProtocolGuid + + + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/Pci= HotPlug.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/Pc= iHotPlug.inf new file mode 100644 index 0000000000..dd4e41a409 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug= .inf @@ -0,0 +1,62 @@ +## @file +# This module will perform specific PCI-Express devices +# resource configuration. +# +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D PciHotPlug + FILE_GUID =3D 3022E512-B94A-4F12-806D-7EF1177899D8 + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_DRIVER + ENTRY_POINT =3D PciHotPlug +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + BaseMemoryLib + MemoryAllocationLib + DevicePathLib + DebugLib + UefiLib + HobLib + PchPcieRpLib + ConfigBlockLib + TbtCommonLib + +[Packages] + MdePkg/MdePkg.dec + MinPlatformPkg/MinPlatformPkg.dec + WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec + CoffeelakeSiliconPkg/SiPkg.dec + +[Sources] + PciHotPlug.c + PciHotPlug.h + +[Protocols] + gEfiPciHotPlugInitProtocolGuid ## PRODUCES + gSaPolicyProtocolGuid ## CONSUMES + +[Guids] + gEfiHobListGuid ## CONSUMES + gPcieRpConfigGuid ## CONSUMES + +[Pcd] + +[Depex] + gDxeTbtPolicyProtocolGuid + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dx= e/TbtDxe.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/= Dxe/TbtDxe.inf new file mode 100644 index 0000000000..5160bb1dbb --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDx= e.inf @@ -0,0 +1,51 @@ +## @file +# +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D TbtDxe + FILE_GUID =3D 19C9762C-3A88-41B0-906F-8C4C2895A887 + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_DRIVER + ENTRY_POINT =3D TbtDxeEntryPoint + +[LibraryClasses] + DebugLib + BaseMemoryLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + UefiDriverEntryPoint + HobLib + UefiLib + TbtCommonLib + DxeTbtPolicyLib + AslUpdateLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + MinPlatformPkg/MinPlatformPkg.dec + WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec + CoffeelakeSiliconPkg/SiPkg.dec + +[Sources] + TbtDxe.c + +[Protocols] + gTbtNvsAreaProtocolGuid ## CONSUMES + gDxeTbtPolicyProtocolGuid + +[Guids] + gTbtInfoHobGuid ## CONSUMES + +[Depex] + gEfiVariableWriteArchProtocolGuid AND + gEfiVariableArchProtocolGuid + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pe= i/PeiTbtInit.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtI= nit/Pei/PeiTbtInit.inf new file mode 100644 index 0000000000..07962ffa10 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb= tInit.inf @@ -0,0 +1,47 @@ +## @file +# Component information file for the TBT Init PEI module. +# +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D PeiTbtInit + FILE_GUID =3D 90BF2BFB-F998-4cbc-AD72-008D4D047A4B + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D PEIM + ENTRY_POINT =3D TbtInitEntryPoint + +[LibraryClasses] + PeimEntryPoint + DebugLib + HobLib + PeiServicesLib + PeiTbtPolicyLib + PeiDTbtInitLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + MinPlatformPkg/MinPlatformPkg.dec + WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec + CoffeelakeSiliconPkg/SiPkg.dec + +[Sources] + PeiTbtInit.c + +[Guids] + gTbtInfoHobGuid ## CONSUMES + +[Ppis] + gEfiEndOfPeiSignalPpiGuid ## CONSUMES + gPeiTbtPolicyBoardInitDonePpiGuid ## CONSUMES + +[Depex] + gEfiPeiMemoryDiscoveredPpiGuid + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Sm= m/TbtSmm.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/= Smm/TbtSmm.inf new file mode 100644 index 0000000000..3d4e6ceea0 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSm= m.inf @@ -0,0 +1,80 @@ +## @file +# Component information file for the ThunderBolt Smm module. +# +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D TbtSmm + FILE_GUID =3D 5BDCD685-D80A-42E6-9867-A84CCE7F828E + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_SMM_DRIVER + PI_SPECIFICATION_VERSION =3D 1.10 + ENTRY_POINT =3D TbtSmmEntryPoint + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + BaseMemoryLib + DebugLib + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + IoLib + PciExpressLib + HobLib + ReportStatusCodeLib + PciSegmentLib + UefiLib + SmmServicesTableLib + GpioLib + PchInfoLib + TbtCommonLib + PchPmcLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + MinPlatformPkg/MinPlatformPkg.dec + WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec + CoffeelakeSiliconPkg/SiPkg.dec + +[Pcd] +# gBoardModuleTokenSpaceGuid.PcdSwSmiDTbtEnumerate ## CONSUMES + gMinPlatformPkgTokenSpaceGuid.PcdPciExpressRegionLength ## CONSUMES + +[FixedPcd] + gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress ## CONSUMES + +[Sources] + TbtSmiHandler.h + TbtSmiHandler.c + TbtSmm.c + +[Protocols] + gTbtNvsAreaProtocolGuid ## CONSUMES + gEfiSmmSxDispatch2ProtocolGuid ## CONSUMES + gEfiSmmSwDispatch2ProtocolGuid ## CONSUMES + gEfiSmmVariableProtocolGuid ## CONSUMES + gDxeTbtPolicyProtocolGuid + +[Guids] + gTbtInfoHobGuid ## CONSUMES + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## CONSUMES + +[Depex] + gEfiSmmBase2ProtocolGuid AND + gEfiSmmSxDispatch2ProtocolGuid AND + gEfiSmmSwDispatch2ProtocolGuid AND + gEfiGlobalNvsAreaProtocolGuid AND + gEfiVariableWriteArchProtocolGuid AND + gEfiVariableArchProtocolGuid AND + gEfiSmmVariableProtocolGuid + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Po= licyInitDxe.inf b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitD= xe/PolicyInitDxe.inf new file mode 100644 index 0000000000..65c531a532 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyIni= tDxe.inf @@ -0,0 +1,176 @@ +## @file +# Module Information file for the PolicyInit DXE driver. +# +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D PolicyInitDxe + FILE_GUID =3D 490D0119-4448-440D-8F5C-F58FB53EE057 + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_DRIVER + ENTRY_POINT =3D PolicyInitDxeEntryPoint + +[LibraryClasses] + BaseLib + BaseMemoryLib + CpuPlatformLib + DebugLib + DxeServicesTableLib + IoLib + MemoryAllocationLib + DxeSaPolicyLib + DxePchPolicyLib + PcdLib + DxePolicyBoardConfigLib + DxePolicyUpdateLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiLib + UefiRuntimeServicesTableLib + ConfigBlockLib + DevicePathLib + DxeTbtPolicyLib + PchPcieRpLib + +[Packages] + MdePkg/MdePkg.dec + CoffeelakeSiliconPkg/SiPkg.dec + WhiskeylakeOpenBoardPkg/OpenBoardPkg.dec + IntelSiliconPkg/IntelSiliconPkg.dec + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ##= CONSUMES + gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase ##= CONSUMES + gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize ##= CONSUMES + gBoardModuleTokenSpaceGuid.PcdIntelGopEnable + gBoardModuleTokenSpaceGuid.PcdPlatformFlavor + gBoardModuleTokenSpaceGuid.PcdPlatformType + gBoardModuleTokenSpaceGuid.PcdEcPresent + gIntelSiliconPkgTokenSpaceGuid.PcdIntelGraphicsVbtFileGuid + gBoardModuleTokenSpaceGuid.PcdTbtEnable + gSiPkgTokenSpaceGuid.PcdCpuSmmMsrSaveStateEnable ##= CONSUMES + gSiPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable ##= CONSUMES + gSiPkgTokenSpaceGuid.PcdCpuSmmUseDelayIndication ##= CONSUMES + gSiPkgTokenSpaceGuid.PcdCpuSmmUseBlockIndication ##= CONSUMES + gSiPkgTokenSpaceGuid.PcdCpuSmmUseSmmEnableIndication ##= CONSUMES + + gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeUpSupport + gBoardModuleTokenSpaceGuid.PcdVirtualButtonVolumeDownSupport + gBoardModuleTokenSpaceGuid.PcdVirtualButtonHomeButtonSupport + gBoardModuleTokenSpaceGuid.PcdVirtualButtonRotationLockSupport + gBoardModuleTokenSpaceGuid.PcdSlateModeSwitchSupport + gBoardModuleTokenSpaceGuid.PcdAcDcAutoSwitchSupport + gBoardModuleTokenSpaceGuid.PcdPmPowerButtonGpioPin + gBoardModuleTokenSpaceGuid.PcdAcpiEnableAllButtonSupport + gBoardModuleTokenSpaceGuid.PcdAcpiHidDriverButtonSupport + gBoardModuleTokenSpaceGuid.PcdTsOnDimmTemperature + gBoardModuleTokenSpaceGuid.PcdBatteryPresent + + gBoardModuleTokenSpaceGuid.PcdUsbTypeCSupport + gBoardModuleTokenSpaceGuid.PcdUsbTypeCEcLess + gBoardModuleTokenSpaceGuid.PcdEcHotKeyF3Support + gBoardModuleTokenSpaceGuid.PcdEcHotKeyF4Support + gBoardModuleTokenSpaceGuid.PcdEcHotKeyF5Support + gBoardModuleTokenSpaceGuid.PcdEcHotKeyF6Support + gBoardModuleTokenSpaceGuid.PcdEcHotKeyF7Support + gBoardModuleTokenSpaceGuid.PcdEcHotKeyF8Support + + # + # PSS Board Configuration. + # + gBoardModuleTokenSpaceGuid.PcdPssReadSN + gBoardModuleTokenSpaceGuid.PcdPssI2cBusNumber + gBoardModuleTokenSpaceGuid.PcdPssI2cSlaveAddress + + gBoardModuleTokenSpaceGuid.PcdXhciAcpiTableSignature + gBoardModuleTokenSpaceGuid.PcdPreferredPmProfile + gBoardModuleTokenSpaceGuid.PcdFingerPrintSleepGpio + gBoardModuleTokenSpaceGuid.PcdFingerPrintIrqGpio + gBoardModuleTokenSpaceGuid.PcdGnssResetGpio + gBoardModuleTokenSpaceGuid.PcdTouchpadIrqGpio + gBoardModuleTokenSpaceGuid.PcdTouchpanelIrqGpio + + gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecIrqGpio + gBoardModuleTokenSpaceGuid.PcdHdaI2sCodecI2cBusNumber + gBoardModuleTokenSpaceGuid.PcdBleUsbPortNumber + gBoardModuleTokenSpaceGuid.PcdEcSmiGpio + gBoardModuleTokenSpaceGuid.PcdEcLowPowerExitGpio + gBoardModuleTokenSpaceGuid.PcdHidI2cIntPad + gBoardModuleTokenSpaceGuid.PcdDetectPs2KbOnCmdAck + gBoardModuleTokenSpaceGuid.PcdSpdAddressOverride + gBoardModuleTokenSpaceGuid.PcdDDISelection + gBoardModuleTokenSpaceGuid.PcdGfxCrbDetectGpio + gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1 + gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort1Pch + gBoardModuleTokenSpaceGuid.PcdUsbCPort1Proterties + gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2 + gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort2Pch + gBoardModuleTokenSpaceGuid.PcdUsbCPort2Proterties + gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3 + gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort3Pch + gBoardModuleTokenSpaceGuid.PcdUsbCPort3Proterties + gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4 + gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort4Pch + gBoardModuleTokenSpaceGuid.PcdUsbCPort4Proterties + gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5 + gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort5Pch + gBoardModuleTokenSpaceGuid.PcdUsbCPort5Proterties + gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6 + gBoardModuleTokenSpaceGuid.PcdUsbTypeCPort6Pch + gBoardModuleTokenSpaceGuid.PcdUsbCPort6Proterties + gBoardModuleTokenSpaceGuid.PcdMipiCam0LinkUsed + gBoardModuleTokenSpaceGuid.PcdMipiCam1LinkUsed + gBoardModuleTokenSpaceGuid.PcdMipiCam2LinkUsed + gBoardModuleTokenSpaceGuid.PcdMipiCam3LinkUsed + gPlatformModuleTokenSpaceGuid.PcdH8S2113Present + gPlatformModuleTokenSpaceGuid.PcdNat87393Present + gPlatformModuleTokenSpaceGuid.PcdNct677FPresent + gBoardModuleTokenSpaceGuid.PcdConvertableDockSupport + gBoardModuleTokenSpaceGuid.PcdSmcRuntimeSciPin + gBoardModuleTokenSpaceGuid.PcdRealBattery1Control + gBoardModuleTokenSpaceGuid.PcdRealBattery2Control + gBoardModuleTokenSpaceGuid.PcdDimmPopulationError + gBoardModuleTokenSpaceGuid.PcdBtIrqGpio + gBoardModuleTokenSpaceGuid.PcdBtRfKillGpio + gBoardModuleTokenSpaceGuid.PcdWhlErbRtd3TableEnable + gBoardModuleTokenSpaceGuid.PcdTypeCPortsSupported + gBoardModuleTokenSpaceGuid.PcdMipiCamSensor + gBoardModuleTokenSpaceGuid.PcdH8S2113SIO + gBoardModuleTokenSpaceGuid.PcdNCT6776FCOM + gBoardModuleTokenSpaceGuid.PcdNCT6776FSIO + gBoardModuleTokenSpaceGuid.PcdNCT6776FHWMON + gBoardModuleTokenSpaceGuid.PcdGpioTier2WakeEnable + gBoardModuleTokenSpaceGuid.PcdFunctionGopVbtSpecificUpdate + +[Sources] + PolicyInitDxe.c + SaPolicyInitDxe.c + SiliconPolicyInitDxe.c + GopPolicyInitDxe.c + PchPolicyInitDxe.c + CpuPolicyInitDxe.c + BoardInitLib.c + +[Protocols] + gEfiFirmwareVolume2ProtocolGuid ## CONSUMES + gDxeMePolicyGuid ## PRODUCES + gSaPolicyProtocolGuid ## CONSUMES + gPchPolicyProtocolGuid ## CONSUMES + gDxeSiPolicyProtocolGuid ## PRODUCES + gGopPolicyProtocolGuid ## PRODUCES + gDxeCpuPolicyProtocolGuid ## PRODUCES + +[Guids] + gCpuSmmGuid ## CONSUMES + gSiMemoryInfoDataGuid + +[Depex] + gEfiVariableArchProtocolGuid + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/Pci= HotPlug.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciH= otPlug.h new file mode 100644 index 0000000000..f57bfb8c26 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug= .h @@ -0,0 +1,130 @@ +/** @file + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PCI_HOT_PLUG_H_ +#define _PCI_HOT_PLUG_H_ + +// +// External include files do NOT need to be explicitly specified in real E= DKII +// environment +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PCI_HOT_PLUG_DRIVER_PRIVATE_SIGNATURE SIGNATURE_32 ('G', 'U', 'L',= 'P') + +#define ACPI \ + { \ + { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH))= , (UINT8) \ + ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (0x0A03), 0 = \ + } + +#define PCI(device, function) \ + { \ + { HARDWARE_DEVICE_PATH, HW_PCI_DP, { (UINT8) (sizeof (PCI_DEVICE_PATH)= ), (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) } }, \ + (UINTN) function, (UINTN) device \ + } + +#define END \ + { \ + END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { END_DEVICE_PAT= H_LENGTH, 0 } \ + } + +#define LPC(eisaid, function) \ + { \ + { ACPI_DEVICE_PATH, ACPI_DP, { (UINT8) (sizeof (ACPI_HID_DEVICE_PATH))= , (UINT8) \ + ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) } }, EISA_PNP_ID (eisaid), fu= nction \ + } + +typedef struct PCIE_HOT_PLUG_DEVICE_PATH { + ACPI_HID_DEVICE_PATH PciRootBridgeNode; + PCI_DEVICE_PATH PciRootPortNode; + EFI_DEVICE_PATH_PROTOCOL EndDeviceNode; +} PCIE_HOT_PLUG_DEVICE_PATH; + +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; // Handle for protocol this driv= er installs on + EFI_PCI_HOT_PLUG_INIT_PROTOCOL HotPlugInitProtocol; +} PCI_HOT_PLUG_INSTANCE; + +/** + This procedure returns a list of Root Hot Plug controllers that require + initialization during boot process + + @param[in] This The pointer to the instance of the EFI_PCI_HOT_PLU= G_INIT protocol. + @param[out] HpcCount The number of Root HPCs returned. + @param[out] HpcList The list of Root HPCs. HpcCount defines the number= of elements in this list. + + @retval EFI_SUCCESS. +**/ +EFI_STATUS +EFIAPI +GetRootHpcList ( + IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, + OUT UINTN *PhpcCount, + OUT EFI_HPC_LOCATION **PhpcList + ); + +/** + This procedure Initializes one Root Hot Plug Controller + This process may casue initialization of its subordinate buses + + @param[in] This The pointer to the instance of the EFI_PCI_H= OT_PLUG_INIT protocol. + @param[in] HpcDevicePath The Device Path to the HPC that is being ini= tialized. + @param[in] HpcPciAddress The address of the Hot Plug Controller funct= ion on the PCI bus. + @param[in] Event The event that should be signaled when the H= ot Plug Controller initialization is complete. Set to NULL if the caller wa= nts 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 hardwar= e. The type EFI_Hpc_STATE is defined in section 3.1. + + @retval EFI_SUCCESS. +**/ +EFI_STATUS +EFIAPI +InitializeRootHpc ( + IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *PhpcDevicePath, + IN UINT64 PhpcPciAddress, + IN EFI_EVENT Event, OPTIONAL + OUT EFI_HPC_STATE *PhpcState + ); + +/** + Returns the resource padding required by the PCI bus that is controlled = by the specified Hot Plug Controller. + + @param[in] This The pointer to the instance of the EFI_PCI_HO= T_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 functi= on 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 requir= ed 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 call= ee and freed by the caller. + @param[out] Attribute Describes how padding is accounted for. + + @retval EFI_SUCCESS. +**/ +EFI_STATUS +EFIAPI +GetResourcePadding ( + IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *PhpcDevicePath, + IN UINT64 PhpcPciAddress, + OUT EFI_HPC_STATE *PhpcState, + OUT VOID **Padding, + OUT EFI_HPC_PADDING_ATTRIBUTES *Attributes + ); + +#endif + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Sm= m/TbtSmiHandler.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Tbt= Init/Smm/TbtSmiHandler.h new file mode 100644 index 0000000000..b91b0f14bd --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSm= iHandler.h @@ -0,0 +1,180 @@ +/** @file + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _TBT_SMI_HANDLER_H_ +#define _TBT_SMI_HANDLER_H_ + +#include +#include +#include + +#ifdef PROGRESS_CODE +#undef PROGRESS_CODE +#endif + +#define MAX_TBT_DEPTH 6 + +#define P2P_BRIDGE (((PCI_CLASS_BRIDGE) << 8) | (PCI_CLASS_BRID= GE_P2P)) + +#define BAR_ALIGN(v, a) ((((v) - 1) | (a)) + 1) + +#define CMD_BUS_MASTER BIT2 +#define CMD_BM_IO (CMD_BUS_MASTER | BIT0) +#define CMD_BM_MEM (CMD_BUS_MASTER | BIT1) +#define CMD_BM_MEM_IO (CMD_BUS_MASTER | BIT1 | BIT0) + +#define DEF_CACHE_LINE_SIZE 0x20 +#define DEF_RES_IO_PER_DEV 4 +#define DEF_RES_MEM_PER_DEV 32 +#define DEF_RES_PMEM_PER_DEV 32 + +#define DOCK_BUSSES 8 + +#define DISBL_IO_REG1C 0x01F1 +#define DISBL_MEM32_REG20 0x0000FFF0 +#define DISBL_PMEM_REG24 0x0001FFF1 + +#define count(x) (sizeof (x) / sizeof ((x)[0])) + +#define PCIE_CAP_ID_SSID_SSVID 0x0D +#define INVALID_PCI_DEVICE 0xFFFFFFFF +#define PCI_TBT_VESC_REG2 0x510 + +typedef struct _PortInfo { + UINT8 IoBase; + UINT8 IoLimit; + UINT16 MemBase; + UINT16 MemLimit; + UINT64 PMemBase64; + UINT64 PMemLimit64; + UINT8 BusNumLimit; + UINT8 ConfedEP; +} PORT_INFO; + +typedef struct _MEM_REGS { + UINT32 Base; + UINT32 Limit; +} MEM_REGS; + +typedef struct _PMEM_REGS { + UINT64 Base64; + UINT64 Limit64; +} PMEM_REGS; + +typedef struct _IO_REGS { + UINT16 Base; + UINT16 Limit; +} IO_REGS; + +typedef struct _BRDG_RES_CONFIG { + UINT8 Cmd; + UINT8 Cls; + UINT8 IoBase; + UINT8 IoLimit; + UINT16 MemBase; + UINT16 MemLimit; + UINT64 PMemBase64; + UINT64 PMemLimit64; +} BRDG_RES_CONFIG; + +typedef struct _BRDG_CONFIG { + DEV_ID DevId; + UINT8 PBus; + UINT8 SBus; + UINT8 SubBus; + BOOLEAN IsDSBridge; + BRDG_RES_CONFIG Res; +} BRDG_CONFIG; + +enum { + HR_US_PORT, + HR_DS_PORT0, + HR_DS_PORT3, + HR_DS_PORT4, + HR_DS_PORT5, + HR_DS_PORT6, + MAX_CFG_PORTS +}; + +enum { + HR_DS_PORT1 =3D HR_DS_PORT3 +}; + +// +// Alpine Ridge +// +enum { + AR_DS_PORT1 =3D HR_DS_PORT3, + AR_DS_PORT2, + AR_DS_PORT3, + AR_DS_PORT4 +}; + +typedef struct _HR_CONFIG { + UINT16 DeviceId; + UINT8 HRBus; + UINT8 MinDSNumber; + UINT8 MaxDSNumber; + UINT8 BridgeLoops; +} HR_CONFIG; + +STATIC const BRDG_RES_CONFIG NOT_IN_USE_BRIDGE =3D { + CMD_BUS_MASTER, + 0, + DISBL_IO_REG1C & 0xFF, + DISBL_IO_REG1C >> 8, + DISBL_MEM32_REG20 & 0xFFFF, + DISBL_MEM32_REG20 >> 16, + DISBL_PMEM_REG24 & 0xFFFF, + DISBL_PMEM_REG24 >> 16 +}; + +typedef union _BRDG_CIO_MAP_REG { + UINT32 AB_REG; + struct { + UINT32 NumOfDSPorts : 5; + UINT32 CioPortMap : 27; + } Bits; +} BRDG_CIO_MAP_REG; + +// +// Functions +// +VOID +ThunderboltCallback ( + IN UINT8 Type + ); + +VOID +TbtDisablePCIDevicesAndBridges ( + IN UINT8 Type + ); + +VOID +EndOfThunderboltCallback( + IN UINTN RpSegment, + IN UINTN RpBus, + IN UINTN RpDevice, + IN UINTN RpFunction +); + +VOID +ConfigureTbtAspm( + IN UINT8 Type, + IN UINT16 Aspm +); + +UINT8 +PcieFindCapId ( + IN UINT8 Segment, + IN UINT8 Bus, + IN UINT8 Device, + IN UINT8 Function, + IN UINT8 CapId + ); + +#endif + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Bo= ardInitLib.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/= BoardInitLib.h new file mode 100644 index 0000000000..ac13acc27d --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInit= Lib.h @@ -0,0 +1,32 @@ +/** @file + Header file for board Init function for DXE Init phase. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _DXE_BOARD_INIT_LIB_H_ +#define _DXE_BOARD_INIT_LIB_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +EFI_STATUS +EFIAPI +BoardConfigInit ( + VOID + ); + +#endif // _DXE_BOARD_INIT_LIB_H_ + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Cp= uPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInit= Dxe/CpuPolicyInitDxe.h new file mode 100644 index 0000000000..5d0e2777d8 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicy= InitDxe.h @@ -0,0 +1,38 @@ +/** @file + Header file for the SiliconPolicyInitDxe Driver. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _CPU_POLICY_INIT_DXE_H_ +#define _CPU_POLICY_INIT_DXE_H_ + +#include +#include +#include +#include + +#include +#include + + +/** + Initialize Intel CPU DXE Policy + + @param[in] ImageHandle Image handle of this driver. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this drive= r. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initiali= ze the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +CpuPolicyInitDxe ( + IN EFI_HANDLE ImageHandle + ); + +#endif + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Go= pPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInit= Dxe/GopPolicyInitDxe.h new file mode 100644 index 0000000000..ff975efae0 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicy= InitDxe.h @@ -0,0 +1,41 @@ +/** @file +Header file for the GopPolicyInitDxe Driver. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _GOP_POLICY_INIT_DXE_H_ +#define _GOP_POLICY_INIT_DXE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** +Initialize GOP DXE Policy + +@param[in] ImageHandle Image handle of this driver. + +@retval EFI_SUCCESS Initialization complete. +@retval EFI_UNSUPPORTED The chipset is unsupported by this driver. +@retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize= the driver. +@retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +GopPolicyInitDxe( + IN EFI_HANDLE ImageHandle + ); + +#endif + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Pc= hPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInit= Dxe/PchPolicyInitDxe.h new file mode 100644 index 0000000000..1055fed7c8 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicy= InitDxe.h @@ -0,0 +1,52 @@ +/** @file + Header file for the PchPolicyInitDxe Driver. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _PCH_POLICY_INIT_DXE_H_ +#define _PCH_POLICY_INIT_DXE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern UINT8 mFirmwareConfiguration; + +/** + PCH DXE Policy Driver Entry Point \n + - Introduction \n + Pch DXE drivers behavior can be controlled by platform policy without = modifying reference code directly. + Platform policy Protocol is initialized with default settings in this = funciton. + This policy Protocol has to be initialized prior to PCH initialization= DXE drivers execution. + + - @pre + - Runtime variable service should be ready if policy initialization re= quired. + + - @result + PCH_POLICY_PROTOCOL will be installed successfully and ready for Pch r= eference code use. + + - Porting Recommendations \n + Policy should be initialized basing on platform design or user selecti= on (like BIOS Setup Menu) + + @param[in] ImageHandle - Image handle of this driver. + + @retval EFI_SUCCESS Initialization complete. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize= the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +PchPolicyInitDxe ( + IN EFI_HANDLE ImageHandle + ); + +#endif + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Po= licyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe= /PolicyInitDxe.h new file mode 100644 index 0000000000..d2aac9823e --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyIni= tDxe.h @@ -0,0 +1,45 @@ +/** @file + Header file for the PolicyInitDxe Driver. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _POLICY_INIT_DXE_H_ +#define _POLICY_INIT_DXE_H_ + + +#include +#include +#include +#include + +#include "SaPolicyInitDxe.h" +#include "PchPolicyInitDxe.h" +#include "SiliconPolicyInitDxe.h" +#include "GopPolicyInitDxe.h" +#include "CpuPolicyInitDxe.h" + +#include +/** + Initialize DXE Platform Policy + + @param[in] ImageHandle - Image handle of this driver. + @param[in] SystemTable - Global system service table. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driv= er. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize= the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ + +EFI_STATUS +EFIAPI +PolicyInitDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +#endif + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Sa= PolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitD= xe/SaPolicyInitDxe.h new file mode 100644 index 0000000000..0f86711e6a --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyI= nitDxe.h @@ -0,0 +1,56 @@ +/** @file + Header file for the SaPolicyInitDxe Driver. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SA_POLICY_INIT_DXE_H_ +#define _SA_POLICY_INIT_DXE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +extern UINT8 mFirmwareConfiguration; + +/** + SA DXE Policy Driver Entry Point \n + - Introduction \n + System Agent DXE drivers behavior can be controlled by platform policy= without modifying reference code directly. + Platform policy Protocol is initialized with default settings in this = funciton. + This policy Protocol has to be initialized prior to System Agent initi= alization DXE drivers execution. + + - @pre + - Runtime variable service should be ready if policy initialization re= quired. + + - @result + SA_POLICY_PROTOCOL will be installed successfully and ready for System= Agent reference code use. + + - Porting Recommendations \n + Policy should be initialized basing on platform design or user selecti= on (like BIOS Setup Menu) + + @param[in] ImageHandle - Image handle of this driver. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize= the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +SaPolicyInitDxe ( + IN EFI_HANDLE ImageHandle + ); + +#endif + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Si= liconPolicyInitDxe.h b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Policy= InitDxe/SiliconPolicyInitDxe.h new file mode 100644 index 0000000000..a2c5f548fa --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPo= licyInitDxe.h @@ -0,0 +1,37 @@ +/** @file + Header file for the SiliconPolicyInitDxe Driver. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _SILICON_POLICY_INIT_DXE_H_ +#define _SILICON_POLICY_INIT_DXE_H_ + +#include +#include +#include +#include +#include + +#include + +/** + Initilize Intel CPU DXE Policy + + @param[in] ImageHandle Image handle of this driver. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this dr= iver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initiali= ze the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +SiliconPolicyInitDxe ( + IN EFI_HANDLE ImageHandle + ); + +#endif + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiG= nvsInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGn= vsInit.c new file mode 100644 index 0000000000..1ff129c307 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/AcpiGnvsInit= .c @@ -0,0 +1,96 @@ +/** @file + Acpi Gnvs Init Library. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#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 =3D EFI_SIZE_TO_PAGES (sizeof (EFI_GLOBAL_NVS_AREA)); + Address =3D 0xffffffff; // allocate address below 4G. + + Status =3D 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 =3D gBS->LocateProtocol ( + &gEfiMpServiceProtocolGuid, + NULL, + (VOID **) &MpService + ); + ASSERT_EFI_ERROR (Status); + + // + // Determine the number of processors + // + MpService->GetNumberOfProcessors ( + MpService, + &NumberOfCPUs, + &NumberOfEnabledCPUs + ); + + *GlobalNvs =3D (VOID *) (UINTN) Address; + SetMem (*GlobalNvs, sizeof (EFI_GLOBAL_NVS_AREA), 0); + + // + // GNVS default value init here... + // + GNVS =3D (EFI_GLOBAL_NVS_AREA_PROTOCOL *) &Address; + + GNVS->Area->ThreadCount =3D (UINT8)NumberOfEnabledCPUs; + + // + // Miscellaneous + // + GNVS->Area->PL1LimitCS =3D 0; + GNVS->Area->PL1LimitCSValue =3D 4500; + + return EFI_SUCCESS; +} + + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Board= AcpiDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardA= cpiDxe.c new file mode 100644 index 0000000000..cb5f328a39 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/BoardAcpiDxe= .c @@ -0,0 +1,290 @@ +/** @file + ACPI Platform Driver + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#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 mG= lobalNvsArea; + +/** +@brief + Global NVS initialize. + + @param[in] GlobalNvs - Pointer of Global NVS area + + @retval EFI_SUCCESS - Allocate Global NVS completed. + @retval EFI_OUT_OF_RESOURCES - Failed to allocate required page for GNVS= . +**/ +EFI_STATUS +EFIAPI +AcpiGnvsInit ( + IN OUT VOID **GlobalNvs + ); + +// +// Function implementations +// + +/** + Locate the first instance of a protocol. If the protocol requested is a= n + FV protocol, then it will return the first FV that contains the ACPI tab= le + storage file. + + @param[in] Protocol The protocol to find. + @param[in] Instance Return pointer to the first instance of th= e protocol. + @param[in] Type TRUE if the desired protocol is a FV proto= col. + + @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 =3D 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 =3D 0; Index < NumberOfHandles; Index++) { + + // + // Get the protocol on this handle + // This should not fail because of LocateHandleBuffer + // + Status =3D gBS->HandleProtocol ( + HandleBuffer[Index], + Protocol, + Instance + ); + ASSERT_EFI_ERROR (Status); + + if (!Type) { + + // + // Not looking for the FV protocol, so find the first instance of th= e + // protocol. There should not be any errors because our handle buff= er + // should always contain at least one or LocateHandleBuffer would ha= ve + // returned not found. + // + break; + } + // + // See if it has the ACPI storage file + // + Size =3D 0; + FvStatus =3D 0; + Status =3D ((EFI_FIRMWARE_VOLUME2_PROTOCOL *) (*Instance))->ReadFile ( + *Instance, + gEfiAcpiMult= iTableStorageGuid, + NULL, + &Size, + &FileType, + &Attributes, + &FvStatus + ); + // + // If we found it, then we are done + // + if (Status =3D=3D EFI_SUCCESS) { + break; + } + } + + // + // Our exit status is determined by the success of the previous operatio= ns + // If the protocol was found, Instance already points to it. + // + // + // Free any allocated buffers + // + FreePool (HandleBuffer); + + return Status; +} + +EFI_STATUS +PublishAcpiTablesFromFv ( + IN EFI_GUID *gEfiAcpiMultiTableStorageGuid + ) +{ + EFI_STATUS Status; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol; + EFI_ACPI_COMMON_HEADER *CurrentTable; + UINT32 FvStatus; + UINTN Size; + UINTN TableHandle; + INTN Instance; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + + Instance =3D 0; + TableHandle =3D 0; + CurrentTable =3D NULL; + FwVol =3D NULL; + + // + // Find the AcpiSupport protocol + // + Status =3D LocateSupportProtocol ( + &gEfiAcpiTableProtocolGuid, + gEfiAcpiMultiTableStorageGuid, + (VOID **) &AcpiTable, + FALSE + ); + ASSERT_EFI_ERROR (Status); + + // + // Locate the firmware volume protocol + // + Status =3D LocateSupportProtocol ( + &gEfiFirmwareVolume2ProtocolGuid, + gEfiAcpiMultiTableStorageGuid, + (VOID **) &FwVol, + TRUE + ); + + // + // Read tables from the storage file. + // + + while (Status =3D=3D EFI_SUCCESS) { + Status =3D FwVol->ReadSection ( + FwVol, + gEfiAcpiMultiTableStorageGuid, + EFI_SECTION_RAW, + Instance, + (VOID **) &CurrentTable, + &Size, + &FvStatus + ); + + if (!EFI_ERROR (Status)) { + // + // Add the table + // + TableHandle =3D 0; + + Status =3D AcpiTable->InstallAcpiTable ( + AcpiTable, + CurrentTable, + CurrentTable->Length, + &TableHandle + ); + + + ASSERT_EFI_ERROR (Status); + + // + // Increment the instance + // + Instance++; + CurrentTable =3D 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 =3D NULL; + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiGlobalNvsAreaProtocolGuid, + &mGlobalNvsArea, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/Pci= HotPlug.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciH= otPlug.c new file mode 100644 index 0000000000..2b36475c53 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/PciHotPlug/PciHotPlug= .c @@ -0,0 +1,353 @@ +/** @file + Pci Hotplug Driver : This file will perform specific PCI-EXPRESS + Devics resource configuration. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// 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_PREFE= TCH_MEM + PADDING_IO) + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_HPC_LOCATION mPcieLocation[PCIE= _NUM + PEG_NUM]; + +GLOBAL_REMOVE_IF_UNREFERENCED UINTN mHpcCount =3D 0; + +GLOBAL_REMOVE_IF_UNREFERENCED PCIE_HOT_PLUG_DEVICE_PATH mHotplugPcieDevice= PathTemplate =3D { + 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 =3D 0; + + DEBUG ((DEBUG_INFO, "PciHotPlug Entry\n")); + + PcieRootPortHpeData =3D PcdGet32 (PcdPchPcieRootPortHpe); + // + // PCH Rootports Hotplug device path creation + // + for (Index =3D 0; Index < PCIE_NUM; Index++) { + if (((PcieRootPortHpeData >> Index) & BIT0) =3D=3D BIT0) { // Check th= e Rootport no's hotplug is set + Status =3D GetPchPcieRpDevFun (Index, &RpDev, &RpFunc); // Get the a= ctual device/function no corresponding to the Rootport no provided + ASSERT_EFI_ERROR (Status); + + HotplugPcieDevicePath =3D NULL; + HotplugPcieDevicePath =3D AllocatePool (sizeof (PCIE_HOT_PLUG_DEVICE= _PATH)); + ASSERT (HotplugPcieDevicePath !=3D NULL); + if (HotplugPcieDevicePath =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem (HotplugPcieDevicePath, &mHotplugPcieDevicePathTemplate, siz= eof (PCIE_HOT_PLUG_DEVICE_PATH)); + HotplugPcieDevicePath->PciRootPortNode.Device =3D (UINT8) RpDev; // = Update real Device no + HotplugPcieDevicePath->PciRootPortNode.Function =3D (UINT8) RpFunc; = // Update real Function no + + mPcieLocation[mHpcCount].HpcDevicePath =3D (EFI_DEVICE_PATH_PROTOCOL= *)HotplugPcieDevicePath; + mPcieLocation[mHpcCount].HpbDevicePath =3D (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 =3D AllocatePool (sizeof (PCI_HOT_PLUG_INSTANCE)); + ASSERT (PciHotPlug !=3D NULL); + if (PciHotPlug =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Initialize driver private data. + // + ZeroMem (PciHotPlug, sizeof (PCI_HOT_PLUG_INSTANCE)); + + PciHotPlug->Signature =3D PCI_HOT_PLUG_DRI= VER_PRIVATE_SIGNATURE; + PciHotPlug->HotPlugInitProtocol.GetRootHpcList =3D GetRootHpcList; + PciHotPlug->HotPlugInitProtocol.InitializeRootHpc =3D InitializeRootHp= c; + PciHotPlug->HotPlugInitProtocol.GetResourcePadding =3D GetResourcePaddi= ng; + + Status =3D 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_PLU= G_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 =3D mHpcCount; + *HpcList =3D 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_H= OT_PLUG_INIT protocol. + @param[in] HpcDevicePath The Device Path to the HPC that is being ini= tialized. + @param[in] HpcPciAddress The address of the Hot Plug Controller funct= ion on the PCI bus. + @param[in] Event The event that should be signaled when the H= ot Plug Controller initialization is complete. Set to NULL if the caller wa= nts 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 hardwar= e. 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 =3D 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_HO= T_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 functi= on 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 requir= ed 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 call= ee 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 =3D 0; + UINT16 RsvdPcieMegaMem =3D 10; + UINT8 PcieMemAddrRngMax =3D 0; + UINT16 RsvdPciePMegaMem =3D 10; + UINT8 PciePMemAddrRngMax =3D 0; + UINT8 RsvdTbtExtraBusNum =3D 0; + UINT16 RsvdTbtPcieMegaMem =3D 10; + UINT8 TbtPcieMemAddrRngMax =3D 0; + UINT16 RsvdTbtPciePMegaMem =3D 10; + UINT8 TbtPciePMemAddrRngMax =3D 0; + UINT8 RsvdPcieKiloIo =3D 4; + BOOLEAN SetResourceforTbt =3D FALSE; + UINTN RpIndex; + UINTN RpDev; + UINTN RpFunc; + +DEBUG ((DEBUG_INFO, "GetResourcePadding : Start \n")); + + PaddingResource =3D AllocatePool (PADDING_NUM * sizeof (EFI_ACPI_ADDRESS= _SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); + ASSERT (PaddingResource !=3D NULL); + if (PaddingResource =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + *Padding =3D (VOID *) PaddingResource; + + RpDev =3D (UINTN) ((HpcPciAddress >> 16) & 0xFF); + RpFunc =3D (UINTN) ((HpcPciAddress >> 8) & 0xFF); + + // Get the actual Rootport no corresponding to the device/function no pr= ovided + if (RpDev =3D=3D SA_PEG_DEV_NUM) { + // PEG + RpIndex =3D PCIE_NUM + RpFunc; + DEBUG ((DEBUG_INFO, "GetResourcePadding : PEG Rootport no %02d Bus 0x0= 0, Device 0x%x, Function 0x%x \n", (RpIndex-PCIE_NUM), RpDev, RpFunc)); + } else { + // PCH + Status =3D GetPchPcieRpNumber (RpDev, RpFunc, &RpIndex); + DEBUG ((DEBUG_INFO, "GetResourcePadding : PCH Rootport no %02d Bus 0x0= 0, Device 0x%x, Function 0x%x \n", RpIndex, RpDev, RpFunc)); + } + + GetRootporttoSetResourcesforTbt(RpIndex, &RsvdTbtExtraBusNum, &RsvdTbtPc= ieMegaMem ,&TbtPcieMemAddrRngMax ,&RsvdTbtPciePMegaMem ,&TbtPciePMemAddrRng= Max, &SetResourceforTbt); + if (SetResourceforTbt) { + RsvdExtraBusNum =3D RsvdTbtExtraBusNum; + RsvdPcieMegaMem =3D RsvdTbtPcieMegaMem; + PcieMemAddrRngMax =3D TbtPcieMemAddrRngMax; + RsvdPciePMegaMem =3D RsvdTbtPciePMegaMem; + PciePMemAddrRngMax =3D TbtPciePMemAddrRngMax; + } + + // + // Padding for bus + // + ZeroMem (PaddingResource, PADDING_NUM * sizeof (EFI_ACPI_ADDRESS_SPACE_D= ESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); + *Attributes =3D EfiPaddingPciBus; + + PaddingResource->Desc =3D 0x8A; + PaddingResource->Len =3D 0x2B; + PaddingResource->ResType =3D ACPI_ADDRESS_SPACE_TYPE_BUS; + PaddingResource->GenFlag =3D 0x0; + PaddingResource->SpecificFlag =3D 0; + PaddingResource->AddrRangeMin =3D 0; + PaddingResource->AddrRangeMax =3D 0; + PaddingResource->AddrLen =3D RsvdExtraBusNum; + + // + // Padding for non-prefetchable memory + // + PaddingResource++; + PaddingResource->Desc =3D 0x8A; + PaddingResource->Len =3D 0x2B; + PaddingResource->ResType =3D ACPI_ADDRESS_SPACE_TYPE_MEM; + PaddingResource->GenFlag =3D 0x0; + if (SetResourceforTbt) { + PaddingResource->AddrSpaceGranularity =3D 32; + } else { + PaddingResource->AddrSpaceGranularity =3D 32; + } + PaddingResource->SpecificFlag =3D 0; + // + // Pad non-prefetchable + // + PaddingResource->AddrRangeMin =3D 0; + PaddingResource->AddrLen =3D RsvdPcieMegaMem * 0x100000; + if (SetResourceforTbt) { + PaddingResource->AddrRangeMax =3D (1 << PcieMemAddrRngMax) - 1; + } else { + PaddingResource->AddrRangeMax =3D 1; + } + + // + // Padding for prefetchable memory + // + PaddingResource++; + PaddingResource->Desc =3D 0x8A; + PaddingResource->Len =3D 0x2B; + PaddingResource->ResType =3D ACPI_ADDRESS_SPACE_TYPE_MEM; + PaddingResource->GenFlag =3D 0x0; + if (SetResourceforTbt) { + PaddingResource->AddrSpaceGranularity =3D 32; + } else { + PaddingResource->AddrSpaceGranularity =3D 32; + } + PaddingResource->SpecificFlag =3D 06; + // + // Padding for prefetchable memory + // + PaddingResource->AddrRangeMin =3D 0; + if (SetResourceforTbt) { + PaddingResource->AddrLen =3D RsvdPciePMegaMem * 0x100000; + } else { + PaddingResource->AddrLen =3D RsvdPcieMegaMem * 0x100000; + } + // + // Pad 16 MB of MEM + // + if (SetResourceforTbt) { + PaddingResource->AddrRangeMax =3D (1 << PciePMemAddrRngMax) - 1; + } else { + PaddingResource->AddrRangeMax =3D 1; + } + // + // Alignment + // + // Padding for I/O + // + PaddingResource++; + PaddingResource->Desc =3D 0x8A; + PaddingResource->Len =3D 0x2B; + PaddingResource->ResType =3D ACPI_ADDRESS_SPACE_TYPE_IO; + PaddingResource->GenFlag =3D 0x0; + PaddingResource->SpecificFlag =3D 0; + PaddingResource->AddrRangeMin =3D 0; + PaddingResource->AddrLen =3D RsvdPcieKiloIo * 0x400; + // + // Pad 4K of IO + // + PaddingResource->AddrRangeMax =3D 1; + // + // Alignment + // + // Terminate the entries. + // + PaddingResource++; + ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Desc =3D ACPI_END= _TAG_DESCRIPTOR; + ((EFI_ACPI_END_TAG_DESCRIPTOR *) PaddingResource)->Checksum =3D 0x0; + + *HpcState =3D EFI_HPC_STATE_INITIALIZED | EFI_HPC_STATE_ENABLED; + + return EFI_SUCCESS; +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dx= e/TbtDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dx= e/TbtDxe.c new file mode 100644 index 0000000000..c670f23320 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Dxe/TbtDx= e.c @@ -0,0 +1,228 @@ +/** @file + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GLOBAL_REMOVE_IF_UNREFERENCED TBT_NVS_AREA_PROTOCOL mT= btNvsAreaProtocol; +GLOBAL_REMOVE_IF_UNREFERENCED TBT_INFO_HOB *g= TbtInfoHob =3D 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 =3D gBS->LocateProtocol ( + &gDxeTbtPolicyProtocolGuid, + NULL, + (VOID **) &DxeTbtConfig + ); + ASSERT_EFI_ERROR (Status); + + Pages =3D EFI_SIZE_TO_PAGES (sizeof (TBT_NVS_AREA)); + Address =3D 0xffffffff; // allocate address below 4G. + + Status =3D gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + Pages, + &Address + ); + ASSERT_EFI_ERROR (Status); + + *mTbtNvsAreaPtr =3D (VOID *) (UINTN) Address; + SetMem (*mTbtNvsAreaPtr, sizeof (TBT_NVS_AREA), 0); + + // + // TBTNvsAreaProtocol default value init here + // + TbtNvsAreaProtocol =3D (TBT_NVS_AREA_PROTOCOL *) &Address; + + // + // Initialize default values + // + TbtNvsAreaProtocol->Area->WAKFinished =3D 0; + TbtNvsAreaProtocol->Area->DiscreteTbtSupport =3D ((gTbtInfoHob-> DT= btControllerConfig.DTbtControllerEn =3D=3D 1 ) ? TRUE : FALSE); + TbtNvsAreaProtocol->Area->TbtAcpiRemovalSupport =3D 0; + TbtNvsAreaProtocol->Area->TbtGpioFilter =3D (UINT8) DxeTbtConf= ig->TbtCommonConfig.Gpio5Filter; +// TbtNvsAreaProtocol->Area->TrOsup =3D (UINT8) DxeTbtCo= nfig->TbtCommonConfig.TrA0OsupWa; + TbtNvsAreaProtocol->Area->TbtFrcPwrEn =3D gTbtInfoHob->DTbtC= ommonConfig.Gpio3ForcePwr; + TbtNvsAreaProtocol->Area->TbtAspm =3D (UINT8) DxeTbtConf= ig->TbtCommonConfig.TbtAspm; +// TbtNvsAreaProtocol->Area->TbtL1SubStates =3D (UINT8) DxeTbtCo= nfig->TbtCommonConfig.TbtL1SubStates; + TbtNvsAreaProtocol->Area->TbtSetClkReq =3D (UINT8) DxeTbtConf= ig->TbtCommonConfig.TbtSetClkReq; + TbtNvsAreaProtocol->Area->TbtLtr =3D (UINT8) DxeTbtConf= ig->TbtCommonConfig.TbtLtr; +// TbtNvsAreaProtocol->Area->TbtPtm =3D (UINT8) DxeTbtCo= nfig->TbtCommonConfig.TbtPtm; + TbtNvsAreaProtocol->Area->TbtWakeupSupport =3D (UINT8) DxeTbtConf= ig->TbtCommonConfig.TbtWakeupSupport; + TbtNvsAreaProtocol->Area->TbtAcDcSwitch =3D (UINT8) DxeTbtConf= ig->TbtCommonConfig.TbtAcDcSwitch; + TbtNvsAreaProtocol->Area->Rtd3TbtSupport =3D (UINT8) DxeTbtConf= ig->TbtCommonConfig.Rtd3Tbt; // TBT RTD3 Enable. + TbtNvsAreaProtocol->Area->Rtd3TbtOffDelay =3D (UINT16) DxeTbtCon= fig->TbtCommonConfig.Rtd3TbtOffDelay; // TBT RTD3 Off delay in ms. + TbtNvsAreaProtocol->Area->Rtd3TbtClkReq =3D (UINT8) DxeTbtConf= ig->TbtCommonConfig.Rtd3TbtClkReq; // TBT RTD3 ClkReq Mask Enable. + TbtNvsAreaProtocol->Area->Rtd3TbtClkReqDelay =3D (UINT16) DxeTbtCon= fig->TbtCommonConfig.Rtd3TbtClkReqDelay; // TBT RTD3 ClkReq mask delay in m= s. + TbtNvsAreaProtocol->Area->TbtWin10Support =3D (UINT8) DxeTbtConf= ig->TbtCommonConfig.Win10Support; // TBT FW Execution Mode + + // + // DTBT Controller 1 + // + TbtNvsAreaProtocol->Area->DTbtControllerEn0 =3D gTbtInfoHob-> DTbt= ControllerConfig.DTbtControllerEn; + TbtNvsAreaProtocol->Area->RootportSelected0 =3D gTbtInfoHob-> DTbt= ControllerConfig.PcieRpNumber; + TbtNvsAreaProtocol->Area->RootportSelected0Type =3D gTbtInfoHob-> DTbt= ControllerConfig.Type; + TbtNvsAreaProtocol->Area->RootportEnabled0 =3D gTbtInfoHob-> DTbt= ControllerConfig.DTbtControllerEn; + TbtNvsAreaProtocol->Area->TbtFrcPwrGpioNo0 =3D gTbtInfoHob-> DTbt= ControllerConfig.ForcePwrGpio.GpioPad; + TbtNvsAreaProtocol->Area->TbtFrcPwrGpioLevel0 =3D gTbtInfoHob-> DTbt= ControllerConfig.ForcePwrGpio.GpioLevel; + TbtNvsAreaProtocol->Area->TbtCioPlugEventGpioNo0 =3D gTbtInfoHob-> DTbt= ControllerConfig.CioPlugEventGpio.GpioPad; + TbtNvsAreaProtocol->Area->TbtPcieRstGpioNo0 =3D gTbtInfoHob-> DTbt= ControllerConfig.PcieRstGpio.GpioPad; + TbtNvsAreaProtocol->Area->TbtPcieRstGpioLevel0 =3D gTbtInfoHob-> DTbt= ControllerConfig.PcieRstGpio.GpioLevel; + + TbtNvsAreaProtocol->Area->TBtCommonGpioSupport =3D gTbtInfoHob->DTbtC= ommonConfig.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 callbac= k. + @param[in] Context - A pointer to private data registered with the cal= lback 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 =3D InitializeAslUpdateLib (); + ASSERT_EFI_ERROR (Status); + + Address =3D (UINT32) (UINTN) mTbtNvsAreaProtocol.Area; + Length =3D (UINT16) sizeof (TBT_NVS_AREA); + DEBUG ((DEBUG_INFO, "Patch TBT NvsAreaAddress: TBT NVS Address %x Length= %x\n", Address, Length)); + Status =3D UpdateNameAslCode (SIGNATURE_32 ('T','N','V','B'), &Address,= sizeof (Address)); + ASSERT_EFI_ERROR (Status); + Status =3D UpdateNameAslCode (SIGNATURE_32 ('T','N','V','L'), &Length, = sizeof (Length)); + ASSERT_EFI_ERROR (Status); + + if (gTbtInfoHob !=3D NULL) { + if (gTbtInfoHob-> DTbtControllerConfig.DTbtControllerEn =3D=3D 1) { + if (gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSigna= turePorting =3D=3D TRUE) { + DEBUG ((DEBUG_INFO, "Patch ATBT Method Name\n")); + Signature =3D gTbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.= AcpiGpeSignature; + Status =3D UpdateNameAslCode (SIGNATURE_32 ('A','T','B','T'), &Si= gnature, 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 =3D (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid); + if (gTbtInfoHob =3D=3D 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 =3D NULL; + + Status =3D 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 =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + TbtAcpiEndOfDxeCallback, + NULL, + &gEfiEndOfDxeEventGroupGuid, + &EndOfDxeEvent + ); + ASSERT_EFI_ERROR (Status); +**/ + return EFI_SUCCESS; +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pe= i/PeiTbtInit.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtIni= t/Pei/PeiTbtInit.c new file mode 100644 index 0000000000..bdd8de0cfd --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Pei/PeiTb= tInit.c @@ -0,0 +1,211 @@ +/** @file + Source code file for TBT Init PEI module + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* +/** + This function Update and Print PEI TBT Policy after TbtPolicyBoardInitDo= ne + + @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 fu= nction. + + @retval EFI_SUCCESS The function completes successfully + @retval others +**/ + + +/** + This function pass PEI TBT Policy to Hob at the end of PEI + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification = event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this fu= nction. + + @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 =3D PeiServicesGetBootMode (&BootMode); + ASSERT_EFI_ERROR (Status); + if (BootMode =3D=3D BOOT_ON_S3_RESUME ) { + return EFI_SUCCESS; + } + + Status =3D 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 =3D 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 =3D gTbtInfoHobGuid; + + // + // Update DTBT Policy + // + TbtInfoHob-> DTbtControllerConfig.DTbtControllerEn =3D PeiTbtConfig-> DT= btControllerConfig.DTbtControllerEn; + TbtInfoHob-> DTbtControllerConfig.Type =3D PeiTbtConfig-> DTbtController= Config.Type; + TbtInfoHob-> DTbtControllerConfig.PcieRpNumber =3D PeiTbtConfig-> DTbtCo= ntrollerConfig.PcieRpNumber; + TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioPad =3D PeiTbtConfig-= > DTbtControllerConfig.ForcePwrGpio.GpioPad; + TbtInfoHob-> DTbtControllerConfig.ForcePwrGpio.GpioLevel =3D PeiTbtConfi= g-> DTbtControllerConfig.ForcePwrGpio.GpioLevel; + TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.GpioPad =3D PeiTbtCon= fig-> DTbtControllerConfig.CioPlugEventGpio.GpioPad; + TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature =3D = PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature; + TbtInfoHob-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorti= ng =3D PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignatur= ePorting; + TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioPad =3D PeiTbtConfig->= DTbtControllerConfig.PcieRstGpio.GpioPad; + TbtInfoHob-> DTbtControllerConfig.PcieRstGpio.GpioLevel =3D PeiTbtConfig= -> DTbtControllerConfig.PcieRstGpio.GpioLevel; + + TbtInfoHob->DTbtCommonConfig.TbtBootOn =3D PeiTbtConfig->DTbtCommonConfi= g.TbtBootOn; + TbtInfoHob->DTbtCommonConfig.TbtUsbOn =3D PeiTbtConfig->DTbtCommonConfig= .TbtUsbOn; + TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwr =3D PeiTbtConfig->DTbtCommonC= onfig.Gpio3ForcePwr; + TbtInfoHob->DTbtCommonConfig.Gpio3ForcePwrDly =3D PeiTbtConfig->DTbtComm= onConfig.Gpio3ForcePwrDly; + TbtInfoHob->DTbtCommonConfig.DTbtSharedGpioConfiguration =3D PeiTbtConfi= g->DTbtCommonConfig.DTbtSharedGpioConfiguration; + TbtInfoHob->DTbtCommonConfig.PcieRstSupport =3D PeiTbtConfig->DTbtCommon= Config.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 fu= nction. + + @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 =3D EFI_SUCCESS; + PeiTbtConfig =3D NULL; + DTbtExisted =3D FALSE; + + Status =3D 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 =3D=3D 1) { + DTbtExisted =3D TRUE; + } + + if (DTbtExisted =3D=3D TRUE) { + // + // Call Init function + // + Status =3D TbtInit (); + } + + return EFI_SUCCESS; +} + +/** + TBT Init PEI module entry point + + @param[in] FileHandle Not used. + @param[in] PeiServices General purpose services available to e= very PEIM. + + @retval EFI_SUCCESS The function completes successfully + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create databa= se +**/ +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 =3D InstallPeiTbtPolicy (); + ASSERT_EFI_ERROR (Status); + + + UpdatePeiTbtPolicy (); + + TbtPrintPeiPolicyConfig (); + // + // Performing PassTbtPolicyToHob and TbtInitEndOfPei + // + Status =3D PassTbtPolicyToHob (); + + Status =3D TbtInitEndOfPei (); + + return Status; +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Sm= m/TbtSmiHandler.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Tbt= Init/Smm/TbtSmiHandler.c new file mode 100644 index 0000000000..a6bdc6ef9f --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSm= iHandler.c @@ -0,0 +1,1609 @@ +/** @file + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#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_PORT= S]; + +extern UINT8 gCurrentDiscreteTbtRootPort; +extern UINT8 gCurrentDiscreteTbtRootPortType; + +BOOLEAN isLegacyDevice =3D FALSE; +STATIC UINT8 TbtSegment =3D 0; + +STATIC +VOID +PortInfoInit ( + IN OUT PORT_INFO *PortInfo + ) +{ + PortInfo->BusNumLimit =3D 4; +} + +STATIC +VOID +UnsetVesc ( + IN UINT8 Bus, + IN UINT8 Dev, + IN UINT8 Fun + ) +{ + UINT8 Dbus; + UINT32 Data32; + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fu= n, 0); + + // + // Check for abcence of DS bridge + // + if(0xFFFF =3D=3D PciSegmentRead16(gDeviceBaseAddress + PCI_DEVICE_ID_OFF= SET)) { + return; + } + + // + // Unset vesc_reg2[23] bit (to have an option to access below DS) + // + Data32 =3D PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2); + Data32 &=3D 0xFF7FFFFF; + PciSegmentWrite32(gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32); + // + // Go to Device behind DS + // + Dbus =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_= REGISTER_OFFSET); + DEBUG((DEBUG_INFO, "Dbus =3D %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 -> thi= s will flush all future MemWr + // + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Dbus, 0x00, = 0x00, 0); + if(0xFFFF =3D=3D PciSegmentRead16(gDeviceBaseAddress + PCI_DEVICE_ID_OFF= SET)) + { + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fu= n, 0); + Data32 =3D PciSegmentRead32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2); + Data32 |=3D 0x00800000; + PciSegmentWrite32 (gDeviceBaseAddress + PCI_TBT_VESC_REG2, Data32); + } +}// Unset_VESC_REG2 + +STATIC +UINT16 +MemPerSlot ( + IN UINT16 CurrentUsage + ) +{ + if (CurrentUsage =3D=3D 0) { + return 0; + } + + if (CurrentUsage <=3D 16) { + return 16; + } + + if (CurrentUsage <=3D 64) { + return 64; + } + + if (CurrentUsage <=3D 128) { + return 128; + } + + if (CurrentUsage <=3D 256) { + return 256; + } + + if (CurrentUsage <=3D 512) { + return 512; + } + + if (CurrentUsage <=3D 1024) { + return 1024; + } + + return CurrentUsage; +} // MemPerSlot + +STATIC +UINT64 +PMemPerSlot ( + IN UINT64 CurrentUsage + ) +{ + if (CurrentUsage =3D=3D 0) { + return 0; + } + + if (CurrentUsage <=3D 1024ULL) { + return 1024ULL; + } + + if (CurrentUsage <=3D 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 =3D CMD_BUS_MASTER; + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, 0x= 00, 0); + + PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGIST= ER_OFFSET, SubBus); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd); + + DeltaMem =3D PortInfo->MemBase - CurrentPi->MemBase; + if (isLegacyDevice) { + if (Depth >=3D 0 && (DeltaMem < MEM_PER_SLOT)) { + PortInfo->MemBase +=3D MEM_PER_SLOT - DeltaMem; + } + } else { + if (DeltaMem < MemPerSlot (DeltaMem)) { + PortInfo->MemBase +=3D MemPerSlot (DeltaMem) - DeltaMem; + } + } + + if (PortInfo->MemBase > CurrentPi->MemBase && (PortInfo->MemBase - 0x10)= <=3D PortInfo->MemLimit) { + PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.= MemoryBase), CurrentPi->MemBase); + PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.= MemoryLimit), PortInfo->MemBase - 0x10); + Cmd |=3D CMD_BM_MEM; + } else { + PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.= MemoryBase), DISBL_MEM32_REG20); + PortInfo->MemBase =3D CurrentPi->MemBase; + } + + DeltaPMem =3D PortInfo->PMemBase64 - CurrentPi->PMemBase64; + if (isLegacyDevice) { + if ((Depth >=3D 0) && ((UINTN)DeltaPMem < (UINTN)PMEM_PER_SLOT)) { + PortInfo->PMemBase64 +=3D PMEM_PER_SLOT - DeltaPMem; + } + } else { + if (DeltaPMem < PMemPerSlot (DeltaPMem)) { + PortInfo->PMemBase64 +=3D PMemPerSlot (DeltaPMem) - DeltaPMem; + } + } + + if (PortInfo->PMemBase64 > CurrentPi->PMemBase64 && (PortInfo->PMemBase6= 4 - 0x10) <=3D 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 |=3D 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 =3D CurrentPi->PMemBase64; + } + + PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CA= CHE_LINE_SIZE); +} // SetPhyPortResources + +STATIC +UINT32 +SaveSetGetRestoreBar ( + IN UINTN Bar + ) +{ + UINT32 BarReq; + UINT32 OrigBar; + + OrigBar =3D PciSegmentRead32(Bar); // Save BAR + PciSegmentWrite32(Bar, 0xFFFFFFFF); // Set BAR + BarReq =3D 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 =3D ~(BarReq & 0xFFFC); + Size =3D Alignment + 1; + + if (IoReg->Base > IoReg->Limit || !Size) { + return ; + + } + + NewBase =3D BAR_ALIGN (IoReg->Base, Alignment); + if (NewBase > IoReg->Limit || NewBase + Size - 1 > IoReg->Limit) { + return ; + + } + PciSegmentWrite16(BAR, NewBase); + IoReg->Base =3D NewBase + Size; // Advance to new position + *Cmd |=3D 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 =3D ~(BarReq & 0xFFFFFFF0); + Size =3D Alignment + 1; + + if (MemReg->Base > MemReg->Limit || !Size) { + return ; + + } + + NewBase =3D BAR_ALIGN (MemReg->Base, Alignment); + if (NewBase > MemReg->Limit || NewBase + Size - 1 > MemReg->Limit) { + return ; + + } + + PciSegmentWrite32(BAR, NewBase); + MemReg->Base =3D NewBase + Size; // Advance to new position + *Cmd |=3D 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 =3D ~(BarReq & 0xFFFFFFF0); + Size =3D Alignment + 1; + + if (MemReg->Base64 > MemReg->Limit64 || !Size) { + return ; + } + + NewBase =3D 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 =3D NewBase + Size; // Advance to new position + *Cmd |=3D 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 br= idge + IN OUT PORT_INFO *PortInfo + ) +{ + UINT8 Fun; + UINT8 Reg; + UINT32 BarReq; + IO_REGS Io; + MEM_REGS Mem; + PMEM_REGS PMem; + UINT8 Cmd; + + Io.Base =3D PortInfo->IoBase << 8; + Io.Limit =3D (PortInfo->IoLimit << 8) | 0xFF; + Mem.Base =3D PortInfo->MemBase << 16; + Mem.Limit =3D (PortInfo->MemLimit << 16) | 0xFFFF; + PMem.Base64 =3D PortInfo->PMemBase64 << 16; + PMem.Limit64 =3D (PortInfo->PMemLimit64 << 16) | 0xFFFF; + + for (Fun =3D 0; Fun < MaxFun; ++Fun) { + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, = Fun, 0); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BUS_MAS= TER); + Cmd =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET); + if (0xFFFF =3D=3D PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID= _OFFSET)) { + continue; + + } + + for (Reg =3D PCI_BASE_ADDRESSREG_OFFSET; Reg <=3D MaxBar; Reg +=3D 4) = { + BarReq =3D SaveSetGetRestoreBar(gDeviceBaseAddress + Reg); // Perfor= m 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 =3D=3D Reg, BarRe= q, &Cmd, &PMem); + } else { + SetMemBar ((gDeviceBaseAddress + Reg), BarReq, &Cmd, &Mem); + } + + if (BIT2 =3D=3D (BarReq & (BIT2 | BIT1))) { + // + // Base address is 64 bits wide + // + Reg +=3D 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 &=3D ~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 =3D (UINT8) (BAR_ALIGN (Io.Base, 0xFFF) >> 8); + } + + if (Mem.Base > ((UINT32) PortInfo->MemBase << 16)) { + PortInfo->MemBase =3D (UINT16) (BAR_ALIGN (Mem.Base, 0xFFFFF) >> 16); + } + + if (PMem.Base64 > (PortInfo->PMemBase64 << 16)) { + PortInfo->PMemBase64 =3D (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 =3D HrConfigs[HR_US_PORT].DevId.Bus + 1= ; + HrConfigs[AR_DS_PORT2].DevId.Dev =3D 2; + HrConfigs[AR_DS_PORT2].DevId.Fun =3D 0; + HrConfigs[AR_DS_PORT2].PBus =3D HrConfigs[AR_DS_PORT2].DevId.Bus; + HrConfigs[AR_DS_PORT2].SBus =3D HrConfigs[AR_DS_PORT2].PBus + 1; + HrConfigs[AR_DS_PORT2].SubBus =3D HrConfigs[AR_DS_PORT2].PBus + 1; + // + // CIO port + // + HrConfigs[AR_DS_PORT1].DevId.Bus =3D HrConfigs[HR_US_PORT].DevId.Bus + 1= ; + HrConfigs[AR_DS_PORT1].DevId.Dev =3D 1; + HrConfigs[AR_DS_PORT1].DevId.Fun =3D 0; + HrConfigs[AR_DS_PORT1].PBus =3D HrConfigs[AR_DS_PORT1].DevId.Bus; + HrConfigs[AR_DS_PORT1].SBus =3D HrConfigs[HR_DS_PORT0].SubBus + 1; + HrConfigs[AR_DS_PORT1].SubBus =3D 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 =3D HrConfigs[AR_DS_PORT1].DevId.Dev; + Hr_Config->MaxDSNumber =3D HrConfigs[AR_DS_PORT2].DevId.Dev; + Hr_Config->BridgeLoops =3D 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 =3D 1; + Hr_Config->MaxDSNumber =3D 4; + Hr_Config->BridgeLoops =3D 6; + for(j =3D 2, i =3D Hr_Config->MinDSNumber; j < count(HrConfigs) && i= <=3D Hr_Config->MaxDSNumber; ++j, ++i) + { + HrConfigs[j].DevId.Bus =3D HrConfigs[HR_US_PORT].DevId.Bus + 1; + HrConfigs[j].DevId.Dev =3D i; + HrConfigs[j].DevId.Fun =3D 0; + HrConfigs[j].PBus =3D HrConfigs[j].DevId.Bus; + HrConfigs[j].Res.Cls =3D 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 =3D 0; i < count(HrConfigs); ++i) { + HrConfigs[i].IsDSBridge =3D TRUE; + } + // + // US(HRBus:0:0) + // + HrConfigs[HR_US_PORT].DevId.Bus =3D Hr_Config->HRBus; + HrConfigs[HR_US_PORT].DevId.Dev =3D 0; + HrConfigs[HR_US_PORT].DevId.Fun =3D 0; + HrConfigs[HR_US_PORT].Res =3D *HrResConf; + HrConfigs[HR_US_PORT].Res.IoBase =3D 0xF1; + HrConfigs[HR_US_PORT].Res.IoLimit =3D 0x01; + HrConfigs[HR_US_PORT].PBus =3D HrConfigs[HR_US_PORT].DevId.Bus; + HrConfigs[HR_US_PORT].SBus =3D HrConfigs[HR_US_PORT].PBus + 1; + HrConfigs[HR_US_PORT].SubBus =3D BusNumLimit; + HrConfigs[HR_US_PORT].IsDSBridge =3D FALSE; + + // + // HIA resides here + // + HrConfigs[HR_DS_PORT0].DevId.Bus =3D HrConfigs[HR_US_PORT].DevId.Bus = + 1; + HrConfigs[HR_DS_PORT0].DevId.Dev =3D 0; + HrConfigs[HR_DS_PORT0].DevId.Fun =3D 0; + HrConfigs[HR_DS_PORT0].Res =3D NOT_IN_USE_BRIDGE; + HrConfigs[HR_DS_PORT0].Res.MemBase =3D HrResConf->MemLimit; + HrConfigs[HR_DS_PORT0].Res.MemLimit =3D HrResConf->MemLimit; + HrResConf->MemLimit -=3D 0x10; //This 1 MB chunk will be = used by HIA + HrConfigs[HR_DS_PORT0].Res.Cmd =3D CMD_BM_MEM; + HrConfigs[HR_DS_PORT0].Res.Cls =3D DEF_CACHE_LINE_SIZE; + HrConfigs[HR_DS_PORT0].PBus =3D HrConfigs[HR_DS_PORT0].DevId.Bus= ; + HrConfigs[HR_DS_PORT0].SBus =3D HrConfigs[HR_DS_PORT0].PBus + 1; + HrConfigs[HR_DS_PORT0].SubBus =3D 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 =3D 3; + Hr_Config->MaxDSNumber =3D 6; + Hr_Config->BridgeLoops =3D count (HrConfigs); + + for (j =3D 2, i =3D Hr_Config->MinDSNumber; j < count (HrConfigs) && i= <=3D Hr_Config->MaxDSNumber; ++j, ++i) { + HrConfigs[j].DevId.Bus =3D HrConfigs[HR_US_PORT].DevId.Bus + 1; + HrConfigs[j].DevId.Dev =3D i; + HrConfigs[j].DevId.Fun =3D 0; + HrConfigs[j].PBus =3D HrConfigs[j].DevId.Bus; + HrConfigs[j].Res.Cls =3D DEF_CACHE_LINE_SIZE; + } + } +} // InitCommonHRConfigs + +STATIC +VOID +InitHRDSPort_Disable ( + IN UINT8 id, + IN OUT BRDG_CONFIG *BrdgConf + ) +{ + HrConfigs[id].Res =3D NOT_IN_USE_BRIDGE; + HrConfigs[id].SBus =3D BrdgConf->SBus; + HrConfigs[id].SubBus =3D BrdgConf->SBus; + + BrdgConf->SBus++; +} // InitHRDSPort_Disable + +//AR only + +STATIC +VOID +InitARDSPort_1Port( + IN OUT BRDG_CONFIG* BrdgConf +) +{ + UINT16 MemBase =3D BrdgConf->Res.MemBase & 0xFFF0; + UINT64 PMemBase64 =3D BrdgConf->Res.PMemBase64 & ~0xFULL; + UINT8 BusRange =3D BrdgConf->SubBus - BrdgConf->PBus - 2; + + HrConfigs[AR_DS_PORT1].Res =3D NOT_IN_USE_BRIDGE; + HrConfigs[AR_DS_PORT1].Res.Cls =3D DEF_CACHE_LINE_SIZE; + HrConfigs[AR_DS_PORT1].Res.Cmd =3D CMD_BM_MEM; + HrConfigs[AR_DS_PORT1].Res.MemBase =3D MemBase; + HrConfigs[AR_DS_PORT1].Res.MemLimit =3D BrdgConf->Res.MemLimit - 1; + HrConfigs[AR_DS_PORT1].Res.PMemBase64 =3D PMemBase64; + HrConfigs[AR_DS_PORT1].Res.PMemLimit64 =3D BrdgConf->Res.PMemLimit64; + HrConfigs[AR_DS_PORT1].SBus =3D BrdgConf->SBus; + HrConfigs[AR_DS_PORT1].SubBus =3D BrdgConf->SBus + BusRange; + + BrdgConf->SBus =3D HrConfigs[AR_DS_PORT1].SubBus + 1; + + HrConfigs[AR_DS_PORT2].Res =3D NOT_IN_USE_BRIDGE; + HrConfigs[AR_DS_PORT2].Res.Cls =3D DEF_CACHE_LINE_SIZE; + HrConfigs[AR_DS_PORT2].Res.Cmd =3D CMD_BM_MEM; + HrConfigs[AR_DS_PORT2].Res.MemBase =3D BrdgConf->Res.MemLimit; + HrConfigs[AR_DS_PORT2].Res.MemLimit =3D BrdgConf->Res.MemLimit; + HrConfigs[AR_DS_PORT2].SBus =3D BrdgConf->SBus; + HrConfigs[AR_DS_PORT2].SubBus =3D BrdgConf->SBus; + + BrdgConf->SBus =3D HrConfigs[AR_DS_PORT2].SubBus + 1; +}//InitARDSPort_1Port + +STATIC +VOID +InitARDSPort_2Port( + IN OUT BRDG_CONFIG* BrdgConf +) +{ + UINT16 MemBase =3D BrdgConf->Res.MemBase & 0xFFF0; + UINT64 PMemBase64 =3D BrdgConf->Res.PMemBase64 & ~0xFULL; + UINT8 BusRange =3D BrdgConf->SubBus - BrdgConf->PBus - 3; + + // Busses are split between ports 1 and 4 + BusRange /=3D 2; + + HrConfigs[AR_DS_PORT1].Res =3D NOT_IN_USE_BRIDGE; + HrConfigs[AR_DS_PORT1].Res.Cls =3D DEF_CACHE_LINE_SIZE; + HrConfigs[AR_DS_PORT1].Res.Cmd =3D CMD_BM_MEM; + HrConfigs[AR_DS_PORT1].Res.MemBase =3D MemBase; + HrConfigs[AR_DS_PORT1].Res.MemLimit =3D MemBase + 0x17F0 - 1; + HrConfigs[AR_DS_PORT1].Res.PMemBase64 =3D PMemBase64; + HrConfigs[AR_DS_PORT1].Res.PMemLimit64 =3D PMemBase64 + 0x2000 - 1; + HrConfigs[AR_DS_PORT1].SBus =3D BrdgConf->SBus; + HrConfigs[AR_DS_PORT1].SubBus =3D BrdgConf->SBus + BusRange; + + BrdgConf->SBus =3D HrConfigs[AR_DS_PORT1].SubBus + 1; + + HrConfigs[AR_DS_PORT2].Res =3D NOT_IN_USE_BRIDGE; + HrConfigs[AR_DS_PORT2].Res.Cls =3D DEF_CACHE_LINE_SIZE; + HrConfigs[AR_DS_PORT2].Res.Cmd =3D CMD_BM_MEM; + HrConfigs[AR_DS_PORT2].Res.MemBase =3D MemBase + 0x17F0; + HrConfigs[AR_DS_PORT2].Res.MemLimit =3D MemBase + 0x1800 - 1; + HrConfigs[AR_DS_PORT2].SBus =3D BrdgConf->SBus; + HrConfigs[AR_DS_PORT2].SubBus =3D BrdgConf->SBus; + + BrdgConf->SBus =3D HrConfigs[AR_DS_PORT2].SubBus + 1; + + + HrConfigs[AR_DS_PORT4].Res =3D NOT_IN_USE_BRIDGE; + HrConfigs[AR_DS_PORT4].Res.Cls =3D DEF_CACHE_LINE_SIZE; + HrConfigs[AR_DS_PORT4].Res.Cmd =3D CMD_BM_MEM; + HrConfigs[AR_DS_PORT4].Res.MemBase =3D MemBase + 0x1800; + HrConfigs[AR_DS_PORT4].Res.MemLimit =3D BrdgConf->Res.MemLimit; + HrConfigs[AR_DS_PORT4].Res.PMemBase64 =3D PMemBase64 + 0x2000; + HrConfigs[AR_DS_PORT4].Res.PMemLimit64 =3D BrdgConf->Res.PMemLimit64; + HrConfigs[AR_DS_PORT4].SBus =3D BrdgConf->SBus; + HrConfigs[AR_DS_PORT4].SubBus =3D BrdgConf->SubBus; + + BrdgConf->SBus =3D 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 =3D HrResConf->MemBase & 0xFFF0; + MemLimit =3D HrResConf->MemLimit & 0xFFF0; + PMemBase64 =3D HrResConf->PMemBase64 & 0xFFF0; + PMemLimit64 =3D 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 =3D { { 0 } }; + + InitCommonHRConfigs (Hr_Config, BusNumLimit, HrResConf); + BrdgConf.PBus =3D Hr_Config->HRBus + 2;// Take into account busses + BrdgConf.SBus =3D Hr_Config->HRBus + 3;// for US and DS of HIA + BrdgConf.SubBus =3D BusNumLimit; + BrdgConf.Res =3D *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 =3D { 0 }; + UINT8 i; + BOOLEAN Ret; + + Ret =3D TRUE; + + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, RpDe= vice, RpFunction, 0); + Hr_Config->HRBus =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE= _SECONDARY_BUS_REGISTER_OFFSET); + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (RpSegment, Hr_Config->= HRBus, 0x00, 0x00, 0); + Hr_Config->DeviceId =3D PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVIC= E_ID_OFFSET); + if (!(IsTbtHostRouter (Hr_Config->DeviceId))) { + return FALSE; + } + TbtSegment =3D (UINT8)RpSegment; + + HrResConf.Cmd =3D CMD_BM_MEM; + HrResConf.Cls =3D DEF_CACHE_LINE_SIZE; + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus, R= pDevice, RpFunction, 0); + HrResConf.IoBase =3D PciSegmentRead8 (gDeviceBaseAddress + OFFSET_= OF (PCI_TYPE01, Bridge.IoBase)); + HrResConf.IoLimit =3D PciSegmentRead8 (gDeviceBaseAddress + OFFSET_= OF (PCI_TYPE01, Bridge.IoLimit)); + HrResConf.MemBase =3D PciSegmentRead16 (gDeviceBaseAddress + OFFSET= _OF (PCI_TYPE01, Bridge.MemoryBase)); + HrResConf.MemLimit =3D PciSegmentRead16 (gDeviceBaseAddress + OFFSET= _OF (PCI_TYPE01, Bridge.MemoryLimit)); + HrResConf.PMemBase64 =3D PciSegmentRead16 (gDeviceBaseAddress + OFFSET= _OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)); + HrResConf.PMemLimit64 =3D PciSegmentRead16 (gDeviceBaseAddress + OFFSET= _OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)); + HrResConf.PMemBase64 |=3D (UINT64)(PciSegmentRead32 (gDeviceBaseAddress= + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16; + HrResConf.PMemLimit64 |=3D (UINT64)(PciSegmentRead32 (gDeviceBaseAddress= + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16; + BusNumLimit =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDI= NATE_BUS_REGISTER_OFFSET); + + Ret =3D InitHRResConfigs (Hr_Config, BusNumLimit, &HrResConf); + + for (i =3D 0; i < Hr_Config->BridgeLoops; ++i) { + UINT8 Bus; + UINT8 Dev; + UINT8 Fun; + Bus =3D HrConfigs[i].DevId.Bus; + Dev =3D HrConfigs[i].DevId.Dev; + Fun =3D HrConfigs[i].DevId.Fun; + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, F= un, 0); + + PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, HrCo= nfigs[i].Res.Cls); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER= _OFFSET, HrConfigs[i].PBus); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGIST= ER_OFFSET, HrConfigs[i].SBus); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGI= STER_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.I= oBase), HrConfigs[i].Res.IoBase); + PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.I= oLimit), 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 =3D=3D AR_HR_2C || Hr_Config->DeviceId =3D=3D AR= _HR_4C || Hr_Config->DeviceId =3D=3D AR_HR_LP) { + for (i =3D 0; i < Hr_Config->BridgeLoops; ++i) { + if(HrConfigs[i].IsDSBridge) { + UnsetVesc(HrConfigs[i].DevId.Bus, HrConfigs[i].DevId.Dev, HrConfig= s[i].DevId.Fun); + } + } + } + + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,(Hr_Config->H= RBus + 2), 0x00, 0x00, 0); + PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PC= I_BAR_IDX0 * 4), HrConfigs[HR_DS_PORT0].Res.MemLimit << 16); + PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFSET + (PC= I_BAR_IDX1 * 4), (HrConfigs[HR_DS_PORT0].Res.MemLimit + 0x4) << 16); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_CACHELINE_SIZE_OFFSET, DEF_CA= CHE_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 =3D 0; + + for (Device =3D 0; Device < MAX_DEVICE; Device++) { + // + // Continue if device is absent + // + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Devic= e, 0x00, 0); + if (0xFFFF =3D=3D PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID= _OFFSET)) { + continue; + + } + + if (P2P_BRIDGE !=3D PciSegmentRead16 (gDeviceBaseAddress + (PCI_CLASSC= ODE_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 =3D Bus + RetBusNum; // DS Bridge + + if (SBus + 1 >=3D 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_REGIST= ER_OFFSET, SBus); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGI= STER_OFFSET, PortInfo->BusNumLimit); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, CMD_BM_MEM)= ; + + if(ArPcie) { + UnsetVesc(Bus, Device, 0x00); + } + + UsedBusNumbers =3D ConfigureSlot(SBus, PCI_MAX_DEVICE + 1, -1, FALSE, Po= rtInfo); + RetBusNum +=3D UsedBusNumbers; + + SetPhyPortResources ( + Bus, + Device, + SBus + UsedBusNumbers, + Depth, + &CurrentSlot, + PortInfo + ); + } + // + // for (Device =3D 0; Device <=3D 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 =3D CMD_BUS_MASTER; + + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, 0x0= 0, 0); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_O= FFSET, Bus); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER= _OFFSET, SBus); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGIST= ER_OFFSET, SubBus); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, Cmd); + + if (PortInfo->IoBase <=3D PortInfo->IoLimit) { + PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.I= oBase), PortInfo->IoBase); + PciSegmentWrite8 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.I= oLimit), PortInfo->IoLimit); + PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.= IoBaseUpper16), 0x00000000); + Cmd |=3D CMD_BM_IO; + } else { + PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.= IoBase), DISBL_IO_REG1C); + } + + if (PortInfo->MemBase <=3D PortInfo->MemLimit) { + PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.= MemoryBase), PortInfo->MemBase); + PciSegmentWrite16 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.= MemoryLimit), PortInfo->MemLimit); + Cmd |=3D CMD_BM_MEM; + } else { + PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, Bridge.= MemoryBase), DISBL_MEM32_REG20); + } + + if (PortInfo->PMemBase64 <=3D 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 |=3D 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_CA= CHE_LINE_SIZE); +} // SetCioPortResources + +STATIC +VOID +SetSlotsAsUnused ( + IN UINT8 Bus, + IN UINT8 MaxSlotNum, + IN UINT8 CioSlot, + IN OUT PORT_INFO *PortInfo + ) +{ + UINT8 Slot; + for (Slot =3D MaxSlotNum; Slot > CioSlot; --Slot) { + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Slot, = 0x00, 0); + if (0xFFFF =3D=3D 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_REGIST= ER_OFFSET, PortInfo->BusNumLimit); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGI= STER_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_MAS= TER); + PortInfo->BusNumLimit--; + } +} // SetSlotsAsUnused + +STATIC +UINT16 +FindVendorSpecificHeader( + IN UINT8 Bus +) +{ + PCI_EXP_EXT_HDR *ExtHdr; + UINT32 ExtHdrValue; + UINT16 ExtendedRegister; + + ExtHdr =3D (PCI_EXP_EXT_HDR*) &ExtHdrValue; + ExtendedRegister =3D 0x100; + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x= 00, 0); + while (ExtendedRegister) { + ExtHdrValue =3D PciSegmentRead32 (gDeviceBaseAddress + ExtendedRegiste= r); + if (ExtHdr->CapabilityId =3D=3D 0xFFFF) { + return 0x0000; // No Vendor-Specific Extended Capability header + } + + if (PCI_EXPRESS_EXTENDED_CAPABILITY_VENDOR_SPECIFIC_ID =3D=3D ExtHdr->= CapabilityId) { + return ExtendedRegister; + } + + ExtendedRegister =3D (UINT16) ExtHdr->NextCapabilityOffset; + } + return 0x0000; // No Vendor-Specific Extended Capability header +} + +STATIC +UINT8 +FindSsid_SsvidHeader ( + IN UINT8 Bus + ) +{ + UINT8 CapHeaderId; + UINT8 CapHeaderOffset; + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x= 00, 0); + CapHeaderOffset =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_CAPBILIT= Y_POINTER_OFFSET); + + while (CapHeaderOffset !=3D 0) { + CapHeaderId =3D PciSegmentRead8 (gDeviceBaseAddress + CapHeaderOffset)= ; + + if (CapHeaderId =3D=3D PCIE_CAP_ID_SSID_SSVID) { + return CapHeaderOffset; + } + + CapHeaderOffset =3D PciSegmentRead8 (gDeviceBaseAddress + CapHeaderOff= set + 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 =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, 0x00, 0= x00, 0); + DevId =3D PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_= ID_OFFSET); + + // + // Init out params in case device is not recognised + // + *CioSlot =3D 4; + *MaxSlotNum =3D 7; + *ArPcie =3D FALSE; + + switch (DevId) { + // + // For known device IDs + // + case 0x1578: + *ArPcie =3D 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 =3D FindVendorSpecificHeader(Bus); + if (!VSECRegister) { + return TRUE; // Just return + } + // + // Go to Bridge/CIO map register + // + VSECRegister +=3D 0x18; + BridgMap.AB_REG =3D 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 =3D (UINT8) BridgMap.Bits.NumOfDSPorts; + +#ifdef _MSC_VER + if(!_BitScanForward(&BitScanRes, BridgMap.Bits.CioPortMap)) { // No DS b= ridge which is CIO port + return FALSE; + } +#else +#ifdef __GNUC__ + if (BridgMap.Bits.CioPortMap =3D=3D 0) { + return FALSE; + } + BitScanRes =3D __builtin_ctz (BridgMap.Bits.CioPortMap); +#else +#error Unsupported Compiler +#endif +#endif + + *CioSlot =3D (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 =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, 0x00, 0x= 00, 0); + DevId =3D 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 =3D %d\n",DevId)); + return TRUE; + // + // Legacy device by Device Id + // + } + + SidRegister =3D FindSsid_SsvidHeader(Bus); + + if (!SidRegister) { + return TRUE; // May be absent for legacy devices + } + // + // Go to register + // + SidRegister +=3D 0x4; + Sid =3D PciSegmentRead32(gDeviceBaseAddress + SidRegister); + DEBUG((DEBUG_INFO, "SID")); + DEBUG((DEBUG_INFO, " =3D %d\n", Sid)); + +return TBT_LEGACY_SUB_SYS_ID =3D=3D Sid || 0 =3D=3D Sid; +} // IsLegacyDevice + +STATIC +VOID +UnsetVescEp( + IN UINT8 Bus, + IN UINT8 MaxSlotNum + ) +{ + UINT8 i; + + for (i =3D 0; i <=3D 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 =3D 4; + MaxSlotNum =3D 7; + CopyMem (&PortInfoOrg, PortInfo, sizeof (PORT_INFO)); + + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, *Bus, 0x00, = 0x00, 0); + cmd =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_COMMAND_= OFFSET); + // AR ONLY + // Endpoint on CIO slot, but not a bridge device + if (P2P_BRIDGE !=3D PciSegmentRead16 (gDeviceBaseAddress + (PCI_CLASSCOD= E_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 sca= n + // + CioSlotPresent =3D GetCioSlotByDevId(*Bus, &CioSlot, &MaxSlotNum, &ArP= cie); + MaxPHYSlots =3D 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 =3D *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 =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,CioBus, Cio= Slot, 0x00, 0); + PortInfo->BusNumLimit =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_= BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET); + PortInfo->IoBase =3D PciSegmentRead8 (gDeviceBaseAddress + OFFS= ET_OF (PCI_TYPE01, Bridge.IoBase)); + PortInfo->IoLimit =3D PciSegmentRead8 (gDeviceBaseAddress + OFFS= ET_OF (PCI_TYPE01, Bridge.IoLimit)); + PortInfo->MemBase =3D PciSegmentRead16 (gDeviceBaseAddress + OFF= SET_OF (PCI_TYPE01, Bridge.MemoryBase)); + PortInfo->MemLimit =3D PciSegmentRead16 (gDeviceBaseAddress + OFF= SET_OF (PCI_TYPE01, Bridge.MemoryLimit)); + PortInfo->PMemBase64 =3D PciSegmentRead16 (gDeviceBaseAddress + OFF= SET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0; + PortInfo->PMemLimit64 =3D PciSegmentRead16 (gDeviceBaseAddress + OFF= SET_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0; + PortInfo->PMemBase64 |=3D (UINT64)(PciSegmentRead32 (gDeviceBaseAddr= ess + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16; + PortInfo->PMemLimit64 |=3D (UINT64)(PciSegmentRead32 (gDeviceBaseAddr= ess + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16; + PortInfo->PMemLimit64 |=3D 0xF; + // + // Jump to next EP + // + *Bus =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BU= S_REGISTER_OFFSET); + // + // Should we continue? + // + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus, 0x00,= 0x00, 0); + Continue =3D 0xFFFF !=3D PciSegmentRead16 (gDeviceBaseAddress= + PCI_DEVICE_ID_OFFSET); + return Continue; + } + // + // Set is legacy dvice + // + isLegacyDevice =3D IsLegacyDevice (*Bus); + + SetCioPortResources ( + *Bus, + 0, // Assign all available resources to US port of EP + *Bus + 1, + PortInfo->BusNumLimit, + 0, + PortInfo + ); + + SBus =3D *Bus + 1;// Jump to DS port + + if (CioSlotPresent) { + MaxPHYSlots =3D CioSlot; + } + + UsedBusNumbers =3D ConfigureSlot(SBus, MaxPHYSlots, Depth, ArPcie, PortI= nfo); + 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 =3D 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 =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,*Bus, 0x00, 0= x00, 0); + Continue =3D 0xFFFF !=3D 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 =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun= , 0); + PortInfo->BusNumLimit =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_BR= IDGE_SUBORDINATE_BUS_REGISTER_OFFSET); + PortInfo->IoBase =3D PciSegmentRead8 (gDeviceBaseAddress + OFFSET= _OF (PCI_TYPE01, Bridge.IoBase)) & 0xF0; + PortInfo->IoLimit =3D PciSegmentRead8 (gDeviceBaseAddress + OFFSET= _OF (PCI_TYPE01, Bridge.IoLimit)) & 0xF0; + PortInfo->MemBase =3D PciSegmentRead16 (gDeviceBaseAddress + OFFSE= T_OF (PCI_TYPE01, Bridge.MemoryBase)) & 0xFFF0; + PortInfo->MemLimit =3D PciSegmentRead16 (gDeviceBaseAddress + OFFSE= T_OF (PCI_TYPE01, Bridge.MemoryLimit)) & 0xFFF0; + PortInfo->PMemBase64 =3D PciSegmentRead16 (gDeviceBaseAddress + OFFSE= T_OF (PCI_TYPE01, Bridge.PrefetchableMemoryBase)) & 0xFFF0; + PortInfo->PMemLimit64 =3D PciSegmentRead16 (gDeviceBaseAddress + OFFSE= T_OF (PCI_TYPE01, Bridge.PrefetchableMemoryLimit)) & 0xFFF0; + PortInfo->PMemBase64 |=3D (UINT64)(PciSegmentRead32 (gDeviceBaseAddres= s + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableBaseUpper32))) << 16; + PortInfo->PMemLimit64 |=3D (UINT64)(PciSegmentRead32 (gDeviceBaseAddres= s + OFFSET_OF (PCI_TYPE01, Bridge.PrefetchableLimitUpper32))) << 16; + PortInfo->IoLimit |=3D 0xF; + PortInfo->MemLimit |=3D 0xF; + PortInfo->PMemLimit64 |=3D 0xF; +} // GetPortResources + +STATIC +VOID +ConfigurePort ( + IN UINT8 Bus, + IN UINT8 Dev, + IN UINT8 Fun, + IN OUT PORT_INFO *PortInfo + ) +{ + INT8 i; + UINT8 USBusNum; + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, Dev, Fun= , 0); + USBusNum =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE_S= ECONDARY_BUS_REGISTER_OFFSET); + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, USBusNum, 0x= 00, 0x00, 0); + if (0xFFFF =3D=3D PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVICE_ID_O= FFSET)) { + // + // Nothing to do if TBT device is not connected + // + return ; + } + + GetPortResources(Bus, Dev, Fun, PortInfo);// Take reserved resources fro= m DS port + // + // Assign resources to EPs + // + for (i =3D 0; i < MAX_TBT_DEPTH; ++i) { + PortInfo->ConfedEP++; + if (!ConfigureEP (i, &USBusNum, PortInfo)) { + return ; + } + } +} // ConfigurePort + +VOID +ThunderboltCallback ( + IN UINT8 Type + ) +{ + PORT_INFO PortInfoOrg =3D { 0 }; + HR_CONFIG HrConfig =3D { 0 }; + UINT8 i; + UINTN Segment =3D 0; + UINTN Bus =3D 0; + UINTN Device; + UINTN Function; + + DEBUG((DEBUG_INFO, "ThunderboltCallback.Entry\n")); + + DEBUG((DEBUG_INFO, "PortInfo Initialization\n")); + PortInfoInit (&PortInfoOrg); + if(Type =3D=3D DTBT_CONTROLLER) { + if (gCurrentDiscreteTbtRootPort =3D=3D 0) { + DEBUG((DEBUG_ERROR, "Invalid RP Input\n")); + return; + } + GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType, gCurrentDiscreteTbtRo= otPort - 1, &Device, &Function); + DEBUG((DEBUG_INFO, "InitializeHostRouter. \n")); + if (!InitializeHostRouter (&HrConfig, Segment, Bus, Device, Function))= { + return ; + } + // + // Configure DS ports + // + for (i =3D HrConfig.MinDSNumber; i <=3D 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 =3D MaxBus; Bus > MinBus; --Bus) { + for (Dev =3D 0; Dev <=3D PCI_MAX_DEVICE; ++Dev) { + for (Fun =3D 0; Fun <=3D PCI_MAX_FUNC; ++Fun) { + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, De= v, Fun, 0); + if (INVALID_PCI_DEVICE =3D=3D PciSegmentRead32 (gDeviceBaseAddress= + PCI_VENDOR_ID_OFFSET)) { + if (Fun =3D=3D 0) { + break; + + } + + continue; + } + + RegVal =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_HEADER_TYPE_O= FFSET); + if (HEADER_TYPE_DEVICE =3D=3D (RegVal & 1)) { + // + // ******** Disable PCI Device ******** + // BIT0 I/O Space Enabled BIT1 Memory Space Enabled + // BIT2 Bus Master Enabled BIT4 Memory Write and Invalidatio= n Enable + // + PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, (UINT8)= ~(BIT0 | BIT1 | BIT2 | BIT4)); + PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFS= ET + (PCI_BAR_IDX0 * 4), 0); + PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFS= ET + (PCI_BAR_IDX1 * 4), 0); + PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFS= ET + (PCI_BAR_IDX2 * 4), 0); + PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFS= ET + (PCI_BAR_IDX3 * 4), 0); + PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFS= ET + (PCI_BAR_IDX4 * 4), 0); + PciSegmentWrite32 (gDeviceBaseAddress + PCI_BASE_ADDRESSREG_OFFS= ET + (PCI_BAR_IDX5 * 4), 0); + } + } + } + } + // + // now no more PCI dev on another side of PCI Bridge can safty disable P= CI Bridge + // + for (Bus =3D MaxBus; Bus > MinBus; --Bus) { + for (Dev =3D 0; Dev <=3D PCI_MAX_DEVICE; ++Dev) { + for (Fun =3D 0; Fun <=3D PCI_MAX_FUNC; ++Fun) { + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment,Bus, De= v, Fun, 0); + if (INVALID_PCI_DEVICE =3D=3D PciSegmentRead32 (gDeviceBaseAddress= + PCI_VENDOR_ID_OFFSET)) { + if (Fun =3D=3D 0) { + break; + } + + continue; + } + + RegVal =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_HEADER_TYPE_O= FFSET); + if (HEADER_TYPE_PCI_TO_PCI_BRIDGE =3D=3D (RegVal & BIT0)) { + PciSegmentAnd8 (gDeviceBaseAddress + PCI_COMMAND_OFFSET, (UINT8)= ~(BIT0 | BIT1 | BIT2 | BIT4)); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_PRIMARY_BUS_RE= GISTER_OFFSET, 0); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BU= S_REGISTER_OFFSET, 0); + PciSegmentWrite8 (gDeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_= REGISTER_OFFSET, 0); + PciSegmentWrite32 (gDeviceBaseAddress + OFFSET_OF (PCI_TYPE01, B= ridge.PrefetchableBaseUpper32), 0); + } + } // for ( Fun .. ) + } // for ( Dev ... ) + } // for ( Bus ... ) +} // DisablePCIDevicesAndBridges + +VOID +TbtDisablePCIDevicesAndBridges ( + IN UINT8 Type + ) +{ + UINTN Segment =3D 0; + UINTN Bus =3D 0; + UINTN Device; + UINTN Function; + UINT8 MinBus; + UINT8 MaxBus; + UINT16 DeviceId; + + MinBus =3D 1; + if(Type =3D=3D DTBT_CONTROLLER) { + // + // for(Dev =3D 0; Dev < 8; ++Dev) + // { + // PciOr8(PCI_LIB_ADDRESS(2, Dev, 0, PCI_BRIDGE_CONTROL_REGISTER_OFFSE= T), 0x40); + // gBS->Stall(2000); // 2msec + // PciAnd8(PCI_LIB_ADDRESS(2, Dev, 0, PCI_BRIDGE_CONTROL_REGISTER_OFFS= ET), 0xBF); + // } + // gBS->Stall(200 * 1000); // 200 msec + // + if (gCurrentDiscreteTbtRootPort =3D=3D 0) { + DEBUG((DEBUG_ERROR, "Invalid RP Input\n")); + return; + } + GetDTbtRpDevFun(gCurrentDiscreteTbtRootPortType, gCurrentDiscreteTbtRo= otPort - 1, &Device, &Function); + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, = Function, 0); + MinBus =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE= _SECONDARY_BUS_REGISTER_OFFSET); + MaxBus =3D PciSegmentRead8 (gDeviceBaseAddress + PCI_BRIDGE= _SUBORDINATE_BUS_REGISTER_OFFSET); + gDeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (Segment, MinBus, 0x00,= 0x00, 0); + DeviceId =3D PciSegmentRead16 (gDeviceBaseAddress + PCI_DEVIC= E_ID_OFFSET); + if (!(IsTbtHostRouter (DeviceId))) { + return; + } + TbtSegment =3D (UINT8)Segment; + MinBus++; + // + // @todo : Move this out when we dont have Loop for ITBT + // + DisablePCIDevicesAndBridges(MinBus, MaxBus); + + } +} // DisablePCIDevicesAndBridges + + + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Sm= m/TbtSmm.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Sm= m/TbtSmm.c new file mode 100644 index 0000000000..721438c718 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/TbtInit/Smm/TbtSm= m.c @@ -0,0 +1,1765 @@ +/** @file + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// 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_CL= ASS_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 recom= mended maximum value for Snoop Latency can we put like this ? +#define LTR_MAX_NON_SNOOP_LATENCY_VALUE 0x0846 ///< Intel recom= mended maximum value for Non-Snoop Latency can we put like this ? + + +GLOBAL_REMOVE_IF_UNREFERENCED TBT_NVS_AREA *mTbtNvsAreaPtr; +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 gCurrentDiscrete= TbtRootPort; +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 gCurrentDiscrete= TbtRootPortType; +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 TbtLtrMaxSnoopLa= tency; +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 TbtLtrMaxNoSnoop= Latency; +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 gDTbtPcieRstSupp= ort; +GLOBAL_REMOVE_IF_UNREFERENCED TBT_INFO_HOB *gTbtInfoHob =3D= NULL; +STATIC UINTN mPciExpressBaseA= ddress; +STATIC UINT8 TbtSegment =3D 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 =3D Advanced Error Reporting Capability + 0x0002 =3D Virtual Channel Capability + 0x0003 =3D Device Serial Number Capability + 0x0004 =3D 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 =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, Functio= n, 0); + + /// + /// Start to search at Offset 0x100 + /// Get Capability Header, A pointer value of 00h is used to indicate th= e last capability in the list. + /// + CapHeaderId =3D 0; + CapHeaderOffset =3D 0x100; + while (CapHeaderOffset !=3D 0 && CapHeaderId !=3D 0xFFFF) { + CapHeaderId =3D PciSegmentRead16 (DeviceBase + CapHeaderOffset); + if (CapHeaderId =3D=3D CapId) { + return CapHeaderOffset; + } + /// + /// Each capability must be DWORD aligned. + /// The bottom two bits of all pointers are reserved and must be imple= mented as 00b + /// although software must mask them to allow for future uses of these= bits. + /// + CapHeaderOffset =3D (PciSegmentRead16 (DeviceBase + CapHeaderOffset + = 2) >> 4) & ((UINT16) ~(BIT0 | BIT1)); + } + + return 0; +} + +/** + Find the Offset to a given Capabilities ID + CAPID list: + 0x01 =3D PCI Power Management Interface + 0x04 =3D Slot Identification + 0x05 =3D MSI Capability + 0x10 =3D 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 =3D PCI_SEGMENT_LIB_ADDRESS (Segment, Bus, Device, Function, = 0); + + if ((PciSegmentRead8 (DeviceBase + PCI_PRIMARY_STATUS_OFFSET) & EFI_PCI_= STATUS_CAPABILITY) =3D=3D 0x00) { + /// + /// Function has no capability pointer + /// + return 0; + } + + /// + /// Check the header layout to determine the Offset of Capabilities Poin= ter Register + /// + if ((PciSegmentRead8 (DeviceBase + PCI_HEADER_TYPE_OFFSET) & HEADER_LAYO= UT_CODE) =3D=3D (HEADER_TYPE_CARDBUS_BRIDGE)) { + /// + /// If CardBus bridge, start at Offset 0x14 + /// + CapHeaderOffset =3D 0x14; + } else { + /// + /// Otherwise, start at Offset 0x34 + /// + CapHeaderOffset =3D 0x34; + } + /// + /// Get Capability Header, A pointer value of 00h is used to indicate th= e last capability in the list. + /// + CapHeaderId =3D 0; + CapHeaderOffset =3D PciSegmentRead8 (DeviceBase + CapHeaderOffset) & ((U= INT8) ~(BIT0 | BIT1)); + while (CapHeaderOffset !=3D 0 && CapHeaderId !=3D 0xFF) { + CapHeaderId =3D PciSegmentRead8 (DeviceBase + CapHeaderOffset); + if (CapHeaderId =3D=3D 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 =3D 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 ad= dress + @param[in] L1SubstateExtCapOffset Pointer to L1 Substate Capabilit= y 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_O= FFSET,(UINT32) ((PortTpowerOnValue << N_PCIE_EX_L1SCTL2_POWT) | PortTpowerO= nScale)); + + 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 =3D 0; + PortCommonModeRestoreTime =3D 0; + PortTpowerOnValue =3D 0; + PortTpowerOnScale =3D 0; + Data32 =3D 0; + + ComponentABaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev= , Fun, 0); + if (RootL1SubstateExtCapOffset !=3D 0) { + Data32 =3D PciSegmentRead32 (ComponentABaseAddress + RootL1SubstateExt= CapOffset + R_PCIE_EX_L1SCAP_OFFSET); + PortL1SubstateCapSupport =3D (Data32) & 0x0F; + PortCommonModeRestoreTime =3D (Data32 >> 8) & 0xFF; + PortTpowerOnScale =3D (Data32 >> 16) & 0x3; + PortTpowerOnValue =3D (Data32 >> 19) & 0x1F; + } else { + MaxL1Level =3D 0; // If L1 Substates from Root Port sid= e is disable, then Disable from Device side also. + } + + SecBus =3D PciSegmentRead8 (ComponentABaseAddress + PCI_B= RIDGE_SECONDARY_BUS_REGISTER_OFFSET); + ComponentBBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, SecBus, 0= , 0, 0); + + if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET) =3D= =3D 0xFFFF) { + ComponentBL1SubstateExtCapOffset =3D PcieFindExtendedCapId ( + SecBus, + 0, + 0, + V_PCIE_EX_L1S_CID + ); + if (ComponentBL1SubstateExtCapOffset !=3D 0) { + ComponentBL1Substates =3D PciSegmentRead32 (ComponentBBaseAddress + = ComponentBL1SubstateExtCapOffset + R_PCIE_EX_L1SCAP_OFFSET); + ComponentBCommonModeRestoreTime =3D (ComponentBL1Substates >> 8) & 0= xFF; + ComponentBTpowerOnScale =3D (ComponentBL1Substates >> 16) & = 0x3; + ComponentBTpowerOnValue =3D (ComponentBL1Substates >> 19) & = 0x1F; + + if (MaxL1Level =3D=3D 3) { + if (Data32 >=3D ComponentBL1Substates) { + if (~(Data32 | BIT2)) { + MaxL1Level =3D 1; + } + } + else { + if (~(ComponentBL1Substates | BIT2)) { + MaxL1Level =3D 1; + } + } + } + + if (MaxL1Level =3D=3D 3) { + ConfigureL1s ( + ComponentABaseAddress, + RootL1SubstateExtCapOffset, + PortL1SubstateCapSupport, + ComponentBCommonModeRestoreTime, + ComponentBTpowerOnValue, + ComponentBTpowerOnScale, + MaxL1Level + ); + + ConfigureL1s ( + ComponentBBaseAddress, + ComponentBL1SubstateExtCapOffset, + ComponentBL1Substates, + PortCommonModeRestoreTime, + PortTpowerOnValue, + PortTpowerOnScale, + MaxL1Level + ); + } + + if (MaxL1Level =3D=3D 1) { + PciSegmentOr32 ( + ComponentABaseAddress + RootL1SubstateExtCapOffset + R_PCIE_EX_L= 1SCTL1_OFFSET, + (UINT32) (BIT3 | BIT1) + ); + + PciSegmentOr32 ( + ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_PCI= E_EX_L1SCTL1_OFFSET, + (UINT32) (BIT3 | BIT1) + ); + } + else { + if (RootL1SubstateExtCapOffset !=3D 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 !=3D 0) { + PciSegmentOr32 ( + ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_P= CIE_EX_L1SCTL1_OFFSET, + (UINT32) (BIT3 | BIT1) + ); + + PciSegmentOr32 ( + ComponentBBaseAddress + ComponentBL1SubstateExtCapOffset + R_P= CIE_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 =3D 3; // L0s and L1 Supported + for (Fun =3D 0; Fun <=3D PCI_MAX_FUNC; ++Fun) { + // + // Check for Device availability + // + DeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, F= un, 0); + if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) =3D=3D= 0xFFFF) { + // Device not present + continue; + } + + CapHeaderOffset =3D PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10); + + AspmVal =3D (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0= x00C) >> 10) & 3; + if (LowerAspm > AspmVal) { + LowerAspm =3D AspmVal; + } + } //Fun + + for (Fun =3D 0; Fun <=3D PCI_MAX_FUNC; ++Fun) { + // + // Check for Device availability + // + DeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, F= un, 0); + if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) =3D=3D= 0xFFFF) { + // + // Device not present + // + continue; + } + + CapHeaderOffset =3D PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10); + + PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xF= FFC, LowerAspm); + } //Fun +} + +UINT16 +LimitAspmLevel ( + IN UINT16 SelectedAspm, + IN UINT16 MaxAspmLevel + ) +{ + SelectedAspm =3D SelectedAspm & MaxAspmLevel; + + return SelectedAspm; +} + +UINT16 +FindOptimalAspm ( + IN UINT16 ComponentAaspm, + IN UINT16 ComponentBaspm + ) +{ + UINT16 SelectedAspm; + + SelectedAspm =3D 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 =3D 0; + AspmFound =3D FALSE; + + for (BusNo =3D MaxBus; (BusNo !=3D 0xFF) && (!AspmFound); --BusNo) { + for (DevNo =3D 0; (DevNo <=3D PCI_MAX_DEVICE) && (!AspmFound); ++DevNo= ) { + for (FunNo =3D 0; (FunNo <=3D PCI_MAX_FUNC) && (!AspmFound); ++FunNo= ) { + // + // Check for Device availability + // + DevBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, BusNo, Dev= No, FunNo, 0); + if (PciSegmentRead16 (DevBaseAddress + PCI_DEVICE_ID_OFFSET) =3D= =3D 0xFFFF) { + // + // Device not present + // + continue; + } + + RegVal =3D PciSegmentRead8 (DevBaseAddress + PCI_HEADER_TYPE_OFFSE= T); + if ((RegVal & (BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6)) != =3D 0x01) { + // + // Not a PCI-to-PCI bridges device + // + continue; + } + + SecBusNo =3D PciSegmentRead8 (DevBaseAddress + PCI_BRIDGE_SECONDAR= Y_BUS_REGISTER_OFFSET); + + if (SecBusNo =3D=3D Bus) { + // + // This is the Rootbridge for the given 'Bus' device + // + CapHeaderOffset_B =3D PcieFindCapId (TbtSegment, BusNo, DevNo, F= unNo, 0x10); + SelectedAspm =3D (PciSegmentRead16 (DevBaseAddress + CapHea= derOffset_B + 0x00C) >> 10) & 3; + AspmFound =3D TRUE; + } + } //FunNo + } //DevNo + } //BusNo + + return (SelectedAspm); +} + +VOID +NoAspmSupport ( + IN UINT8 Bus, + IN UINT8 Dev, + IN UINT8 Fun, + IN UINT8 CapHeaderOffset + ) +{ + UINT64 DeviceBaseAddress; + + DeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun= , 0); + PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFF= C, 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 =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun= , 0); + ComponentAaspm =3D (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOf= fset + 0x00C) >> 10) & 3; + ComponentBaspm =3D FindComponentBaspm (Bus, MaxBus); + SelectedAspm =3D FindOptimalAspm (ComponentAaspm, ComponentBaspm); + SelectedAspm =3D LimitAspmLevel (SelectedAspm, MaxAspmLevel); + PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFF= C, 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 =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun= , 0); + ComponentAaspm =3D (PciSegmentRead16 (DeviceBaseAddress + CapHeaderOf= fset + 0x00C) >> 10) & 3; + ComponentBaspm =3D FindComponentBaspm (Bus, MaxBus); + SelectedAspm =3D FindOptimalAspm (ComponentAaspm, ComponentBaspm); + SelectedAspm =3D LimitAspmLevel (SelectedAspm, MaxAspmLevel); + PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10, 0xFFF= C, 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 =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,= Fun, 0); + ComponentAaspm =3D (PciSegmentRead16 (ComponentABaseAddress + Cap= HeaderOffset + 0x00C) >> 10) & 3; + + SecBus =3D PciSegmentRead8 (ComponentABaseAddress + PCI_B= RIDGE_SECONDARY_BUS_REGISTER_OFFSET); + ComponentBBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, SecBus, 0= , 0, 0); + ComponentBaspm =3D 0; // No ASPM Support + if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET) !=3D= 0xFFFF) { + CapHeaderOffset_B =3D PcieFindCapId (TbtSegment, SecBus, 0, 0, 0x10); + ComponentBaspm =3D (PciSegmentRead16 (ComponentBBaseAddress + CapHe= aderOffset_B + 0x00C) >> 10) & 3; + } + + SelectedAspm =3D FindOptimalAspm (ComponentAaspm, ComponentBaspm); + SelectedAspm =3D LimitAspmLevel (SelectedAspm, MaxAspmLevel); + PciSegmentAndThenOr16 (ComponentABaseAddress + CapHeaderOffset + 0x10, 0= xFFFC, 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 =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,= Fun, 0); + ComponentAaspm =3D (PciSegmentRead16 (ComponentABaseAddress + Cap= HeaderOffset + 0x00C) >> 10) & 3; + + SecBus =3D PciSegmentRead8 (ComponentABaseAddress + PCI_B= RIDGE_SECONDARY_BUS_REGISTER_OFFSET); + ComponentBBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, SecBus, 0= , 0, 0); + ComponentBaspm =3D 0; // No ASPM Support + if (PciSegmentRead16 (ComponentBBaseAddress + PCI_DEVICE_ID_OFFSET) !=3D= 0xFFFF) { + CapHeaderOffset_B =3D PcieFindCapId (TbtSegment, SecBus, 0, 0, 0x10); + ComponentBaspm =3D (PciSegmentRead16 (ComponentBBaseAddress + CapHe= aderOffset_B + 0x00C) >> 10) & 3; + } + + SelectedAspm =3D FindOptimalAspm (ComponentAaspm, ComponentBaspm); + SelectedAspm =3D LimitAspmLevel (SelectedAspm, MaxAspmLevel); + PciSegmentAndThenOr16 (ComponentABaseAddress + CapHeaderOffset + 0x10, 0= xFFFC, 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 =3D 0; + MaxBus =3D 0; + + MinBus =3D PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus= , RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET)); + MaxBus =3D PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus= , RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET)); + DeviceId =3D PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinB= us, 0x00, 0x00, PCI_DEVICE_ID_OFFSET)); + if (!(IsTbtHostRouter (DeviceId))) { + return; + } + + TbtSegment =3D (UINT8)RpSegment; + + RootBus =3D (UINT8)RpBus; + RootDev =3D (UINT8)RpDevice; + RootFun =3D (UINT8)RpFunction; + + // + // Enumerate all the bridges and devices which are available on TBT hos= t controller + // + for (Bus =3D MinBus; Bus <=3D MaxBus; ++Bus) { + for (Dev =3D 0; Dev <=3D PCI_MAX_DEVICE; ++Dev) { + // + // Check for Device availability + // + DeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev,= 0, 0); + if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) =3D= =3D 0xFFFF) { + // + // Device not present + // + continue; + } + + RegVal =3D PciSegmentRead8 (DeviceBaseAddress + PCI_HEADER_TYPE_OFFS= ET); + if ((RegVal & BIT7) =3D=3D 0) { + // + // Not a multi-function device + // + continue; + } + + MultiFunctionDeviceAspm(Bus, Dev); + } //Dev + } //Bus + + + for (Bus =3D MinBus; Bus <=3D MaxBus; ++Bus) { + for (Dev =3D 0; Dev <=3D PCI_MAX_DEVICE; ++Dev) { + for (Fun =3D 0; Fun <=3D PCI_MAX_FUNC; ++Fun) { + // + // Check for Device availability + // + DeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, De= v, Fun, 0); + if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) = =3D=3D 0xFFFF) { + // + // Device not present + // + continue; + } + + CapHeaderOffset =3D PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10= ); + DevicePortType =3D (PciSegmentRead16 (DeviceBaseAddress + CapHead= erOffset + 0x002) >> 4) & 0xF; + if(PciSegmentRead8 (DeviceBaseAddress + PCI_CLASSCODE_OFFSET) =3D= =3D PCI_CLASS_SERIAL) { + MaxAspmLevel =3D (UINT16) 0x1; + } + + switch (DevicePortType) { + case 0: + // + // PCI Express Endpoint + // + EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, Max= AspmLevel); + break; + + case 1: + // + // Legacy PCI Express Endpoint + // + EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, Max= AspmLevel); + break; + + case 4: + // + // Root Port of PCI Express Root Complex + // + RootportAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxAspmLeve= l); + break; + + case 5: + // + // Upstream Port of PCI Express Switch + // + UpstreamAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, Max= AspmLevel); + break; + + case 6: + // + // Downstream Port of PCI Express Switch + // + DownstreamAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxAspmLe= vel); + 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, Max= AspmLevel); + break; + + case 10: + // + // Root Complex Event Collector + // + EndpointAspmSupport (Bus, Dev, Fun, CapHeaderOffset, MaxBus, Max= AspmLevel); + break; + + default: + break; + } + // + // switch(DevicePortType) + // + } + // + // Fun + // + } + // + // Dev + // + } + // + // Bus + // + CapHeaderOffset =3D PcieFindCapId (TbtSegment, RootBus, RootDev, RootFun= , 0x10); + RootportAspmSupport (RootBus, RootDev, RootFun, CapHeaderOffset, MaxAspm= Level); +} + + + +VOID +ThunderboltEnableL1Sub ( + IN UINT16 MaxL1Level, + IN UINTN RpSegment, + IN UINTN RpBus, + IN UINTN RpDevice, + IN UINTN RpFunction + ) +{ + UINT16 CapHeaderOffsetExtd; + + RpBus =3D 0; + + CapHeaderOffsetExtd =3D PcieFindExtendedCapId ((UINT8) RpBus, (UINT8) Rp= Device, (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 =3D 0; + MaxBus =3D 0; + + MinBus =3D PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus= , RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET)); + MaxBus =3D PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus= , RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET)); + DeviceId =3D PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinB= us, 0x00, 0x00, PCI_DEVICE_ID_OFFSET)); + if (!(IsTbtHostRouter (DeviceId))) { + return; + } + + TbtSegment =3D (UINT8)RpSegment; + RootBus =3D (UINT8)RpBus; + RootDev =3D (UINT8)RpDevice; + RootFun =3D (UINT8)RpFunction; + + // + // Enumerate all the bridges and devices which are available on TBT hos= t controller + // + for (Bus =3D MinBus; Bus <=3D MaxBus; ++Bus) { + for (Dev =3D 0; Dev <=3D PCI_MAX_DEVICE; ++Dev) { + for (Fun =3D 0; Fun <=3D PCI_MAX_FUNC; ++Fun) { + // + // Check for Device availability + // + DeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, De= v, Fun, 0); + if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) = =3D=3D 0xFFFF) { + // + // Device not present + // + continue; + } + + CapHeaderOffset =3D PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0x10= ); + PciSegmentAndThenOr16 (DeviceBaseAddress + CapHeaderOffset + 0x10,= 0xFFFC, 0x00); + } //Fun + } //Dev + } //Bus + + CapHeaderOffset =3D 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 =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, = Function, 0); + CapHeaderOffset =3D PcieFindCapId (TbtSegment, Bus, Device, Function, = 0x10); + + // + // Check if CLKREQ# is supported + // + if ((PciSegmentRead32 (DeviceBaseAddress + CapHeaderOffset + 0x0C) & BIT= 18) !=3D 0) { + Data16 =3D PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x0= 10); + + if (ClkReqSetup) { + Data16 =3D Data16 | BIT8; // Enable Clock Power Management + } else { + Data16 =3D Data16 & (UINT16)(~BIT8); // Disable Clock Power Managem= ent + } + + 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 =3D PCI_SEGMENT_LIB_ADDRESS(TbtSegment, Bus, Device, = Function, 0); + CapHeaderOffset =3D PcieFindExtendedCapId(Bus, Device, Function, 0x001F= /*V_PCIE_EX_PTM_CID*/); + if(CapHeaderOffset !=3D 0) { + PtmCapabilityRegister =3D PciSegmentRead16(DeviceBaseAddress + CapHe= aderOffset + 0x04); + // + // Check if PTM Requester/ Responder capability for the EP/Down strea= m etc + // + if ((PtmCapabilityRegister & (BIT1 | BIT0)) !=3D 0) { + PtmControlRegister =3D PciSegmentRead16(DeviceBaseAddress + CapHea= derOffset + 0x08); + + if (PtmSetup) { + PtmControlRegister =3D PtmControlRegister | BIT0; // Enable PTM + if(IsRoot) { + PtmControlRegister =3D PtmControlRegister | BIT1; // Enable P= TM + } + PtmControlRegister =3D PtmControlRegister | (PtmCapabilityRegis= ter & 0xFF00); // Programm Local Clock Granularity + } else { + PtmControlRegister =3D PtmControlRegister & (UINT16)(~(BIT0 | B= IT1)); // Disable Clock Power Management + } + + PciSegmentWrite16(DeviceBaseAddress + CapHeaderOffset + 0x08, PtmC= ontrolRegister); + } + } +} + +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 =3D 0; + MaxBus =3D 0; + + if ((Configuration !=3D 1) && (Configuration !=3D 2)) { + return; + } + MinBus =3D PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus= , RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET)); + MaxBus =3D PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus= , RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET)); + DeviceId =3D PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinB= us, 0x00, 0x00, PCI_DEVICE_ID_OFFSET)); + if (!(IsTbtHostRouter (DeviceId))) { + return; + } + + TbtSegment =3D (UINT8)RpSegment; + // + // Enumerate all the bridges and devices which are available on TBT hos= t controller + // + for (Bus =3D MaxBus; Bus >=3D MinBus; --Bus) { + for (Dev =3D 0; Dev <=3D PCI_MAX_DEVICE; ++Dev) { + for (Fun =3D 0; Fun <=3D PCI_MAX_FUNC; ++Fun) { + // + // Check for Device availability + // + DeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, De= v, Fun, 0); + if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) = =3D=3D 0xFFFF) { + if (Fun =3D=3D 0) { + // + // IF Fun is zero, stop enumerating other functions of the par= ticular bridge + // + break; + } + // + // otherwise, just skip checking for CLKREQ support + // + continue; + } + switch (Configuration) { + case 1: + TbtProgramClkReq (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtSe= tClkReq); + break; + case 2: + TbtProgramPtm (Bus, Dev, Fun, (UINT8) mTbtNvsAreaPtr->TbtPtm, = FALSE); + TbtProgramPtm((UINT8) RpBus, (UINT8) RpDevice, (UINT8) RpFunct= ion, (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 =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Device, = Function, 0); + CapHeaderOffset =3D PcieFindCapId (TbtSegment, Bus, Device, Function, = 0x10); + + // + // Check if LTR# is supported + // + if ((PciSegmentRead32 (DeviceBaseAddress + CapHeaderOffset + 0x24) & BIT= 11) !=3D 0) { + Data16 =3D PciSegmentRead16 (DeviceBaseAddress + CapHeaderOffset + 0x0= 28); + + if (LtrSetup) { + Data16 =3D Data16 | BIT10; // LTR Mechanism Enable + } else { + Data16 =3D 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 =3D 0; + MaxBus =3D 0; + + MinBus =3D PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus= , RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET)); + MaxBus =3D PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus= , RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET)); + DeviceId =3D PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinB= us, 0x00, 0x00, PCI_DEVICE_ID_OFFSET)); + if (!(IsTbtHostRouter (DeviceId))) { + return; + } + + TbtSegment =3D (UINT8)RpSegment; + // + // Enumerate all the bridges and devices which are available on TBT hos= t controller + // + for (Bus =3D MinBus; Bus <=3D MaxBus; ++Bus) { + for (Dev =3D 0; Dev <=3D PCI_MAX_DEVICE; ++Dev) { + for (Fun =3D 0; Fun <=3D PCI_MAX_FUNC; ++Fun) { + // + // Check for Device availability + // + DeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, De= v, Fun, 0); + if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) = =3D=3D 0xFFFF) { + if (Fun =3D=3D 0) { + // + // IF Fun is zero, stop enumerating other functions of the par= ticular 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, (UIN= T8) mTbtNvsAreaPtr->TbtLtr); +} + +/* + US ports and endpoints which declare support must also have the LTR capa= bility structure (cap ID 18h). + In this structure you need to enter the max snoop latency and max non-sn= oop 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 f= rom the platform architect or whatever. +*/ +VOID +ThunderboltGetLatencyLtr ( + VOID + ) +{ + PCH_SERIES PchSeries; + + PchSeries =3D GetPchSeries (); + + if(gCurrentDiscreteTbtRootPortType =3D=3D DTBT_TYPE_PEG) { + // PEG selector + TbtLtrMaxSnoopLatency =3D LTR_MAX_SNOOP_LATENCY_VALUE; + TbtLtrMaxNoSnoopLatency =3D LTR_MAX_NON_SNOOP_LATENCY_VALUE; + } else if (gCurrentDiscreteTbtRootPortType =3D=3D DTBT_TYPE_PCH) { + // PCH selector + + if (PchSeries =3D=3D PchLp) { + TbtLtrMaxSnoopLatency =3D 0x1003; + TbtLtrMaxNoSnoopLatency =3D 0x1003; + } + if (PchSeries =3D=3D PchH) { + TbtLtrMaxSnoopLatency =3D 0x0846; + TbtLtrMaxNoSnoopLatency =3D 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 =3D=3D 0) { + return; + } + DeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, Dev, Fun= , 0); + PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffsetExtd + 0x004, LtrM= axSnoopLatency); + PciSegmentWrite16 (DeviceBaseAddress + CapHeaderOffsetExtd + 0x006, LtrM= axNoSnoopLatency); +} + +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 =3D 0; + MaxBus =3D 0; + + MinBus =3D PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus= , RpDevice, RpFunction, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET)); + MaxBus =3D PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, RpBus= , RpDevice, RpFunction, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET)); + DeviceId =3D PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (RpSegment, MinB= us, 0x00, 0x00, PCI_DEVICE_ID_OFFSET)); + if (!(IsTbtHostRouter (DeviceId))) { + return; + } + + TbtSegment =3D (UINT8)RpSegment; + + for (Bus =3D MinBus; Bus <=3D MaxBus; ++Bus) { + for (Dev =3D 0; Dev <=3D PCI_MAX_DEVICE; ++Dev) { + for (Fun =3D 0; Fun <=3D PCI_MAX_FUNC; ++Fun) { + // + // Check for Device availability + // + DeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Bus, De= v, Fun, 0); + if (PciSegmentRead16 (DeviceBaseAddress + PCI_DEVICE_ID_OFFSET) = =3D=3D 0xFFFF) { + // + // Device not present + // + continue; + } + + CapHeaderOffsetStd =3D PcieFindCapId (TbtSegment, Bus, Dev, Fun, 0= x10); + DevicePortType =3D (PciSegmentRead16 (DeviceBaseAddress + CapHead= erOffsetStd + 0x002) >> 4) & 0xF; + + CapHeaderOffsetExtd =3D PcieFindExtendedCapId (Bus, Dev, Fun, 0x00= 18); + + switch (DevicePortType) { + case 0: + // + // PCI Express Endpoint + // + SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd, TbtLtrMaxSnoo= pLatency, TbtLtrMaxNoSnoopLatency); + break; + + case 1: + // + // Legacy PCI Express Endpoint + // + SetLatencyLtr (Bus, Dev, Fun, CapHeaderOffsetExtd, TbtLtrMaxSnoo= pLatency, 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, TbtLtrMaxSnoo= pLatency, 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 =3D (UINTN) ((Usec * 10) / 3); + // + // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter ti= ck + // periods, thus attempting to ensure Microseconds of stall time. + // + if (Counter !=3D 0) { + + PrevData =3D IoRead32 (PcdGet16 (PcdAcpiBaseAddress) + R_PCH_ACPI_PM1_= TMR); + for (Index =3D 0; Index < Counter;) { + Data32 =3D IoRead32 (PcdGet16 (PcdAcpiBaseAddress) + R_PCH_ACPI_PM1_= TMR); + if (Data32 < PrevData) { + // + // Reset if there is a overlap + // + PrevData =3D Data32; + continue; + } + + Index +=3D (Data32 - PrevData); + PrevData =3D 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 h= andler by SmiHandlerRegister(). + @param[in] DispatchContext - Points to an optional handler contex= t 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 environme= nt into an SMM environment. + @param[in, out] CommBufferSize - The size of the CommBuffer. + + @retval EFI_SUCCESS - The interrupt was handled successful= ly. +**/ +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 =3D 0; + HoustRouteBus =3D 3; + SecSubBusAssigned =3D FALSE; + Timeout =3D 600; + RootportSelected =3D 0; + TbtCioPlugEventGpioNo =3D 0; + TbtFrcPwrGpioNo =3D 0; + TbtFrcPwrGpioLevel =3D 0; + TbtPcieRstGpioNo =3D 0; + TbtPcieRstGpioLevel =3D 0; + Index =3D 0; + + EntryDispatchContext =3D (EFI_SMM_SX_REGISTER_CONTEXT*) DispatchContext; + +// CableConnected =3D GetTbtHostRouterStatus (); + //SaveTbtHostRouterStatus (CableConnected & 0xF0); + // + // Get the Power State and Save + // + if (((mTbtNvsAreaPtr->DTbtControllerEn0 =3D=3D 0) && (Index =3D=3D 0))) = { + + RootportSelected =3D mTbtNvsAreaPtr->RootportSelected0; + TbtCioPlugEventGpioNo =3D mTbtNvsAreaPtr->TbtCioPlugEventGpioNo0; + TbtFrcPwrGpioNo =3D mTbtNvsAreaPtr->TbtFrcPwrGpioNo0; + TbtFrcPwrGpioLevel =3D mTbtNvsAreaPtr->TbtFrcPwrGpioLevel0; + TbtPcieRstGpioNo =3D mTbtNvsAreaPtr->TbtPcieRstGpioNo0; + TbtPcieRstGpioLevel =3D mTbtNvsAreaPtr->TbtPcieRstGpioLevel0; + } + + Status =3D GetDTbtRpDevFun (gCurrentDiscreteTbtRootPortType, RootportSel= ected - 1, &RpDev, &RpFunc); + ASSERT_EFI_ERROR (Status); + CapHeaderOffset =3D PcieFindCapId (TbtSegment, 0x00, (UINT8)RpDev, (UINT= 8)RpFunc, 0x01); + DeviceBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS (TbtSegment, 0x00, (UINT32= )RpDev, (UINT32)RpFunc, 0); + PowerState =3D &*((volatile UINT32 *) (mPciExpressBaseAddress + D= eviceBaseAddress + CapHeaderOffset + 4)); //PMCSR + PowerStatePrev =3D *PowerState; + *PowerState &=3D 0xFFFFFFFC; + + HoustRouteBus =3D PciSegmentRead8 (DeviceBaseAddress + PCI_BRIDGE_SECOND= ARY_BUS_REGISTER_OFFSET); + // + // Check the Subordinate bus .If it is Zero ,assign temporary bus to + // find the device presence . + // + if (HoustRouteBus =3D=3D 0) { + PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTE= R_OFFSET, 0xF0); + PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGIS= TER_OFFSET, 0xF0); + HoustRouteBus =3D 0xF0; + SecSubBusAssigned =3D 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 GPI= O Programming. + // + GpioSetPadInterruptConfig (TbtCioPlugEventGpioNo, GpioIntDis); + // + // Read the TBT Host router DeviceID + // + DeviceId =3D PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (TbtSegment, Hous= tRouteBus, 0, 0, PCI_DEVICE_ID_OFFSET)); + + // + // Check For HostRouter Presence + // + if (IsTbtHostRouter (DeviceId)) { + // CableConnected =3D GetTbtHostRouterStatus (); + if (!((CableConnected & (DTBT_SAVE_STATE_OFFSET << Index)) =3D=3D (DTB= T_SAVE_STATE_OFFSET << Index))) { + CableConnected =3D CableConnected | (DTBT_SAVE_STATE_OFFSET << Index= ); + // SaveTbtHostRouterStatus (CableConnected); + } + } + + // + // Check value of Tbt2Pcie reg, if Tbt is not present, bios needs to app= ly force power prior to sending mailbox command + // + GET_TBT2PCIE_REGISTER_ADDRESS(TbtSegment, HoustRouteBus, 0x00, 0x00, Tbt= 2Pcie) + RegisterValue =3D PciSegmentRead32 (Tbt2Pcie); + if (0xFFFFFFFF =3D=3D RegisterValue) { + + GpioWrite (TbtFrcPwrGpioNo,TbtFrcPwrGpioLevel); + + while (Timeout -- > 0) { + RegisterValue =3D PciSegmentRead32 (Tbt2Pcie); + if (0xFFFFFFFF !=3D 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 c= ycle. + // + + if( (EntryDispatchContext->Type =3D=3D SxS3) || (EntryDispatchContext-= >Type =3D=3D 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 =3D=3D 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 c= ycle. + // + if( (EntryDispatchContext->Type =3D=3D SxS3) || (EntryDispatchContext-= >Type =3D=3D 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 =3D PowerStatePrev; + // + // Restore the bus number in case we assigned temporarily + // + if (SecSubBusAssigned) { + PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTE= R_OFFSET, 0x00); + PciSegmentWrite8 (DeviceBaseAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGIS= TER_OFFSET, 0x00); + } + if (gDTbtPcieRstSupport) { + GpioWrite (TbtPcieRstGpioNo,TbtPcieRstGpioLevel); + } + return EFI_SUCCESS; +} + +VOID +ThunderboltSwSmiCallback ( + IN UINT8 Type + ) +{ + UINT8 ThunderboltSmiFunction; + + DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback Entry\n")); + ThunderboltSmiFunction =3D mTbtNvsAreaPtr->ThunderboltSmiFunction; + DEBUG ((DEBUG_INFO, "ThunderboltSwSmiCallback. ThunderboltSmiFunction=3D= %d\n", ThunderboltSmiFunction)); + if (Type =3D=3D DTBT_CONTROLLER) { + gCurrentDiscreteTbtRootPort =3D mTbtNvsAreaPtr->CurrentDiscreteTbt= RootPort; + gCurrentDiscreteTbtRootPortType =3D mTbtNvsAreaPtr->CurrentDiscreteTbt= RootPortType; + } + + 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 =3D EFI_UNSUPPORTED; + + if(Type =3D=3D DTBT_CONTROLLER) { + SxHandler =3D SxDTbtEntryCallback; + SwHandler =3D DiscreteThunderboltSwSmiCallback; + SmiInputValue =3D PcdGet8 (PcdSwSmiDTbtEnumerate); + gDTbtPcieRstSupport =3D gTbtInfoHob->DTbtCommonConfig.PcieRstSupport; + Status =3D EFI_SUCCESS; + } + if (EFI_ERROR (Status)) { + return Status; + } + + SwDispatchHandle =3D NULL; + S3DispatchHandle =3D NULL; + S4DispatchHandle =3D NULL; + S5DispatchHandle =3D NULL; + + Status =3D gSmst->SmmLocateProtocol ( + &gEfiSmmSxDispatch2ProtocolGuid, + NULL, + (VOID **) &SxDispatchProtocol + ); + ASSERT_EFI_ERROR (Status); + // + // Register S3 entry phase call back function + // + EntryDispatchContext.Type =3D SxS3; + EntryDispatchContext.Phase =3D SxEntry; + Status =3D SxDispatchProtocol->Register ( + SxDispatchProtocol, + SxHandler, + &EntryDispatchContext, + &S3DispatchHandle + ); + ASSERT_EFI_ERROR (Status); + // + // Register S4 entry phase call back function + // + EntryDispatchContext.Type =3D SxS4; + EntryDispatchContext.Phase =3D SxEntry; + Status =3D SxDispatchProtocol->Register ( + SxDispatchProtocol, + SxHandler, + &EntryDispatchContext, + &S4DispatchHandle + ); + ASSERT_EFI_ERROR (Status); + // + // Register S5 entry phase call back function + // + EntryDispatchContext.Type =3D SxS5; + EntryDispatchContext.Phase =3D SxEntry; + Status =3D SxDispatchProtocol->Register ( + SxDispatchProtocol, + SxHandler, + &EntryDispatchContext, + &S5DispatchHandle + ); + ASSERT_EFI_ERROR (Status); + // + // Locate the SMM SW dispatch protocol + // + Status =3D gSmst->SmmLocateProtocol ( + &gEfiSmmSwDispatch2ProtocolGuid, + NULL, + (VOID **) &SwDispatch + ); + + ASSERT_EFI_ERROR (Status); + // + // Register SWSMI handler + // + SwContext.SwSmiInputValue =3D SmiInputValue; + Status =3D 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 =3D EFI_SUCCESS; + + Status =3D 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 =3D PcdGet64 (PcdPciExpressBaseAddress); + // + // Locate Tbt shared data area + // + Status =3D gBS->LocateProtocol (&gTbtNvsAreaProtocolGuid, NULL, (VOID **= ) &TbtNvsAreaProtocol); + ASSERT_EFI_ERROR (Status); + mTbtNvsAreaPtr =3D TbtNvsAreaProtocol->Area; + + // + // Get TBT INFO HOB + // + gTbtInfoHob =3D (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid); + if (gTbtInfoHob =3D=3D 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 !=3D 0) { + ThunderboltEnableL1Sub (mTbtNvsAreaPtr->TbtL1SubStates, RpSegment, RpB= us, RpDevice, RpFunction); + } + ConfigureTbtPm(RpSegment, RpBus, RpDevice, RpFunction, 1); + if (!mTbtNvsAreaPtr->TbtAspm) { //Aspm disable case + ThunderboltDisableAspmWithoutLtr (RpSegment, RpBus, RpDevice, RpFuncti= on); + } else { //Aspm enable case + ThunderboltEnableAspmWithoutLtr ((UINT16)mTbtNvsAreaPtr->TbtAspm, RpSe= gment, 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 =3D 0; + UINTN RpBus =3D 0; + UINTN RpDevice; + UINTN RpFunction; + + if(Type =3D=3D DTBT_CONTROLLER) { + if (gCurrentDiscreteTbtRootPort =3D=3D 0) { + return; + } + GetDTbtRpDevFun(DTBT_CONTROLLER, gCurrentDiscreteTbtRootPort - 1, &RpD= evice, &RpFunction); + + ConfigureTbtPm (RpSegment, RpBus, RpDevice, RpFunction, 1); + if (!mTbtNvsAreaPtr->TbtAspm) { //Aspm disable case + ThunderboltDisableAspmWithoutLtr (RpSegment, RpBus, RpDevice, RpFunc= tion); + } else { //Aspm enable case + ThunderboltEnableAspmWithoutLtr ((UINT16) Aspm, RpSegment, RpBus, Rp= Device, RpFunction); + } + + if (mTbtNvsAreaPtr->TbtLtr) { + ThunderboltGetLatencyLtr (); + ThunderboltSetLatencyLtr (RpSegment, RpBus, RpDevice, RpFunction); + } + ConfigureLtr (RpSegment, RpBus, RpDevice, RpFunction); + } // EndOfThunderboltCallback +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/Ac= piTimerLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/= AcpiTimerLib.c new file mode 100644 index 0000000000..ec06eee73f --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Library/AcpiTimerLib/AcpiTimer= Lib.c @@ -0,0 +1,394 @@ +/** @file + ACPI Timer implements one instance of Timer Library. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +// +// OVERRIDE: OverrideBegin +// +#include +// +// OVERRIDE: OverrideEnd +// + + +/** + Internal function to retrieves the 64-bit frequency in Hz. + + Internal function to retrieves the 64-bit frequency in Hz. + + @return The frequency in Hz. + +**/ +UINT64 +InternalGetPerformanceCounterFrequency ( + VOID + ); + +/** + The constructor function enables ACPI IO space. + + If ACPI I/O space not enabled, this function will enable it. + It will always return RETURN_SUCCESS. + + @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS. + +**/ +RETURN_STATUS +EFIAPI +AcpiTimerLibConstructor ( + VOID + ) +{ + UINTN Bus; + UINTN Device; + UINTN Function; + UINTN EnableRegister; + UINT8 EnableMask; + + // + // ASSERT for the invalid PCD values. They must be configured to the rea= l value. + // + ASSERT (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) !=3D 0xFFFF); + ASSERT (PcdGet16 (PcdAcpiIoPortBaseAddress) !=3D 0xFFFF); + + // + // If the register offset to the BAR for the ACPI I/O Port Base Address = is 0x0000, then + // no PCI register programming is required to enable access to the the A= CPI registers + // specified by PcdAcpiIoPortBaseAddress + // + if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) =3D=3D 0x0000) { + return RETURN_SUCCESS; + } + + // + // ASSERT for the invalid PCD values. They must be configured to the rea= l value. + // + ASSERT (PcdGet8 (PcdAcpiIoPciDeviceNumber) !=3D 0xFF); + ASSERT (PcdGet8 (PcdAcpiIoPciFunctionNumber) !=3D 0xFF); + ASSERT (PcdGet16 (PcdAcpiIoPciEnableRegisterOffset) !=3D 0xFFFF); + + // + // Retrieve the PCD values for the PCI configuration space required to p= rogram the ACPI I/O Port Base Address + // + Bus =3D PcdGet8 (PcdAcpiIoPciBusNumber); + Device =3D PcdGet8 (PcdAcpiIoPciDeviceNumber); + Function =3D PcdGet8 (PcdAcpiIoPciFunctionNumber); + EnableRegister =3D PcdGet16 (PcdAcpiIoPciEnableRegisterOffset); + EnableMask =3D PcdGet8 (PcdAcpiIoBarEnableMask); + + // + // If ACPI I/O space is not enabled yet, program ACPI I/O base address a= nd enable it. + // + if ((PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister)) = & EnableMask) !=3D EnableMask) { + PciWrite16 ( + PCI_LIB_ADDRESS (Bus, Device, Function, PcdGet16 (PcdAcpiIoPciBarReg= isterOffset)), + PcdGet16 (PcdAcpiIoPortBaseAddress) + ); + PciOr8 ( + PCI_LIB_ADDRESS (Bus, Device, Function, EnableRegister), + EnableMask + ); + } + + return RETURN_SUCCESS; +} + +/** + Internal function to retrieve the ACPI I/O Port Base Address. + + Internal function to retrieve the ACPI I/O Port Base Address. + + @return The 16-bit ACPI I/O Port Base Address. + +**/ +UINT16 +InternalAcpiGetAcpiTimerIoPort ( + VOID + ) +{ + UINT16 Port; + + Port =3D PcdGet16 (PcdAcpiIoPortBaseAddress); + + // + // If the register offset to the BAR for the ACPI I/O Port Base Address = is not 0x0000, then + // read the PCI register for the ACPI BAR value in case the BAR has been= programmed to a + // value other than PcdAcpiIoPortBaseAddress + // + if (PcdGet16 (PcdAcpiIoPciBarRegisterOffset) !=3D 0x0000) { + Port =3D PciRead16 (PCI_LIB_ADDRESS ( + PcdGet8 (PcdAcpiIoPciBusNumber), + PcdGet8 (PcdAcpiIoPciDeviceNumber), + PcdGet8 (PcdAcpiIoPciFunctionNumber), + PcdGet16 (PcdAcpiIoPciBarRegisterOffset) + )); + } + + return (Port & PcdGet16 (PcdAcpiIoPortBaseAddressMask)) + PcdGet16 (PcdA= cpiPm1TmrOffset); +} + +/** + Stalls the CPU for at least the given number of ticks. + + Stalls the CPU for at least the given number of ticks. It's invoked by + MicroSecondDelay() and NanoSecondDelay(). + + @param Delay A period of time to delay in ticks. + +**/ +VOID +InternalAcpiDelay ( + IN UINT32 Delay + ) +{ + UINT16 Port; + UINT32 Ticks; + UINT32 Times; + + Port =3D InternalAcpiGetAcpiTimerIoPort (); + Times =3D Delay >> 22; + Delay &=3D BIT22 - 1; + do { + // + // The target timer count is calculated here + // + Ticks =3D IoBitFieldRead32 (Port, 0, 23) + Delay; + Delay =3D BIT22; + // + // Wait until time out + // Delay >=3D 2^23 could not be handled by this function + // Timer wrap-arounds are handled correctly by this function + // + while (((Ticks - IoBitFieldRead32 (Port, 0, 23)) & BIT23) =3D=3D 0) { + CpuPause (); + } + } while (Times-- > 0); +} + +/** + Stalls the CPU for at least the given number of microseconds. + + Stalls the CPU for the number of microseconds specified by MicroSeconds. + + @param MicroSeconds The minimum number of microseconds to delay. + + @return MicroSeconds + +**/ +UINTN +EFIAPI +MicroSecondDelay ( + IN UINTN MicroSeconds + ) +{ + InternalAcpiDelay ( + (UINT32)DivU64x32 ( + MultU64x32 ( + MicroSeconds, + ACPI_TIMER_FREQUENCY + ), + 1000000u + ) + ); + return MicroSeconds; +} + +/** + Stalls the CPU for at least the given number of nanoseconds. + + Stalls the CPU for the number of nanoseconds specified by NanoSeconds. + + @param NanoSeconds The minimum number of nanoseconds to delay. + + @return NanoSeconds + +**/ +UINTN +EFIAPI +NanoSecondDelay ( + IN UINTN NanoSeconds + ) +{ + InternalAcpiDelay ( + (UINT32)DivU64x32 ( + MultU64x32 ( + NanoSeconds, + ACPI_TIMER_FREQUENCY + ), + 1000000000u + ) + ); + return NanoSeconds; +} + +/** + Retrieves the current value of a 64-bit free running performance counter= . + + Retrieves the current value of a 64-bit free running performance counter= . The + counter can either count up by 1 or count down by 1. If the physical + performance counter counts by a larger increment, then the counter value= s + must be translated. The properties of the counter can be retrieved from + GetPerformanceCounterProperties(). + + @return The current value of the free running performance counter. + +**/ +UINT64 +EFIAPI +GetPerformanceCounter ( + VOID + ) +{ + return AsmReadTsc (); +} + +/** + Retrieves the 64-bit frequency in Hz and the range of performance counte= r + values. + + If StartValue is not NULL, then the value that the performance counter s= tarts + with immediately after is it rolls over is returned in StartValue. If + EndValue is not NULL, then the value that the performance counter end wi= th + immediately before it rolls over is returned in EndValue. The 64-bit + frequency of the performance counter in Hz is always returned. If StartV= alue + is less than EndValue, then the performance counter counts up. If StartV= alue + is greater than EndValue, then the performance counter counts down. For + example, a 64-bit free running counter that counts up would have a Start= Value + of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counte= r + that counts down would have a StartValue of 0xFFFFFF and an EndValue of = 0. + + @param StartValue The value the performance counter starts with when i= t + rolls over. + @param EndValue The value that the performance counter ends with bef= ore + it rolls over. + + @return The frequency in Hz. + +**/ +UINT64 +EFIAPI +GetPerformanceCounterProperties ( + OUT UINT64 *StartValue, OPTIONAL + OUT UINT64 *EndValue OPTIONAL + ) +{ + if (StartValue !=3D NULL) { + *StartValue =3D 0; + } + + if (EndValue !=3D NULL) { + *EndValue =3D 0xffffffffffffffffULL; + } + return InternalGetPerformanceCounterFrequency (); +} + +/** + Converts elapsed ticks of performance counter to time in nanoseconds. + + This function converts the elapsed ticks of running performance counter = to + time value in unit of nanoseconds. + + @param Ticks The number of elapsed ticks of running performance cou= nter. + + @return The elapsed time in nanoseconds. + +**/ +UINT64 +EFIAPI +GetTimeInNanoSecond ( + IN UINT64 Ticks + ) +{ + UINT64 Frequency; + UINT64 NanoSeconds; + UINT64 Remainder; + INTN Shift; + Frequency =3D GetPerformanceCounterProperties (NULL, NULL); + + // + // Ticks + // Time =3D --------- x 1,000,000,000 + // Frequency + // + NanoSeconds =3D MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remai= nder), 1000000000u); + + // + // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit. + // Since 2^29 < 1,000,000,000 =3D 0x3B9ACA00 < 2^30, Remainder should < = 2^(64-30) =3D 2^34, + // i.e. highest bit set in Remainder should <=3D 33. + // + Shift =3D MAX (0, HighBitSet64 (Remainder) - 33); + Remainder =3D RShiftU64 (Remainder, (UINTN) Shift); + Frequency =3D RShiftU64 (Frequency, (UINTN) Shift); + NanoSeconds +=3D DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u)= , Frequency, NULL); + + return NanoSeconds; +} + +// +// OVERRIDE: OverrideBegin +// +/** + Calculate TSC frequency. + + The TSC counting frequency is determined by using CPUID leaf 0x15 that i= s the preferred + method for Skylake and beyond. Frequency in MHz =3D Core XTAL frequency= * EBX/EAX. + In newer flavors of the CPU, core xtal frequency is returned in ECX (or = 0 if not + supported). If ECX is 0, 24MHz is assumed. + @return The number of TSC counts per second. + +**/ +UINT64 +InternalCalculateTscFrequency ( + VOID + ) +{ + UINT64 TscFrequency; + UINT64 CoreXtalFrequency; + UINT32 RegEax; + UINT32 RegEbx; + UINT32 RegEcx; + + // + // Use CPUID leaf 0x15. + // TSC frequency =3D (Core Xtal Frequency) * EBX/EAX. EBX returns 0 if = not + // supported. ECX, if non zero, provides Core Xtal Frequency in hertz + // (SDM Dec 2016). + // + AsmCpuid (CPUID_TIME_STAMP_COUNTER, &RegEax, &RegEbx, &RegEcx, NULL); + ASSERT (RegEbx !=3D 0); + + // + // If core xtal frequency (ECX) returns 0, it is safe to use 24MHz for p= ost + // Skylake client CPU's. + // + if (RegEcx =3D=3D 0) { + CoreXtalFrequency =3D 24000000ul; + } else { + CoreXtalFrequency =3D (UINT64)RegEcx; + } + + // + // Calculate frequency. For integer division, round up/down result + // correctly by adding denominator/2 to the numerator prior to division. + // + TscFrequency =3D DivU64x32 (MultU64x32 (CoreXtalFrequency, RegEbx) + (UI= NT64)(RegEax >> 1), RegEax); + + return TscFrequency; +} +// +// OVERRIDE: OverrideEnd +// + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Bo= ardInitLib.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/= BoardInitLib.c new file mode 100644 index 0000000000..2bba58eed3 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/BoardInit= Lib.c @@ -0,0 +1,612 @@ +/** @file + Source code for the board configuration init function in DXE init phase. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "BoardInitLib.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// +// Null function for nothing GOP VBT update. +// +VOID +GopVbtSpecificUpdateNull( + IN CHILD_STRUCT **ChildStructPtr +); + +// +// for CFL U DDR4 +// +VOID +CflUDdr4GopVbtSpecificUpdate( + IN CHILD_STRUCT **ChildStructPtr +); + +/** + Updates DIMM slots status for Desktop,server and workstation boards + +**/ +VOID +UpdateDimmPopulationConfig( + VOID + ) +{ + MEMORY_INFO_DATA_HOB *MemInfo; + UINT8 Slot0; + UINT8 Slot1; + UINT8 Slot2; + UINT8 Slot3; + CONTROLLER_INFO *ControllerInfo; + EFI_HOB_GUID_TYPE *GuidHob; + + GuidHob =3D NULL; + MemInfo =3D NULL; + + GuidHob =3D GetFirstGuidHob (&gSiMemoryInfoDataGuid); + ASSERT (GuidHob !=3D NULL); + if (GuidHob !=3D NULL) { + MemInfo =3D (MEMORY_INFO_DATA_HOB *) GET_GUID_HOB_DATA (GuidHob); + } + if (MemInfo !=3D NULL) { + if (PcdGet8 (PcdPlatformFlavor) =3D=3D FlavorDesktop || + PcdGet8 (PcdPlatformFlavor) =3D=3D FlavorUpServer || + PcdGet8 (PcdPlatformFlavor) =3D=3D FlavorWorkstation) { + ControllerInfo =3D &MemInfo->Controller[0]; + Slot0 =3D ControllerInfo->ChannelInfo[0].DimmInfo[0].Status; + Slot1 =3D ControllerInfo->ChannelInfo[0].DimmInfo[1].Status; + Slot2 =3D ControllerInfo->ChannelInfo[1].DimmInfo[0].Status; + Slot3 =3D ControllerInfo->ChannelInfo[1].DimmInfo[1].Status; + + // + // Channel 0 Channel 1 + // Slot0 Slot1 Slot0 Slot1 - Population AIO= board + // 0 0 0 0 - Invalid - In= valid + // 0 0 0 1 - Valid - In= valid + // 0 0 1 0 - Invalid - Va= lid + // 0 0 1 1 - Valid - Va= lid + // 0 1 0 0 - Valid - In= valid + // 0 1 0 1 - Valid - In= valid + // 0 1 1 0 - Invalid - In= valid + // 0 1 1 1 - Valid - In= valid + // 1 0 0 0 - Invalid - Va= lid + // 1 0 0 1 - Invalid - In= valid + // 1 0 1 0 - Invalid - Va= lid + // 1 0 1 1 - Invalid - Va= lid + // 1 1 0 0 - Valid - Va= lid + // 1 1 0 1 - Valid - In= valid + // 1 1 1 0 - Invalid - Va= lid + // 1 1 1 1 - Valid - Va= lid + // + + if ((Slot0 && (Slot1 =3D=3D 0)) || (Slot2 && (Slot3 =3D=3D 0))) { + PcdSetBoolS (PcdDimmPopulationError, TRUE); + } + } + } +} + +/** + Init Misc Platform Board Config Block. + + @param[in] BoardId An unsigned integer represent the board id= . + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +BoardMiscInit ( + IN UINT16 BoardId + ) +{ +// PcdSet64S (PcdFuncBoardHookPlatformSetupOverride, (UINT64) (UINTN) Boa= rdHookPlatformSetup); + + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSetBoolS (PcdPssReadSN, TRUE); + PcdSet8S (PcdPssI2cSlaveAddress, 0x6E); + PcdSet8S (PcdPssI2cBusNumber, 0x04); + break; + default: + PcdSetBoolS (PcdPssReadSN, FALSE); + PcdSet8S (PcdPssI2cSlaveAddress, 0x6E); + PcdSet8S (PcdPssI2cBusNumber, 0x04); + break; + } + + + return EFI_SUCCESS; +} + +/** + Init Platform Board Config Block for ACPI platform. + + @param[in] BoardId An unsigned integer represent the board id= . + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +InitAcpiPlatformPcd ( + IN UINT16 BoardId + ) +{ + TBT_INFO_HOB *TbtInfoHob =3D NULL; + + TbtInfoHob =3D (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid); + + // + // Update OEM table ID + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + if ((TbtInfoHob !=3D NULL) && (TbtInfoHob->DTbtControllerConfig[0].D= TbtControllerEn =3D=3D 1)) { + PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_',= 'w', 'h', 'l', 't', '4')); + } else { + PcdSet64S (PcdXhciAcpiTableSignature, SIGNATURE_64 ('x', 'h', '_',= 'w', 'h', 'l', 'd', '4')); + } + break; + default: + PcdSet64S (PcdXhciAcpiTableSignature, 0); + break; + } + + // + // Modify Preferred_PM_Profile field based on Board SKU's. Default is se= t to Mobile + // + PcdSet8S (PcdPreferredPmProfile, EFI_ACPI_2_0_PM_PROFILE_MOBILE); + + // + // Assign FingerPrint, Gnss, TouchPanel, Audio related GPIO. + // + switch(BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSet32S (PcdFingerPrintSleepGpio, GPIO_CNL_LP_GPP_B17); + PcdSet32S (PcdFingerPrintIrqGpio, GPIO_CNL_LP_GPP_B16); + // + // Configure WWAN Reset pin + // + PcdSet32S (PcdGnssResetGpio, GPIO_CNL_LP_GPP_F1); + PcdSet32S (PcdTouchpanelIrqGpio, GPIO_CNL_LP_GPP_D10); + PcdSet32S (PcdTouchpadIrqGpio, GPIO_CNL_LP_GPP_B3); + PcdSet32S (PcdHdaI2sCodecIrqGpio, GPIO_CNL_LP_GPP_C8); + break; + default: + break; + } + + // + // Configure GPIOs for discrete USB BT module + // + switch(BoardId) { + + case BoardIdWhiskeyLakeRvp: + PcdSet32S (PcdBtIrqGpio, GPIO_CNL_LP_GPP_B2); + PcdSet32S (PcdBtRfKillGpio, GPIO_CNL_LP_GPP_B4); + break; + default: + break; + } + + // + // Board Specific Init + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSetBoolS(PcdWhlErbRtd3TableEnable, TRUE); + PcdSet8S (PcdHdaI2sCodecI2cBusNumber, 0); // I2S Audio Codec conntec= ted to I2C0 + PcdSet8S (PcdBleUsbPortNumber, 9); + break; + default: + break; + } + + return EFI_SUCCESS; +} + +/** + Init Common Platform Board Config Block. + + @param[in] BoardId An unsigned integer represent the board id= . + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +InitCommonPlatformPcd ( + IN UINT16 BoardId + ) +{ + PCD64_BLOB Data64; + TBT_INFO_HOB *TbtInfoHob =3D NULL; + + TbtInfoHob =3D (TBT_INFO_HOB *) GetFirstGuidHob (&gTbtInfoHobGuid); + + + // + // Enable EC SMI# for SMI + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSet32S (PcdEcSmiGpio, GPIO_CNL_LP_GPP_E3); + PcdSet32S (PcdEcLowPowerExitGpio, GPIO_CNL_LP_GPP_B23); + break; + }; + + // + // HID I2C Interrupt GPIO. + // + switch (BoardId) { + default: + // on all supported boards interrupt input is on same GPIO pad. How = convenient. + PcdSet32S (PcdHidI2cIntPad, GPIO_CNL_LP_GPP_D10); + break; + } + + // + // PS2 KB Specific Init for Sds Serial platform. + // + if (BoardId =3D=3D BoardIdWhiskeyLakeRvp) { + PcdSetBoolS (PcdDetectPs2KbOnCmdAck, TRUE); + } else { + PcdSetBoolS (PcdDetectPs2KbOnCmdAck, FALSE); + } + + switch (BoardId) { + default: + PcdSetBoolS (PcdSpdAddressOverride, FALSE); + break; + } + + // + // DDISelection + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSet8S (PcdDDISelection, 1); + break; + default: + PcdSet8S (PcdDDISelection, 0); + break; + } + + // + // GFX Detect + // + switch (BoardId) { + default: + // Not all the boards support GFX_CRB_DET. This is not an error. + Data64.BoardGpioConfig.Type =3D BoardGpioTypeNotSupported; + break; + } + + PcdSet64S (PcdGfxCrbDetectGpio, Data64.Blob); + + // + // USB Type-C + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSetBoolS(PcdUsbTypeCSupport, TRUE); + // Discete Ports + PcdSet8S(PcdTypeCPortsSupported, 2); + // TBT Port 1 mapping and properties [TBT AIC] + PcdSet8S(PcdUsbTypeCPort1, 1); + PcdSet8S(PcdUsbTypeCPort1Pch, 5); + // TBT Port 2 mapping and properties [TBT AIC] + PcdSet8S(PcdUsbTypeCPort2, 2); + PcdSet8S(PcdUsbTypeCPort2Pch, 7); + break; + default: + PcdSetBoolS (PcdUsbTypeCSupport, FALSE); + break; + } + + // + // Battery Present + // + switch (BoardId) { + default: + PcdSet8S (PcdBatteryPresent, BOARD_REAL_BATTERY_SUPPORTED | BOARD_VIRT= UAL_BATTERY_SUPPORTED); + break; + } + + // + // TS-on-DIMM temperature + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSetBoolS (PcdTsOnDimmTemperature, TRUE); + break; + default: + PcdSetBoolS (PcdTsOnDimmTemperature, FALSE); + break; + } + // + // Real Battery 1 Control & Real Battery 2 Control + // + PcdSet8S (PcdRealBattery1Control, 1); + PcdSet8S (PcdRealBattery2Control, 2); + + // + // Mipi Camera Sensor + // + PcdSetBoolS (PcdMipiCamSensor, FALSE); + // + // Mipi Camera Sensor Link Used + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSet8S (PcdMipiCam0LinkUsed, 3); + PcdSet8S (PcdMipiCam1LinkUsed, 6); + PcdSet8S (PcdMipiCam2LinkUsed, 9); + PcdSet8S (PcdMipiCam3LinkUsed, 7); + break; + default: + break; + } + + // + // H8S2113 SIO + // + switch(BoardId) { + default: + PcdSetBoolS (PcdH8S2113SIO, FALSE); + break; + } + + + // + // NCT6776F COM, SIO & HWMON + // + PcdSetBoolS (PcdNCT6776FCOM, FALSE); + PcdSetBoolS (PcdNCT6776FSIO, FALSE); + PcdSetBoolS (PcdNCT6776FHWMON, FALSE); + + // + // SMC Runtime Sci Pin + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSet32S (PcdSmcRuntimeSciPin, (UINT32) GPIO_CNL_LP_GPP_E16); + break; + default: + PcdSet32S (PcdSmcRuntimeSciPin, 0x00); + break; + } + + // + // Convertable Dock Support + // + switch (BoardId) { + default: + PcdSetBoolS (PcdConvertableDockSupport, FALSE); + break; + } + + // + // Ec Hotkey F3, F4, F5, F6, F7 and F8 Support + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSet8S (PcdEcHotKeyF3Support, 1); + PcdSet8S (PcdEcHotKeyF4Support, 1); + PcdSet8S (PcdEcHotKeyF5Support, 1); + PcdSet8S (PcdEcHotKeyF6Support, 1); + PcdSet8S (PcdEcHotKeyF7Support, 1); + PcdSet8S (PcdEcHotKeyF8Support, 1); + break; + default: + PcdSet8S (PcdEcHotKeyF3Support, 0); + PcdSet8S (PcdEcHotKeyF4Support, 0); + PcdSet8S (PcdEcHotKeyF5Support, 0); + PcdSet8S (PcdEcHotKeyF6Support, 0); + PcdSet8S (PcdEcHotKeyF7Support, 0); + PcdSet8S (PcdEcHotKeyF8Support, 0); + break; + } + + // + // Virtual Button Volume Up & Done Support + // Virtual Button Home Button Support + // Virtual Button Rotation Lock Support + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSetBoolS (PcdVirtualButtonVolumeUpSupport, TRUE); + PcdSetBoolS (PcdVirtualButtonVolumeDownSupport, TRUE); + PcdSetBoolS (PcdVirtualButtonHomeButtonSupport, FALSE); + PcdSetBoolS (PcdVirtualButtonRotationLockSupport, FALSE); + break; + default: + PcdSetBoolS (PcdVirtualButtonVolumeUpSupport, FALSE); + PcdSetBoolS (PcdVirtualButtonVolumeDownSupport, FALSE); + PcdSetBoolS (PcdVirtualButtonHomeButtonSupport, FALSE); + PcdSetBoolS (PcdVirtualButtonRotationLockSupport, FALSE); + break; + } + + // + // Slate Mode Switch Support + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSetBoolS (PcdSlateModeSwitchSupport, TRUE); + break; + default: + PcdSetBoolS (PcdSlateModeSwitchSupport, FALSE); + break; + } + + // + // Ac Dc Auto Switch Support + // + switch (BoardId) { + default: + PcdSetBoolS (PcdAcDcAutoSwitchSupport, TRUE); + break; + } + + // + // Pm Power Button Gpio Pin + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSet32S (PcdPmPowerButtonGpioPin, (UINT32) GPIO_CNL_LP_GPD3); + break; + default: + PcdSet32S (PcdPmPowerButtonGpioPin, 0x00); + break; + } + + // + // Acpi Enable All Button Support + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSetBoolS (PcdAcpiEnableAllButtonSupport, TRUE); + break; + default: + PcdSetBoolS (PcdAcpiEnableAllButtonSupport, FALSE); + break; + } + + // + // Acpi Hid Driver Button Support + // + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + PcdSetBoolS (PcdAcpiHidDriverButtonSupport, TRUE); + break; + default: + PcdSetBoolS (PcdAcpiHidDriverButtonSupport, FALSE); + break; + } + + // + // USB Type C EC less + // + switch (BoardId) { + default: + PcdSetBoolS (PcdUsbTypeCEcLess, FALSE); + break; + } + + return EFI_SUCCESS; +} + +/** + Check if given rootport has device connected and enable wake capability + + @param[in] RpNum An unsigned integer represent the root port = number. + + @retval TRUE if endpoint was connected + @retval FALSE if no endpoint was detected +**/ +BOOLEAN +IsPcieEndPointPresent ( + IN UINT8 RpNum + ) +{ + EFI_STATUS Status; + UINTN RpDev; + UINTN RpFun; + UINT64 RpBaseAddress; + + Status =3D GetPchPcieRpDevFun (RpNum, &RpDev, &RpFun); + if (!EFI_ERROR (Status)) { + // + // check if device is present + // + RpBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS ( + DEFAULT_PCI_SEGMENT_NUMBER_PCH, + DEFAULT_PCI_BUS_NUMBER_PCH, + RpDev, + RpFun, + 0 + ); + + if ((PciSegmentRead16 (RpBaseAddress) !=3D 0xFFFF) && + (PciSegmentRead16 (RpBaseAddress + R_PCH_PCIE_CFG_SLSTS) & B_PCIE_= SLSTS_PDS)) { + return TRUE; + } + } + + return FALSE; + +} + +/** + Enable Tier2 GPIO Sci wake capability. + + @param[in] BoardId An unsigned integrer represent the board id. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +Tier2GpioWakeSupport ( + IN UINT16 BoardId + ) +{ + BOOLEAN Tier2GpioWakeEnable; + + Tier2GpioWakeEnable =3D FALSE; + switch (BoardId) { + case BoardIdWhiskeyLakeRvp: + // + // Root port #14: M.2 WLAN + // + if (IsPcieEndPointPresent (13)) { + Tier2GpioWakeEnable =3D TRUE; + } + break; + default: + break; + } + PcdSetBoolS (PcdGpioTier2WakeEnable, Tier2GpioWakeEnable); + + return EFI_SUCCESS; +} + +/** + Board configuration init function for DXE phase. + + @param Content pointer to the buffer contain init information for boar= d init. + + @retval EFI_SUCCESS The function completed successfully. +**/ +EFI_STATUS +EFIAPI +BoardConfigInit ( + VOID + ) +{ + EFI_STATUS Status; + UINT16 BoardId; + + BoardId =3D BoardIdWhiskeyLakeRvp; + + Status =3D InitAcpiPlatformPcd (BoardId); + ASSERT_EFI_ERROR(Status); + + Status =3D InitCommonPlatformPcd (BoardId); + ASSERT_EFI_ERROR(Status); + + Status =3D BoardMiscInit (BoardId); + ASSERT_EFI_ERROR(Status); + + Status =3D Tier2GpioWakeSupport (BoardId); + ASSERT_EFI_ERROR(Status); + + return EFI_SUCCESS; +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Cp= uPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInit= Dxe/CpuPolicyInitDxe.c new file mode 100644 index 0000000000..eb7c3bbea0 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/CpuPolicy= InitDxe.c @@ -0,0 +1,46 @@ +/** @file + This file is SampleCode for Intel Silicon DXE Platform Policy initialzat= ion. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +DXE_CPU_POLICY_PROTOCOL mCpuPolicyData; + +/** + Initialize Intel CPU DXE Platform Policy + + @param[in] ImageHandle Image handle of this driver. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize= the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +CpuPolicyInitDxe ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + ZeroMem(&mCpuPolicyData, sizeof (DXE_CPU_POLICY_PROTOCOL)); + mCpuPolicyData.Revision =3D DXE_CPU_POLICY_PROTO= COL_REVISION; + + UpdateDxeSiCpuPolicy(&mCpuPolicyData); + + // + // Install CpuInstallPolicyProtocol. + // While installed, RC assumes the Policy is ready and finalized. So ple= ase + // update and override any setting before calling this function. + // + Status =3D CpuInstallPolicyProtocol(ImageHandle, &mCpuPolicyData); + ASSERT_EFI_ERROR (Status); + + return Status; +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Go= pPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInit= Dxe/GopPolicyInitDxe.c new file mode 100644 index 0000000000..66aab2d198 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/GopPolicy= InitDxe.c @@ -0,0 +1,174 @@ +/** @file + This file initialises and Installs GopPolicy Protocol. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "GopPolicyInitDxe.h" +#include + +GLOBAL_REMOVE_IF_UNREFERENCED GOP_POLICY_PROTOCOL mGOPPolicy; +GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mVbtSize =3D 0; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS mVbtAddress =3D 0= ; + +// +// Function implementations +// + +/** + + @param[out] CurrentLidStatus + + @retval EFI_SUCCESS + @retval EFI_UNSUPPORTED +**/ + +EFI_STATUS +EFIAPI +GetPlatformLidStatus ( + OUT LID_STATUS *CurrentLidStatus + ) +{ + return EFI_UNSUPPORTED; +} + +/** + + @param[out] CurrentDockStatus + + @retval EFI_SUCCESS + @retval EFI_UNSUPPORTED +**/ +EFI_STATUS +EFIAPI +GetPlatformDockStatus ( + OUT DOCK_STATUS CurrentDockStatus + ) +{ + return EFI_UNSUPPORTED; +} + + +/** + + @param[out] VbtAddress + @param[out] VbtSize + + @retval EFI_SUCCESS + @retval EFI_NOT_FOUND +**/ +EFI_STATUS +EFIAPI +GetVbtData ( + OUT EFI_PHYSICAL_ADDRESS *VbtAddress, + OUT UINT32 *VbtSize + ) +{ + EFI_STATUS Status; + UINTN FvProtocolCount; + EFI_HANDLE *FvHandles; + EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; + UINTN Index; + UINT32 AuthenticationStatus; + UINT8 *Buffer; + UINTN VbtBufferSize; + + Status =3D EFI_NOT_FOUND; + if ( mVbtAddress =3D=3D 0) { + Fv =3D NULL; + Buffer =3D 0; + FvHandles =3D NULL; + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolume2ProtocolGuid, + NULL, + &FvProtocolCount, + &FvHandles + ); + if (!EFI_ERROR (Status)) { + for (Index =3D 0; Index < FvProtocolCount; Index++) { + Status =3D gBS->HandleProtocol ( + FvHandles[Index], + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **) &Fv + ); + VbtBufferSize =3D 0; + Status =3D Fv->ReadSection ( + Fv, + PcdGetPtr(PcdIntelGraphicsVbtFileGuid), + EFI_SECTION_RAW, + 0, + (VOID **) &Buffer, + &VbtBufferSize, + &AuthenticationStatus + ); + if (!EFI_ERROR (Status)) { + *VbtAddress =3D (EFI_PHYSICAL_ADDRESS)Buffer; + *VbtSize =3D (UINT32)VbtBufferSize; + mVbtAddress =3D *VbtAddress; + mVbtSize =3D *VbtSize; + Status =3D EFI_SUCCESS; + break; + } + } + } else { + Status =3D EFI_NOT_FOUND; + } + + if (FvHandles !=3D NULL) { + FreePool (FvHandles); + FvHandles =3D NULL; + } + } else { + *VbtAddress =3D mVbtAddress; + *VbtSize =3D mVbtSize; + Status =3D EFI_SUCCESS; + } + + return Status; +} + +/** +Initialize GOP DXE Policy + +@param[in] ImageHandle Image handle of this driver. + +@retval EFI_SUCCESS Initialization complete. +@retval EFI_UNSUPPORTED The chipset is unsupported by this driver. +@retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize= the driver. +@retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ + +EFI_STATUS +EFIAPI +GopPolicyInitDxe ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + // + // Initialize the EFI Driver Library + // + SetMem (&mGOPPolicy, sizeof (GOP_POLICY_PROTOCOL), 0); + + mGOPPolicy.Revision =3D GOP_POLICY_PROTOCOL_REVISION_03; + mGOPPolicy.GetPlatformLidStatus =3D GetPlatformLidStatus; + mGOPPolicy.GetVbtData =3D GetVbtData; + mGOPPolicy.GetPlatformDockStatus =3D GetPlatformDockStatus; + + // + // Install protocol to allow access to this Policy. + // + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gGopPolicyProtocolGuid, + &mGOPPolicy, + NULL + ); + + return Status; +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Pc= hPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInit= Dxe/PchPolicyInitDxe.c new file mode 100644 index 0000000000..2a1604fa13 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PchPolicy= InitDxe.c @@ -0,0 +1,55 @@ +/** @file + This file is SampleCode for PCH DXE Policy initialization. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "PchPolicyInitDxe.h" + +// +// Function implementations +// + +/** + Initialize PCH DXE Policy + + @param[in] ImageHandle Image handle of this driver. + + @retval EFI_SUCCESS Initialization complete. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initiali= ze the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +PchPolicyInitDxe ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + PCH_POLICY_PROTOCOL *PchPolicy; + + // + // Call CreatePchDxeConfigBlocks to create & initialize platform policy = structure + // and get all Intel default policy settings. + // + Status =3D CreatePchDxeConfigBlocks (&PchPolicy); + DEBUG((DEBUG_INFO, "PchPolicy->TableHeader.NumberOfBlocks =3D 0x%x\n", P= chPolicy->TableHeader.NumberOfBlocks)); + ASSERT_EFI_ERROR (Status); + + if (mFirmwareConfiguration !=3D FwConfigDefault) { + UpdateDxePchPolicy (PchPolicy); + } + + // + // Install PchInstallPolicyProtocol. + // While installed, RC assumes the Policy is ready and finalized. So ple= ase + // update and override any setting before calling this function. + // + Status =3D PchInstallPolicyProtocol (ImageHandle, PchPolicy); + ASSERT_EFI_ERROR (Status); + + return Status; +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Po= licyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe= /PolicyInitDxe.c new file mode 100644 index 0000000000..ccaa57ce16 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/PolicyIni= tDxe.c @@ -0,0 +1,88 @@ +/** @file + This file is a wrapper for Platform Policy driver. Get Setup + Value to initialize Intel DXE Platform Policy. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "PolicyInitDxe.h" +#include +#include "BoardInitLib.h" + +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mFirmwareConfiguration =3D = 0; + +/** + Initialize DXE Platform Policy + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable Global system service table. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize= the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +PolicyInitDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status =3D BoardConfigInit(); + + mFirmwareConfiguration =3D FwConfigProduction; + // + // SystemAgent Dxe Platform Policy Initialization + // + Status =3D SaPolicyInitDxe (ImageHandle); + DEBUG ((DEBUG_INFO, "SystemAgent Dxe Platform Policy Initialization done= \n")); + ASSERT_EFI_ERROR (Status); + + // + // PCH Dxe Platform Policy Initialization + // + Status =3D PchPolicyInitDxe (ImageHandle); + DEBUG ((DEBUG_INFO, "PCH Dxe Platform Policy Initialization done\n")); + ASSERT_EFI_ERROR (Status); + + // + // Silicon Dxe Platform Policy Initialization + // + Status =3D SiliconPolicyInitDxe (ImageHandle); + DEBUG ((DEBUG_INFO, "Silicon Dxe Platform Policy Initialization done\n")= ); + ASSERT_EFI_ERROR (Status); + + // + // CPU DXE Platform Policy Initialization + // + Status =3D CpuPolicyInitDxe (ImageHandle); + DEBUG ((DEBUG_INFO, "Cpu Dxe Platform Policy Initialization done\n")); + ASSERT_EFI_ERROR (Status); + + + if (PcdGetBool(PcdIntelGopEnable)) { + // + // GOP Dxe Policy Initialization + // + Status =3D GopPolicyInitDxe(ImageHandle); + DEBUG((DEBUG_INFO, "GOP Dxe Policy Initialization done\n")); + ASSERT_EFI_ERROR(Status); + } + if (PcdGetBool(PcdTbtEnable)) { + // + // Update TBT Policy + // + Status =3D InstallTbtPolicy (ImageHandle); + DEBUG ((DEBUG_INFO, "Install Tbt Policy done\n")); + ASSERT_EFI_ERROR (Status); + } + + return Status; + +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Sa= PolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitD= xe/SaPolicyInitDxe.c new file mode 100644 index 0000000000..c0095c09c3 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SaPolicyI= nitDxe.c @@ -0,0 +1,60 @@ +/** @file + This file is SampleCode for SA DXE Policy initialization. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "SaPolicyInitDxe.h" + + +// +// Function implementations +// + +/** + Initialize SA DXE Policy + + @param[in] ImageHandle Image handle of this driver. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this drive= r. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initiali= ze the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +SaPolicyInitDxe ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + SA_POLICY_PROTOCOL *SaPolicy; + + // + // Call CreateSaDxeConfigBlocks to create & initialize platform policy s= tructure + // and get all Intel default policy settings. + // + Status =3D CreateSaDxeConfigBlocks(&SaPolicy); + DEBUG((DEBUG_INFO, "SaPolicy->TableHeader.NumberOfBlocks =3D 0x%x\n ", S= aPolicy->TableHeader.NumberOfBlocks)); + ASSERT_EFI_ERROR(Status); + + UpdateDxeSaPolicyBoardConfig (SaPolicy); + + if (mFirmwareConfiguration !=3D FwConfigDefault) { + + UpdateDxeSaPolicy (SaPolicy); + } + + // + // Install SaInstallPolicyProtocol. + // While installed, RC assumes the Policy is ready and finalized. So ple= ase + // update and override any setting before calling this function. + // + Status =3D SaInstallPolicyProtocol (ImageHandle, SaPolicy); + ASSERT_EFI_ERROR (Status); + + return Status; +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/Si= liconPolicyInitDxe.c b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/Policy= InitDxe/SiliconPolicyInitDxe.c new file mode 100644 index 0000000000..15adca5cdd --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Policy/PolicyInitDxe/SiliconPo= licyInitDxe.c @@ -0,0 +1,46 @@ +/** @file + This file is SampleCode for Intel Silicon DXE Platform Policy initialzat= ion. + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include + +DXE_SI_POLICY_PROTOCOL mSiPolicyData =3D { 0 }; + +/** + Initilize Intel Cpu DXE Platform Policy + + @param[in] ImageHandle Image handle of this driver. + + @retval EFI_SUCCESS Initialization complete. + @exception EFI_UNSUPPORTED The chipset is unsupported by this driver. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize= the driver. + @retval EFI_DEVICE_ERROR Device error, driver exits abnormally. +**/ +EFI_STATUS +EFIAPI +SiliconPolicyInitDxe ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + mSiPolicyData.Revision =3D DXE_SI_POLICY_PROTOCO= L_REVISION; + + /// + /// Install the DXE_SI_POLICY_PROTOCOL interface + /// + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gDxeSiPolicyProtocolGuid, + &mSiPolicyData, + NULL + ); + ASSERT_EFI_ERROR (Status); + return Status; +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/= AMLUPD.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/= AMLUPD.asl new file mode 100644 index 0000000000..7e44f5585a --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/AMLUPD.= asl @@ -0,0 +1,20 @@ +/** @file + ACPI DSDT table + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +//////////////////////////////////////////////////////////////////////////= ///////// +//Values are set like this to have ASL compiler reserve enough space for o= bjects +//////////////////////////////////////////////////////////////////////////= ///////// +// +// Available Sleep states +// +Name(SS1,0) +Name(SS2,0) +Name(SS3,1) +Name(SS4,1) + + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/= DSDT.ASL b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DS= DT.ASL new file mode 100644 index 0000000000..dd85f07bd2 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/DSDT.AS= L @@ -0,0 +1,37 @@ +/** @file + ACPI DSDT table + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "PlatformBoardId.h" + +DefinitionBlock ( + "DSDT.aml", + "DSDT", + 0x02, // DSDT revision. + // A Revision field value greater than or equal to 2 signifies tha= t integers + // declared within the Definition Block are to be evaluated as 64-= bit values + "INTEL", // OEM ID (6 byte string) + "WHL ",// OEM table ID (8 byte string) + 0x0 // OEM version of DSDT table (4 byte Integer) +) + +// BEGIN OF ASL SCOPE +{ + // Miscellaneous services enabled in Project + Include ("AMLUPD.asl") + Include ("PciTree.asl") + Include ("Platform.asl") + + Name(\_S0, Package(4){0x0,0x0,0,0}) // mandatory System state + if(SS1) { Name(\_S1, Package(4){0x1,0x0,0,0})} + if(SS3) { Name(\_S3, Package(4){0x5,0x0,0,0})} + if(SS4) { Name(\_S4, Package(4){0x6,0x0,0,0})} + Name(\_S5, Package(4){0x7,0x0,0,0}) // mandatory System state + +}// End of ASL File + + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/= HostBus.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt= /HostBus.asl new file mode 100644 index 0000000000..aa302b6e3b --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/HostBus= .asl @@ -0,0 +1,516 @@ +/** @file + This file contains the SystemAgent PCI Configuration space + definition. + It defines various System Agent PCI Configuration Space registers + which will be used to dynamically produce all resources in the Host Bus. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// +// Define various System Agent (SA) PCI Configuration Space +// registers which will be used to dynamically produce all +// resources in the Host Bus _CRS. +// +OperationRegion (HBUS, PCI_Config, 0x00, 0x100) +Field (HBUS, DWordAcc, NoLock, Preserve) +{ + Offset(0x40), // EPBAR (0:0:0:40) + EPEN, 1, // Enable + , 11, + EPBR, 20, // EPBAR [31:12] + + Offset(0x48), // MCHBAR (0:0:0:48) + MHEN, 1, // Enable + , 14, + MHBR, 17, // MCHBAR [31:15] + + Offset(0x50), // GGC (0:0:0:50) + GCLK, 1, // GGCLCK + + Offset(0x54), // DEVEN (0:0:0:54) + D0EN, 1, // DEV0 Enable + D1F2, 1, // DEV1 FUN2 Enable + D1F1, 1, // DEV1 FUN1 Enable + D1F0, 1, // DEV1 FUN0 Enable + + Offset(0x60), // PCIEXBAR (0:0:0:60) + PXEN, 1, // Enable + PXSZ, 2, // PCI Express Size + , 23, + PXBR, 6, // PCI Express BAR [31:26] + + Offset(0x68), // DMIBAR (0:0:0:68) + DIEN, 1, // Enable + , 11, + DIBR, 20, // DMIBAR [31:12] + + Offset(0x70), // MESEG_BASE (0:0:0:70) + , 20, + MEBR, 12, // MESEG_BASE [31:20] + + Offset(0x80), // PAM0 Register (0:0:0:80) + PMLK, 1, // PAM Lock bit. + , 3, + PM0H, 2, // PAM 0, High Nibble + , 2, + + Offset(0x81), // PAM1 Register (0:0:0:81) + PM1L, 2, // PAM1, Low Nibble + , 2, + PM1H, 2, // PAM1, High Nibble + , 2, + + Offset(0x82), // PAM2 Register (0:0:0:82) + PM2L, 2, // PAM2, Low Nibble + , 2, + PM2H, 2, // PAM2, High Nibble + , 2, + + Offset(0x83), // PAM3 Register (0:0:0:83) + PM3L, 2, // PAM3, Low Nibble + , 2, + PM3H, 2, // PAM3, High Nibble + , 2, + + Offset(0x84), // PAM4 Register (0:0:0:84) + PM4L, 2, // PAM4, Low Nibble + , 2, + PM4H, 2, // PAM4, High Nibble + , 2, + + Offset(0x85), // PAM5 Register (0:0:0:85) + PM5L, 2, // PAM5, Low Nibble + , 2, + PM5H, 2, // PAM5, High Nibble + , 2, + + Offset(0x86), // PAM6 Register (0:0:0:86) + PM6L, 2, // PAM6, Low Nibble + , 2, + PM6H, 2, // PAM6, High Nibble + , 2, + + Offset(0xA8), // Top of Upper Usable DRAM Register (0:0:0:A8) + , 20, + TUUD, 19, // TOUUD [38:20] + + Offset(0xBC), // Top of Lower Usable DRAM Register (0:0:0:BC) + , 20, + TLUD, 12, // TOLUD [31:20] + + Offset(0xC8), // ERRSTS register (0:0:0:C8) + , 7, + HTSE, 1 // Host Thermal Sensor Event for SMI/SCI/SERR +} + +// +// Define a buffer that will store all the bus, memory, and IO information +// relating to the Host Bus. This buffer will be dynamically altered in +// the _CRS and passed back to the OS. +// +Name(BUF0,ResourceTemplate() +{ + // + // Bus Number Allocation: Bus 0 to 0xFF + // + WORDBusNumber(ResourceProducer,MinFixed,MaxFixed,PosDecode,0x00, + 0x0000,0x00FF,0x00,0x0100,,,PB00) + + // + // I/O Region Allocation 0 ( 0x0000 - 0x0CF7 ) + // + DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange, + 0x00,0x0000,0x0CF7,0x00,0x0CF8,,,PI00) + + // + // PCI Configuration Registers ( 0x0CF8 - 0x0CFF ) + // + Io(Decode16,0x0CF8,0x0CF8,1,0x08) + + // + // I/O Region Allocation 1 ( 0x0D00 - 0xFFFF ) + // + DWordIo(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange, + 0x00,0x0D00,0xFFFF,0x00,0xF300,,,PI01) + + // + // Video Buffer Area ( 0xA0000 - 0xBFFFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xA0000,0xBFFFF,0x00,0x20000,,,A000) + + // + // ISA Add-on BIOS Area ( 0xC0000 - 0xC3FFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xC0000,0xC3FFF,0x00,0x4000,,,C000) + + // + // ISA Add-on BIOS Area ( 0xC4000 - 0xC7FFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xC4000,0xC7FFF,0x00,0x4000,,,C400) + + // + // ISA Add-on BIOS Area ( 0xC8000 - 0xCBFFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xC8000,0xCBFFF,0x00,0x4000,,,C800) + + // + // ISA Add-on BIOS Area ( 0xCC000 - 0xCFFFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xCC000,0xCFFFF,0x00,0x4000,,,CC00) + + // + // ISA Add-on BIOS Area ( 0xD0000 - 0xD3FFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xD0000,0xD3FFF,0x00,0x4000,,,D000) + + // + // ISA Add-on BIOS Area ( 0xD4000 - 0xD7FFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xD4000,0xD7FFF,0x00,0x4000,,,D400) + + // + // ISA Add-on BIOS Area ( 0xD8000 - 0xDBFFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xD8000,0xDBFFF,0x00,0x4000,,,D800) + + // + // ISA Add-on BIOS Area ( 0xDC000 - 0xDFFFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xDC000,0xDFFFF,0x00,0x4000,,,DC00) + + // + // BIOS Extension Area ( 0xE0000 - 0xE3FFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xE0000,0xE3FFF,0x00,0x4000,,,E000) + + // + // BIOS Extension Area ( 0xE4000 - 0xE7FFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xE4000,0xE7FFF,0x00,0x4000,,,E400) + + // + // BIOS Extension Area ( 0xE8000 - 0xEBFFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xE8000,0xEBFFF,0x00,0x4000,,,E800) + + // + // BIOS Extension Area ( 0xEC000 - 0xEFFFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xEC000,0xEFFFF,0x00,0x4000,,,EC00) + + // + // BIOS Area ( 0xF0000 - 0xFFFFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, + ReadWrite,0x00,0xF0000,0xFFFFF,0x00,0x10000,,,F000) + +// // +// // Memory Hole Region ( 0xF00000 - 0xFFFFFF ) +// // +// DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable, +// ReadWrite,0x00,0xF00000,0xFFFFFF,0x00,0x100000,,,HOLE) + + // + // PCI Memory Region ( TOLUD - 0xDFFFFFFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable, + ReadWrite,0x00,0x00000000,0xDFFFFFFF,0x00,0xE0000000,,,PM01) + + // + // PCI Memory Region ( TOUUD - (TOUUD + ABOVE_4G_MMIO_SIZE) ) + // (This is dummy range for OS compatibility, will patch it in _CRS) + // + QWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable, + ReadWrite,0x00,0x10000,0x1FFFF,0x00,0x10000,,,PM02) + + // + // PCH reserved resources ( 0xFC800000 - 0xFE7FFFFF ) + // + DWordMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,NonCacheable, + ReadWrite,0x00,0xFC800000,0xFE7FFFFF,0x00,0x2000000,,,PM03) +}) + +Name(EP_B, 0) // to store EP BAR +Name(MH_B, 0) // to store MCH BAR +Name(PC_B, 0) // to store PCIe BAR +Name(PC_L, 0) // to store PCIe BAR Length +Name(DM_B, 0) // to store DMI BAR + +// +// Get EP BAR +// +Method(GEPB,0,Serialized) +{ + if(LEqual(EP_B,0)) + { + ShiftLeft(\_SB.PCI0.EPBR,12,EP_B) + } + Return(EP_B) +} + +// +// Get MCH BAR +// +Method(GMHB,0,Serialized) +{ + if(LEqual(MH_B,0)) + { + ShiftLeft(\_SB.PCI0.MHBR,15,MH_B) + } + Return(MH_B) +} + +// +// Get PCIe BAR +// +Method(GPCB,0,Serialized) +{ + if(LEqual(PC_B,0)) + { + ShiftLeft(\_SB.PCI0.PXBR,26,PC_B) + } + Return(PC_B) +} + +// +// Get PCIe Length +// +Method(GPCL,0,Serialized) +{ + if(LEqual(PC_L,0)) { + ShiftRight(0x10000000, \_SB.PCI0.PXSZ,PC_L) + } + Return(PC_L) +} + +// +// Get DMI BAR +// +Method(GDMB,0,Serialized) +{ + if(LEqual(DM_B,0)) + { + ShiftLeft(\_SB.PCI0.DIBR,12,DM_B) + } + Return(DM_B) +} + + +Method(_CRS,0,Serialized) +{ + // + // Fix up Max Bus Number and Length + // + Store(\_SB.PCI0.GPCL(),Local0) + CreateWordField(BUF0, ^PB00._MAX, PBMX) + Store(Subtract(ShiftRight(Local0,20),2), PBMX) + CreateWordField(BUF0, ^PB00._LEN, PBLN) + Store(Subtract(ShiftRight(Local0,20),1), PBLN) + // + // Fix up all of the Option ROM areas from 0xC0000-0xFFFFF. + // + If(PM1L) // \_SB.PCI0 + { + // PAMx !=3D 0. Set length =3D 0. + + CreateDwordField(BUF0, ^C000._LEN,C0LN) + Store(Zero,C0LN) + } + + If(LEqual(PM1L,1)) + { + CreateBitField(BUF0, ^C000._RW,C0RW) + Store(Zero,C0RW) + } + + If(PM1H) + { + CreateDwordField(BUF0, ^C400._LEN,C4LN) + Store(Zero,C4LN) + } + + If(LEqual(PM1H,1)) + { + CreateBitField(BUF0, ^C400._RW,C4RW) + Store(Zero,C4RW) + } + + If(PM2L) + { + CreateDwordField(BUF0, ^C800._LEN,C8LN) + Store(Zero,C8LN) + } + + If(LEqual(PM2L,1)) + { + CreateBitField(BUF0, ^C800._RW,C8RW) + Store(Zero,C8RW) + } + + If(PM2H) + { + CreateDwordField(BUF0, ^CC00._LEN,CCLN) + Store(Zero,CCLN) + } + + If(LEqual(PM2H,1)) + { + CreateBitField(BUF0, ^CC00._RW,CCRW) + Store(Zero,CCRW) + } + + If(PM3L) + { + CreateDwordField(BUF0, ^D000._LEN,D0LN) + Store(Zero,D0LN) + } + + If(LEqual(PM3L,1)) + { + CreateBitField(BUF0, ^D000._RW,D0RW) + Store(Zero,D0RW) + } + + If(PM3H) + { + CreateDwordField(BUF0, ^D400._LEN,D4LN) + Store(Zero,D4LN) + } + + If(LEqual(PM3H,1)) + { + CreateBitField(BUF0, ^D400._RW,D4RW) + Store(Zero,D4RW) + } + + If(PM4L) + { + CreateDwordField(BUF0, ^D800._LEN,D8LN) + Store(Zero,D8LN) + } + + If(LEqual(PM4L,1)) + { + CreateBitField(BUF0, ^D800._RW,D8RW) + Store(Zero,D8RW) + } + + If(PM4H) + { + CreateDwordField(BUF0, ^DC00._LEN,DCLN) + Store(Zero,DCLN) + } + + If(LEqual(PM4H,1)) + { + CreateBitField(BUF0, ^DC00._RW,DCRW) + Store(Zero,DCRW) + } + + If(PM5L) + { + CreateDwordField(BUF0, ^E000._LEN,E0LN) + Store(Zero,E0LN) + } + + If(LEqual(PM5L,1)) + { + CreateBitField(BUF0, ^E000._RW,E0RW) + Store(Zero,E0RW) + } + + If(PM5H) + { + CreateDwordField(BUF0, ^E400._LEN,E4LN) + Store(Zero,E4LN) + } + + If(LEqual(PM5H,1)) + { + CreateBitField(BUF0, ^E400._RW,E4RW) + Store(Zero,E4RW) + } + + If(PM6L) + { + CreateDwordField(BUF0, ^E800._LEN,E8LN) + Store(Zero,E8LN) + } + + If(LEqual(PM6L,1)) + { + CreateBitField(BUF0, ^E800._RW,E8RW) + Store(Zero,E8RW) + } + + If(PM6H) + { + CreateDwordField(BUF0, ^EC00._LEN,ECLN) + Store(Zero,ECLN) + } + + If(LEqual(PM6H,1)) + { + CreateBitField(BUF0, ^EC00._RW,ECRW) + Store(Zero,ECRW) + } + + If(PM0H) + { + CreateDwordField(BUF0, ^F000._LEN,F0LN) + Store(Zero,F0LN) + } + + If(LEqual(PM0H,1)) + { + CreateBitField(BUF0, ^F000._RW,F0RW) + Store(Zero,F0RW) + } + + // + // Create pointers to Memory Sizing values. + // + CreateDwordField(BUF0, ^PM01._MIN,M1MN) + CreateDwordField(BUF0, ^PM01._MAX,M1MX) + CreateDwordField(BUF0, ^PM01._LEN,M1LN) + + // + // Set Memory Size Values. TLUD represents bits 31:20 of phyical + // TOM, so shift these bits into the correct position and fix up + // the Memory Region available to PCI. + // + Store (0x50800000, M1LN) + Store (0x8F800000, M1MN) + Subtract (Add (M1MN, M1LN), 1, M1MX) + + // + // Create pointers to Memory Sizing values. + // Patch PM02 range basing on memory size and OS type + // + CreateQwordField(BUF0, ^PM02._LEN,MSLN) + // + // Set resource length to 0 + // + Store (0, MSLN) + + D8XH (0, 0xC5) + D8XH (1, 0xAA) + + Return(BUF0) +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/= PciTree.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt= /PciTree.asl new file mode 100644 index 0000000000..ff3b0dbe08 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/PciTree= .asl @@ -0,0 +1,309 @@ +/** @file + ACPI DSDT table + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +Scope(\_SB) { + Name(PD00, Package(){ +// If the setting changed in PCH PxRcConfig policy, platform should also u= pdate static assignment here. +// PCI Bridge +// D31: cAVS, SMBus, GbE, Nothpeak + Package(){0x001FFFFF, 0, 0, 11 }, + Package(){0x001FFFFF, 1, 0, 10 }, + Package(){0x001FFFFF, 2, 0, 11 }, + Package(){0x001FFFFF, 3, 0, 11 }, +// D30: SerialIo and SCS - can't use PIC +// D29: PCI Express Port 9-16 + Package(){0x001DFFFF, 0, 0, 11 }, + Package(){0x001DFFFF, 1, 0, 10 }, + Package(){0x001DFFFF, 2, 0, 11 }, + Package(){0x001DFFFF, 3, 0, 11 }, +// D28: PCI Express Port 1-8 + Package(){0x001CFFFF, 0, 0, 11 }, + Package(){0x001CFFFF, 1, 0, 10 }, + Package(){0x001CFFFF, 2, 0, 11 }, + Package(){0x001CFFFF, 3, 0, 11 }, +// D27: PCI Express Port 17-20 + Package(){0x001BFFFF, 0, 0, 11 }, + Package(){0x001BFFFF, 1, 0, 10 }, + Package(){0x001BFFFF, 2, 0, 11 }, + Package(){0x001BFFFF, 3, 0, 11 }, +// D25: SerialIo - can't use PIC +// D23: SATA controller + Package(){0x0017FFFF, 0, 0, 11 }, +// D22: CSME (HECI, IDE-R, Keyboard and Text redirection + Package(){0x0016FFFF, 0, 0, 11 }, + Package(){0x0016FFFF, 1, 0, 10 }, + Package(){0x0016FFFF, 2, 0, 11 }, + Package(){0x0016FFFF, 3, 0, 11 }, +// D21: SerialIo - can't use PIC +// D20: xHCI, OTG, Thermal Subsystem, Camera IO Host Controller +// D20: xHCI, OTG, CNVi WiFi, SDcard + Package(){0x0014FFFF, 0, 0, 11 }, + Package(){0x0014FFFF, 1, 0, 10 }, + Package(){0x0014FFFF, 2, 0, 11 }, + Package(){0x0014FFFF, 3, 0, 11 }, +// D19: Integrated Sensor Hub - can't use PIC +// D18: Thermal, UFS, SerialIo SPI2 - can't use PIC + Package(){0x0012FFFF, 0, 0, 11 }, + Package(){0x0012FFFF, 1, 0, 10 }, + Package(){0x0012FFFF, 2, 0, 11 }, + Package(){0x0012FFFF, 3, 0, 11 }, + +// Host Bridge +// P.E.G. Root Port D1F0 + Package(){0x0001FFFF, 0, 0, 11 }, + Package(){0x0001FFFF, 1, 0, 10 }, + Package(){0x0001FFFF, 2, 0, 11 }, + Package(){0x0001FFFF, 3, 0, 11 }, +// P.E.G. Root Port D1F1 +// P.E.G. Root Port D1F2 +// SA IGFX Device + Package(){0x0002FFFF, 0, 0, 11 }, +// SA Thermal Device + Package(){0x0004FFFF, 0, 0, 11 }, +// SA IPU Device + Package(){0x0005FFFF, 0, 0, 11 }, +// SA GNA Device + Package(){0x0008FFFF, 0, 0, 11 }, + }) + Name(AR00, Package(){ +// PCI Bridge +// D31: cAVS, SMBus, GbE, Nothpeak + Package(){0x001FFFFF, 0, 0, 16 }, + Package(){0x001FFFFF, 1, 0, 17 }, + Package(){0x001FFFFF, 2, 0, 18 }, + Package(){0x001FFFFF, 3, 0, 19 }, +// D30: SerialIo and SCS + Package(){0x001EFFFF, 0, 0, 20 }, + Package(){0x001EFFFF, 1, 0, 21 }, + Package(){0x001EFFFF, 2, 0, 22 }, + Package(){0x001EFFFF, 3, 0, 23 }, +// D29: PCI Express Port 9-16 + Package(){0x001DFFFF, 0, 0, 16 }, + Package(){0x001DFFFF, 1, 0, 17 }, + Package(){0x001DFFFF, 2, 0, 18 }, + Package(){0x001DFFFF, 3, 0, 19 }, +// D28: PCI Express Port 1-8 + Package(){0x001CFFFF, 0, 0, 16 }, + Package(){0x001CFFFF, 1, 0, 17 }, + Package(){0x001CFFFF, 2, 0, 18 }, + Package(){0x001CFFFF, 3, 0, 19 }, +// D27: PCI Express Port 17-20 + Package(){0x001BFFFF, 0, 0, 16 }, + Package(){0x001BFFFF, 1, 0, 17 }, + Package(){0x001BFFFF, 2, 0, 18 }, + Package(){0x001BFFFF, 3, 0, 19 }, +// D26: eMMC + Package(){0x001AFFFF, 0, 0, 16 }, + Package(){0x001AFFFF, 1, 0, 17 }, + Package(){0x001AFFFF, 2, 0, 18 }, + Package(){0x001AFFFF, 3, 0, 19 }, +// D25: SerialIo + Package(){0x0019FFFF, 0, 0, 32 }, + Package(){0x0019FFFF, 1, 0, 33 }, + Package(){0x0019FFFF, 2, 0, 34 }, +// D23: SATA controller + Package(){0x0017FFFF, 0, 0, 16 }, +// D22: CSME (HECI, IDE-R, Keyboard and Text redirection + Package(){0x0016FFFF, 0, 0, 16 }, + Package(){0x0016FFFF, 1, 0, 17 }, + Package(){0x0016FFFF, 2, 0, 18 }, + Package(){0x0016FFFF, 3, 0, 19 }, +// D21: SerialIo + Package(){0x0015FFFF, 0, 0, 16 }, + Package(){0x0015FFFF, 1, 0, 17 }, + Package(){0x0015FFFF, 2, 0, 18 }, + Package(){0x0015FFFF, 3, 0, 19 }, +// D20: xHCI, OTG, Thermal Subsystem, Camera IO Host Controller +// D20: xHCI, OTG, CNVi WiFi, SDcard + Package(){0x0014FFFF, 0, 0, 16 }, + Package(){0x0014FFFF, 1, 0, 17 }, + Package(){0x0014FFFF, 2, 0, 18 }, + Package(){0x0014FFFF, 3, 0, 19 }, +// D19: Integrated Sensor Hub + Package(){0x0013FFFF, 0, 0, 20 }, +// D18: Thermal, UFS, SerialIo SPI 2 + Package(){0x0012FFFF, 0, 0, 16 }, + Package(){0x0012FFFF, 1, 0, 24 }, + Package(){0x0012FFFF, 2, 0, 18 }, + Package(){0x0012FFFF, 3, 0, 19 }, + +// Host Bridge +// P.E.G. Root Port D1F0 + Package(){0x0001FFFF, 0, 0, 16 }, + Package(){0x0001FFFF, 1, 0, 17 }, + Package(){0x0001FFFF, 2, 0, 18 }, + Package(){0x0001FFFF, 3, 0, 19 }, +// P.E.G. Root Port D1F1 +// P.E.G. Root Port D1F2 +// SA IGFX Device + Package(){0x0002FFFF, 0, 0, 16 }, +// SA Thermal Device + Package(){0x0004FFFF, 0, 0, 16 }, +// SA IPU Device + Package(){0x0005FFFF, 0, 0, 16 }, +// SA GNA Device + Package(){0x0008FFFF, 0, 0, 16 }, + }) + Name(PD04, Package(){ + Package(){0x0000FFFF, 0, 0, 11 }, + Package(){0x0000FFFF, 1, 0, 10 }, + Package(){0x0000FFFF, 2, 0, 11 }, + Package(){0x0000FFFF, 3, 0, 11 }, + }) + Name(AR04, Package(){ + Package(){0x0000FFFF, 0, 0, 16 }, + Package(){0x0000FFFF, 1, 0, 17 }, + Package(){0x0000FFFF, 2, 0, 18 }, + Package(){0x0000FFFF, 3, 0, 19 }, + }) + Name(PD05, Package(){ + Package(){0x0000FFFF, 0, 0, 10 }, + Package(){0x0000FFFF, 1, 0, 11 }, + Package(){0x0000FFFF, 2, 0, 11 }, + Package(){0x0000FFFF, 3, 0, 11 }, + }) + Name(AR05, Package(){ + Package(){0x0000FFFF, 0, 0, 17 }, + Package(){0x0000FFFF, 1, 0, 18 }, + Package(){0x0000FFFF, 2, 0, 19 }, + Package(){0x0000FFFF, 3, 0, 16 }, + }) + Name(PD06, Package(){ + Package(){0x0000FFFF, 0, 0, 11 }, + Package(){0x0000FFFF, 1, 0, 11 }, + Package(){0x0000FFFF, 2, 0, 11 }, + Package(){0x0000FFFF, 3, 0, 10 }, + }) + Name(AR06, Package(){ + Package(){0x0000FFFF, 0, 0, 18 }, + Package(){0x0000FFFF, 1, 0, 19 }, + Package(){0x0000FFFF, 2, 0, 16 }, + Package(){0x0000FFFF, 3, 0, 17 }, + }) + Name(PD07, Package(){ + Package(){0x0000FFFF, 0, 0, 11 }, + Package(){0x0000FFFF, 1, 0, 11 }, + Package(){0x0000FFFF, 2, 0, 10 }, + Package(){0x0000FFFF, 3, 0, 11 }, + }) + Name(AR07, Package(){ + Package(){0x0000FFFF, 0, 0, 19 }, + Package(){0x0000FFFF, 1, 0, 16 }, + Package(){0x0000FFFF, 2, 0, 17 }, + Package(){0x0000FFFF, 3, 0, 18 }, + }) + Name(PD08, Package(){ + Package(){0x0000FFFF, 0, 0, 11 }, + Package(){0x0000FFFF, 1, 0, 10 }, + Package(){0x0000FFFF, 2, 0, 11 }, + Package(){0x0000FFFF, 3, 0, 11 }, + }) + Name(AR08, Package(){ + Package(){0x0000FFFF, 0, 0, 16 }, + Package(){0x0000FFFF, 1, 0, 17 }, + Package(){0x0000FFFF, 2, 0, 18 }, + Package(){0x0000FFFF, 3, 0, 19 }, + }) + Name(PD09, Package(){ + Package(){0x0000FFFF, 0, 0, 10 }, + Package(){0x0000FFFF, 1, 0, 11 }, + Package(){0x0000FFFF, 2, 0, 11 }, + Package(){0x0000FFFF, 3, 0, 11 }, + }) + Name(AR09, Package(){ + Package(){0x0000FFFF, 0, 0, 17 }, + Package(){0x0000FFFF, 1, 0, 18 }, + Package(){0x0000FFFF, 2, 0, 19 }, + Package(){0x0000FFFF, 3, 0, 16 }, + }) + Name(PD0E, Package(){ + Package(){0x0000FFFF, 0, 0, 11 }, + Package(){0x0000FFFF, 1, 0, 11 }, + Package(){0x0000FFFF, 2, 0, 11 }, + Package(){0x0000FFFF, 3, 0, 10 }, + }) + Name(AR0E, Package(){ + Package(){0x0000FFFF, 0, 0, 18 }, + Package(){0x0000FFFF, 1, 0, 19 }, + Package(){0x0000FFFF, 2, 0, 16 }, + Package(){0x0000FFFF, 3, 0, 17 }, + }) + Name(PD0F, Package(){ + Package(){0x0000FFFF, 0, 0, 11 }, + Package(){0x0000FFFF, 1, 0, 11 }, + Package(){0x0000FFFF, 2, 0, 10 }, + Package(){0x0000FFFF, 3, 0, 11 }, + }) + Name(AR0F, Package(){ + Package(){0x0000FFFF, 0, 0, 19 }, + Package(){0x0000FFFF, 1, 0, 16 }, + Package(){0x0000FFFF, 2, 0, 17 }, + Package(){0x0000FFFF, 3, 0, 18 }, + }) + Name(PD02, Package(){ + Package(){0x0000FFFF, 0, 0, 11 }, + Package(){0x0000FFFF, 1, 0, 10 }, + Package(){0x0000FFFF, 2, 0, 11 }, + Package(){0x0000FFFF, 3, 0, 11 }, + }) + Name(AR02, Package(){ +// P.E.G. Port Slot x16 + Package(){0x0000FFFF, 0, 0, 16 }, + Package(){0x0000FFFF, 1, 0, 17 }, + Package(){0x0000FFFF, 2, 0, 18 }, + Package(){0x0000FFFF, 3, 0, 19 }, + }) + Name(PD0A, Package(){ +// P.E.G. Port Slot x8 + Package(){0x0000FFFF, 0, 0, 10 }, + Package(){0x0000FFFF, 1, 0, 11 }, + Package(){0x0000FFFF, 2, 0, 11 }, + Package(){0x0000FFFF, 3, 0, 11 }, + }) + Name(AR0A, Package(){ +// P.E.G. Port Slot x8 + Package(){0x0000FFFF, 0, 0, 17 }, + Package(){0x0000FFFF, 1, 0, 18 }, + Package(){0x0000FFFF, 2, 0, 19 }, + Package(){0x0000FFFF, 3, 0, 16 }, + }) + Name(PD0B, Package(){ +// P.E.G. Port Slot x4 + Package(){0x0000FFFF, 0, 0, 11 }, + Package(){0x0000FFFF, 1, 0, 11 }, + Package(){0x0000FFFF, 2, 0, 11 }, + Package(){0x0000FFFF, 3, 0, 10 }, + }) + Name(AR0B, Package(){ +// P.E.G. Port Slot x4 + Package(){0x0000FFFF, 0, 0, 18 }, + Package(){0x0000FFFF, 1, 0, 19 }, + Package(){0x0000FFFF, 2, 0, 16 }, + Package(){0x0000FFFF, 3, 0, 17 }, + }) + +//------------------------------------------------------------------------= --- +// Begin PCI tree object scope +//------------------------------------------------------------------------= --- + Device(PCI0) { // PCI Bridge "Host Bridge" + Name(_HID, EISAID("PNP0A08")) // Indicates PCI Express/PCI-X Mode2 hos= t hierarchy + Name(_CID, EISAID("PNP0A03")) // To support legacy OS that doesn't und= erstand the new HID + Name(_SEG, 0) + Name(_ADR, 0x00000000) + Method(^BN00, 0){ return(0x0000) } // Returns default Bus number for = Peer PCI busses. Name can be overriden with control method placed directly = under Device scope + Method(_BBN, 0){ return(BN00()) } // Bus number, optional for the Root= PCI Bus + Name(_UID, 0x0000) // Unique Bus ID, optional + Method(_PRT,0) { + If(PICM) {Return(AR00)} // APIC mode + Return (PD00) // PIC Mode + } // end _PRT + + Include("HostBus.asl") + } // end PCI0 Bridge "Host Bridge" +} // end _SB scope + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/= Platform.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsd= t/Platform.asl new file mode 100644 index 0000000000..951c01455f --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Acpi/BoardAcpiDxe/Dsdt/Platfor= m.asl @@ -0,0 +1,76 @@ +/** @file + ACPI DSDT table + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +// Define Port 80 as an ACPI Operating Region to use for debugging. Pleas= e +// note that the Intel CRBs have the ability to ouput a Word to +// Port 80h for debugging purposes, so the model implemented here may not = be +// able to be used on OEM Designs. + +OperationRegion(PRT0,SystemIO,0x80,2) +Field(PRT0,WordAcc,Lock,Preserve) +{ + P80B, 16 +} + +// Port 80h Update: +// Update 2 bytes of Port 80h. +// +// Arguments: +// Arg0: 0 =3D Write Port 80h +// 1 =3D Write Port 81h +// Arg1: 8-bit Value to write +// +// Return Value: +// None + +Name(P80T, 0) // temp buffer for P80 + +Method(D8XH,2,Serialized) +{ + If(LEqual(Arg0,0)) // Write Port 80h + { + Store(Or(And(P80T,0xFF00),Arg1),P80T) + } + If(LEqual(Arg0,1)) // Write Port 81h + { + Store(Or(And(P80T,0x00FF),ShiftLeft(Arg1,8)),P80T) + } + Store(P80T,P80B) +} + +// +// Define SW SMI port as an ACPI Operating Region to use for generate SW S= MI. +// +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 =3D 8259 +// 1 =3D IOAPIC + +Method(\_PIC,1) +{ + Store(Arg0,PICM) +} + +Scope (\) +{ + // + // Global Name, returns current Interrupt controller mode; + // updated from _PIC control method + // + Name(PICM, 0) +} + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables= /Rtd3PcieTbt.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/Acpi= Tables/Rtd3PcieTbt.asl new file mode 100644 index 0000000000..38d60d6dbd --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Rtd3Pc= ieTbt.asl @@ -0,0 +1,405 @@ +/** @file + ACPI RTD3 SSDT table for SPT PCIe + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#define PID_ICC 0xDC +#define R_PCH_PCR_ICC_MSKCKRQ 0x100C = ///< Mask Control CLKREQ + +External(PCRA,MethodObj) +External(PCRO,MethodObj) +External(\MMRP, MethodObj) +External(\MMTB, MethodObj) +External(\TRDO, IntObj) +External(\TRD3, IntObj) +External(\TBPE, IntObj) +External(\TOFF, IntObj) +External(\TBSE, IntObj) +External(\TBOD, IntObj) +External(\TBRP, IntObj) +External(\TBHR, IntObj) +External(\RTBC, IntObj) +External(\TBCD, IntObj) + +Name(G2SD, 0) // Go2Sx done, set by GO2S, cleaned by _ON + +Name(WKEN, 0) + + Method(_S0W, 0) + { + /// This method returns the lowest D-state supported by PCIe root port d= uring 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 WA= KE# 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(In= dex(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(In= dex(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 M= MIO + 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 M= MIO + 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_exi= t + If (TBPE) { + Return() + } + + Store(0,G2SD) + If (\RTBC) { + /// de-assert CLK_REQ MSK + if(LNotEqual(DeRefOf(Index(SCLK, 0)),0)) { // if power gating enab= led + 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 enable= d + 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 hap= pens 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]) =3D 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 M= MIO + 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]) =3D 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 enab= led + 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 enable= d + 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 ena= bled + 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=3DACPI mode, 1=3DGPIO mode) + } + If (LEqual(DeRefOf(Index(WAKG, 0)),2)) { // IOEX mode + \_SB.PCI0.GEXP.SGEP(DeRefOf(Index(WAKG, 1)),DeRefOf(Index(WAKG= , 2)),DeRefOf(Index(WAKG, 3))) + } + } + } + Sleep(\TBOD) + /** @defgroup pcie_off PCIE _OFF method **/ + } // End of Method_OFF + + Name(_PR0, Package(){PXP}) + Name(_PR3, Package(){PXP}) + + diff --git a/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables= /Tbt.asl b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/T= bt.asl new file mode 100644 index 0000000000..66584c21c5 --- /dev/null +++ b/Platform/Intel/WhiskeylakeOpenBoardPkg/Features/Tbt/AcpiTables/Tbt.as= l @@ -0,0 +1,1877 @@ +/** @file + Thunderbolt ACPI methods + + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#define DTBT_CONTROLLER 0x00 +#define DTBT_TYPE_PCH 0x01 +#define DTBT_TYPE_PEG 0x02 +#define DTBT_SMI_HANDLER_NUMBER 0xF7 +#define TBT_SMI_ENUMERATION_FUNCTION 21 +#define TBT_SMI_RESET_SWITCH_FUNCTION 22 +#define TBT_SMI_DISABLE_MSI_FUNCTION 23 +#ifndef BIT29 +#define BIT29 0x20000000 +#endif + +Name(LDLY, 300) //300 ms +Name (TNVB, 0xFFFF0000) // TBT NVS Base address +Name (TNVL, 0xAA55) // TBT NVS Length +Include ("Acpi/TbtNvs.asl") + +External(\_SB.PCI0.RP02.L23D, MethodObj) +External(\_SB.PCI0.RP03.L23D, MethodObj) +External(\_SB.PCI0.RP04.L23D, MethodObj) +External(\_SB.PCI0.RP05.L23D, MethodObj) +External(\_SB.PCI0.RP06.L23D, MethodObj) +External(\_SB.PCI0.RP07.L23D, MethodObj) +External(\_SB.PCI0.RP08.L23D, MethodObj) +External(\_SB.PCI0.RP09.L23D, MethodObj) +External(\_SB.PCI0.RP10.L23D, MethodObj) +External(\_SB.PCI0.RP11.L23D, MethodObj) +External(\_SB.PCI0.RP12.L23D, MethodObj) +External(\_SB.PCI0.RP13.L23D, MethodObj) +External(\_SB.PCI0.RP14.L23D, MethodObj) +External(\_SB.PCI0.RP15.L23D, MethodObj) +External(\_SB.PCI0.RP16.L23D, MethodObj) +External(\_SB.PCI0.RP17.L23D, MethodObj) +External(\_SB.PCI0.RP18.L23D, MethodObj) +External(\_SB.PCI0.RP19.L23D, MethodObj) +External(\_SB.PCI0.RP20.L23D, MethodObj) +External(\_SB.PCI0.RP21.L23D, MethodObj) +External(\_SB.PCI0.RP22.L23D, MethodObj) +External(\_SB.PCI0.RP23.L23D, MethodObj) +External(\_SB.PCI0.RP24.L23D, MethodObj) + +External(\_SB.PCI0.RP01.DL23, MethodObj) +External(\_SB.PCI0.RP02.DL23, MethodObj) +External(\_SB.PCI0.RP03.DL23, MethodObj) +External(\_SB.PCI0.RP04.DL23, MethodObj) +External(\_SB.PCI0.RP05.DL23, MethodObj) +External(\_SB.PCI0.RP06.DL23, MethodObj) +External(\_SB.PCI0.RP07.DL23, MethodObj) +External(\_SB.PCI0.RP08.DL23, MethodObj) +External(\_SB.PCI0.RP09.DL23, MethodObj) +External(\_SB.PCI0.RP10.DL23, MethodObj) +External(\_SB.PCI0.RP11.DL23, MethodObj) +External(\_SB.PCI0.RP12.DL23, MethodObj) +External(\_SB.PCI0.RP13.DL23, MethodObj) +External(\_SB.PCI0.RP14.DL23, MethodObj) +External(\_SB.PCI0.RP15.DL23, MethodObj) +External(\_SB.PCI0.RP16.DL23, MethodObj) +External(\_SB.PCI0.RP17.DL23, MethodObj) +External(\_SB.PCI0.RP18.DL23, MethodObj) +External(\_SB.PCI0.RP19.DL23, MethodObj) +External(\_SB.PCI0.RP20.DL23, MethodObj) +External(\_SB.PCI0.RP21.DL23, MethodObj) +External(\_SB.PCI0.RP22.DL23, MethodObj) +External(\_SB.PCI0.RP23.DL23, MethodObj) +External(\_SB.PCI0.RP24.DL23, MethodObj) + +External(\_SB.PCI0.RTEN, MethodObj) +External(\_SB.PCI0.RTDS, MethodObj) +External(\_SB.PCI0.RP01.PON, MethodObj) +External(\_SB.PCI0.RP02.PON, MethodObj) +External(\_SB.PCI0.RP03.PON, MethodObj) +External(\_SB.PCI0.RP04.PON, MethodObj) +External(\_SB.PCI0.RP05.PON, MethodObj) +External(\_SB.PCI0.RP06.PON, MethodObj) +External(\_SB.PCI0.RP07.PON, MethodObj) +External(\_SB.PCI0.RP08.PON, MethodObj) +External(\_SB.PCI0.RP09.PON, MethodObj) +External(\_SB.PCI0.RP10.PON, MethodObj) +External(\_SB.PCI0.RP11.PON, MethodObj) +External(\_SB.PCI0.RP12.PON, MethodObj) +External(\_SB.PCI0.RP13.PON, MethodObj) +External(\_SB.PCI0.RP14.PON, MethodObj) +External(\_SB.PCI0.RP15.PON, MethodObj) +External(\_SB.PCI0.RP16.PON, MethodObj) +External(\_SB.PCI0.RP17.PON, MethodObj) +External(\_SB.PCI0.RP18.PON, MethodObj) +External(\_SB.PCI0.RP19.PON, MethodObj) +External(\_SB.PCI0.RP20.PON, MethodObj) +External(\_SB.PCI0.RP21.PON, MethodObj) +External(\_SB.PCI0.RP22.PON, MethodObj) +External(\_SB.PCI0.RP23.PON, MethodObj) +External(\_SB.PCI0.RP24.PON, MethodObj) +External(\_SB.PCI0.PEG0.PG00._ON, MethodObj) +External(\_SB.PCI0.PEG1.PG01._ON, MethodObj) +External(\_SB.PCI0.PEG2.PG02._ON, MethodObj) + +Name(TRDO, 0) // 1 during TBT RTD3 _ON +Name(TRD3, 0) // 1 during TBT RTD3 _OFF +Name(TBPE, 0) // Reflects RTD3_PWR_EN value +Name(TOFF, 0) // param to TBT _OFF method + + Method (TBON, 0, Serialized) { + // TBT On process before entering Sx state. + Store(1, TRDO) + Switch (ToInteger(\RPS0)) { // TBT Root port Selector + Case (1) { + If (CondRefOf(\_SB.PCI0.RP01.PON)) { + \_SB.PCI0.RP01.PON() + } + } + Case (2) { + If (CondRefOf(\_SB.PCI0.RP02.PON)) { + \_SB.PCI0.RP02.PON() + } + } + Case (3) { + If (CondRefOf(\_SB.PCI0.RP03.PON)) { + \_SB.PCI0.RP03.PON() + } + } + Case (4) { + If (CondRefOf(\_SB.PCI0.RP04.PON)) { + \_SB.PCI0.RP04.PON() + } + } + Case (5) { + If (CondRefOf(\_SB.PCI0.RP05.PON)) { + \_SB.PCI0.RP05.PON() + } + } + Case (6) { + If (CondRefOf(\_SB.PCI0.RP06.PON)) { + \_SB.PCI0.RP06.PON() + } + } + Case (7) { + If (CondRefOf(\_SB.PCI0.RP07.PON)) { + \_SB.PCI0.RP07.PON() + } + } + Case (8) { + If (CondRefOf(\_SB.PCI0.RP08.PON)) { + \_SB.PCI0.RP08.PON() + } + } + Case (9) { + If (CondRefOf(\_SB.PCI0.RP09.PON)) { + \_SB.PCI0.RP09.PON() + } + } + Case (10) { + If (CondRefOf(\_SB.PCI0.RP10.PON)) { + \_SB.PCI0.RP10.PON() + } + } + Case (11) { + If (CondRefOf(\_SB.PCI0.RP11.PON)) { + \_SB.PCI0.RP11.PON() + } + } + Case (12) { + If (CondRefOf(\_SB.PCI0.RP12.PON)) { + \_SB.PCI0.RP12.PON() + } + } + Case (13) { + If (CondRefOf(\_SB.PCI0.RP13.PON)) { + \_SB.PCI0.RP13.PON() + } + } + Case (14) { + If (CondRefOf(\_SB.PCI0.RP14.PON)) { + \_SB.PCI0.RP14.PON() + } + } + Case (15) { + If (CondRefOf(\_SB.PCI0.RP15.PON)) { + \_SB.PCI0.RP15.PON() + } + } + Case (16) { + If (CondRefOf(\_SB.PCI0.RP16.PON)) { + \_SB.PCI0.RP16.PON() + } + } + Case (17) { + If (CondRefOf(\_SB.PCI0.RP17.PON)) { + \_SB.PCI0.RP17.PON() + } + } + Case (18) { + If (CondRefOf(\_SB.PCI0.RP18.PON)) { + \_SB.PCI0.RP18.PON() + } + } + Case (19) { + If (CondRefOf(\_SB.PCI0.RP19.PON)) { + \_SB.PCI0.RP19.PON() + } + } + Case (20) { + If (CondRefOf(\_SB.PCI0.RP20.PON)) { + \_SB.PCI0.RP20.PON() + } + } + Case (21) { + If (CondRefOf(\_SB.PCI0.RP21.PON)) { + \_SB.PCI0.RP21.PON() + } + } + Case (22) { + If (CondRefOf(\_SB.PCI0.RP22.PON)) { + \_SB.PCI0.RP22.PON() + } + } + Case (23) { + If (CondRefOf(\_SB.PCI0.RP23.PON)) { + \_SB.PCI0.RP23.PON() + } + } + Case (24) { + If (CondRefOf(\_SB.PCI0.RP24.PON)) { + \_SB.PCI0.RP24.PON() + } + } + }//Switch(ToInteger(RPS0)) // TBT Selector + Store(0, TRDO) + } // End of TBON + // + // Name: TBTD + // Description: Function to return the TBT RP# device no + // Input: Arg0 -> Tbt Root Port value from Tbt NVS + // Input: Arg1 -> Tbt port type value from Tbt NVS + // Return: TBT RP# device no + // + Method(TBTD,2) + { + ADBG("TBTD") + If (LEqual(Arg1, DTBT_TYPE_PCH)) { + Switch(ToInteger(Arg0)) + { + Case (Package () {1, 2, 3, 4, 5, 6, 7, 8}) + { + Store(0x1C, Local0) //Device28-Function0...Function7 =3D 11100.0= 00...111 + } + Case (Package () {9, 10, 11, 12, 13, 14, 15, 16}) + { + Store(0x1D, Local0) //Device29-Function0...Function7 =3D 11101.0= 00...111 + } + Case (Package () {17, 18, 19, 20, 21, 22, 23, 24}) + { + Store(0x1B, Local0) //Device27-Function0...Function3 =3D 11011.0= 00...011 + } + } + } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) { + Switch(ToInteger(Arg0)) + { + Case (Package () {1, 2, 3}) + { + Store(0x1, Local0) //Device1-Function0...Function2 =3D 00001.000= ...010 + } + } + } Else { + Store(0xFF, Local0) + } + + ADBG("Device no") + ADBG(Local0) + + Return(Local0) + } // End of Method(TBTD,1) + + // + // Name: TBTF + // Description: Function to return the TBT RP# function no + // Input: Arg0 -> Tbt Root Port value from Tbt NVS + // Input: Arg1 -> Tbt port type value from Tbt NVS + // Return: TBT RP# function no + // + Method(TBTF,2) + { + ADBG("TBTF") + If (LEqual(Arg1, DTBT_TYPE_PCH)) { + Switch(ToInteger(Arg0)) + { + Case (1) + { + Store(And(\RPA1,0xF), Local0) //Device28-Function0 =3D 11100.000 + } + Case (2) + { + Store(And(\RPA2,0xF), Local0) //Device28-Function1 =3D 11100.001 + } + Case (3) + { + Store(And(\RPA3,0xF), Local0) //Device28-Function2 =3D 11100.010 + } + Case (4) + { + Store(And(\RPA4,0xF), Local0) //Device28-Function3 =3D 11100.011 + } + Case (5) + { + Store(And(\RPA5,0xF), Local0) //Device28-Function4 =3D 11100.100 + } + Case (6) + { + Store(And(\RPA6,0xF), Local0) //Device28-Function5 =3D 11100.101 + } + Case (7) + { + Store(And(\RPA7,0xF), Local0) //Device28-Function6 =3D 11100.110 + } + Case (8) + { + Store(And(\RPA8,0xF), Local0) //Device28-Function7 =3D 11100.111 + } + Case (9) + { + Store(And(\RPA9,0xF), Local0) //Device29-Function0 =3D 11101.000 + } + Case (10) + { + Store(And(\RPAA,0xF), Local0) //Device29-Function1 =3D 11101.001 + } + Case (11) + { + Store(And(\RPAB,0xF), Local0) //Device29-Function2 =3D 11101.010 + } + Case (12) + { + Store(And(\RPAC,0xF), Local0) //Device29-Function3 =3D 11101.011 + } + Case (13) + { + Store(And(\RPAD,0xF), Local0) //Device29-Function4 =3D 11101.100 + } + Case (14) + { + Store(And(\RPAE,0xF), Local0) //Device29-Function5 =3D 11101.101 + } + Case (15) + { + Store(And(\RPAF,0xF), Local0) //Device29-Function6 =3D 11101.110 + } + Case (16) + { + Store(And(\RPAG,0xF), Local0) //Device29-Function7 =3D 11101.111 + } + Case (17) + { + Store(And(\RPAH,0xF), Local0) //Device27-Function0 =3D 11011.000 + } + Case (18) + { + Store(And(\RPAI,0xF), Local0) //Device27-Function1 =3D 11011.001 + } + Case (19) + { + Store(And(\RPAJ,0xF), Local0) //Device27-Function2 =3D 11011.010 + } + Case (20) + { + Store(And(\RPAK,0xF), Local0) //Device27-Function3 =3D 11011.011 + } + Case (21) + { + Store(And(\RPAL,0xF), Local0) //Device27-Function4 =3D 11011.100 + } + Case (22) + { + Store(And(\RPAM,0xF), Local0) //Device27-Function5 =3D 11011.101 + } + Case (23) + { + Store(And(\RPAN,0xF), Local0) //Device27-Function6 =3D 11011.110 + } + Case (24) + { + Store(And(\RPAO,0xF), Local0) //Device27-Function7 =3D 11011.111 + } + } + } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) { + Switch(ToInteger(Arg0)) + { + Case (1) + { + Store(0x0, Local0) //Device1-Function0 =3D 00001.000 + } + Case (2) + { + Store(0x1, Local0) //Device1-Function1 =3D 00001.001 + } + Case (3) + { + Store(0x2, Local0) //Device1-Function2 =3D 00001.010 + } + } + } Else { + Store(0xFF, Local0) + } + + ADBG("Function no") + ADBG(Local0) + + Return(Local0) + } // End of Method(TBTF,1) + + // + // Name: MMRP + // Description: Function to return the Pci base address of TBT rootport + // Input: Arg0 -> Tbt Root Port value from Tbt NVS + // Input: Arg1 -> Tbt port type value from Tbt NVS + // + + Method(MMRP, 2, Serialized) + { + Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address + Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no + Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no + + Return(Local0) + } // End of Method(MMRP) + + // + // Name: MMRP + // Description: Function to return the Pci base address of TBT Up stream= port + // Input: Arg0 -> Tbt Root Port value from Tbt NVS + // Input: Arg1 -> Tbt port type value from Tbt NVS + // + Method(MMTB, 2, Serialized) + { + ADBG("MMTB") + + Store(\_SB.PCI0.GPCB(), Local0) // MMIO Base address + + Add(Local0, ShiftLeft(TBTD(Arg0, Arg1), 15), Local0) // Device no + Add(Local0, ShiftLeft(TBTF(Arg0, Arg1), 12), Local0) // Function no + + OperationRegion (MMMM, SystemMemory, Local0, 0x1A) + Field (MMMM, AnyAcc, NoLock, Preserve) + { + Offset(0x19), + SBUS, 8 + } + Store(SBUS, Local2) + Store(\_SB.PCI0.GPCB(), Local0) + Multiply(Local2, 0x100000, Local2) + Add(Local2, Local0, Local0) // TBT HR US port + + ADBG("TBT-US-ADR") + ADBG(Local0) + + Return(Local0) + } // End of Method(MMTB, 1, Serialized) + // + // Name: FFTB + // Description: Function to Check for FFFF in TBT PCIe + // Input: Arg0 -> Tbt Root Port value from Tbt NVS + // Input: Arg1 -> Tbt port type value from Tbt NVS + // Return: 1 if TBT PCIe space has value FFFF, 0 if not + // + Method(FFTB, 2, Serialized) + { + ADBG("FFTB") + + Add(MMTB(Arg0, Arg1), 0x548, Local0) + OperationRegion(PXVD,SystemMemory,Local0,0x08) + Field(PXVD,DWordAcc, NoLock, Preserve) + { + TB2P, 32, + P2TB, 32 + } + + Store(TB2P, Local1) + + If(LEqual(Local1, 0xFFFFFFFF)) + { + ADBG("FFTb 1") + Return (1) + } + Else + { + ADBG("FFTb 0") + Return (0) + } + } // End of Method(FFTB) + +Name(TDMA, 0x80000000) // Address of Thunderbolt(TM) debug memory buffer, = fixed up during POST + +Scope(\_GPE) +{ + // + // + //OS up Mail Box command execution to host router upstream port each tim= e + //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=3D", 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=3D", ToHexString(Local1))) + } // End of Method(WSUB) + + // Wait for _WAK finished + Method(WWAK) + { + ADBG("WWAK") + + Wait(WFEV, 0xFFFF) + Signal(WFEV) // Set it, to enter on next HP + } // End of Method(WWAK) + + Method(NTFY, 2, Serialized) + { + ADBG("NTFY") + + If(LEqual(NOHP,1)) + { + If (LEqual(Arg1, DTBT_TYPE_PCH)) { + Switch(ToInteger(Arg0)) // TBT Selector + { + Case (1) + { + ADBG("Notify RP01") + Notify(\_SB.PCI0.RP01,0) + } + Case (2) + { + ADBG("Notify RP02") + Notify(\_SB.PCI0.RP02,0) + } + Case (3) + { + ADBG("Notify RP03") + Notify(\_SB.PCI0.RP03,0) + } + Case (4) + { + ADBG("Notify RP04") + Notify(\_SB.PCI0.RP04,0) + } + Case (5) + { + ADBG("Notify RP05") + Notify(\_SB.PCI0.RP05,0) + } + Case (6) + { + ADBG("Notify RP06") + Notify(\_SB.PCI0.RP06,0) + } + Case (7) + { + ADBG("Notify RP07") + Notify(\_SB.PCI0.RP07,0) + } + Case (8) + { + ADBG("Notify RP08") + Notify(\_SB.PCI0.RP08,0) + } + Case (9) + { + ADBG("Notify RP09") + Notify(\_SB.PCI0.RP09,0) + } + Case (10) + { + ADBG("Notify RP10") + Notify(\_SB.PCI0.RP10,0) + } + Case (11) + { + ADBG("Notify RP11") + Notify(\_SB.PCI0.RP11,0) + } + Case (12) + { + ADBG("Notify RP12") + Notify(\_SB.PCI0.RP12,0) + } + Case (13) + { + ADBG("Notify RP13") + Notify(\_SB.PCI0.RP13,0) + } + Case (14) + { + ADBG("Notify RP14") + Notify(\_SB.PCI0.RP14,0) + } + Case (15) + { + ADBG("Notify RP15") + Notify(\_SB.PCI0.RP15,0) + } + Case (16) + { + ADBG("Notify RP16") + Notify(\_SB.PCI0.RP16,0) + } + Case (17) + { + ADBG("Notify RP17") + Notify(\_SB.PCI0.RP17,0) + } + Case (18) + { + ADBG("Notify RP18") + Notify(\_SB.PCI0.RP18,0) + } + Case (19) + { + ADBG("Notify RP19") + Notify(\_SB.PCI0.RP19,0) + } + Case (20) + { + ADBG("Notify RP20") + Notify(\_SB.PCI0.RP20,0) + } + Case (21) + { + ADBG("Notify RP21") + Notify(\_SB.PCI0.RP21,0) + } + Case (22) + { + ADBG("Notify RP22") + Notify(\_SB.PCI0.RP22,0) + } + Case (23) + { + ADBG("Notify RP23") + Notify(\_SB.PCI0.RP23,0) + } + Case (24) + { + ADBG("Notify RP24") + Notify(\_SB.PCI0.RP24,0) + } + }//Switch(ToInteger(TBSS)) // TBT Selector + } ElseIf (LEqual(Arg1, DTBT_TYPE_PEG)) { + Switch(ToInteger(Arg0)) + { + Case (1) + { + ADBG("Notify PEG0") + Notify(\_SB.PCI0.PEG0,0) + } + Case (2) + { + ADBG("Notify PEG1") + Notify(\_SB.PCI0.PEG1,0) + } + Case (3) + { + ADBG("Notify PEG2") + Notify(\_SB.PCI0.PEG2,0) + } + } + }//Switch(ToInteger(TBSS)) // TBT Selector + }//If(NOHP()) + P8XH(0,0xC2) + P8XH(1,0xC2) + }// End of Method(NTFY) + +// +// TBT BIOS, GPIO 5 filtering, +// Hot plug of 12V USB devices, into TBT host router, cause electrical no= ise on PCH GPIOs, +// This noise cause false hot-plug events, and negatively influence BIOS = assisted hot-plug. +// WHL-PCH GPIO does not implement Glitch Filter logic (refer to GPIO HAS= ) on any GPIO pad. Native functions have to implement their own digital gli= tch-filter logic +// if needed. As HW filter was not implemented on WHL PCH, because of tha= t 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 fl= ow, if bit is 0 BIOS will exit from method +// + + Method(GNIS,2, Serialized) + { + + ADBG("GNIS") + If(LEqual(GP5F, 0)) + { + ADBG("GNIS_Dis=3D0") + 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=3D", ToHexString(Local1))) + If(LEqual(Local1, 0xFFFFFFFF)) // Disconnect? + { + ADBG("GNIS=3D0") + Return(0) + } + Store(HPFI, Local2) + ADBG(Concatenate("HPFI=3D", ToHexString(Local2))) + If(LEqual(Local2, 0x01)) + { + Store(0x00, HPFI) + ADBG("GNIS=3D0") + Return(0) + } + // Any other values treated as a GPIO noise + ADBG("GNIS=3D1") + 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=3D", ToHexString(Local1))) + //ADBG(Concatenate("BIT29=3D", 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 us= ed as 1 Tier GPIO Handler for 1st controller + // If CIO GPIO(1 Tier) is Same for all the controllers, this will be use= d 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 G= PI 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 indic= ator} + // 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 regist= er + If(LEqual(Local7, 0xFFFF)) + { + ADBG("Referenced device is not present") + Return(0) + } + + Store(PERW(Arg0, Arg1, Arg2, Arg3, 0x06), Local0) //Device Status re= gister + 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) //Capa= bilityPtr + Return(0) + } + } // End of Method(STDC,5,Serialized) + +} // End Scope(\_SB) + --=20 2.16.2.windows.1