From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.31, mailfrom: chasel.chiu@intel.com) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by groups.io with SMTP; Fri, 16 Aug 2019 18:13:42 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Aug 2019 18:13:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,395,1559545200"; d="scan'208";a="328835824" Received: from pgsmsx103.gar.corp.intel.com ([10.221.44.82]) by orsmga004.jf.intel.com with ESMTP; 16 Aug 2019 18:13:35 -0700 Received: from pgsmsx111.gar.corp.intel.com ([169.254.2.22]) by PGSMSX103.gar.corp.intel.com ([169.254.2.25]) with mapi id 14.03.0439.000; Sat, 17 Aug 2019 09:13:33 +0800 From: "Chiu, Chasel" To: "Kubacki, Michael A" , "devel@edk2.groups.io" CC: "Chaganty, Rangasai V" , "Desimone, Nathaniel L" , "Gao, Liming" , "Kinney, Michael D" , "Sinha, Ankit" Subject: Re: [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI library instances Thread-Topic: [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI library instances Thread-Index: AQHVVJEaCpi2Ok7BF02B31ucvjpkN6b+iMXQ Date: Sat, 17 Aug 2019 01:13:33 +0000 Message-ID: <3C3EFB470A303B4AB093197B6777CCEC5046234E@PGSMSX111.gar.corp.intel.com> References: <20190817001603.30632-1-michael.a.kubacki@intel.com> <20190817001603.30632-20-michael.a.kubacki@intel.com> In-Reply-To: <20190817001603.30632-20-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: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiNzk2M2U5ZWYtZDk4YS00YTgzLTlmZjItMmQxM2Y0ZGY2MGRiIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiR3lXM1JZYll0blVnS1ZqTlwvRUNleW9Bck1idWI5WE53cFdENHNWVmNLM3dyTVprTW9pdXNXVUg1blh5RkhqbHYifQ== x-ctpclassification: CTP_NT x-originating-ip: [172.30.20.206] MIME-Version: 1.0 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Chasel Chiu > -----Original Message----- > From: Kubacki, Michael A > Sent: Saturday, August 17, 2019 8:16 AM > To: devel@edk2.groups.io > Cc: Chaganty, Rangasai V ; Chiu, Chasel > ; Desimone, Nathaniel L > ; Gao, Liming ; > Kinney, Michael D ; Sinha, Ankit > > Subject: [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add P= EI > library instances >=20 > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D2082 >=20 > Adds PCH PEI library class instances. These libraries may also be > compatible in other boot phases as indicated by the library type. >=20 > * PeiDxeSmmBiosLockLib > * PeiDxeSmmGpioLib > * PeiDxeSmmPchCycleDecodingLib > * PeiDxeSmmPchDmiWithS3Lib > * PeiDxeSmmPchEspiLib > * PeiDxeSmmPchGbeLib > * PeiDxeSmmPchHsioLib > * PeiDxeSmmPchInfoLib > * PeiDxeSmmPchPcieRpLib > * PeiDxeSmmPchPcrLib > * PeiDxeSmmPchPmcLib > * PeiDxeSmmPchSbiAccessLib > * PeiDxeSmmPchSerialIoLib > * PeiDxeSmmPchSerialIoUartLib > * PeiDxeSmmPchWdtCommonLib > * PeiDxeSmmPmcLib > * PeiDxeSmmSataLib > * PeiOcWdtLib > * PeiOcWdtLibNull > * PeiPchPolicyLib > * PeiPchResetLib > * PeiResetSystemLib > * PeiSpiLib >=20 > Cc: Sai Chaganty > Cc: Chasel Chiu > Cc: Nate DeSimone > Cc: Liming Gao > Cc: Michael D Kinney > Cc: Ankit Sinha > Signed-off-by: Michael Kubacki > --- >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/PeiDx > eSmmBiosLockLib.inf | 40 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSm > mGpioLib.inf | 48 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingL > ib/PeiDxeSmmPchCycleDecodingLib.inf | 42 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiDxe > SmmPchEspiLib.inf | 38 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiDxe > SmmPchGbeLib.inf | 38 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiDxe > SmmPchHsioLib.inf | 37 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiDxe > SmmPchInfoLibCnl.inf | 42 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiD > xeSmmPchPcieRpLib.inf | 37 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeS > mmPchPcrLib.inf | 35 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiDxe > SmmPchPmcLib.inf | 36 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/P > eiDxeSmmPchSbiAccessLib.inf | 35 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/Pe= i > DxeSmmPchSerialIoLibCnl.inf | 39 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLi= b > /PeiDxeSmmPchSerialIoUartLib.inf | 35 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLi > b/PeiDxeSmmPchWdtCommonLib.inf | 31 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSm > mPmcLib.inf | 43 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeSm > mSataLibCnl.inf | 32 + > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.i= nf > | 39 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLi= b > Null.inf | 24 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPoli= cyLi > bCnl.inf | 86 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchReset= Li > b.inf | 41 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiReset= Sy > stemLib.inf | 49 + > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf > | 42 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLibra > ry.h | 117 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInf= o > LibPrivate.h | 45 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/Pc= h > SerialIoLibInternal.h | 16 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPoli= cyLi > brary.h | 35 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/BiosL= o > ckLib.c | 98 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioInit.= c > | 553 ++++ > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib.= c > | 2710 ++++++++++++++++++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNam > es.c | 87 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNativ > eLib.c | 234 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodingL > ib/PchCycleDecodingLib.c | 1136 ++++++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchEsp > iLib.c | 505 ++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchGb > eLib.c | 82 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PchHsi > oLib.c | 127 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInf= o > Lib.c | 272 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInf= o > LibClient.c | 87 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchInf= o > LibCnl.c | 386 +++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/PchP > cieRpLib.c | 183 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPcrL= i > b.c | 279 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchPm > cLib.c | 101 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib/P > chSbiAccessLib.c | 270 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/Pc= h > SerialIoLib.c | 516 ++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/Pc= h > SerialIoLibCnl.c | 181 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUartLi= b > /PeiDxeSmmPchSerialIoUartLib.c | 372 +++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommonLi > b/WdtCommon.c | 242 ++ > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c > | 330 +++ > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib.= c > | 41 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCd= f > .c | 101 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLibCn= l > .c | 88 + > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.c > | 130 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdtLi= b > Null.c | 23 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMemP= r > intPolicy.c | 307 +++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrintPo= licy > .c | 778 ++++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPoli= cyLi > b.c | 739 ++++++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPoli= cyLi > bCnl.c | 169 ++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPreM= e > mPolicyLib.c | 318 +++ > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.c > | 109 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiReset= Sy > stemLib.c | 257 ++ > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c > | 217 ++ > 60 files changed, 13130 insertions(+) >=20 > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/Pei > DxeSmmBiosLockLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/Pei > DxeSmmBiosLockLib.inf > new file mode 100644 > index 0000000000..6db81f6cf3 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/Pei > DxeSmmBiosLockLib.inf > @@ -0,0 +1,40 @@ > +## @file > +# BIOS LOCK library. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmBiosLockLib > +FILE_GUID =3D 64EBA6B1-CC36-4C2E-A0F5-D90199432E6C > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D BiosLockLib > + > + > +[LibraryClasses] > +BaseLib > +DebugLib > +PcdLib > +PciSegmentLib > +S3BootScriptLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +BiosLockLib.c > + > + > +[Pcd] > +gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeS > mmGpioLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeS > mmGpioLib.inf > new file mode 100644 > index 0000000000..00d06591fc > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/PeiDxeS > mmGpioLib.inf > @@ -0,0 +1,48 @@ > +## @file > +# Component description file for the PeiDxeSmmGpioLib > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmGpioLib > +FILE_GUID =3D 16EC5CA8-8195-4847-B6CB-662BD7B763F2 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D GpioLib > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC > +# > + > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +PrintLib > +PchCycleDecodingLib > +PchSbiAccessLib > +PmcPrivateLib > +GpioPrivateLib > +SataLib > +GpioHelpersLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +GpioLib.c > +GpioLibrary.h > +GpioNativeLib.c > +GpioInit.c > +GpioNames.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodi > ngLib/PeiDxeSmmPchCycleDecodingLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodi > ngLib/PeiDxeSmmPchCycleDecodingLib.inf > new file mode 100644 > index 0000000000..2a53f42004 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodi > ngLib/PeiDxeSmmPchCycleDecodingLib.inf > @@ -0,0 +1,42 @@ > +## @file > +# PCH cycle decoding Lib. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchCycleDecodingLib > +FILE_GUID =3D 676C749F-9CD1-46B7-BAFD-4B1BC36B4C8E > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchCycleDecodingLib > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +PciSegmentLib > +PchInfoLib > +PchPcrLib > +PchDmiLib > +PchEspiLib > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > +PcAtChipsetPkg/PcAtChipsetPkg.dec > + > +[Sources] > +PchCycleDecodingLib.c > + > +[Pcd] > +gSiPkgTokenSpaceGuid.PcdSiHpetBaseAddress ## CONSUMES > +gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress ## CONSUMES > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiD > xeSmmPchEspiLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiD > xeSmmPchEspiLib.inf > new file mode 100644 > index 0000000000..a775210984 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PeiD > xeSmmPchEspiLib.inf > @@ -0,0 +1,38 @@ > +## @file > +# Component description file for the PeiDxeSmmPchEspiLib > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchEspiLib > +FILE_GUID =3D 7F25F990-7989-4413-B414-1EDE557E9389 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchEspiLib > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC > +# > + > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +PchPcrLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PchEspiLib.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiD > xeSmmPchGbeLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiD > xeSmmPchGbeLib.inf > new file mode 100644 > index 0000000000..a685104249 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PeiD > xeSmmPchGbeLib.inf > @@ -0,0 +1,38 @@ > +## @file > +# PCH Gbe Library. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchGbeLib > +FILE_GUID =3D FC022ED0-6EB3-43E1-A740-0BA27CBBD010 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchGbeLib > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +PciSegmentLib > +PchInfoLib > +PchPcrLib > +PchCycleDecodingLib > +PmcPrivateLib > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PchGbeLib.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiD > xeSmmPchHsioLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiD > xeSmmPchHsioLib.inf > new file mode 100644 > index 0000000000..7c67e0fa20 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/PeiD > xeSmmPchHsioLib.inf > @@ -0,0 +1,37 @@ > +## @file > +# PCH HSIO Library. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchHsioLib > +FILE_GUID =3D 6B2D3D0D-9A04-4E7C-AE84-1C2EF2E00E2E > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchHsioLib > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +MmPciLib > +PchInfoLib > +PchPcrLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PchHsioLib.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiD= x > eSmmPchInfoLibCnl.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiD > xeSmmPchInfoLibCnl.inf > new file mode 100644 > index 0000000000..b9781de810 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PeiD > xeSmmPchInfoLibCnl.inf > @@ -0,0 +1,42 @@ > +## @file > +# PCH information library for PCH. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchInfoLibCnl > +FILE_GUID =3D 455CD363-0E78-46B7-8DD3-634003F1614F > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchInfoLib > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +PrintLib > +PciSegmentLib > +PchPcrLib > +PmcPrivateLib > +PcdLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PchInfoLib.c > +PchInfoLibClient.c > +PchInfoLibCnl.c > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/Pe > iDxeSmmPchPcieRpLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/Pe > iDxeSmmPchPcieRpLib.inf > new file mode 100644 > index 0000000000..b1ee095423 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/Pe > iDxeSmmPchPcieRpLib.inf > @@ -0,0 +1,37 @@ > +## @file > +# PCH PCIE root port Library. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchPcieRpLib > +FILE_GUID =3D B4129C2C-E0C5-4E04-A82A-C61D4F0B2C75 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchPcieRpLib > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +PciSegmentLib > +PchInfoLib > +PchPcrLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PchPcieRpLib.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDx > eSmmPchPcrLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDx > eSmmPchPcrLib.inf > new file mode 100644 > index 0000000000..0244e1c0c8 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PeiDx > eSmmPchPcrLib.inf > @@ -0,0 +1,35 @@ > +## @file > +# PCH PCR Library. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchPcrLib > +FILE_GUID =3D 117C8D19-445B-46BF-B624-109F63709375 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchPcrLib > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +PchInfoLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PchPcrLib.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiD > xeSmmPchPmcLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiD > xeSmmPchPmcLib.inf > new file mode 100644 > index 0000000000..3b1f1e467b > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PeiD > xeSmmPchPmcLib.inf > @@ -0,0 +1,36 @@ > +## @file > +# PEI/DXE/SMM PCH PMC Lib. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchPmcLib > +FILE_GUID =3D 9D60C364-5086-41E3-BC9D-C62AB7233DBF > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchPmcLib > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +MmPciLib > +PchCycleDecodingLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PchPmcLib.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib > /PeiDxeSmmPchSbiAccessLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib > /PeiDxeSmmPchSbiAccessLib.inf > new file mode 100644 > index 0000000000..ceb109168b > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib > /PeiDxeSmmPchSbiAccessLib.inf > @@ -0,0 +1,35 @@ > +## @file > +# PCH SBI access library. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchSbiAccessLib > +FILE_GUID =3D 96ECB0FB-A975-4DC8-B88A-D90C3378CE87 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchSbiAccessLib > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +PciSegmentLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PchSbiAccessLib.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/= P > eiDxeSmmPchSerialIoLibCnl.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/= P > eiDxeSmmPchSerialIoLibCnl.inf > new file mode 100644 > index 0000000000..3bfada0b22 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/= P > eiDxeSmmPchSerialIoLibCnl.inf > @@ -0,0 +1,39 @@ > +## @file > +# Component description file for PEI/DXE/SMM PCH Serial IO Lib. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchSerialIoLibCnl > +FILE_GUID =3D 613A22A2-5736-40f8-909B-DF10EA389C72 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchSerialIoLib > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +PcdLib > +PciSegmentLib > +GpioPrivateLib > +PchPcrLib > +PchSerialIoUartLib > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PchSerialIoLib.c > +PchSerialIoLibCnl.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUart= L > ib/PeiDxeSmmPchSerialIoUartLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUart= L > ib/PeiDxeSmmPchSerialIoUartLib.inf > new file mode 100644 > index 0000000000..1becfc7a96 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUart= L > ib/PeiDxeSmmPchSerialIoUartLib.inf > @@ -0,0 +1,35 @@ > +## @file > +# Component description file for PCH Serial IO UART Lib. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchSerialIoUartLib > +FILE_GUID =3D 55463A54-FD0D-4e8e-8D57-D54FAAEFDC2F > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PchSerialIoUartLib > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +PchSerialIoLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PeiDxeSmmPchSerialIoUartLib.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommo > nLib/PeiDxeSmmPchWdtCommonLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommo > nLib/PeiDxeSmmPchWdtCommonLib.inf > new file mode 100644 > index 0000000000..8a01a749bf > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommo > nLib/PeiDxeSmmPchWdtCommonLib.inf > @@ -0,0 +1,31 @@ > +## @file > +# Component description file for the PchWdtCommonLib > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION =3D 0x00010005 > + BASE_NAME =3D PeiDxeSmmPchWdtCommonLib > + FILE_GUID =3D 171F78D2-0A52-4692-8830-AB693791EA2= 3 > + MODULE_TYPE =3D BASE > + VERSION_STRING =3D 1.0 > + LIBRARY_CLASS =3D PchWdtCommonLib > + > +[Sources] > + WdtCommon.c > + > +[Packages] > + MdePkg/MdePkg.dec > + CoffeelakeSiliconPkg/SiPkg.dec > + > +[LibraryClasses] > + IoLib > + DebugLib > + PmcLib > + > +[Pcd] > + gSiPkgTokenSpaceGuid.PcdOcEnableWdtforDebug ## CONSUMES > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeS > mmPmcLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeS > mmPmcLib.inf > new file mode 100644 > index 0000000000..78e212eeb0 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PeiDxeS > mmPmcLib.inf > @@ -0,0 +1,43 @@ > +## @file > +# PEI/DXE/SMM PCH PMC Lib. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPmcLib > +FILE_GUID =3D 9D60C364-5086-41E3-BC9D-C62AB7233DBF > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D PmcLib > + > + > +[LibraryClasses] > +BaseLib > +IoLib > +DebugLib > +PciSegmentLib > +PchCycleDecodingLib > +PchPcrLib > +PchInfoLib > +PmcPrivateLib > +BaseMemoryLib > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Pcd] > +gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress > + > + > +[Sources] > +PmcLib.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeS > mmSataLibCnl.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeS > mmSataLibCnl.inf > new file mode 100644 > index 0000000000..128b348b3d > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/PeiDxeS > mmSataLibCnl.inf > @@ -0,0 +1,32 @@ > +## @file > +# PEI/DXE/SMM PCH SATA library for Cannon Lake PCH. > +# > +# All function in this library is available for PEI, DXE, and SMM, > +# But do not support UEFI RUNTIME environment call. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiDxeSmmPchSataLibCnl > +FILE_GUID =3D 5163ECE3-5372-47E1-B057-2282E753DD55 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D SataLib > + > +[LibraryClasses] > +BaseLib > +PciSegmentLib > +PchInfoLib > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > +[Sources] > +SataLib.c > +SataLibCnl.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.= i > nf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.= i > nf > new file mode 100644 > index 0000000000..37d0c80ea4 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.= i > nf > @@ -0,0 +1,39 @@ > +## @file > +# Component Description File for OcWdt Support. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiOcWdtLib > +FILE_GUID =3D D5207C23-3632-4078-A671-3B5C364B2BDB > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D PEIM > +LIBRARY_CLASS =3D OcWdtLib > + > + > +[LibraryClasses] > +IoLib > +DebugLib > +PeiServicesLib > +PchWdtCommonLib > +PmcLib > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PeiOcWdtLib.c > + > + > +[Ppis] > +gWdtPpiGuid ## PRODUCES > + > +[Pcd] > +gSiPkgTokenSpaceGuid.PcdOcEnableWdtforDebug ## CONSUMES > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdt > LibNull.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdt > LibNull.inf > new file mode 100644 > index 0000000000..68ff41ef7f > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdt > LibNull.inf > @@ -0,0 +1,24 @@ > +## @file > +# Component Description File for OcWdt Support. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiOcWdtLib > +FILE_GUID =3D DB65B36B-E276-4A2b-AB20-61764889E483 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D PEIM > +LIBRARY_CLASS =3D OcWdtLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > + > + > +[Sources] > +PeiOcWdtLibNull.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPo= lic > yLibCnl.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPo= lic > yLibCnl.inf > new file mode 100644 > index 0000000000..49e63cfc51 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPo= lic > yLibCnl.inf > @@ -0,0 +1,86 @@ > +## @file > +# Component description file for the PeiPchPolicy libbrary. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiPchPolicyLibCnl > +FILE_GUID =3D BB1AC992-B2CA-4744-84B7-915C185576C5 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D PEIM > +LIBRARY_CLASS =3D PchPolicyLib > + > + > +[LibraryClasses] > +DebugLib > +IoLib > +PcdLib > +PeiServicesLib > +BaseMemoryLib > +MemoryAllocationLib > +PchInfoLib > +ConfigBlockLib > +SiConfigBlockLib > +SataLib > +PchPcieRpLib > +CpuPlatformLib > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Pcd] > +gSiPkgTokenSpaceGuid.PcdSmbusBaseAddress > +gSiPkgTokenSpaceGuid.PcdSerialIoUartDebugEnable > +gSiPkgTokenSpaceGuid.PcdSerialIoUartNumber > + > + > +[Sources] > +PeiPchPolicyLib.c > +PeiPchPolicyLibCnl.c > +PeiPchPolicyLibrary.h > +PeiPchPreMemPolicyLib.c > +PchPrintPolicy.c > +PchPreMemPrintPolicy.c > + > +[Guids] > +gPchGeneralConfigGuid ## CONSUMES > +gPcieRpConfigGuid ## CONSUMES > +gSataConfigGuid ## CONSUMES > +gIoApicConfigGuid ## CONSUMES > +gDmiConfigGuid ## CONSUMES > +gFlashProtectionConfigGuid ## CONSUMES > +gHdAudioConfigGuid ## CONSUMES > +gInterruptConfigGuid ## CONSUMES > +gIshConfigGuid ## CONSUMES > +gLanConfigGuid ## CONSUMES > +gLockDownConfigGuid ## CONSUMES > +gP2sbConfigGuid ## CONSUMES > +gPmConfigGuid ## CONSUMES > +gScsConfigGuid ## CONSUMES > +gSerialIoConfigGuid ## CONSUMES > +gSerialIrqConfigGuid ## CONSUMES > +gThermalConfigGuid ## CONSUMES > +gUsbConfigGuid ## CONSUMES > +gEspiConfigGuid ## CONSUMES > +gCnviConfigGuid ## CONSUMES > +gHsioConfigGuid ## CONSUMES > +gPchGeneralPreMemConfigGuid ## COMSUMES > +gDciPreMemConfigGuid ## CONSUMES > +gWatchDogPreMemConfigGuid ## CONSUMES > +gPchTraceHubPreMemConfigGuid ## CONSUMES > +gSmbusPreMemConfigGuid ## CONSUMES > +gLpcPreMemConfigGuid ## CONSUMES > +gHsioPciePreMemConfigGuid ## CONSUMES > +gHsioSataPreMemConfigGuid ## CONSUMES > +gPcieRpPreMemConfigGuid ## CONSUMES > +gHdAudioPreMemConfigGuid ## CONSUMES > +gIshPreMemConfigGuid ## CONSUMES > + > +[Ppis] > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchRes= et > Lib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchRes= et > Lib.inf > new file mode 100644 > index 0000000000..41e339a2e8 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PeiPchRes= et > Lib.inf > @@ -0,0 +1,41 @@ > +## @file > +# Component description file for PCH Reset Lib Pei Phase > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiPchResetLib > +FILE_GUID =3D DB91FFF0-5B99-4A88-9EC8-183A2106DCA2 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D PEIM > +LIBRARY_CLASS =3D PchResetLib > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 IPF > +# > + > +[LibraryClasses] > +DebugLib > +PeiServicesLib > +PeiServicesTablePointerLib > +MemoryAllocationLib > +ResetSystemLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PchReset.c > + > +[Ppis] > +gEfiPeiReset2PpiGuid ## PRODUCES > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiRes= et > SystemLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiRes= et > SystemLib.inf > new file mode 100644 > index 0000000000..f8f8bf1b66 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiRes= et > SystemLib.inf > @@ -0,0 +1,49 @@ > +## @file > +# Component description file for Intel Ich7 Reset System Library. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiResetSystemLib > +FILE_GUID =3D D4FF05AA-3C7D-4B8A-A1EE-AA5EFA0B1732 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D PEIM > +UEFI_SPECIFICATION_VERSION =3D 2.00 > +LIBRARY_CLASS =3D ResetSystemLib > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 IPF > +# > + > +[LibraryClasses] > +IoLib > +DebugLib > +BaseMemoryLib > +PeiServicesLib > +PmcLib > +PmcPrivateLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PeiResetSystemLib.c > + > + > +[Ppis] > +gMeDidSentPpiGuid ## CONSUMES > +gPchResetCallbackPpiGuid ## CONSUMES > + > + > +[Guids] > +gPchGlobalResetGuid > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.inf > new file mode 100644 > index 0000000000..fb2fad78d3 > --- /dev/null > +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PeiSpiLib.= inf > @@ -0,0 +1,42 @@ > +## @file > +# Component description file for PCH Reset Lib Pei Phase > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D PeiSpiLib > +FILE_GUID =3D 4998447D-7948-448F-AB75-96E24E18FF23 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D PEIM > +LIBRARY_CLASS =3D SpiLib > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 IPF > +# > + > +[LibraryClasses] > +DebugLib > +PeiServicesLib > +PeiServicesTablePointerLib > +MemoryAllocationLib > +PciSegmentLib > +PchSpiCommonLib > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +PchSpi.c > + > + > +[Ppis] > +gPchSpiPpiGuid ## PRODUCES > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib > rary.h > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib > rary.h > new file mode 100644 > index 0000000000..7a480b6cad > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib > rary.h > @@ -0,0 +1,117 @@ > +/** @file > + Header file for GPIO Lib implementation. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _GPIO_LIBRARY_H_ > +#define _GPIO_LIBRARY_H_ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +// BIT15-0 - pad number > +// BIT31-16 - group info > +// BIT23- 16 - group index > +// BIT31- 24 - chipset ID > +#define PAD_INFO_MASK 0x0000FFFF > +#define GROUP_INFO_POSITION 16 > +#define GROUP_INFO_MASK 0xFFFF0000 > +#define GROUP_INDEX_MASK 0x00FF0000 > +#define UNIQUE_ID_MASK 0xFF000000 > +#define UNIQUE_ID_POSITION 24 > + > +#define GPIO_PAD_DEF(Group,Pad) (UINT32)(((Group) << 16) + > (Pad)) > +#define GPIO_GROUP_DEF(Index,ChipsetId) ((Index) | ((ChipsetId) <<= 8)) > +#define GPIO_GET_GROUP_INDEX(Group) ((Group) & 0xFF) > +#define GPIO_GET_GROUP_FROM_PAD(Pad) ((Pad) >> 16) > +#define GPIO_GET_GROUP_INDEX_FROM_PAD(Pad) > GPIO_GET_GROUP_INDEX (((Pad) >> 16)) > +#define GPIO_GET_PAD_NUMBER(Pad) ((Pad) & 0xFFFF) > +#define GPIO_GET_CHIPSET_ID(Pad) ((Pad) >> 24) > + > +#define GPIO_GET_PAD_POSITION(PadNumber) ((PadNumber) % 32) > +#define GPIO_GET_DW_NUM(PadNumber) ((PadNumber) / 32u) > + > +// > +// Number of PADCFG_DW registers > +// > +#define GPIO_PADCFG_DW_REG_NUMBER 4 > + > +/** > + This internal procedure will calculate GPIO_RESET_CONFIG value (new > type) > + based on provided PadRstCfg for a specific GPIO Pad. > + > + @param[in] GpioPad GPIO Pad > + @param[in] PadRstCfg GPIO PadRstCfg value > + > + @retval GpioResetConfig GPIO Reset configuration (new type) > +**/ > +GPIO_RESET_CONFIG > +GpioResetConfigFromPadRstCfg ( > + IN GPIO_PAD GpioPad, > + IN UINT32 PadRstCfg > + ); > + > +/** > + This internal procedure will calculate PadRstCfg register value based > + on provided GPIO Reset configuration for a certain pad. > + > + @param[in] GpioPad GPIO Pad > + @param[in] GpioResetConfig GPIO Reset configuration > + @param[out] PadRstCfg GPIO PadRstCfg value > + > + @retval EFI_SUCCESS The function completed successfu= lly > + @retval EFI_INVALID_PARAMETER Invalid configuration > +**/ > +EFI_STATUS > +GpioPadRstCfgFromResetConfig ( > + IN GPIO_PAD GpioPad, > + IN GPIO_RESET_CONFIG GpioResetConfig, > + OUT UINT32 *PadRstCfg > + ); > + > +/** > + This procedure will calculate PADCFG register value based on GpioConfi= g > data > + > + @param[in] GpioPad GPIO Pad > + @param[in] GpioConfig GPIO Configuration data > + @param[out] PadCfgDwReg PADCFG DWx register value > + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register > bits to be modified > +**/ > +VOID > +GpioPadCfgRegValueFromGpioConfig ( > + IN GPIO_PAD GpioPad, > + IN CONST GPIO_CONFIG *GpioConfig, > + OUT UINT32 *PadCfgDwReg, > + OUT UINT32 *PadCfgDwRegMask > + ); > + > +/** > + Generates GPIO group name from GroupIndex > + > + @param[in] GroupIndex Gpio GroupIndex > + > + @retval CHAR8* Pointer to the GPIO group name > +**/ > +CONST > +CHAR8* > +GpioGetGroupName ( > + IN UINT32 GroupIndex > + ); > + > +#endif // _GPIO_LIBRARY_H_ > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI= n > foLibPrivate.h > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI > nfoLibPrivate.h > new file mode 100644 > index 0000000000..79e03fef44 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI > nfoLibPrivate.h > @@ -0,0 +1,45 @@ > +/** @file > + Private header for PCH Info Lib. > + > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +/** > + Structure for PCH SKU string mapping > +**/ > +struct PCH_SKU_STRING { > + UINT16 Id; > + CHAR8 *String; > +}; > + > +extern struct PCH_SKU_STRING mSkuStrs[]; > + > +/** > + Determine Pch Series based on Device Id > + > + @param[in] LpcDeviceId Lpc Device Id > + > + @retval PCH_SERIES Pch Series > +**/ > +PCH_SERIES > +PchSeriesFromLpcDid ( > + IN UINT16 LpcDeviceId > + ); > + > +/** > +Determine Pch Generation based on Device Id > + > +@param[in] LpcDeviceId Lpc Device Id > + > +@retval PCH_GENERATION Pch Generation > +**/ > +PCH_GENERATION > +PchGenerationFromDid ( > + IN UINT16 LpcDeviceId > + ); > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/= P > chSerialIoLibInternal.h > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/= P > chSerialIoLibInternal.h > new file mode 100644 > index 0000000000..17e4bb863a > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/= P > chSerialIoLibInternal.h > @@ -0,0 +1,16 @@ > +/** @file > + Header file for PchSerialIoLibInternal. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _PCH_SERIAL_IO_LIB_INTERNAL_H_ > +#define _PCH_SERIAL_IO_LIB_INTERNAL_H_ > + > +typedef struct { > + UINT8 DevNum; > + UINT8 FuncNum; > +} SERIAL_IO_BDF_NUMBERS; > +#endif > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPo= lic > yLibrary.h > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPo= lic > yLibrary.h > new file mode 100644 > index 0000000000..abd7e63365 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPo= lic > yLibrary.h > @@ -0,0 +1,35 @@ > +/** @file > + Header file for the PeiPchPolicy library. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#ifndef _PEI_PCH_POLICY_LIBRARY_H_ > +#define _PEI_PCH_POLICY_LIBRARY_H_ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** > + Adds interrupt configuration for device > + > + @param[in/out] InterruptConfig Pointer to interrupt config > +**/ > +VOID > +LoadDeviceInterruptConfig ( > + IN OUT PCH_INTERRUPT_CONFIG *InterruptConfig > + ); > + > +#endif // _PEI_PCH_POLICY_LIBRARY_H_ > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/Bio= s > LockLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/Bio= s > LockLib.c > new file mode 100644 > index 0000000000..20c024e893 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmBiosLockLib/Bio= s > LockLib.c > @@ -0,0 +1,98 @@ > +/** @file > + Bios Lock library. > + > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + 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 > + > +/** > + Enable BIOS lock. This will set the LE (Lock Enable) and EISS (Enable = In > SMM.STS). > + When this is set, attempts to write the WPD (Write Protect Disable) bi= t in > PCH > + will cause a SMI which will allow the BIOS to verify that the write is= from a > valid source. > + > + Bios should always enable LockDownConfig.BiosLock policy to set Bios L= ock > bit in FRC. > + If capsule udpate is enabled, it's expected to not do BiosLock by sett= ing > BiosLock policy disable > + so it can udpate BIOS region. > + After flash update, it should utilize this lib to do BiosLock for secu= rity. > +**/ > +VOID > +BiosLockEnable ( > + VOID > + ) > +{ > + UINT64 LpcBaseAddress; > + UINT64 SpiBaseAddress; > + > + LpcBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_LPC, > + PCI_FUNCTION_NUMBER_PCH_LPC, > + 0 > + ); > + SpiBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_SPI, > + PCI_FUNCTION_NUMBER_PCH_SPI, > + 0 > + ); > + > + /// > + /// PCH BIOS Spec Flash Security Recommendation > + /// > + /// BIOS needs to enable the BIOS Lock Enable (BLE) feature of the PCH= by > setting > + /// SPI/eSPI/LPC PCI offset DCh[1] =3D 1b. > + /// When this bit is set, attempts to write the Write Protect Disable = (WPD) > bit > + /// in PCH will cause a SMI which will allow the BIOS to verify that t= he write > is > + /// from a valid source. > + /// Remember that BIOS needs to set SPI/LPC/eSPI PCI Offset DC [0] =3D= 0b to > enable > + /// BIOS region protection before exiting the SMI handler. > + /// Also, TCO_EN bit needs to be set (SMI_EN Register, ABASE + 30h[13]= =3D 1b) > to keep > + /// BLE feature enabled after booting to the OS. > + /// Intel requires that BIOS enables the Lock Enable (LE) feature of t= he PCH > to > + /// ensure SMM protection of flash. > + /// RC installs a default SMI handler that clears WPD. > + /// There could be additional SMI handler to log such attempt if desir= ed. > + /// > + /// BIOS needs to enable the "Enable in SMM.STS" (EISS) feature of the= PCH > by setting > + /// SPI PCI offset DCh[5] =3D 1b for SPI or setting eSPI PCI offset DC= h[5] =3D 1b for > eSPI. > + /// When this bit is set, the BIOS region is not writable until SMM se= ts the > InSMM.STS bit, > + /// to ensure BIOS can only be modified from SMM. Please refer to CPU = BWG > for more details > + /// on InSMM.STS bit. > + /// Intel requires that BIOS enables the Lock Enable (LE) feature of t= he PCH > to ensure > + /// SMM protection of flash. > + /// SPI PCI offset DCh[1] =3D 1b for SPI or setting eSPI PCI offset DC= h[1] =3D 1b for > eSPI. > + /// When this bit is set, EISS is locked down. > + /// > + PciSegmentOr8 (SpiBaseAddress + R_SPI_CFG_BC, B_SPI_CFG_BC_EISS | > B_SPI_CFG_BC_LE); > + S3BootScriptSaveMemWrite ( > + S3BootScriptWidthUint8, > + PcdGet64 (PcdPciExpressBaseAddress) + SpiBaseAddress + R_SPI_CFG_BC, > + 1, > + (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + SpiBaseAddre= ss > + R_SPI_CFG_BC) > + ); > + PciSegmentOr8 (LpcBaseAddress + R_LPC_CFG_BC, B_LPC_CFG_BC_EISS | > B_LPC_CFG_BC_LE); > + S3BootScriptSaveMemWrite ( > + S3BootScriptWidthUint8, > + PcdGet64 (PcdPciExpressBaseAddress) + LpcBaseAddress + > R_LPC_CFG_BC, > + 1, > + (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + > LpcBaseAddress + R_LPC_CFG_BC) > + ); > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioIni > t.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioIni > t.c > new file mode 100644 > index 0000000000..76eb3a9b81 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioIni > t.c > @@ -0,0 +1,553 @@ > +/** @file > + This file contains routines for GPIO initialization > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "GpioLibrary.h" > +#include > + > +// > +// GPIO_GROUP_DW_DATA structure is used by GpioConfigurePch function > +// to cache values which will be programmed into respective GPIO registe= rs > +// after all GpioPads are processed. This way MMIO accesses are decrease= d > +// and instead of doing one programming for one GpioPad there is only > +// one access for whole register. > +// > +typedef struct { > + UINT32 HostSoftOwnReg; > + UINT32 HostSoftOwnRegMask; > + UINT32 GpiGpeEnReg; > + UINT32 GpiGpeEnRegMask; > + UINT32 GpiNmiEnReg; > + UINT32 GpiNmiEnRegMask; > + UINT32 GpiSmiEnReg; > + UINT32 GpiSmiEnRegMask; > + UINT32 ConfigUnlockMask; > + UINT32 OutputUnlockMask; > +} GPIO_GROUP_DW_DATA; > + > +// > +// GPIO_GROUP_DW_NUMBER contains number of DWords required to > +// store Pad data for all groups. Each pad uses one bit. > +// > +// For Cannonlake only vGPIO group has >32 pads but those pads > +// will not be accessed by this function so GPIO_GROUP_DW_NUMBER can be > 1 > +// > +#define GPIO_GROUP_DW_NUMBER 1 > + > +/** > + Get GPIO DW Register values (HOSTSW_OWN, GPE_EN, NMI_EN, Lock). > + > + @param[in] PadNumber GPIO pad number > + @param[in] GpioConfig GPIO Config data > + @param[in out] DwRegsValues Values for GPIO DW Registers > + > + @retval None > +**/ > +STATIC > +VOID > +GpioDwRegValueFromGpioConfig ( > + IN UINT32 PadNumber, > + IN CONST GPIO_CONFIG *GpioConfig, > + IN OUT GPIO_GROUP_DW_DATA *GroupDwData > + ) > +{ > + UINT32 PadBitPosition; > + UINT32 DwNum; > + > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); > + DwNum =3D GPIO_GET_DW_NUM (PadNumber); > + > + if (DwNum >=3D GPIO_GROUP_DW_NUMBER) { > + ASSERT (FALSE); > + return; > + } > + // > + // Update value to be programmed in HOSTSW_OWN register > + // > + GroupDwData[DwNum].HostSoftOwnRegMask |=3D > (GpioConfig->HostSoftPadOwn & 0x1) << PadBitPosition; > + GroupDwData[DwNum].HostSoftOwnReg |=3D > (GpioConfig->HostSoftPadOwn >> 0x1) << PadBitPosition; > + > + // > + // Update value to be programmed in GPI_GPE_EN register > + // > + GroupDwData[DwNum].GpiGpeEnRegMask |=3D > (GpioConfig->InterruptConfig & 0x1) << PadBitPosition; > + GroupDwData[DwNum].GpiGpeEnReg |=3D ((GpioConfig->InterruptConfig & > GpioIntSci) >> 3) << PadBitPosition; > + > + // > + // Update value to be programmed in GPI_NMI_EN register > + // > + GroupDwData[DwNum].GpiNmiEnRegMask |=3D > (GpioConfig->InterruptConfig & 0x1) << PadBitPosition; > + GroupDwData[DwNum].GpiNmiEnReg |=3D ((GpioConfig->InterruptConfig & > GpioIntNmi) >> 1) << PadBitPosition; > + > + // > + // Update value to be programmed in GPI_SMI_EN register > + GroupDwData[DwNum].GpiSmiEnRegMask |=3D > (GpioConfig->InterruptConfig & 0x1) << PadBitPosition; > + GroupDwData[DwNum].GpiSmiEnReg |=3D ((GpioConfig->InterruptConfig & > GpioIntSmi) >> 2) << PadBitPosition; > + if ((GpioConfig->InterruptConfig & GpioIntSmi) =3D=3D GpioIntSmi) { > + GroupDwData[DwNum].HostSoftOwnRegMask |=3D 1 << PadBitPosition; > + GroupDwData[DwNum].HostSoftOwnReg |=3D 1 << PadBitPosition; > + } > + > + // > + // Update information on Pad Configuration Lock > + // > + GroupDwData[DwNum].ConfigUnlockMask |=3D ((GpioConfig->LockConfig >> > 1) & 0x1) << PadBitPosition; > + > + // > + // Update information on Pad Configuration Lock Tx > + // > + GroupDwData[DwNum].OutputUnlockMask |=3D ((GpioConfig->LockConfig > >> 3) & 0x1) << PadBitPosition; > + > + // > + // if pad in GpioMode is an output default action should be to leave o= utput > unlocked > + // > + if ((GpioConfig->PadMode =3D=3D GpioPadModeGpio) && > + (GpioConfig->Direction =3D=3D GpioDirOut) && > + ((GpioConfig->LockConfig & > B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) =3D=3D GpioLockDefault)) { > + GroupDwData[DwNum].OutputUnlockMask |=3D 0x1 << PadBitPosition; > + } > +} > + > +/** > + This internal procedure will scan GPIO initialization table and unlock > + all pads present in it > + > + @param[in] NumberOfItem Number of GPIO pad records in ta= ble > + @param[in] GpioInitTableAddress GPIO initialization table > + @param[in] Index Index of GPIO Initialization tab= le record > + > + @retval EFI_SUCCESS The function completed successfu= lly > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +STATIC > +EFI_STATUS > +GpioUnlockPadsForAGroup ( > + IN UINT32 NumberOfItems, > + IN GPIO_INIT_CONFIG *GpioInitTableAddress, > + IN UINT32 Index > + ) > +{ > + UINT32 PadsToUnlock[GPIO_GROUP_DW_NUMBER]; > + UINT32 DwNum; > + UINT32 PadBitPosition; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + CONST GPIO_INIT_CONFIG *GpioData; > + GPIO_GROUP Group; > + UINT32 GroupIndex; > + UINT32 PadNumber; > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + GpioData =3D &GpioInitTableAddress[Index]; > + Group =3D GpioGetGroupFromGpioPad (GpioData->GpioPad); > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioData->GpioPad); > + > + ZeroMem (PadsToUnlock, sizeof (PadsToUnlock)); > + // > + // Loop through pads for one group. If pad belongs to a different grou= p then > + // break and move to register programming. > + // > + while (Index < NumberOfItems) { > + > + GpioData =3D &GpioInitTableAddress[Index]; > + if (GroupIndex !=3D GpioGetGroupIndexFromGpioPad (GpioData->GpioPad)= ) > { > + //if next pad is from different group then break loop > + break; > + } > + > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioData->GpioPad); > + // > + // Check if legal pin number > + // > + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup) { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds > possible range for group %d\n", PadNumber, GroupIndex)); > + return EFI_INVALID_PARAMETER; > + } > + > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); > + DwNum =3D GPIO_GET_DW_NUM (PadNumber); > + > + if (DwNum >=3D GPIO_GROUP_DW_NUMBER) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + // > + // Update pads which need to be unlocked > + // > + PadsToUnlock[DwNum] |=3D 0x1 << PadBitPosition; > + > + //Move to next item > + Index++; > + } > + > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { > + // > + // Unlock pads > + // > + if (PadsToUnlock[DwNum] !=3D 0) { > + GpioUnlockPadCfgForGroupDw (Group, DwNum, > PadsToUnlock[DwNum]); > + GpioUnlockPadCfgTxForGroupDw (Group, DwNum, > PadsToUnlock[DwNum]); > + } > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will initialize multiple PCH GPIO pins > + > + @param[in] NumberofItem Number of GPIO pads to be update= d > + @param[in] GpioInitTableAddress GPIO initialization table > + > + @retval EFI_SUCCESS The function completed successfu= lly > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +STATIC > +EFI_STATUS > +GpioConfigurePch ( > + IN UINT32 NumberOfItems, > + IN GPIO_INIT_CONFIG *GpioInitTableAddress > + ) > +{ > + UINT32 Index; > + UINT32 PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER]; > + UINT32 > PadCfgDwRegMask[GPIO_PADCFG_DW_REG_NUMBER]; > + UINT32 PadCfgReg; > + GPIO_GROUP_DW_DATA GroupDwData[GPIO_GROUP_DW_NUMBER]; > + UINT32 DwNum; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + GPIO_PAD_OWN PadOwnVal; > + CONST GPIO_INIT_CONFIG *GpioData; > + UINT32 GroupIndex; > + UINT32 PadNumber; > + PCH_SBI_PID GpioCom; > + > + PadOwnVal =3D GpioPadOwnHost; > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + Index =3D 0; > + while (Index < NumberOfItems) { > + > + GpioData =3D &GpioInitTableAddress[Index]; > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioData->GpioPad); > + GpioCom =3D GpioGroupInfo[GroupIndex].Community; > + > + DEBUG_CODE_BEGIN(); > + if (!GpioIsCorrectPadForThisChipset (GpioData->GpioPad)) { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) used > on this chipset!\n", GpioData->GpioPad)); > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + DEBUG_CODE_END (); > + > + // > + // Unlock pads for a given group which are going to be reconfigured > + // > + // > + // Because PADCFGLOCK/LOCKTX register reset domain is Powergood, loc= k > settings > + // will get back to default only after G3 or DeepSx transition. On t= he other > hand GpioPads > + // configuration is controlled by a configurable type of reset - Pad= RstCfg. > This means that if > + // PadRstCfg !=3D Powergood GpioPad will have its configuration lock= ed > despite it being not the > + // one desired by BIOS. Before reconfiguring all pads they will get = unlocked. > + // > + GpioUnlockPadsForAGroup (NumberOfItems, GpioInitTableAddress, > Index); > + > + ZeroMem (GroupDwData, sizeof (GroupDwData)); > + // > + // Loop through pads for one group. If pad belongs to a different gr= oup > then > + // break and move to register programming. > + // > + while (Index < NumberOfItems) { > + > + GpioData =3D &GpioInitTableAddress[Index]; > + if (GroupIndex !=3D GpioGetGroupIndexFromGpioPad > (GpioData->GpioPad)) { > + //if next pad is from different group then break loop > + break; > + } > + > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioData->GpioPad); > + > + DEBUG_CODE_BEGIN (); > + // > + // Check if legal pin number > + // > + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup) { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds > possible range for group %d\n", PadNumber, GroupIndex)); > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Check if selected GPIO Pad is not owned by CSME/ISH > + // > + GpioGetPadOwnership (GpioData->GpioPad, &PadOwnVal); > + > + if (PadOwnVal !=3D GpioPadOwnHost) { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Accessing pad not owned by > host (Group=3D%d, Pad=3D%d)!\n", GroupIndex, PadNumber)); > + DEBUG ((DEBUG_ERROR, "** Please make sure the GPIO usage in sync > between CSME and BIOS configuration. \n")); > + DEBUG ((DEBUG_ERROR, "** All the GPIO occupied by CSME should no= t > do any configuration by BIOS.\n")); > + //Move to next item > + Index++; > + continue; > + } > + > + // > + // Check if Pad enabled for SCI is to be in unlocked state > + // > + if (((GpioData->GpioConfig.InterruptConfig & GpioIntSci) =3D=3D Gp= ioIntSci) > && > + ((GpioData->GpioConfig.LockConfig & > B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK) !=3D GpioPadConfigUnlock)){ > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a used for SCI is not > unlocked!\n", GpioName (GpioData->GpioPad))); > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + DEBUG_CODE_END (); > + > + ZeroMem (PadCfgDwReg, sizeof (PadCfgDwReg)); > + ZeroMem (PadCfgDwRegMask, sizeof (PadCfgDwRegMask)); > + // > + // Get GPIO PADCFG register value from GPIO config data > + // > + GpioPadCfgRegValueFromGpioConfig ( > + GpioData->GpioPad, > + &GpioData->GpioConfig, > + PadCfgDwReg, > + PadCfgDwRegMask > + ); > + > + // > + // Create PADCFG register offset using group and pad number > + // > + PadCfgReg =3D S_GPIO_PCR_PADCFG * PadNumber + > GpioGroupInfo[GroupIndex].PadCfgOffset; > + > + // > + // Write PADCFG DW0 register > + // > + MmioAndThenOr32 ( > + PCH_PCR_ADDRESS (GpioCom, PadCfgReg), > + ~PadCfgDwRegMask[0], > + PadCfgDwReg[0] > + ); > + > + // > + // Write PADCFG DW1 register > + // > + MmioAndThenOr32 ( > + PCH_PCR_ADDRESS (GpioCom, PadCfgReg + 0x4), > + ~PadCfgDwRegMask[1], > + PadCfgDwReg[1] > + ); > + > + // > + // Write PADCFG DW2 register > + // > + MmioAndThenOr32 ( > + PCH_PCR_ADDRESS (GpioCom, PadCfgReg + 0x8), > + ~PadCfgDwRegMask[2], > + PadCfgDwReg[2] > + ); > + > + // > + // Get GPIO DW register values from GPIO config data > + // > + GpioDwRegValueFromGpioConfig ( > + PadNumber, > + &GpioData->GpioConfig, > + GroupDwData > + ); > + > + //Move to next item > + Index++; > + } > + > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { > + // > + // Write HOSTSW_OWN registers > + // > + if (GpioGroupInfo[GroupIndex].HostOwnOffset !=3D > NO_REGISTER_FOR_PROPERTY) { > + MmioAndThenOr32 ( > + PCH_PCR_ADDRESS (GpioCom, > GpioGroupInfo[GroupIndex].HostOwnOffset + DwNum * 0x4), > + ~GroupDwData[DwNum].HostSoftOwnRegMask, > + GroupDwData[DwNum].HostSoftOwnReg > + ); > + } > + > + // > + // Write GPI_GPE_EN registers > + // > + if (GpioGroupInfo[GroupIndex].GpiGpeEnOffset !=3D > NO_REGISTER_FOR_PROPERTY) { > + MmioAndThenOr32 ( > + PCH_PCR_ADDRESS (GpioCom, > GpioGroupInfo[GroupIndex].GpiGpeEnOffset + DwNum * 0x4), > + ~GroupDwData[DwNum].GpiGpeEnRegMask, > + GroupDwData[DwNum].GpiGpeEnReg > + ); > + } > + > + // > + // Write GPI_NMI_EN registers > + // > + if (GpioGroupInfo[GroupIndex].NmiEnOffset !=3D > NO_REGISTER_FOR_PROPERTY) { > + MmioAndThenOr32 ( > + PCH_PCR_ADDRESS (GpioCom, > GpioGroupInfo[GroupIndex].NmiEnOffset + DwNum * 0x4), > + ~GroupDwData[DwNum].GpiNmiEnRegMask, > + GroupDwData[DwNum].GpiNmiEnReg > + ); > + } else if (GroupDwData[DwNum].GpiNmiEnReg !=3D 0x0) { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads > supporting NMI\n", GroupIndex)); > + ASSERT_EFI_ERROR (EFI_UNSUPPORTED); > + } > + > + // > + // Write GPI_SMI_EN registers > + // > + if (GpioGroupInfo[GroupIndex].SmiEnOffset !=3D > NO_REGISTER_FOR_PROPERTY) { > + MmioAndThenOr32 ( > + PCH_PCR_ADDRESS (GpioCom, > GpioGroupInfo[GroupIndex].SmiEnOffset + DwNum * 0x4), > + ~GroupDwData[DwNum].GpiSmiEnRegMask, > + GroupDwData[DwNum].GpiSmiEnReg > + ); > + } else if (GroupDwData[DwNum].GpiSmiEnReg !=3D 0x0) { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads > supporting SMI\n", GroupIndex)); > + ASSERT_EFI_ERROR (EFI_UNSUPPORTED); > + } > + > + // > + // Update Pad Configuration unlock data > + // > + if (GroupDwData[DwNum].ConfigUnlockMask) { > + GpioStoreGroupDwUnlockPadConfigData (GroupIndex, DwNum, > GroupDwData[DwNum].ConfigUnlockMask); > + } > + > + // > + // Update Pad Output unlock data > + // > + if (GroupDwData[DwNum].OutputUnlockMask) { > + GpioStoreGroupDwUnlockOutputData (GroupIndex, DwNum, > GroupDwData[DwNum].OutputUnlockMask); > + } > + } > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will clear all status bits of any GPIO interrupts. > +**/ > +STATIC > +VOID > +GpioClearAllGpioInterrupts ( > + VOID > + ) > +{ > + GPIO_GROUP Group; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + GPIO_GROUP GpioGroupLowest; > + GPIO_GROUP GpioGroupHighest; > + UINT32 GroupIndex; > + UINT32 GpioGroupInfoLength; > + UINT32 DwNum; > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + GpioGroupLowest =3D GpioGetLowestGroup (); > + GpioGroupHighest =3D GpioGetHighestGroup (); > + > + for (Group =3D GpioGroupLowest; Group <=3D GpioGroupHighest; Group++) = { > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); > + // > + // Check if group has GPI IS register > + // > + if (GpioGroupInfo[GroupIndex].GpiIsOffset !=3D > NO_REGISTER_FOR_PROPERTY) { > + // > + // Clear all GPI_IS Status bits by writing '1' > + // > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { > + MmioWrite32 ( > + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, > GpioGroupInfo[GroupIndex].GpiIsOffset + DwNum * 0x4), > + 0xFFFFFFFF > + ); > + } > + } > + > + // > + // Check if group has GPI_GPE_STS register > + // > + if (GpioGroupInfo[GroupIndex].GpiGpeStsOffset !=3D > NO_REGISTER_FOR_PROPERTY) { > + // > + // Clear all GPI_GPE_STS Status bits by writing '1' > + // > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { > + MmioWrite32 ( > + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, > GpioGroupInfo[GroupIndex].GpiGpeStsOffset + DwNum * 0x4), > + 0xFFFFFFFF > + ); > + } > + } > + > + // > + // Check if group has SMI_STS register > + // > + if (GpioGroupInfo[GroupIndex].SmiStsOffset !=3D > NO_REGISTER_FOR_PROPERTY) { > + // > + // Clear all SMI_STS Status bits by writing '1' > + // > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { > + MmioWrite32 ( > + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, > GpioGroupInfo[GroupIndex].SmiStsOffset + DwNum * 4), > + 0xFFFFFFFF > + ); > + } > + } > + > + // > + // Check if group has NMI_STS register > + // > + if (GpioGroupInfo[GroupIndex].NmiStsOffset !=3D > NO_REGISTER_FOR_PROPERTY) { > + // > + // Clear all NMI_STS Status bits by writing '1' > + // > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { > + MmioWrite32 ( > + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, > GpioGroupInfo[GroupIndex].NmiStsOffset + DwNum * 4), > + 0xFFFFFFFF > + ); > + } > + } > + > + } > +} > + > +/** > + This procedure will initialize multiple GPIO pins. Use GPIO_INIT_CONFI= G > structure. > + Structure contains fields that can be used to configure each pad. > + Pad not configured using GPIO_INIT_CONFIG will be left with hardware > default values. > + Separate fields could be set to hardware default if it does not matter= , except > + GpioPad and PadMode. > + Function will work in most efficient way if pads which belong to the s= ame > group are > + placed in adjacent records of the table. > + Although function can enable pads for Native mode, such programming is > done > + by reference code when enabling related silicon feature. > + > + @param[in] NumberofItem Number of GPIO pads to be update= d > + @param[in] GpioInitTableAddress GPIO initialization table > + > + @retval EFI_SUCCESS The function completed successfu= lly > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioConfigurePads ( > + IN UINT32 NumberOfItems, > + IN GPIO_INIT_CONFIG *GpioInitTableAddress > + ) > +{ > + EFI_STATUS Status; > + Status =3D GpioConfigurePch (NumberOfItems, GpioInitTableAddress); > + GpioClearAllGpioInterrupts (); > + return Status; > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib > .c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib > .c > new file mode 100644 > index 0000000000..0be50f75df > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioLib > .c > @@ -0,0 +1,2710 @@ > +/** @file > + This file contains routines for GPIO > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "GpioLibrary.h" > +#include > + > +/** > + This procedure will check if GpioGroup argument is correct and > + supplied DW reg number can be used for this group to access DW registe= rs. > + Function will check below conditions: > + - Valid GpioGroup > + - DwNum is has valid value for this group > + > + @param[in] Group GPIO group > + @param[in] DwNum Register number for current group (parameter > applicable in accessing whole register). > + For group which has less then 32 pads per grou= p DwNum > must be 0. > + > + @retval TRUE DW Reg number and GpioGroup is valid > + @retval FALSE DW Reg number and GpioGroup is invalid > +**/ > +STATIC > +BOOLEAN > +GpioIsGroupAndDwNumValid ( > + IN GPIO_GROUP Group, > + IN UINT32 DwNum > + ) > +{ > + UINT32 GroupIndex; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); > + > + if ((Group < GpioGetLowestGroup ()) || (Group > GpioGetHighestGroup ()= ) > || (GroupIndex >=3D GpioGroupInfoLength)) { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group argument (%d) is not within > range of possible groups for this PCH\n", GroupIndex)); > + goto Error; > + } > + > + // > + // Check if DwNum argument does not exceed number of DWord registers > + // resulting from available pads for certain group > + // > + if (DwNum > GPIO_GET_DW_NUM > (GpioGroupInfo[GroupIndex].PadPerGroup - 1)){ > + goto Error; > + } > + > + return TRUE; > +Error: > + ASSERT (FALSE); > + return FALSE; > +} > + > +// > +// Possible registers to be accessed using GpioReadReg()/GpioWriteReg() > functions > +// > +typedef enum { > + GpioHostOwnershipRegister =3D 0, > + GpioGpeEnableRegister, > + GpioGpeStatusRegister, > + GpioSmiEnableRegister, > + GpioSmiStatusRegister, > + GpioNmiEnableRegister, > + GpioPadConfigLockRegister, > + GpioPadLockOutputRegister > +} GPIO_REG; > + > +/** > + This procedure will read GPIO register > + > + @param[in] RegType GPIO register type > + @param[in] Group GPIO group > + @param[in] DwNum Register number for current group > (parameter applicable in accessing whole register). > + For group which has less then 32 pads = per group > DwNum must be 0. > + @param[out] ReadVal Read data > +**/ > +STATIC > +VOID > +GpioReadReg ( > + IN GPIO_REG RegType, > + IN GPIO_GROUP Group, > + IN UINT32 DwNum, > + OUT UINT32 *ReadVal > + ) > +{ > + UINT32 RegOffset; > + UINT32 GroupIndex; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + > + RegOffset =3D NO_REGISTER_FOR_PROPERTY; > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + switch (RegType) { > + case GpioHostOwnershipRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].HostOwnOffset; > + break; > + case GpioGpeEnableRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeEnOffset; > + break; > + case GpioGpeStatusRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeStsOffset; > + break; > + case GpioSmiEnableRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].SmiEnOffset; > + break; > + case GpioSmiStatusRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].SmiStsOffset; > + break; > + case GpioNmiEnableRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].NmiEnOffset; > + break; > + case GpioPadConfigLockRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockOffset; > + break; > + case GpioPadLockOutputRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockTxOffset; > + break; > + default: > + break; > + } > + > + // > + // Check if selected register exists > + // > + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) { > + *ReadVal =3D 0; > + ASSERT (FALSE); > + return; > + } > + > + // > + // If there are more then 32 pads per group then certain > + // group information would be split into more then one DWord register. > + // > + if ((RegType =3D=3D GpioPadConfigLockRegister) || (RegType =3D=3D > GpioPadLockOutputRegister)) { > + // > + // PadConfigLock and OutputLock registers when used for group > containing more than 32 pads > + // are not placed in a continuous way, e.g: > + // 0x0 - PadConfigLock_DW0 > + // 0x4 - OutputLock_DW0 > + // 0x8 - PadConfigLock_DW1 > + // 0xC - OutputLock_DW1 > + // > + RegOffset +=3D DwNum * 0x8; > + } else { > + RegOffset +=3D DwNum * 0x4; > + } > + > + *ReadVal =3D MmioRead32 (PCH_PCR_ADDRESS > (GpioGroupInfo[GroupIndex].Community, RegOffset)); > +} > + > +/** > + This function determines if the group is SMI capable. > + > + @param[in] Group GPIO group > + @param[in] DwNum Register number for current group > (parameter applicable in accessing whole register). > + For group which has less then 32 pads = per group > DwNum must be 0. > + @retval TRUE The function completed successfully > + @retval FALSE Setting SMI for a group is not support= ed > +**/ > +STATIC > +BOOLEAN > +GpioIsSmiSupportedByGroupDw ( > + IN GPIO_GROUP Group, > + IN UINT32 Dw > + ) > +{ > + UINT32 RegOffset; > + UINT32 GroupIndex; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + RegOffset =3D GpioGroupInfo[GroupIndex].SmiStsOffset; > + > + // > + // Check if selected register exists > + // > + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) { > + return FALSE; > + } > + > + return TRUE; > +} > + > +/** > + This function determines if the group is NMI capable. > + > + @param[in] Group GPIO group > + @param[in] DwNum Register number for current group > (parameter applicable in accessing whole register). > + For group which has less then 32 pads = per group > DwNum must be 0. > + @retval TRUE The function completed successfully > + @retval FALSE Setting NMI for a group is not support= ed > +**/ > +STATIC > +BOOLEAN > +GpioIsNmiSupportedByGroupDw ( > + IN GPIO_GROUP Group, > + IN UINT32 Dw > + ) > +{ > + UINT32 RegOffset; > + UINT32 GroupIndex; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + RegOffset =3D GpioGroupInfo[GroupIndex].NmiEnOffset; > + > + // > + // Check if selected register exists > + // > + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) { > + return FALSE; > + } > + > + return TRUE; > +} > + > +/** > + This procedure will write GPIO register > + > + @param[in] RegType GPIO register type > + @param[in] Group GPIO group > + @param[in] DwNum Register number for current group > (parameter applicable in accessing whole register). > + For group which has less then 32 pads = per group > DwNum must be 0. > + @param[in] RegAndMask Mask which will be AND'ed with registe= r > value > + @param[in] RegOrMask Mask which will be OR'ed with register > value > +**/ > +STATIC > +VOID > +GpioWriteReg ( > + IN GPIO_REG RegType, > + IN GPIO_GROUP Group, > + IN UINT32 DwNum, > + IN UINT32 RegAndMask, > + IN UINT32 RegOrMask > + ) > +{ > + UINT32 RegOffset; > + UINT32 GroupIndex; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + UINT32 PadCfgLock; > + BOOLEAN Lockable; > + EFI_STATUS Status; > + > + Lockable =3D FALSE; > + PadCfgLock =3D 0; > + RegOffset =3D NO_REGISTER_FOR_PROPERTY; > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + switch (RegType) { > + case GpioHostOwnershipRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].HostOwnOffset; > + break; > + case GpioGpeEnableRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeEnOffset; > + Lockable =3D TRUE; > + break; > + case GpioGpeStatusRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeStsOffset; > + break; > + case GpioSmiEnableRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].SmiEnOffset; > + Lockable =3D TRUE; > + break; > + case GpioSmiStatusRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].SmiStsOffset; > + break; > + case GpioNmiEnableRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].NmiEnOffset; > + Lockable =3D TRUE; > + break; > + case GpioPadConfigLockRegister: > + case GpioPadLockOutputRegister: > + default: > + break; > + } > + > + // > + // Check if selected register exists > + // > + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) { > + return; > + } > + > + if (Lockable) { > + GpioGetPadCfgLockForGroupDw (Group, DwNum, &PadCfgLock); > + if (PadCfgLock) { > + // > + // Check if for pads which are going to be reconfigured lock is se= t. > + // > + if ((~RegAndMask | RegOrMask) & PadCfgLock) { > + // > + // Unlock all pads for this Group DW reg for simplicity > + // even if not all of those pads will have their settings reprog= rammed > + // > + Status =3D GpioUnlockPadCfgForGroupDw (Group, DwNum, PadCfgLock)= ; > + if (EFI_ERROR (Status)) { > + ASSERT (FALSE); > + return; > + } > + } else { > + // > + // No need to perform an unlock as pads which are going to be > reconfigured > + // are not in locked state > + // > + PadCfgLock =3D 0; > + } > + } > + } > + > + // > + // If there are more then 32 pads per group then certain > + // group information would be split into more then one DWord register. > + // > + RegOffset +=3D DwNum * 0x4; > + > + MmioAndThenOr32 ( > + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, RegOffset), > + RegAndMask, > + RegOrMask > + ); > + > + if (Lockable && PadCfgLock) { > + // > + // Lock previously unlocked pads > + // > + Status =3D GpioLockPadCfgForGroupDw (Group, DwNum, PadCfgLock); > + if (EFI_ERROR (Status)) { > + ASSERT (FALSE); > + return; > + } > + } > +} > + > +/** > + This procedure will write GPIO Lock/LockTx register using SBI. > + > + @param[in] RegType GPIO register (Lock or LockTx) > + @param[in] Group GPIO group number > + @param[in] DwNum Register number for current group. > + For group which has less then 32 pads = per group > DwNum must be 0. > + @param[in] LockRegAndMask Mask which will be AND'ed with Lock > register value > + @param[in] LockRegOrMask Mask which will be Or'ed with Lock > register value > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_UNSUPPORTED Feature is not supported for this grou= p or > pad > +**/ > +STATIC > +EFI_STATUS > +GpioWriteLockReg ( > + IN GPIO_REG RegType, > + IN GPIO_GROUP Group, > + IN UINT32 DwNum, > + IN UINT32 LockRegAndMask, > + IN UINT32 LockRegOrMask > + ) > +{ > + UINT8 Response; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + UINT32 RegOffset; > + UINT32 OldLockVal; > + UINT32 NewLockVal; > + UINT32 GroupIndex; > + EFI_STATUS Status; > + > + OldLockVal =3D 0; > + NewLockVal =3D 0; > + > + RegOffset =3D NO_REGISTER_FOR_PROPERTY; > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + switch (RegType) { > + case GpioPadConfigLockRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockOffset; > + GpioGetPadCfgLockForGroupDw (Group, DwNum, &OldLockVal); > + break; > + case GpioPadLockOutputRegister: > + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockTxOffset; > + GpioGetPadCfgLockTxForGroupDw (Group, DwNum, &OldLockVal); > + break; > + default: > + break; > + } > + > + // > + // Check if selected register exists > + // > + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // If there are more then 32 pads per group then certain > + // group information would be split into more then one DWord register. > + // PadConfigLock and OutputLock registers when used for group containi= ng > more than 32 pads > + // are not placed in a continuous way, e.g: > + // 0x0 - PadConfigLock_DW0 > + // 0x4 - OutputLock_DW0 > + // 0x8 - PadConfigLock_DW1 > + // 0xC - OutputLock_DW1 > + // > + RegOffset +=3D DwNum *0x8; > + > + NewLockVal =3D (OldLockVal & LockRegAndMask) | LockRegOrMask; > + > + Status =3D PchSbiExecutionEx ( > + GpioGroupInfo[GroupIndex].Community, > + RegOffset, > + GpioLockUnlock, > + FALSE, > + 0x000F, > + 0x0000, > + 0x0000, > + &NewLockVal, > + &Response > + ); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > + > +/** > + This internal procedure will calculate GPIO_RESET_CONFIG value (new > type) > + based on provided PadRstCfg for a specific GPIO Pad. > + > + @param[in] GpioPad GPIO Pad > + @param[in] PadRstCfg GPIO PadRstCfg value > + > + @retval GpioResetConfig GPIO Reset configuration (new type) > +**/ > +GPIO_RESET_CONFIG > +GpioResetConfigFromPadRstCfg ( > + IN GPIO_PAD GpioPad, > + IN UINT32 PadRstCfg > + ) > +{ > + GPIO_GROUP Group; > + > + static GPIO_RESET_CONFIG GppPadRstCfgToGpioResetConfigMap[] =3D { > + GpioResumeReset, > + GpioHostDeepReset, > + GpioPlatformReset}; > + static GPIO_RESET_CONFIG GpdPadRstCfgToGpioResetConfigMap[] =3D { > + GpioDswReset, > + GpioHostDeepReset, > + GpioPlatformReset, > + GpioResumeReset}; > + > + Group =3D GpioGetGroupFromGpioPad (GpioPad); > + > + if (GpioIsDswGroup (Group) && PadRstCfg < 4) { > + return GpdPadRstCfgToGpioResetConfigMap[PadRstCfg]; > + } else if (PadRstCfg < 3) { > + return GppPadRstCfgToGpioResetConfigMap[PadRstCfg]; > + } else { > + ASSERT (FALSE); > + return GpioResetDefault; > + } > +} > + > +/** > + This internal procedure will calculate PadRstCfg register value based > + on provided GPIO Reset configuration for a certain pad. > + > + @param[in] GpioPad GPIO Pad > + @param[in] GpioResetConfig GPIO Reset configuration > + @param[out] PadRstCfg GPIO PadRstCfg value > + > + @retval EFI_SUCCESS The function completed successfu= lly > + @retval EFI_INVALID_PARAMETER Invalid configuration > +**/ > +EFI_STATUS > +GpioPadRstCfgFromResetConfig ( > + IN GPIO_PAD GpioPad, > + IN GPIO_RESET_CONFIG GpioResetConfig, > + OUT UINT32 *PadRstCfg > + ) > +{ > + GPIO_GROUP Group; > + > + Group =3D GpioGetGroupFromGpioPad (GpioPad); > + > + switch (GpioResetConfig) { > + case GpioResetDefault: > + *PadRstCfg =3D 0x0; > + break; > + case GpioHostDeepReset: > + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_DEEP_RST; > + break; > + case GpioPlatformReset: > + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_GPIO_RST; > + break; > + case GpioResumeReset: > + if (GpioIsDswGroup (Group)) { > + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_RESUME_RST; > + } else { > + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_POW_GOOD; > + } > + break; > + case GpioDswReset: > + if (GpioIsDswGroup (Group)) { > + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_POW_GOOD; > + } else { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Only GPD group pads can use > GpioDswReset: %a\n", GpioName (GpioPad))); > + goto Error; > + } > + break; > + default: > + goto Error; > + } > + > + return EFI_SUCCESS; > +Error: > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > +} > + > +/** > + This internal procedure will get GPIO_CONFIG data from PADCFG register= s > value > + > + @param[in] GpioPad GPIO Pad > + @param[in] PadCfgDwReg PADCFG DWx register values > + @param[out] GpioData GPIO Configuration data > + > + @retval Status > +**/ > +STATIC > +VOID > +GpioConfigFromPadCfgRegValue ( > + IN GPIO_PAD GpioPad, > + IN CONST UINT32 *PadCfgDwReg, > + OUT GPIO_CONFIG *GpioConfig > + ) > +{ > + UINT32 PadRstCfg; > + > + // > + // Get Reset Type (PadRstCfg) > + // > + PadRstCfg =3D (PadCfgDwReg[0] & B_GPIO_PCR_RST_CONF) >> > N_GPIO_PCR_RST_CONF; > + > + GpioConfig->PowerConfig =3D GpioResetConfigFromPadRstCfg ( > + GpioPad, > + PadRstCfg > + ); > + > + // > + // Get how interrupt is triggered (RxEvCfg) > + // > + GpioConfig->InterruptConfig =3D ((PadCfgDwReg[0] & > B_GPIO_PCR_RX_LVL_EDG) >> (N_GPIO_PCR_RX_LVL_EDG - > (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1))) | (0x1 << > N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS); > + > + // > + // Get interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI) > + // > + GpioConfig->InterruptConfig |=3D ((PadCfgDwReg[0] & > (B_GPIO_PCR_RX_NMI_ROUTE | B_GPIO_PCR_RX_SCI_ROUTE | > B_GPIO_PCR_RX_SMI_ROUTE | B_GPIO_PCR_RX_APIC_ROUTE)) >> > (N_GPIO_PCR_RX_NMI_ROUTE - > (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1))) | (0x1 << > N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS); > + > + // > + // Get GPIO direction (GPIORxDis and GPIOTxDis) > + // > + GpioConfig->Direction =3D ((PadCfgDwReg[0] & (B_GPIO_PCR_RXDIS | > B_GPIO_PCR_TXDIS)) >> (N_GPIO_PCR_TXDIS - > (N_GPIO_DIRECTION_DIR_BIT_POS + 1))) | (0x1 << > N_GPIO_DIRECTION_DIR_BIT_POS); > + > + // > + // Get GPIO input inversion (RXINV) > + // (Only meaningful if input enabled) > + // > + if((PadCfgDwReg[0] & B_GPIO_PCR_RXDIS) =3D=3D 0) { > + GpioConfig->Direction |=3D ((PadCfgDwReg[0] & B_GPIO_PCR_RXINV) >> > (N_GPIO_PCR_RXINV - (N_GPIO_DIRECTION_INV_BIT_POS + 1))) | (0x1 << > N_GPIO_DIRECTION_INV_BIT_POS); > + } > + > + // > + // Get GPIO output state (GPIOTxState) > + // > + GpioConfig->OutputState =3D ((PadCfgDwReg[0] & B_GPIO_PCR_TX_STATE) << > (N_GPIO_PCR_TX_STATE + (N_GPIO_OUTPUT_BIT_POS + 1))) | (0x1 << > N_GPIO_OUTPUT_BIT_POS); > + > + // > + // Configure GPIO RX raw override to '1' (RXRAW1) > + // > + GpioConfig->OtherSettings =3D ((PadCfgDwReg[0] & B_GPIO_PCR_RX_RAW1) > >> (N_GPIO_PCR_RX_RAW1 - (N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS + 1))) > | (0x1 << N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS); > + > + // > + // Get GPIO Pad Mode (PMode) > + // > + GpioConfig->PadMode =3D ((PadCfgDwReg[0] & B_GPIO_PCR_PAD_MODE) >> > (N_GPIO_PCR_PAD_MODE - (N_GPIO_PAD_MODE_BIT_POS + 1))) | (0x1 << > N_GPIO_PAD_MODE_BIT_POS); > + > + // > + // Get GPIO termination (Term) > + // > + GpioConfig->ElectricalConfig =3D ((PadCfgDwReg[1] & B_GPIO_PCR_TERM) >= > > (N_GPIO_PCR_TERM - (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS > + 1))) | (0x1 << N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS); > +} > + > +/** > + This procedure will read multiple GPIO settings > + > + @param[in] GpioPad GPIO Pad > + @param[out] GpioData GPIO data structure > + > + @retval EFI_SUCCESS The function completed successfu= lly > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioGetPadConfig ( > + IN GPIO_PAD GpioPad, > + OUT GPIO_CONFIG *GpioData > + ) > +{ > + UINT32 PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER]; > + UINT32 RegVal; > + GPIO_GROUP Group; > + UINT32 PadNumber; > + UINT32 PadBitPosition; > + > + Group =3D GpioGetGroupFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // Read PADCFG DW0 register > + // > + PadCfgDwReg[0] =3D GpioReadPadCfgReg (GpioPad, 0); > + > + // > + // Read PADCFG DW1 register > + // > + PadCfgDwReg[1] =3D GpioReadPadCfgReg (GpioPad, 1); > + > + // > + // Read PADCFG DW2 register > + // > + PadCfgDwReg[2] =3D GpioReadPadCfgReg (GpioPad, 2); > + > + GpioConfigFromPadCfgRegValue ( > + GpioPad, > + PadCfgDwReg, > + GpioData > + ); > + > + // > + // Read HOSTSW_OWN registers > + // > + GpioReadReg ( > + GpioHostOwnershipRegister, > + Group, > + GPIO_GET_DW_NUM (PadNumber), > + &RegVal > + ); > + > + // > + // Get Host Software Ownership > + // > + GpioData->HostSoftPadOwn =3D (((RegVal >> PadBitPosition) & 0x1) << > (N_GPIO_HOSTSW_OWN_BIT_POS + 1)) | (0x1 << > N_GPIO_HOSTSW_OWN_BIT_POS); > + > + // > + // Read PADCFGLOCK register > + // > + GpioReadReg ( > + GpioPadConfigLockRegister, > + Group, > + GPIO_GET_DW_NUM (PadNumber), > + &RegVal > + ); > + > + // > + // Get Pad Configuration Lock state > + // > + GpioData->LockConfig =3D ((!((RegVal >> PadBitPosition) & 0x1)) << 1) = | 0x1; > + > + // > + // Read PADCFGLOCKTX register > + // > + GpioReadReg ( > + GpioPadLockOutputRegister, > + Group, > + GPIO_GET_DW_NUM (PadNumber), > + &RegVal > + ); > + > + // > + // Get Pad Configuration Lock Tx state > + // > + GpioData->LockConfig |=3D ((!((RegVal >> PadBitPosition) & 0x1)) << 2)= | 0x1; > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will calculate PADCFG register value based on GpioConfi= g > data > + > + @param[in] GpioPad GPIO Pad > + @param[in] GpioConfig GPIO Configuration data > + @param[out] PadCfgDwReg PADCFG DWx register value > + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register > bits to be modified > +**/ > +VOID > +GpioPadCfgRegValueFromGpioConfig ( > + IN GPIO_PAD GpioPad, > + IN CONST GPIO_CONFIG *GpioConfig, > + OUT UINT32 *PadCfgDwReg, > + OUT UINT32 *PadCfgDwRegMask > + ) > +{ > + UINT32 PadRstCfg; > + EFI_STATUS Status; > + > + // > + // Configure Reset Type (PadRstCfg) > + // Reset configuration depends on group type. > + // This field requires support for new and deprecated settings. > + // > + Status =3D GpioPadRstCfgFromResetConfig ( > + GpioPad, > + GpioConfig->PowerConfig, > + &PadRstCfg > + ); > + if (EFI_ERROR (Status)) { > + return; > + } > + > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->PowerConfig & > B_GPIO_RESET_CONFIG_RESET_MASK) >> > N_GPIO_RESET_CONFIG_RESET_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 : > B_GPIO_PCR_RST_CONF); > + PadCfgDwReg[0] |=3D PadRstCfg << N_GPIO_PCR_RST_CONF; > + > + // > + // Configure how interrupt is triggered (RxEvCfg) > + // > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->InterruptConfig & > B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> > N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 : > B_GPIO_PCR_RX_LVL_EDG); > + PadCfgDwReg[0] |=3D (((GpioConfig->InterruptConfig & > B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> > (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1)) << N_GPIO_PCR_RX_LVL_EDG); > + > + // > + // Configure interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI) > + // > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->InterruptConfig & > B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> > N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS) =3D=3D GpioHardwareDefault) ? > 0x0 : (B_GPIO_PCR_RX_NMI_ROUTE | B_GPIO_PCR_RX_SCI_ROUTE | > B_GPIO_PCR_RX_SMI_ROUTE | B_GPIO_PCR_RX_APIC_ROUTE)); > + PadCfgDwReg[0] |=3D (((GpioConfig->InterruptConfig & > B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> > (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1)) << > N_GPIO_PCR_RX_NMI_ROUTE); > + > + // > + // Configure GPIO direction (GPIORxDis and GPIOTxDis) > + // > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->Direction & > B_GPIO_DIRECTION_DIR_MASK) >> N_GPIO_DIRECTION_DIR_BIT_POS) =3D=3D > GpioHardwareDefault) ? 0x0 : (B_GPIO_PCR_RXDIS | B_GPIO_PCR_TXDIS)); > + PadCfgDwReg[0] |=3D (((GpioConfig->Direction & > B_GPIO_DIRECTION_DIR_MASK) >> (N_GPIO_DIRECTION_DIR_BIT_POS + 1)) << > N_GPIO_PCR_TXDIS); > + > + // > + // Configure GPIO input inversion (RXINV) > + // > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->Direction & > B_GPIO_DIRECTION_INV_MASK) >> N_GPIO_DIRECTION_INV_BIT_POS) =3D=3D > GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_RXINV); > + PadCfgDwReg[0] |=3D (((GpioConfig->Direction & > B_GPIO_DIRECTION_INV_MASK) >> (N_GPIO_DIRECTION_INV_BIT_POS + 1)) << > N_GPIO_PCR_RXINV); > + > + // > + // Configure GPIO output state (GPIOTxState) > + // > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->OutputState & > B_GPIO_OUTPUT_MASK) >> N_GPIO_OUTPUT_BIT_POS) =3D=3D > GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_TX_STATE); > + PadCfgDwReg[0] |=3D (((GpioConfig->OutputState & B_GPIO_OUTPUT_MASK) > >> (N_GPIO_OUTPUT_BIT_POS + 1)) << N_GPIO_PCR_TX_STATE); > + > + // > + // Configure GPIO RX raw override to '1' (RXRAW1) > + // > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->OtherSettings & > B_GPIO_OTHER_CONFIG_RXRAW_MASK) >> > N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 : > B_GPIO_PCR_RX_RAW1); > + PadCfgDwReg[0] |=3D (((GpioConfig->OtherSettings & > B_GPIO_OTHER_CONFIG_RXRAW_MASK) >> > (N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS + 1)) << N_GPIO_PCR_RX_RAW1); > + > + // > + // Configure GPIO Pad Mode (PMode) > + // > + PadCfgDwRegMask[0] |=3D ((((GpioConfig->PadMode & > B_GPIO_PAD_MODE_MASK) >> N_GPIO_PAD_MODE_BIT_POS) =3D=3D > GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_PAD_MODE); > + PadCfgDwReg[0] |=3D (((GpioConfig->PadMode & B_GPIO_PAD_MODE_MASK) > >> (N_GPIO_PAD_MODE_BIT_POS + 1)) << N_GPIO_PCR_PAD_MODE); > + > + // > + // Configure GPIO termination (Term) > + // > + PadCfgDwRegMask[1] |=3D ((((GpioConfig->ElectricalConfig & > B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> > N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS) =3D=3D > GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_TERM); > + PadCfgDwReg[1] |=3D (((GpioConfig->ElectricalConfig & > B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> > (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS + 1)) << > N_GPIO_PCR_TERM); > +} > + > +/** > + This procedure will configure multiple GPIO settings > + > + @param[in] GpioPad GPIO Pad > + @param[in] GpioData GPIO data structure > + > + @retval EFI_SUCCESS The function completed successfu= lly > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioSetPadConfig ( > + IN GPIO_PAD GpioPad, > + IN GPIO_CONFIG *GpioData > + ) > +{ > + EFI_STATUS Status; > + UINT32 PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER]; > + UINT32 PadCfgDwRegMask[GPIO_PADCFG_DW_REG_NUMBER]; > + UINT32 HostSoftOwnReg; > + UINT32 HostSoftOwnRegMask; > + UINT32 GpiGpeEnReg; > + UINT32 GpiGpeEnRegMask; > + UINT32 GpiNmiEnReg; > + UINT32 GpiNmiEnRegMask; > + UINT32 GpiSmiEnReg; > + UINT32 GpiSmiEnRegMask; > + GPIO_GROUP Group; > + UINT32 GroupIndex; > + UINT32 PadNumber; > + UINT32 PadBitPosition; > + UINT32 DwNum; > + GPIO_LOCK_CONFIG LockConfig; > + > + Status =3D EFI_SUCCESS; > + ZeroMem (PadCfgDwReg, sizeof (PadCfgDwReg)); > + ZeroMem (PadCfgDwRegMask, sizeof (PadCfgDwRegMask)); > + > + Group =3D GpioGetGroupFromGpioPad (GpioPad); > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); > + DwNum =3D GPIO_GET_DW_NUM (PadNumber); > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // Check if Pad enabled for SCI is to be in unlocked state > + // > + if (((GpioData->InterruptConfig & GpioIntSci) =3D=3D GpioIntSci) && > + ((GpioData->LockConfig & > B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK) !=3D GpioPadConfigUnlock)){ > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a for SCI is not unlocked!\n", > GpioName (GpioPad))); > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Get GPIO PADCFG register value from GPIO config data > + // > + GpioPadCfgRegValueFromGpioConfig ( > + GpioPad, > + GpioData, > + PadCfgDwReg, > + PadCfgDwRegMask > + ); > + > + // > + // Write PADCFG DW0 register > + // > + GpioWritePadCfgReg ( > + GpioPad, > + 0, > + ~PadCfgDwRegMask[0], > + PadCfgDwReg[0] > + ); > + > + // > + // Write PADCFG DW1 register > + // > + GpioWritePadCfgReg ( > + GpioPad, > + 1, > + ~PadCfgDwRegMask[1], > + PadCfgDwReg[1] > + ); > + > + // > + // Write PADCFG DW2 register > + // > + GpioWritePadCfgReg ( > + GpioPad, > + 2, > + ~PadCfgDwRegMask[2], > + PadCfgDwReg[2] > + ); > + > + // > + // Update value to be programmed in HOSTSW_OWN register > + // > + if ((GpioData->InterruptConfig & GpioIntSmi) =3D=3D GpioIntSmi) { > + HostSoftOwnRegMask =3D 1 << PadBitPosition; > + HostSoftOwnReg =3D 1 << PadBitPosition; > + } else { > + HostSoftOwnRegMask =3D (GpioData->HostSoftPadOwn & 0x1) << > PadBitPosition; > + HostSoftOwnReg =3D (GpioData->HostSoftPadOwn >> 0x1) << > PadBitPosition; > + } > + > + // > + // Write HOSTSW_OWN registers > + // > + GpioWriteReg ( > + GpioHostOwnershipRegister, > + Group, > + DwNum, > + ~HostSoftOwnRegMask, > + HostSoftOwnReg > + ); > + > + // > + // Update value to be programmed in GPI_GPE_EN register > + // > + GpiGpeEnRegMask =3D (GpioData->InterruptConfig & 0x1) << PadBitPositio= n; > + GpiGpeEnReg =3D ((GpioData->InterruptConfig & GpioIntSci) >> 3) << > PadBitPosition; > + > + // > + // Write GPI_GPE_EN registers > + // > + GpioWriteReg ( > + GpioGpeEnableRegister, > + Group, > + DwNum, > + ~GpiGpeEnRegMask, > + GpiGpeEnReg > + ); > + > + // > + // Update value to be programmed in GPI_NMI_EN register > + // > + GpiNmiEnRegMask =3D (GpioData->InterruptConfig & 0x1) << PadBitPositio= n; > + GpiNmiEnReg =3D ((GpioData->InterruptConfig & GpioIntNmi) >> 1) << > PadBitPosition; > + > + if (GpioIsNmiSupportedByGroupDw (Group, DwNum)) { > + GpioWriteReg ( > + GpioNmiEnableRegister, > + Group, > + DwNum, > + ~GpiNmiEnRegMask, > + GpiNmiEnReg > + ); > + } else { > + if (GpiNmiEnReg =3D=3D 0) { > + // > + // Not all GPIO have NMI capabilities. Since we always try to prog= ram this > register, > + // even when not enabling NMI for a pad so do not report such acce= ss as > an error > + // > + Status =3D EFI_SUCCESS; > + } else { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %a has no pads > supporting NMI\n", GpioGetGroupName (GroupIndex))); > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + } > + > + // > + // Update value to be programmed in GPI_SMI_EN register > + // > + GpiSmiEnRegMask =3D (GpioData->InterruptConfig & 0x1) << PadBitPositio= n; > + GpiSmiEnReg =3D ((GpioData->InterruptConfig & GpioIntSmi) >> 2) << > PadBitPosition; > + > + if (GpioIsSmiSupportedByGroupDw (Group, DwNum)) { > + GpioWriteReg ( > + GpioSmiEnableRegister, > + Group, > + DwNum, > + ~GpiSmiEnRegMask, > + GpiSmiEnReg > + ); > + } else { > + if (GpiSmiEnReg =3D=3D 0) { > + // > + // Not all GPIO have SMI capabilities. Since we always try to prog= ram this > register, > + // even when not enabling SMI for a pad so do not report such acce= ss as > an error > + // > + Status =3D EFI_SUCCESS; > + } else { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %a has no pads > supporting SMI\n", GpioGetGroupName (GroupIndex))); > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + } > + > + // > + // Store unlock data > + // > + if (GpioData->LockConfig !=3D GpioLockDefault) { > + LockConfig =3D GpioData->LockConfig & > B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK; > + // > + // If pad in GpioMode is an output default action should be to leave > output unlocked > + // > + if ((GpioData->PadMode =3D=3D GpioPadModeGpio) && > + (GpioData->Direction =3D=3D GpioDirOut) && > + ((GpioData->LockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) > =3D=3D GpioLockDefault)) { > + LockConfig |=3D GpioOutputStateUnlock; > + } else { > + LockConfig |=3D GpioData->LockConfig & > B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK; > + } > + Status =3D GpioStoreUnlockData (GpioPad, LockConfig); > + } > + > + return Status; > +} > + > +/** > + This procedure will set GPIO output level > + > + @param[in] GpioPad GPIO pad > + @param[in] Value Output value > + 0: OutputLow, 1: OutputHigh > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioSetOutputValue ( > + IN GPIO_PAD GpioPad, > + IN UINT32 Value > + ) > +{ > + if (Value > 1) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + GpioWritePadCfgReg ( > + GpioPad, > + 0, > + (UINT32)~B_GPIO_PCR_TX_STATE, > + Value << N_GPIO_PCR_TX_STATE > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will get GPIO output level > + > + @param[in] GpioPad GPIO pad > + @param[out] OutputVal GPIO Output value > + 0: OutputLow, 1: OutputHigh > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioGetOutputValue ( > + IN GPIO_PAD GpioPad, > + OUT UINT32 *OutputVal > + ) > +{ > + UINT32 PadCfgReg; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + PadCfgReg =3D GpioReadPadCfgReg (GpioPad, 0); > + > + *OutputVal =3D (PadCfgReg & B_GPIO_PCR_TX_STATE) >> > N_GPIO_PCR_TX_STATE; > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will get GPIO input level > + > + @param[in] GpioPad GPIO pad > + @param[out] InputVal GPIO Input value > + 0: InputLow, 1: InpuHigh > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioGetInputValue ( > + IN GPIO_PAD GpioPad, > + OUT UINT32 *InputVal > + ) > +{ > + UINT32 PadCfgReg; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + PadCfgReg =3D GpioReadPadCfgReg (GpioPad, 0); > + > + *InputVal =3D (PadCfgReg & B_GPIO_PCR_RX_STATE) >> > N_GPIO_PCR_RX_STATE; > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will get GPIO IOxAPIC interrupt number > + > + @param[in] GpioPad GPIO pad > + @param[out] IrqNum IRQ number > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioGetPadIoApicIrqNumber ( > + IN GPIO_PAD GpioPad, > + OUT UINT32 *IrqNum > + ) > +{ > + UINT32 PadCfgReg; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + PadCfgReg =3D GpioReadPadCfgReg (GpioPad, 1); > + > + *IrqNum =3D (PadCfgReg & B_GPIO_PCR_INTSEL) >> N_GPIO_PCR_INTSEL; > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will configure GPIO input inversion > + > + @param[in] GpioPad GPIO pad > + @param[in] Value Value for GPIO input inversion > + 0: No input inversion, 1: Invert input > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioSetInputInversion ( > + IN GPIO_PAD GpioPad, > + IN UINT32 Value > + ) > +{ > + if (Value > 1) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + GpioWritePadCfgReg ( > + GpioPad, > + 0, > + (UINT32)~B_GPIO_PCR_RXINV, > + Value << N_GPIO_PCR_RXINV > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will get GPIO pad input inversion value > + > + @param[in] GpioPad GPIO pad > + @param[out] InvertState GPIO inversion state > + 0: No input inversion, 1: Inverted inp= ut > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioGetInputInversion ( > + IN GPIO_PAD GpioPad, > + OUT UINT32 *InvertState > + ) > +{ > + UINT32 PadCfgReg; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + PadCfgReg =3D GpioReadPadCfgReg (GpioPad, 0); > + > + *InvertState =3D (PadCfgReg & B_GPIO_PCR_RXINV) >> N_GPIO_PCR_RXINV; > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will set GPIO interrupt settings > + > + @param[in] GpioPad GPIO pad > + @param[in] Value Value of Level/Edge > + use GPIO_INT_CONFIG as argument > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioSetPadInterruptConfig ( > + IN GPIO_PAD GpioPad, > + IN GPIO_INT_CONFIG Value > + ) > +{ > + EFI_STATUS Status; > + BOOLEAN IsNmiSupported; > + UINT32 RxLvlEdgeValue; > + UINT32 IntRouteValue; > + UINT32 PadNumber; > + UINT32 GpeEnable; > + UINT32 NmiEnable; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + Status =3D EFI_SUCCESS; > + > + if (((Value & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> > N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS) !=3D GpioHardwareDefault) { > + RxLvlEdgeValue =3D ((Value & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> > (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1)) << N_GPIO_PCR_RX_LVL_EDG; > + > + GpioWritePadCfgReg ( > + GpioPad, > + 0, > + (UINT32)~B_GPIO_PCR_RX_LVL_EDG, > + RxLvlEdgeValue > + ); > + } > + > + if (((Value & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> > N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS) !=3D GpioHardwareDefault) { > + > + IntRouteValue =3D ((Value & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> > (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1)) << > N_GPIO_PCR_RX_NMI_ROUTE; > + > + GpioWritePadCfgReg ( > + GpioPad, > + 0, > + (UINT32)~(B_GPIO_PCR_RX_NMI_ROUTE | B_GPIO_PCR_RX_SCI_ROUTE > | B_GPIO_PCR_RX_SMI_ROUTE | B_GPIO_PCR_RX_APIC_ROUTE), > + IntRouteValue > + ); > + > + if ((Value & GpioIntSci) =3D=3D GpioIntSci) { > + GpeEnable =3D 0x1; > + } else { > + GpeEnable =3D 0x0; > + } > + > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + GpioWriteReg ( > + GpioGpeEnableRegister, > + GpioGetGroupFromGpioPad (GpioPad), > + GPIO_GET_DW_NUM (PadNumber), > + ~(1 << GPIO_GET_PAD_POSITION (PadNumber)), > + GpeEnable << GPIO_GET_PAD_POSITION (PadNumber) > + ); > + > + if ((Value & GpioIntNmi) =3D=3D GpioIntNmi) { > + NmiEnable =3D 0x1; > + } else { > + NmiEnable =3D 0x0; > + } > + > + IsNmiSupported =3D GpioIsNmiSupportedByGroupDw ( > + GpioGetGroupFromGpioPad (GpioPad), > + GPIO_GET_DW_NUM (PadNumber) > + ); > + if (IsNmiSupported) { > + GpioWriteReg ( > + GpioNmiEnableRegister, > + GpioGetGroupFromGpioPad (GpioPad), > + GPIO_GET_DW_NUM (PadNumber), > + ~(1 << GPIO_GET_PAD_POSITION (PadNumber)), > + NmiEnable << GPIO_GET_PAD_POSITION (PadNumber) > + ); > + } else { > + if (NmiEnable =3D=3D 0) { > + // > + // Not all GPIO have NMI capabilities. Since we always try to pr= ogram > this register, > + // even when not enabling NMI for a pad so do not report such ac= cess > as an error > + // > + return EFI_SUCCESS; > + } else { > + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %a has no pads > supporting NMI\n", GpioGetGroupName (GpioGetGroupIndexFromGpioPad > (GpioPad)))); > + ASSERT (FALSE); > + } > + } > + } > + > + return Status; > +} > + > +/** > + This procedure will set GPIO electrical settings > + > + @param[in] GpioPad GPIO pad > + @param[in] Value Value of termination > + use GPIO_ELECTRICAL_CONFIG as argument > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioSetPadElectricalConfig ( > + IN GPIO_PAD GpioPad, > + IN GPIO_ELECTRICAL_CONFIG Value > + ) > +{ > + UINT32 TermValue; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + if (((Value & B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> > N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS) !=3D > GpioHardwareDefault) { > + TermValue =3D ((Value & > B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> > (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS + 1)) << > N_GPIO_PCR_TERM; > + > + GpioWritePadCfgReg ( > + GpioPad, > + 1, > + (UINT32)~B_GPIO_PCR_TERM, > + TermValue > + ); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will set GPIO Reset settings > + > + @param[in] GpioPad GPIO pad > + @param[in] Value Value for Pad Reset Configuration > + use GPIO_RESET_CONFIG as argument > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioSetPadResetConfig ( > + IN GPIO_PAD GpioPad, > + IN GPIO_RESET_CONFIG Value > + ) > +{ > + UINT32 PadRstCfg; > + EFI_STATUS Status; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + if (((Value & B_GPIO_RESET_CONFIG_RESET_MASK) >> > N_GPIO_RESET_CONFIG_RESET_BIT_POS) !=3D GpioHardwareDefault) { > + > + // > + // Reset configuration depends on group type. > + // This field requires support for new and deprecated settings. > + // > + Status =3D GpioPadRstCfgFromResetConfig ( > + GpioPad, > + Value, > + &PadRstCfg > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + GpioWritePadCfgReg ( > + GpioPad, > + 0, > + (UINT32)~B_GPIO_PCR_RST_CONF, > + PadRstCfg << N_GPIO_PCR_RST_CONF > + ); > + } > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will get GPIO Reset settings > + > + @param[in] GpioPad GPIO pad > + @param[in] Value Value of Pad Reset Configuration > + based on GPIO_RESET_CONFIG > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioGetPadResetConfig ( > + IN GPIO_PAD GpioPad, > + IN GPIO_RESET_CONFIG *Value > + ) > +{ > + UINT32 PadRstCfg; > + UINT32 PadCfgDw0Reg; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!GpioIsPadHostOwned (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + PadCfgDw0Reg =3D GpioReadPadCfgReg (GpioPad, 0); > + > + // > + // Get Reset Type (PadRstCfg) > + // > + PadRstCfg =3D (PadCfgDw0Reg & B_GPIO_PCR_RST_CONF) >> > N_GPIO_PCR_RST_CONF; > + > + *Value =3D GpioResetConfigFromPadRstCfg ( > + GpioPad, > + PadRstCfg > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will get GPIO Host Software Pad Ownership for certain g= roup > + > + @param[in] Group GPIO group > + @param[in] DwNum Host Ownership register number for > current group. > + For group which has less then 32 pads = per group > DwNum must be 0. > + @param[out] HostSwRegVal Value of Host Software Pad Ownership > register > + Bit position - PadNumber > + Bit value - 0: ACPI Mode, 1: GPIO Driv= er mode > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter > number > +**/ > +EFI_STATUS > +GpioGetHostSwOwnershipForGroupDw ( > + IN GPIO_GROUP Group, > + IN UINT32 DwNum, > + OUT UINT32 *HostSwRegVal > + ) > +{ > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { > + return EFI_INVALID_PARAMETER; > + } > + > + GpioReadReg ( > + GpioHostOwnershipRegister, > + Group, > + DwNum, > + HostSwRegVal > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will get GPIO Host Software Pad Ownership for certain g= roup > + > + @param[in] Group GPIO group > + @param[in] DwNum Host Ownership register number for > current group > + For group which has less then 32 pads = per group > DwNum must be 0. > + @param[in] HostSwRegVal Value of Host Software Pad Ownership > register > + Bit position - PadNumber > + Bit value - 0: ACPI Mode, 1: GPIO Driv= er mode > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter > number > +**/ > +EFI_STATUS > +GpioSetHostSwOwnershipForGroupDw ( > + IN GPIO_GROUP Group, > + IN UINT32 DwNum, > + IN UINT32 HostSwRegVal > + ) > +{ > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { > + return EFI_INVALID_PARAMETER; > + } > + > + GpioWriteReg ( > + GpioHostOwnershipRegister, > + Group, > + DwNum, > + 0, > + HostSwRegVal > + ); > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will get Gpio Pad Host Software Ownership > + > + @param[in] GpioPad GPIO pad > + @param[out] PadHostSwOwn Value of Host Software Pad Owner > + 0: ACPI Mode, 1: GPIO Driver mode > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioGetHostSwOwnershipForPad ( > + IN GPIO_PAD GpioPad, > + OUT UINT32 *PadHostSwOwn > + ) > +{ > + UINT32 PadNumber; > + UINT32 HostSwRegVal; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + GpioReadReg ( > + GpioHostOwnershipRegister, > + GpioGetGroupFromGpioPad (GpioPad), > + GPIO_GET_DW_NUM (PadNumber), > + &HostSwRegVal > + ); > + > + *PadHostSwOwn =3D (HostSwRegVal >> GPIO_GET_PAD_POSITION > (PadNumber)) & 0x1; > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will set Gpio Pad Host Software Ownership > + > + @param[in] GpioPad GPIO pad > + @param[in] PadHostSwOwn Pad Host Software Owner > + 0: ACPI Mode, 1: GPIO Driver mode > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioSetHostSwOwnershipForPad ( > + IN GPIO_PAD GpioPad, > + IN UINT32 PadHostSwOwn > + ) > +{ > + UINT32 PadNumber; > + > + if (!GpioIsPadValid (GpioPad) || (PadHostSwOwn > 1)) { > + return EFI_INVALID_PARAMETER; > + } > + > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + GpioWriteReg ( > + GpioHostOwnershipRegister, > + GpioGetGroupFromGpioPad (GpioPad), > + GPIO_GET_DW_NUM (PadNumber), > + (UINT32)~(1 << GPIO_GET_PAD_POSITION (PadNumber)), > + PadHostSwOwn << GPIO_GET_PAD_POSITION (PadNumber) > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will get Gpio Pad Ownership > + > + @param[in] GpioPad GPIO pad > + @param[out] PadOwnVal Value of Pad Ownership > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioGetPadOwnership ( > + IN GPIO_PAD GpioPad, > + OUT GPIO_PAD_OWN *PadOwnVal > + ) > +{ > + UINT32 Mask; > + UINT32 RegOffset; > + UINT32 GroupIndex; > + UINT32 PadNumber; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + UINT32 PadOwnRegValue; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + // > + // Calculate RegOffset using Pad Ownership offset and GPIO Pad number. > + // One DWord register contains information for 8 pads. > + // > + RegOffset =3D GpioGroupInfo[GroupIndex].PadOwnOffset + (PadNumber >> 3= ) > * 0x4; > + > + // > + // Calculate pad bit position within DWord register > + // > + PadNumber %=3D 8; > + Mask =3D (BIT1 | BIT0) << (PadNumber * 4); > + > + PadOwnRegValue =3D MmioRead32 (PCH_PCR_ADDRESS > (GpioGroupInfo[GroupIndex].Community, RegOffset)); > + > + *PadOwnVal =3D (GPIO_PAD_OWN) ((PadOwnRegValue & Mask) >> > (PadNumber * 4)); > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will check state of Pad Config Lock for pads within one= group > + > + @param[in] Group GPIO group > + @param[in] DwNum PadCfgLock register number for current > group. > + For group which has less then 32 pads = per group > DwNum must be 0. > + @param[out] PadCfgLockRegVal Value of PadCfgLock register > + Bit position - PadNumber > + Bit value - 0: NotLocked, 1: Locked > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter > number > +**/ > +EFI_STATUS > +GpioGetPadCfgLockForGroupDw ( > + IN GPIO_GROUP Group, > + IN UINT32 DwNum, > + OUT UINT32 *PadCfgLockRegVal > + ) > +{ > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { > + return EFI_INVALID_PARAMETER; > + } > + > + GpioReadReg ( > + GpioPadConfigLockRegister, > + Group, > + DwNum, > + PadCfgLockRegVal > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will check state of Pad Config Lock for selected pad > + > + @param[in] GpioPad GPIO pad > + @param[out] PadCfgLock PadCfgLock for selected pad > + 0: NotLocked, 1: Locked > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioGetPadCfgLock ( > + IN GPIO_PAD GpioPad, > + OUT UINT32 *PadCfgLock > + ) > +{ > + UINT32 PadNumber; > + UINT32 PadCfgLockRegVal; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + GpioReadReg ( > + GpioPadConfigLockRegister, > + GpioGetGroupFromGpioPad (GpioPad), > + GPIO_GET_DW_NUM (PadNumber), > + &PadCfgLockRegVal > + ); > + > + *PadCfgLock =3D (PadCfgLockRegVal >> GPIO_GET_PAD_POSITION > (PadNumber)) & 0x1; > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will check state of Pad Config Tx Lock for pads within = one > group > + > + @param[in] Group GPIO group > + @param[in] DwNum PadCfgLockTx register number for curre= nt > group. > + For group which has less then 32 pads = per group > DwNum must be 0. > + @param[out] PadCfgLockTxRegVal Value of PadCfgLockTx register > + Bit position - PadNumber > + Bit value - 0: NotLockedTx, 1: LockedT= x > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter > number > +**/ > +EFI_STATUS > +GpioGetPadCfgLockTxForGroupDw ( > + IN GPIO_GROUP Group, > + IN UINT32 DwNum, > + OUT UINT32 *PadCfgLockTxRegVal > + ) > +{ > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { > + return EFI_INVALID_PARAMETER; > + } > + > + GpioReadReg ( > + GpioPadLockOutputRegister, > + Group, > + DwNum, > + PadCfgLockTxRegVal > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will check state of Pad Config Tx Lock for selected pad > + > + @param[in] GpioPad GPIO pad > + @param[out] PadCfgLock PadCfgLockTx for selected pad > + 0: NotLockedTx, 1: LockedTx > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioGetPadCfgLockTx ( > + IN GPIO_PAD GpioPad, > + OUT UINT32 *PadCfgLockTx > + ) > +{ > + UINT32 PadNumber; > + UINT32 PadCfgLockTxRegVal; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + GpioReadReg ( > + GpioPadLockOutputRegister, > + GpioGetGroupFromGpioPad (GpioPad), > + GPIO_GET_DW_NUM (PadNumber), > + &PadCfgLockTxRegVal > + ); > + > + *PadCfgLockTx =3D (PadCfgLockTxRegVal >> GPIO_GET_PAD_POSITION > (PadNumber)) & 0x1; > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will clear PadCfgLock for selected pads within one grou= p. > + This function should be used only inside SMI. > + > + @param[in] Group GPIO group > + @param[in] DwNum PadCfgLock register number for current > group. > + For group which has less then 32 pads = per group > DwNum must be 0. > + @param[in] PadsToUnlock Bitmask for pads which are going to be > unlocked, > + Bit position - PadNumber > + Bit value - 0: DoNotUnlock, 1: Unlock > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioUnlockPadCfgForGroupDw ( > + IN GPIO_GROUP Group, > + IN UINT32 DwNum, > + IN UINT32 PadsToUnlock > + ) > +{ > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { > + return EFI_INVALID_PARAMETER; > + } > + > + return GpioWriteLockReg ( > + GpioPadConfigLockRegister, > + Group, > + DwNum, > + ~PadsToUnlock, > + 0 > + ); > +} > + > +/** > + This procedure will clear PadCfgLock for selected pad. > + This function should be used only inside SMI. > + > + @param[in] GpioPad GPIO pad > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioUnlockPadCfg ( > + IN GPIO_PAD GpioPad > + ) > +{ > + GPIO_GROUP Group; > + UINT32 PadNumber; > + > + Group =3D GpioGetGroupFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + return GpioUnlockPadCfgForGroupDw ( > + Group, > + GPIO_GET_DW_NUM (PadNumber), > + 1 << GPIO_GET_PAD_POSITION (PadNumber) > + ); > +} > + > +/** > + This procedure will set PadCfgLock for selected pads within one group > + > + @param[in] Group GPIO group > + @param[in] DwNum PadCfgLock register number for current > group. > + For group which has less then 32 pads = per group > DwNum must be 0. > + @param[in] PadsToLock Bitmask for pads which are going to be > locked > + Bit position - PadNumber > + Bit value - 0: DoNotLock, 1: Lock > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter > number > +**/ > +EFI_STATUS > +GpioLockPadCfgForGroupDw ( > + IN GPIO_GROUP Group, > + IN UINT32 DwNum, > + IN UINT32 PadsToLock > + ) > +{ > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { > + return EFI_INVALID_PARAMETER; > + } > + > + return GpioWriteLockReg ( > + GpioPadConfigLockRegister, > + Group, > + DwNum, > + ~0u, > + PadsToLock > + ); > +} > + > +/** > + This procedure will set PadCfgLock for selected pad > + > + @param[in] GpioPad GPIO pad > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioLockPadCfg ( > + IN GPIO_PAD GpioPad > + ) > +{ > + GPIO_GROUP Group; > + UINT32 PadNumber; > + > + Group =3D GpioGetGroupFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + return GpioLockPadCfgForGroupDw ( > + Group, > + GPIO_GET_DW_NUM (PadNumber), > + 1 << GPIO_GET_PAD_POSITION (PadNumber) > + ); > +} > + > +/** > + This procedure will clear PadCfgLockTx for selected pads within one gr= oup. > + This function should be used only inside SMI. > + > + @param[in] Group GPIO group > + @param[in] DwNum PadCfgLockTx register number for curre= nt > group. > + For group which has less then 32 pads = per group > DwNum must be 0. > + @param[in] PadsToUnlockTx Bitmask for pads which are going to be > unlocked, > + Bit position - PadNumber > + Bit value - 0: DoNotUnLockTx, 1: LockT= x > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioUnlockPadCfgTxForGroupDw ( > + IN GPIO_GROUP Group, > + IN UINT32 DwNum, > + IN UINT32 PadsToUnlockTx > + ) > +{ > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { > + return EFI_INVALID_PARAMETER; > + } > + > + return GpioWriteLockReg ( > + GpioPadLockOutputRegister, > + Group, > + DwNum, > + ~PadsToUnlockTx, > + 0 > + ); > +} > + > +/** > + This procedure will clear PadCfgLockTx for selected pad. > + This function should be used only inside SMI. > + > + @param[in] GpioPad GPIO pad > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioUnlockPadCfgTx ( > + IN GPIO_PAD GpioPad > + ) > +{ > + GPIO_GROUP Group; > + UINT32 PadNumber; > + > + Group =3D GpioGetGroupFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + return GpioUnlockPadCfgTxForGroupDw ( > + Group, > + GPIO_GET_DW_NUM (PadNumber), > + 1 << GPIO_GET_PAD_POSITION (PadNumber) > + ); > +} > + > +/** > + This procedure will set PadCfgLockTx for selected pads within one grou= p > + > + @param[in] Group GPIO group > + @param[in] DwNum PadCfgLock register number for current > group. > + For group which has less then 32 pads = per group > DwNum must be 0. > + @param[in] PadsToLockTx Bitmask for pads which are going to be > locked, > + Bit position - PadNumber > + Bit value - 0: DoNotLockTx, 1: LockTx > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter > number > +**/ > +EFI_STATUS > +GpioLockPadCfgTxForGroupDw ( > + IN GPIO_GROUP Group, > + IN UINT32 DwNum, > + IN UINT32 PadsToLockTx > + ) > +{ > + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { > + return EFI_INVALID_PARAMETER; > + } > + > + return GpioWriteLockReg ( > + GpioPadLockOutputRegister, > + Group, > + DwNum, > + ~0u, > + PadsToLockTx > + ); > +} > + > +/** > + This procedure will set PadCfgLockTx for selected pad > + > + @param[in] GpioPad GPIO pad > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioLockPadCfgTx ( > + IN GPIO_PAD GpioPad > + ) > +{ > + GPIO_GROUP Group; > + UINT32 PadNumber; > + > + Group =3D GpioGetGroupFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + return GpioLockPadCfgTxForGroupDw ( > + Group, > + GPIO_GET_DW_NUM (PadNumber), > + 1 << GPIO_GET_PAD_POSITION (PadNumber) > + ); > +} > + > +/** > + This procedure will get Group to GPE mapping. > + It will assume that only first 32 pads can be mapped to GPE. > + To handle cases where groups have more than 32 pads and higher part of > group > + can be mapped please refer to GpioGetGroupDwToGpeDwX() > + > + @param[out] GroupToGpeDw0 GPIO group to be mapped to GPE_DW0 > + @param[out] GroupToGpeDw1 GPIO group to be mapped to GPE_DW1 > + @param[out] GroupToGpeDw2 GPIO group to be mapped to GPE_DW2 > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioGetGroupToGpeDwX ( > + IN GPIO_GROUP *GroupToGpeDw0, > + IN GPIO_GROUP *GroupToGpeDw1, > + IN GPIO_GROUP *GroupToGpeDw2 > + ) > +{ > + UINT32 GroupDw[3]; > + UINT32 Index; > + EFI_STATUS Status; > + > + Status =3D GpioGetGroupDwToGpeDwX ( > + GroupToGpeDw0, > + &GroupDw[0], > + GroupToGpeDw1, > + &GroupDw[1], > + GroupToGpeDw2, > + &GroupDw[2] > + ); > + > + for (Index =3D 0; Index < ARRAY_SIZE (GroupDw); Index++) { > + if (GroupDw[Index] !=3D 0) { > + Status =3D EFI_UNSUPPORTED; > + ASSERT (FALSE); > + } > + } > + return Status; > +} > + > + > +/** > + This procedure will get Group to GPE mapping. If group has more than 3= 2 > bits > + it is possible to map only single DW of pins (e.g. 0-31, 32-63) becaus= e > + ACPI GPE_DWx register is 32 bits large. > + > + @param[out] GroupToGpeDw0 GPIO group mapped to GPE_DW0 > + @param[out] GroupDwForGpeDw0 DW of pins mapped to GPE_DW0 > + @param[out] GroupToGpeDw1 GPIO group mapped to GPE_DW1 > + @param[out] GroupDwForGpeDw1 DW of pins mapped to GPE_DW1 > + @param[out] GroupToGpeDw2 GPIO group mapped to GPE_DW2 > + @param[out] GroupDwForGpeDw2 DW of pins mapped to GPE_DW2 > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioGetGroupDwToGpeDwX ( > + OUT GPIO_GROUP *GroupToGpeDw0, > + OUT UINT32 *GroupDwForGpeDw0, > + OUT GPIO_GROUP *GroupToGpeDw1, > + OUT UINT32 *GroupDwForGpeDw1, > + OUT GPIO_GROUP *GroupToGpeDw2, > + OUT UINT32 *GroupDwForGpeDw2 > + ) > +{ > + UINT32 PmcGpeDwXValue[3]; > + GPIO_GROUP GroupToGpeDwX[3]; > + UINT32 GroupDwForGpeDwX[3]; > + UINT8 GpeDwXIndex; > + UINT32 Index; > + GPIO_GROUP_TO_GPE_MAPPING *GpioGpeMap; > + UINT32 GpioGpeMapLength; > + > + ZeroMem (GroupToGpeDwX, sizeof (GroupToGpeDwX)); > + ZeroMem (GroupDwForGpeDwX, sizeof (GroupDwForGpeDwX)); > + > + PmcGetGpioGpe (&PmcGpeDwXValue[0], &PmcGpeDwXValue[1], > &PmcGpeDwXValue[2]); > + > + GpioGetGroupToGpeMapping (&GpioGpeMap, &GpioGpeMapLength); > + > + for (GpeDwXIndex =3D 0; GpeDwXIndex < 3; GpeDwXIndex++) { > + for (Index =3D 0; Index < GpioGpeMapLength; Index++) { > + > + if (GpioGpeMap[Index].PmcGpeDwxVal =3D=3D > PmcGpeDwXValue[GpeDwXIndex]) { > + GroupToGpeDwX[GpeDwXIndex] =3D GpioGpeMap[Index].Group; > + GroupDwForGpeDwX[GpeDwXIndex] =3D GpioGpeMap[Index].GroupDw; > + break; > + } > + } > + } > + > + if ((GroupToGpeDwX[0] =3D=3D 0) || > + (GroupToGpeDwX[1] =3D=3D 0) || > + (GroupToGpeDwX[2] =3D=3D 0)) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + > + *GroupToGpeDw0 =3D GroupToGpeDwX[0]; > + *GroupDwForGpeDw0 =3D GroupDwForGpeDwX[0]; > + *GroupToGpeDw1 =3D GroupToGpeDwX[1]; > + *GroupDwForGpeDw1 =3D GroupDwForGpeDwX[1]; > + *GroupToGpeDw2 =3D GroupToGpeDwX[2]; > + *GroupDwForGpeDw2 =3D GroupDwForGpeDwX[2]; > + > + return EFI_SUCCESS; > +} > + > + > +/** > + This procedure will set Group to GPE mapping. > + It will assume that only first 32 pads can be mapped to GPE. > + To handle cases where groups have more than 32 pads and higher part of > group > + can be mapped please refer to GpioSetGroupDwToGpeDwX() > + > + @param[in] GroupToGpeDw0 GPIO group to be mapped to GPE_DW0 > + @param[in] GroupToGpeDw1 GPIO group to be mapped to GPE_DW1 > + @param[in] GroupToGpeDw2 GPIO group to be mapped to GPE_DW2 > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioSetGroupToGpeDwX ( > + IN GPIO_GROUP GroupToGpeDw0, > + IN GPIO_GROUP GroupToGpeDw1, > + IN GPIO_GROUP GroupToGpeDw2 > + ) > +{ > + return GpioSetGroupDwToGpeDwX ( > + GroupToGpeDw0, > + 0, > + GroupToGpeDw1, > + 0, > + GroupToGpeDw2, > + 0 > + ); > +} > + > +/** > + This procedure will set Group to GPE mapping. If group has more than 3= 2 > bits > + it is possible to map only single DW of pins (e.g. 0-31, 32-63) becaus= e > + ACPI GPE_DWx register is 32 bits large. > + > + @param[in] GroupToGpeDw0 GPIO group to be mapped to GPE_DW0 > + @param[in] GroupDwForGpeDw0 DW of pins to be mapped to > GPE_DW0 > + @param[in] GroupToGpeDw1 GPIO group to be mapped to GPE_DW1 > + @param[in] GroupDwForGpeDw1 DW of pins to be mapped to > GPE_DW1 > + @param[in] GroupToGpeDw2 GPIO group to be mapped to GPE_DW2 > + @param[in] GroupDwForGpeDw2 DW of pins to be mapped to > GPE_DW2 > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioSetGroupDwToGpeDwX ( > + IN GPIO_GROUP GroupToGpeDw0, > + IN UINT32 GroupDwForGpeDw0, > + IN GPIO_GROUP GroupToGpeDw1, > + IN UINT32 GroupDwForGpeDw1, > + IN GPIO_GROUP GroupToGpeDw2, > + IN UINT32 GroupDwForGpeDw2 > + ) > +{ > + UINT32 Data32Or; > + UINT32 Data32And; > + PCH_SBI_PID *GpioComSbiIds; > + UINT32 NoOfGpioComs; > + UINT32 GpioComIndex; > + UINT32 GpioGpeDwx[3]; > + UINT32 PmcGpeDwx[3]; > + GPIO_GROUP GroupToGpeDwX[3]; > + UINT32 GroupDwForGpeDwX[3]; > + UINT8 GpeDwXIndex; > + UINT32 Index; > + GPIO_GROUP_TO_GPE_MAPPING *GpioGpeMap; > + UINT32 GpioGpeMapLength; > + > + ZeroMem (GpioGpeDwx, sizeof (GpioGpeDwx)); > + ZeroMem (PmcGpeDwx, sizeof (PmcGpeDwx)); > + // > + // Check if each group number is unique > + // > + if ((GroupToGpeDw0 =3D=3D GroupToGpeDw1) || > + (GroupToGpeDw0 =3D=3D GroupToGpeDw2) || > + (GroupToGpeDw1 =3D=3D GroupToGpeDw2)) { > + return EFI_INVALID_PARAMETER; > + } > + > + GroupToGpeDwX[0] =3D GroupToGpeDw0; > + GroupDwForGpeDwX[0] =3D GroupDwForGpeDw0; > + GroupToGpeDwX[1] =3D GroupToGpeDw1; > + GroupDwForGpeDwX[1] =3D GroupDwForGpeDw1; > + GroupToGpeDwX[2] =3D GroupToGpeDw2; > + GroupDwForGpeDwX[2] =3D GroupDwForGpeDw2; > + > + GpioGetGroupToGpeMapping (&GpioGpeMap, &GpioGpeMapLength); > + > + for (GpeDwXIndex =3D 0; GpeDwXIndex < 3; GpeDwXIndex++) { > + for (Index =3D 0; Index < GpioGpeMapLength; Index++) { > + > + if ((GpioGpeMap[Index].Group =3D=3D GroupToGpeDwX[GpeDwXIndex]) && > + (GpioGpeMap[Index].GroupDw =3D=3D > GroupDwForGpeDwX[GpeDwXIndex])) { > + PmcGpeDwx[GpeDwXIndex] =3D GpioGpeMap[Index].PmcGpeDwxVal; > + GpioGpeDwx[GpeDwXIndex] =3D GpioGpeMap[Index].GpioGpeDwxVal; > + break; > + } > + } > + > + if (Index =3D=3D GpioGpeMapLength) { > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + } > + > + // > + // Program GPE configuration in PMC register > + // > + PmcSetGpioGpe ( > + PmcGpeDwx[0], > + PmcGpeDwx[1], > + PmcGpeDwx[2] > + ); > + > + // > + // Program GPE configuration in GPIO registers > + // > + Data32And =3D (UINT32) ~(B_GPIO_PCR_MISCCFG_GPE0_DW2 | > B_GPIO_PCR_MISCCFG_GPE0_DW1 | B_GPIO_PCR_MISCCFG_GPE0_DW0); > + Data32Or =3D (UINT32) ((GpioGpeDwx[2] << > N_GPIO_PCR_MISCCFG_GPE0_DW2) | > + (GpioGpeDwx[1] << N_GPIO_PCR_MISCCFG_GPE0_DW1) | > + (GpioGpeDwx[0] << N_GPIO_PCR_MISCCFG_GPE0_DW0)); > + > + NoOfGpioComs =3D GpioGetComSbiPortIds (&GpioComSbiIds); > + > + // > + // Program MISCCFG register for each community > + // > + for (GpioComIndex =3D 0; GpioComIndex < NoOfGpioComs; GpioComIndex++) > { > + MmioAndThenOr32 ( > + PCH_PCR_ADDRESS (GpioComSbiIds[GpioComIndex], > R_GPIO_PCR_MISCCFG), > + Data32And, > + Data32Or > + ); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure will get GPE number for provided GpioPad. > + PCH allows to configure mapping between GPIO groups and related GPE > (GpioSetGroupToGpeDwX()) > + what results in the fact that certain Pad can cause different General = Purpose > Event. Only three > + GPIO groups can be mapped to cause unique GPE (1-tier), all others gro= ups > will be under one common > + event (GPE_111 for 2-tier). > + > + 1-tier: > + Returned GpeNumber is in range <0,95>. GpioGetGpeNumber() can be used > + to determine what _LXX ACPI method would be called on event on selecte= d > GPIO pad > + > + 2-tier: > + Returned GpeNumber is 0x6F (111). All GPIO pads which are not mapped t= o > 1-tier GPE > + will be under one master GPE_111 which is linked to _L6F ACPI method. = If it > is needed to determine > + what Pad from 2-tier has caused the event, _L6F method should check > GPI_GPE_STS and GPI_GPE_EN > + registers for all GPIO groups not mapped to 1-tier GPE. > + > + @param[in] GpioPad GPIO pad > + @param[out] GpeNumber GPE number > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioGetGpeNumber ( > + IN GPIO_PAD GpioPad, > + OUT UINT32 *GpeNumber > + ) > +{ > + GPIO_GROUP GroupToGpeDwX[3]; > + UINT32 GroupDw[3]; > + GPIO_GROUP Group; > + UINT32 PadNumber; > + UINT32 Index; > + EFI_STATUS Status; > + > + Group =3D GpioGetGroupFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Get GPIO groups mapping to 1-tier GPE > + // This mapping is dependent on GPIO IP implementation > + // and may change between chipset generations > + // > + Status =3D GpioGetGroupDwToGpeDwX ( > + &GroupToGpeDwX[0], &GroupDw[0], > + &GroupToGpeDwX[1], &GroupDw[1], > + &GroupToGpeDwX[2], &GroupDw[2] > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Check if pad is routed to 1-Tier GPE > + // > + for (Index =3D 0; Index < 3; Index++) { > + if ((Group =3D=3D GroupToGpeDwX[Index]) && (PadNumber >=3D (32 * > GroupDw[Index])) && (PadNumber < (32 * (GroupDw[Index] + 1)))) { > + *GpeNumber =3D PadNumber + (32 * Index) - (32 * GroupDw[Index]); > + return EFI_SUCCESS; > + } > + } > + > + // > + // If Group number doesn't match any of above then > + // it means that the pad is routed to 2-tier GPE > + // which corresponds to GPE_111 (0x6F) > + // > + *GpeNumber =3D PCH_GPIO_2_TIER_MASTER_GPE_NUMBER; > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure is used to clear SMI STS for a specified Pad > + > + @param[in] GpioPad GPIO pad > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioClearGpiSmiSts ( > + IN GPIO_PAD GpioPad > + ) > +{ > + GPIO_GROUP Group; > + UINT32 PadNumber; > + UINT32 DwNum; > + UINT32 PadBitPosition; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + Group =3D GpioGetGroupFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + DwNum =3D GPIO_GET_DW_NUM (PadNumber); > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); > + > + // > + // Clear GPI SMI Status bit by writing '1' > + // > + GpioWriteReg ( > + GpioSmiStatusRegister, > + Group, > + DwNum, > + 0u, > + (UINT32) (BIT0 << PadBitPosition) > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure is used by PchSmiDispatcher and will clear > + all GPI SMI Status bits > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioClearAllGpiSmiSts ( > + VOID > + ) > +{ > + UINT32 DwNum; > + GPIO_GROUP Group; > + GPIO_GROUP GroupMin; > + GPIO_GROUP GroupMax; > + > + GroupMin =3D GpioGetLowestGroup (); > + GroupMax =3D GpioGetHighestGroup (); > + > + for (Group =3D GroupMin; Group <=3D GroupMax; Group++) { > + // > + // Clear all GPI SMI STS > + // > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGetPadPerGroup > (Group)); DwNum++) { > + if (GpioIsSmiSupportedByGroupDw(Group, DwNum)) { > + GpioWriteReg ( > + GpioSmiStatusRegister, > + Group, > + DwNum, > + 0u, > + 0xFFFFFFFF > + ); > + } > + } > + } > + return EFI_SUCCESS; > + > +} > + > +/** > + This procedure is used to disable all GPI SMI > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioDisableAllGpiSmi ( > + VOID > + ) > +{ > + UINT32 DwNum; > + GPIO_GROUP Group; > + GPIO_GROUP GroupMin; > + GPIO_GROUP GroupMax; > + UINT32 SmiEnRegVal; > + > + GroupMin =3D GpioGetLowestGroup (); > + GroupMax =3D GpioGetHighestGroup (); > + > + for (Group =3D GroupMin; Group <=3D GroupMax; Group++) { > + // > + // Disable all GPI SMI > + // > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGetPadPerGroup > (Group)); DwNum++) { > + if (GpioIsSmiSupportedByGroupDw (Group, DwNum)) { > + SmiEnRegVal =3D 0; > + // > + // Check which pins have SMI_EN set > + // > + GpioReadReg ( > + GpioSmiEnableRegister, > + Group, > + DwNum, > + &SmiEnRegVal > + ); > + // > + // Set HOSTSW_OWN to GPIO mode (1) for those pins to disable S= MI > capability > + // > + GpioWriteReg ( > + GpioHostOwnershipRegister, > + Group, > + DwNum, > + ~0u, > + SmiEnRegVal > + ); > + } > + } > + } > + return EFI_SUCCESS; > +} > + > +/** > + This procedure is used to register GPI SMI dispatch function. > + > + @param[in] GpioPad GPIO pad > + @param[out] GpiNum GPI number > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioGetGpiSmiNum ( > + IN GPIO_PAD GpioPad, > + OUT UINTN *GpiNum > + ) > +{ > + UINT32 GroupIndex; > + UINT32 Index; > + UINT32 PadNumber; > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + > + *GpiNum =3D 0; > + > + for (Index =3D 0; Index < GroupIndex; Index++) { > + *GpiNum +=3D (UINTN) (GpioGroupInfo[Index].PadPerGroup); > + } > + *GpiNum +=3D (UINTN) PadNumber; > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure is used to check GPIO inputs belongs to 2 tier or 1 tie= r > architecture > + > + @param[in] GpioPad GPIO pad > + > + @retval Data 0 means 1-tier, 1 means 2-tier > +**/ > +BOOLEAN > +GpioCheckFor2Tier ( > + IN GPIO_PAD GpioPad > + ) > +{ > + UINT32 Data32; > + EFI_STATUS Status; > + > + Status =3D GpioGetGpeNumber (GpioPad, &Data32); > + if (EFI_ERROR (Status)) { > + DEBUG (( DEBUG_ERROR, "GpioCheckFor2Tier: Failed to get GPE number. > Status: %r\n", Status )); > + return FALSE; > + } > + > + if (Data32 =3D=3D PCH_GPIO_2_TIER_MASTER_GPE_NUMBER) { > + return TRUE; > + } > + > + return FALSE; > +} > + > +/** > + This procedure is used to clear GPE STS for a specified GpioPad > + > + @param[in] GpioPad GPIO pad > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioClearGpiGpeSts ( > + IN GPIO_PAD GpioPad > + ) > +{ > + GPIO_GROUP Group; > + UINT32 PadNumber; > + UINT32 DwNum; > + UINT32 PadBitPosition; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // Check for 2-tier > + // > + if (!(GpioCheckFor2Tier (GpioPad))) { > + return EFI_INVALID_PARAMETER; > + } > + > + Group =3D GpioGetGroupFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + DwNum =3D GPIO_GET_DW_NUM (PadNumber); > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); > + > + // > + // Clear GPI GPE Status bit by writing '1' > + // > + GpioWriteReg ( > + GpioGpeStatusRegister, > + Group, > + DwNum, > + 0u, > + (UINT32) (BIT0 << PadBitPosition) > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure is used to read GPE STS for a specified Pad > + > + @param[in] GpioPad GPIO pad > + @param[out] Data GPE STS data > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid GpioPad > +**/ > +EFI_STATUS > +GpioGetGpiGpeSts ( > + IN GPIO_PAD GpioPad, > + OUT UINT32 *Data > + ) > +{ > + UINT32 GpeStsRegVal; > + GPIO_GROUP Group; > + UINT32 PadNumber; > + UINT32 DwNum; > + UINT32 PadBitPosition; > + > + if (!GpioIsPadValid (GpioPad)) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // Check for 2-tier > + // > + if (!(GpioCheckFor2Tier (GpioPad))) { > + return EFI_INVALID_PARAMETER; > + } > + > + Group =3D GpioGetGroupFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + DwNum =3D GPIO_GET_DW_NUM (PadNumber); > + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber); > + > + // > + // Read GPI GPE Status bits > + // > + GpioReadReg ( > + GpioGpeStatusRegister, > + Group, > + DwNum, > + &GpeStsRegVal > + ); > + > + *Data =3D (GpeStsRegVal >> PadBitPosition) & 0x1; > + > + return EFI_SUCCESS; > +} > + > +/** > + This procedure is used to lock all GPIO pads except the ones > + which were requested during their configuration to be left unlocked. > + This function must be called before BIOS_DONE - before POSTBOOT_SAI is > enabled. > + FSP - call this function from wrapper before transition to FSP-S > + UEFI/EDK - call this function before EndOfPei event > + > + @retval EFI_SUCCESS The function completed successfully > + @retval EFI_INVALID_PARAMETER Invalid group or pad number > +**/ > +EFI_STATUS > +GpioLockPads ( > + VOID > + ) > +{ > + UINT32 DwNum; > + GPIO_GROUP Group; > + GPIO_GROUP GroupMin; > + GPIO_GROUP GroupMax; > + UINT32 UnlockedPads; > + EFI_STATUS Status; > + > + GroupMin =3D GpioGetLowestGroup (); > + GroupMax =3D GpioGetHighestGroup (); > + > + for (Group =3D GroupMin; Group <=3D GroupMax; Group++) { > + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGetPadPerGroup > (Group)); DwNum++) { > + > + UnlockedPads =3D GpioGetGroupDwUnlockPadConfigMask > (GpioGetGroupIndexFromGroup (Group), DwNum); > + > + Status =3D GpioLockPadCfgForGroupDw (Group, DwNum, > (UINT32)~UnlockedPads); > + if (EFI_ERROR (Status)) { > + ASSERT (FALSE); > + return Status; > + } > + > + UnlockedPads =3D GpioGetGroupDwUnlockOutputMask > (GpioGetGroupIndexFromGroup (Group), DwNum); > + > + Status =3D GpioLockPadCfgTxForGroupDw (Group, DwNum, > (UINT32)~UnlockedPads); > + if (EFI_ERROR (Status)) { > + ASSERT (FALSE); > + return Status; > + } > + } > + } > + return EFI_SUCCESS; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNa > mes.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNa > mes.c > new file mode 100644 > index 0000000000..ec33d06156 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNa > mes.c > @@ -0,0 +1,87 @@ > +/** @file > + This file contains GPIO name library implementation > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "GpioLibrary.h" > +#include > + > +/** > + Generates GPIO group name from GpioPad > + > + @param[in] GpioPad GpioPad > + > + @retval CHAR8* Pointer to the GPIO group name > +**/ > +CONST > +CHAR8* > +GpioGetGroupName ( > + IN UINT32 GroupIndex > + ) > +{ > + CONST GPIO_GROUP_NAME_INFO* GroupNameInfo; > + > + GroupNameInfo =3D GpioGetGroupNameInfo (GroupIndex); > + if (GroupNameInfo =3D=3D NULL) { > + return NULL; > + } else { > + return GroupNameInfo->GpioGroupPrefix; > + } > +} > + > +/** > + Generates GPIO name from GpioPad > + > + @param[in] GpioPad GpioPad > + @param[out] GpioNameBuffer Caller allocated buffer of > GPIO_NAME_LENGTH_MAX size > + @param[in] GpioNameBufferSize Size of the buffer > + > + @retval CHAR8* Pointer to the GPIO name > +**/ > +CHAR8* > +GpioGetPadName ( > + IN GPIO_PAD GpioPad, > + OUT CHAR8* GpioNameBuffer, > + IN UINT32 GpioNameBufferSize > + ) > +{ > + UINT32 GroupIndex; > + UINT32 PadNumber; > + UINT32 FirstUniquePadNumber; > + CONST GPIO_GROUP_NAME_INFO* GroupNameInfo; > + > + if (GpioNameBuffer =3D=3D NULL) { > + ASSERT (FALSE); > + return NULL; > + } > + if ((GpioNameBufferSize < GPIO_NAME_LENGTH_MAX) || !GpioIsPadValid > (GpioPad)) { > + ASSERT (FALSE); > + *GpioNameBuffer =3D 0; > + return NULL; > + } > + > + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad); > + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad); > + GroupNameInfo =3D GpioGetGroupNameInfo (GroupIndex); > + if (GroupNameInfo =3D=3D NULL) { > + return NULL; > + } > + > + FirstUniquePadNumber =3D GpioGetPadNumberFromGpioPad > (GroupNameInfo->FirstUniqueGpio); > + if ((PadNumber < FirstUniquePadNumber) || > (GroupNameInfo->GroupUniqueNames =3D=3D NULL)) { > + AsciiSPrint (GpioNameBuffer, GPIO_NAME_LENGTH_MAX, "GPIO_%a%d", > GpioGetGroupName (GroupIndex), PadNumber); > + } else { > + if (PadNumber - FirstUniquePadNumber < > GroupNameInfo->UniqueNamesTableSize) { > + AsciiSPrint (GpioNameBuffer, GPIO_NAME_LENGTH_MAX, "GPIO_%a", > GroupNameInfo->GroupUniqueNames[PadNumber - > FirstUniquePadNumber]); > + } else { > + AsciiSPrint (GpioNameBuffer, GPIO_NAME_LENGTH_MAX, "GPIO_%08X", > GpioPad); > + ASSERT (FALSE); > + } > + } > + > + return GpioNameBuffer; > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNa > tiveLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNa > tiveLib.c > new file mode 100644 > index 0000000000..9b71cb1d95 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGpioLib/GpioNa > tiveLib.c > @@ -0,0 +1,234 @@ > +/** @file > + This file contains routines for GPIO native and chipset specific usage > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "GpioLibrary.h" > + > +/** > + This procedure will get number of pads for certain GPIO group > + > + @param[in] Group GPIO group number > + > + @retval Value Pad number for group > + If illegal group number then return 0 > +**/ > +UINT32 > +GpioGetPadPerGroup ( > + IN GPIO_GROUP Group > + ) > +{ > + CONST GPIO_GROUP_INFO *GpioGroupInfo; > + UINT32 GpioGroupInfoLength; > + UINT32 GroupIndex; > + // > + // Check if group argument exceeds GPIO GROUP INFO array > + // > + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength); > + GroupIndex =3D GpioGetGroupIndexFromGroup (Group); > + > + if ((UINTN) GroupIndex >=3D GpioGroupInfoLength) { > + return 0; > + } else { > + return GpioGroupInfo[GroupIndex].PadPerGroup; > + } > +} > + > +/** > + This procedure will get number of groups > + > + @param[in] none > + > + @retval Value Group number > +**/ > +UINT32 > +GpioGetNumberOfGroups ( > + VOID > + ) > +{ > + UINT32 GpioGroupInfoLength; > + > + GpioGetGroupInfoTable (&GpioGroupInfoLength); > + return GpioGroupInfoLength; > +} > +/** > + This procedure will get lowest group > + > + @param[in] none > + > + @retval Value Lowest Group > +**/ > +GPIO_GROUP > +GpioGetLowestGroup ( > + VOID > + ) > +{ > + return GpioGetGroupFromGroupIndex (0); > +} > +/** > + This procedure will get highest group > + > + @param[in] none > + > + @retval Value Highest Group > +**/ > +GPIO_GROUP > +GpioGetHighestGroup ( > + VOID > + ) > +{ > + return GpioGetGroupFromGroupIndex (GpioGetNumberOfGroups () - 1); > +} > + > +/** > + This procedure will get group number > + > + @param[in] GpioPad Gpio Pad > + > + @retval Value Group number > +**/ > +GPIO_GROUP > +GpioGetGroupFromGpioPad ( > + IN GPIO_PAD GpioPad > + ) > +{ > + return GPIO_GET_GROUP_FROM_PAD (GpioPad); > +} > + > +/** > + This procedure will get group index (0 based) > + > + @param[in] GpioPad Gpio Pad > + > + @retval Value Group Index > +**/ > +UINT32 > +GpioGetGroupIndexFromGpioPad ( > + IN GPIO_PAD GpioPad > + ) > +{ > + return (UINT32) GPIO_GET_GROUP_INDEX_FROM_PAD (GpioPad); > +} > + > +/** > + This procedure will get group index (0 based) from group > + > + @param[in] GpioGroup Gpio Group > + > + @retval Value Group Index > +**/ > +UINT32 > +GpioGetGroupIndexFromGroup ( > + IN GPIO_GROUP GpioGroup > + ) > +{ > + return (UINT32) GPIO_GET_GROUP_INDEX (GpioGroup); > +} > + > +/** > + This procedure will get group from group index (0 based) > + > + @param[in] GroupIndex Group Index > + > + @retval GpioGroup Gpio Group > +**/ > +GPIO_GROUP > +GpioGetGroupFromGroupIndex ( > + IN UINT32 GroupIndex > + ) > +{ > + return GPIO_GROUP_DEF (GroupIndex, GpioGetThisChipsetId ()); > +} > + > +/** > + This procedure will get pad number (0 based) from Gpio Pad > + > + @param[in] GpioPad Gpio Pad > + > + @retval Value Pad Number > +**/ > +UINT32 > +GpioGetPadNumberFromGpioPad ( > + IN GPIO_PAD GpioPad > + ) > +{ > + return (UINT32) GPIO_GET_PAD_NUMBER (GpioPad); > +} > +/** > + This procedure will return GpioPad from Group and PadNumber > + > + @param[in] Group GPIO group > + @param[in] PadNumber GPIO PadNumber > + > + @retval GpioPad GpioPad > +**/ > +GPIO_PAD > +GpioGetGpioPadFromGroupAndPadNumber ( > + IN GPIO_GROUP Group, > + IN UINT32 PadNumber > + ) > +{ > + if (IsPchLp ()) { > + return GPIO_PAD_DEF (Group,PadNumber); > + } else { > + return GPIO_PAD_DEF (Group,PadNumber); > + } > +} > + > +/** > + This procedure will return GpioPad from GroupIndex and PadNumber > + > + @param[in] GroupIndex GPIO GroupIndex > + @param[in] PadNumber GPIO PadNumber > + > + @retval GpioPad GpioPad > +**/ > +GPIO_PAD > +GpioGetGpioPadFromGroupIndexAndPadNumber ( > + IN UINT32 GroupIndex, > + IN UINT32 PadNumber > + ) > +{ > + GPIO_GROUP Group; > + > + Group =3D GPIO_GROUP_DEF (GroupIndex, GpioGetThisChipsetId ()); > + return GPIO_PAD_DEF (Group, PadNumber); > +} > + > +/** > + This function checks if SATA GP pin is enabled > + > + @param[in] SataCtrlIndex SATA controller index > + @param[in] SataPort SATA port number > + > + @retval TRUE SATA GPx is enabled (pad is in require= d native > mode) > + FALSE SATA GPx is not enabled > +**/ > +BOOLEAN > +GpioIsSataGpEnabled ( > + IN UINT32 SataCtrlIndex, > + IN UINTN SataPort > + ) > +{ > + EFI_STATUS Status; > + GPIO_PAD_NATIVE_FUNCTION SataGpGpio; > + GPIO_PAD_MODE GpioMode; > + > + ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ()); > + > + GpioGetSataGpPin ( > + SataCtrlIndex, > + SataPort, > + &SataGpGpio > + ); > + > + Status =3D GpioGetPadMode (SataGpGpio.Pad, &GpioMode); > + if ((EFI_ERROR (Status)) || (GpioMode !=3D SataGpGpio.Mode)) { > + return FALSE; > + } else { > + return TRUE; > + } > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodi > ngLib/PchCycleDecodingLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodi > ngLib/PchCycleDecodingLib.c > new file mode 100644 > index 0000000000..24afbbf712 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchCycleDecodi > ngLib/PchCycleDecodingLib.c > @@ -0,0 +1,1136 @@ > +/** @file > + PCH cycle deocding configuration and query 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 > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +typedef enum { > + SlaveLpcEspiCS0, > + SlaveEspiCS1, > + SlaveId_Max > +} SLAVE_ID_INDEX; > + > +/** > + Set PCH TCO base address. > + This cycle decoding is required also on DMI side > + Programming steps: > + 1. set Smbus PCI offset 54h [8] to enable TCO base address. > + 2. program Smbus PCI offset 50h [15:5] to TCO base address. > + 3. set Smbus PCI offset 54h [8] to enable TCO base address. > + 4. program "TCO Base Address" in DMI > + > + @param[in] Address Address for TCO base address. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address passed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchTcoBaseSet ( > + IN UINT16 Address > + ) > +{ > + UINT64 SmbusBase; > + EFI_STATUS Status; > + > + if ((Address & ~B_SMBUS_CFG_TCOBASE_BAR) !=3D 0) { > + DEBUG ((DEBUG_ERROR, "PchTcoBaseSet Error. Invalid Address: %x.\n", > Address)); > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + > + Status =3D PchDmiSetTcoBase (Address); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + > + SmbusBase =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_SMBUS, > + PCI_FUNCTION_NUMBER_PCH_SMBUS, > + 0 > + ); > + if (PciSegmentRead16 (SmbusBase) =3D=3D 0xFFFF) { > + ASSERT (FALSE); > + return EFI_UNSUPPORTED; > + } > + // > + // Verify TCO base is not locked. > + // > + if ((PciSegmentRead8 (SmbusBase + R_SMBUS_CFG_TCOCTL) & > B_SMBUS_CFG_TCOCTL_TCO_BASE_LOCK) !=3D 0) { > + ASSERT (FALSE); > + return EFI_DEVICE_ERROR; > + } > + // > + // Disable TCO in SMBUS Device first before changing base address. > + // Byte access to not touch the TCO_BASE_LOCK bit > + // > + PciSegmentAnd8 ( > + SmbusBase + R_SMBUS_CFG_TCOCTL + 1, > + (UINT8) ~(B_SMBUS_CFG_TCOCTL_TCO_BASE_EN >> 8) > + ); > + // > + // Program TCO in SMBUS Device > + // > + PciSegmentAndThenOr16 ( > + SmbusBase + R_SMBUS_CFG_TCOBASE, > + (UINT16) (~B_SMBUS_CFG_TCOBASE_BAR), > + Address > + ); > + // > + // Enable TCO in SMBUS Device and lock TCO BASE > + // > + PciSegmentOr16 ( > + SmbusBase + R_SMBUS_CFG_TCOCTL, > + B_SMBUS_CFG_TCOCTL_TCO_BASE_EN | > B_SMBUS_CFG_TCOCTL_TCO_BASE_LOCK > + ); > + > + return Status; > +} > + > +/** > + Get PCH TCO base address. > + > + @param[out] Address Address of TCO base address. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid pointer passed. > +**/ > +EFI_STATUS > +PchTcoBaseGet ( > + OUT UINT16 *Address > + ) > +{ > + if (Address =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "PchTcoBaseGet Error. Invalid pointer.\n")); > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + // > + // Read "TCO Base Address" from DMI > + // Don't read TCO base address from SMBUS PCI register since SMBUS mig= ht > be disabled. > + // > + *Address =3D PchDmiGetTcoBase (); > + > + return EFI_SUCCESS; > +} > + > +/** > + Returns PCH LPC device PCI base address. > + > + @retval PCH LPC PCI base address. > +**/ > +STATIC > +UINT64 > +LpcPciBase ( > + VOID > + ) > +{ > + return PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_LPC, > + PCI_FUNCTION_NUMBER_PCH_LPC, > + 0 > + ); > +} > + > +/** > + Function checks if passed Generic LPC IO Address and Length meets > requirements. > + > + @param[in] Address Address for generic IO range dec= oding. > + @param[in] Length Length of generic IO range. > + > + @retval TRUE Passed IO range meets requiremen= ts > + @retval FALSE Passed IO range does not meets > requirements. > +**/ > +STATIC > +BOOLEAN > +IsLpcIoRangeValid ( > + IN UINT32 Address, > + IN UINT32 Length > + ) > +{ > + UINT32 Index; > + UINT32 NumRanges; > + > + STATIC struct EXCEPT_RANGE { > + UINT8 Start; > + UINT8 Length; > + } ExceptRanges[] =3D { {0x00, 0x20}, {0x44, 0x08}, {0x54, 0x0C}, {0x68= , 0x08}, > {0x80, 0x10}, {0xC0, 0x40} }; > + > + NumRanges =3D ARRAY_SIZE (ExceptRanges); > + // > + // For generic IO range, the base address must align to 4 and less tha= n > 0xFFFF, > + // the length must be power of 2 and less than or equal to 256, and th= e > address must be length aligned. > + // IO range below 0x100 will be rejected in this function except below > ranges: > + // 0x00-0x1F, > + // 0x44-0x4B, > + // 0x54-0x5F, > + // 0x68-0x6F, > + // 0x80-0x8F, > + // 0xC0-0xFF > + // > + if (((Length & (Length - 1)) !=3D 0) || > + ((Address & (UINT16) ~B_LPC_CFG_GENX_DEC_IOBAR) !=3D 0) || > + (Length > 256)) { > + return FALSE; > + } > + if (Address < 0x100) { > + for (Index =3D 0; Index < NumRanges; Index++) { > + if ((Address >=3D ExceptRanges[Index].Start) && > + ((Address + Length) <=3D ((UINTN) ExceptRanges[Index].Start + = (UINTN) > ExceptRanges[Index].Length))) { > + break; > + } > + } > + if (Index >=3D NumRanges) { > + return FALSE; > + } > + } > + > + return TRUE; > +} > + > +/** > + Function checks if passed Generic LPC IO Range is already in Gen IO Ra= nge list > + > + @param[in] Address Address for generic IO range dec= oding. > + @param[in] Length Length of generic IO range. > + @param[in] GenIoRangeList Pointer to Generic IO Ranges Lis= t > + > + @retval TRUE Passed IO range alredy covered > + @retval FALSE Passed IO range NOT covered > +**/ > +STATIC > +BOOLEAN > +IsRangeInList ( > + IN UINT32 Address, > + IN UINT32 Length, > + IN PCH_LPC_GEN_IO_RANGE_LIST *GenIoRangeList > + ) > +{ > + UINT32 CurrentBaseAddr; > + UINT32 CurrentLength; > + UINT32 Index; > + > + for (Index =3D 0; Index < PCH_LPC_GEN_IO_RANGE_MAX; Index++) { > + CurrentBaseAddr =3D GenIoRangeList->Range[Index].BaseAddr; > + CurrentLength =3D GenIoRangeList->Range[Index].Length; > + if (GenIoRangeList->Range[Index].Enable =3D=3D 0) { > + continue; > + } > + if ((Address >=3D CurrentBaseAddr) && ((Address + Length) <=3D > (CurrentBaseAddr + CurrentLength))) { > + return TRUE; > + } > + } > + > + return FALSE; > +} > + > +/** > + Function checks if passed Generic LPC IO Range overlaps with existing = range > + > + @param[in] Address Address for generic IO range bas= e > address. > + @param[in] Length Length of generic IO range. > + @param[in] GenIoRangeList Pointer to Generic IO Ranges Lis= t > + > + @retval TRUE Passed LPC IO range overlaps wit= h existing > range > + @retval FALSE Passed LPC IO range NOT overlaps > +**/ > +STATIC > +BOOLEAN > +FindOverlappingGenIoRange ( > + IN UINT32 Address, > + IN UINT32 Length, > + IN PCH_LPC_GEN_IO_RANGE_LIST *GenIoRangeList > + ) > +{ > + UINT32 Index; > + UINT32 CurrentBaseAddr; > + UINT32 CurrentLength; > + > + for (Index =3D 0; Index < PCH_LPC_GEN_IO_RANGE_MAX; Index++) { > + CurrentBaseAddr =3D GenIoRangeList->Range[Index].BaseAddr; > + CurrentLength =3D GenIoRangeList->Range[Index].Length; > + if (GenIoRangeList->Range[Index].Enable =3D=3D 0) { > + continue; > + } > + > + if ((Address >=3D CurrentBaseAddr) && > + (Address <=3D (CurrentBaseAddr + CurrentLength))) { > + return TRUE; > + } else if (((Address + Length) >=3D CurrentBaseAddr) && > + ((Address + Length) <=3D (CurrentBaseAddr + CurrentLength)= )) { > + return TRUE; > + } > + } > + > + return FALSE; > +} > + > +/** > + Function look for empty Generic IO range register. > + If found return range index. > + > + @param[in] GenIoRangeList Pointer to Generic IO Ranges Lis= t > + @param[in] ListLength Length of passed list > + @param[out] RangeIndex Generic IO Range Index > + > + @retval TRUE Empty range found > + @retval FALSE NOT found empty range > +**/ > +STATIC > +BOOLEAN > +FindEmptyGenIoRange ( > + IN PCH_LPC_GEN_IO_RANGE_LIST *GenIoRangeList, > + IN UINT32 ListLength, > + OUT UINT32 *RangeIndex > + ) > +{ > + UINT32 Index; > + > + for (Index =3D 0; Index < ListLength; Index++) { > + if (GenIoRangeList->Range[Index].Enable =3D=3D 0) { > + *RangeIndex =3D Index; > + return TRUE; > + } > + } > + > + return FALSE; > +} > + > +/** > + Get PCH LPC/eSPI and eSPI CS1# generic IO range list. > + This function returns a list of base address, length, and enable for a= ll > LPC/eSPI or eSPI CS1# generic IO range registers. > + > + @param[in] RangeIndex Slave ID (refer to SLAVE_ID_INDE= X) > + @param[out] GenIoRangeList LPC/eSPI or eSPI CS1# generic IO > range registers. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address passed. > +**/ > +EFI_STATUS > +LpcEspiGenIoRangeGetHelper ( > + IN SLAVE_ID_INDEX SlaveId, > + OUT PCH_LPC_GEN_IO_RANGE_LIST *GenIoRangeList > + ) > +{ > + UINT32 Index; > + UINT64 LpcBase; > + UINT32 Data32; > + UINT32 GenIoReg; > + > + if ((GenIoRangeList =3D=3D NULL) || (SlaveId >=3D SlaveId_Max)) { > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + > + LpcBase =3D LpcPciBase (); > + > + if (SlaveId =3D=3D SlaveEspiCS1) { > + GenIoReg =3D R_ESPI_CFG_CS1GIR1; > + } else { > + GenIoReg =3D R_LPC_CFG_GEN1_DEC; > + } > + > + for (Index =3D 0; Index < PCH_LPC_GEN_IO_RANGE_MAX; Index++) { > + if ((SlaveId =3D=3D SlaveEspiCS1) && > + (Index > 0)) { > + // For eSPI CS1# we have only one range. Reset remaining entries t= o zero. > + GenIoRangeList->Range[Index].BaseAddr =3D 0; > + GenIoRangeList->Range[Index].Enable =3D 0; > + GenIoRangeList->Range[Index].Length =3D 0; > + continue; > + } > + Data32 =3D PciSegmentRead32 (LpcBase + GenIoReg + Index * 4); > + GenIoRangeList->Range[Index].BaseAddr =3D Data32 & > B_LPC_CFG_GENX_DEC_IOBAR; > + GenIoRangeList->Range[Index].Length =3D ((Data32 & > B_LPC_CFG_GENX_DEC_IODRA) >> 16) + 4; > + GenIoRangeList->Range[Index].Enable =3D Data32 & > B_LPC_CFG_GENX_DEC_EN; > + } > + > + return EFI_SUCCESS; > +} > + > + > +/** > + Function checks if passed Generic LPC IO Range colliding > + with range alredy defined for other eSPI chiselect (CS) > + > + @param[in] Address Address for generic IO range bas= e > address. > + @param[in] Length Length of generic IO range. > + @param[in] SlaveId Slave ID (refer to SLAVE_ID_INDE= X) > + > + @retval TRUE Passed IO range conflicting > + @retval FALSE There is no conflict > +**/ > +STATIC > +BOOLEAN > +IsRangeColliding ( > + IN UINT32 Address, > + IN UINT32 Length, > + IN SLAVE_ID_INDEX SlaveId > + ) > +{ > + EFI_STATUS Status; > + PCH_LPC_GEN_IO_RANGE_LIST GenIoRangeList; > + > + if (SlaveId =3D=3D SlaveEspiCS1) { > + Status =3D LpcEspiGenIoRangeGetHelper (SlaveLpcEspiCS0, > &GenIoRangeList); > + if (!EFI_ERROR (Status)) { > + if (FindOverlappingGenIoRange (Address, Length, &GenIoRangeList) |= | > + IsRangeInList (Address, Length, &GenIoRangeList)) { > + return TRUE; > + } > + } > + } else { > + Status =3D LpcEspiGenIoRangeGetHelper (SlaveEspiCS1, &GenIoRangeLis= t); > + if (!EFI_ERROR (Status)) { > + if (FindOverlappingGenIoRange (Address, Length, &GenIoRangeList) |= | > + IsRangeInList (Address, Length, &GenIoRangeList)) { > + return TRUE; > + } > + } > + } > + > + return FALSE; > +} > + > +/** > + Set PCH LPC/eSPI and eSPI CS1# generic IO range decoding. > + > + Steps of programming generic IO range: > + 1. Program LPC/eSPI PCI Offset 84h ~ 93h (LPC, eSPI CS0#) or A4h (eSPI= CS1#) > of Mask, Address, and Enable. > + 2. Program LPC/eSPI Generic IO Range in DMI > + > + @param[in] Address Address for generic IO range dec= oding. > + @param[in] Length Length of generic IO range. > + @param[in] SlaveId Slave ID (refer to SLAVE_ID_INDE= X) > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address or length > passed. > + @retval EFI_OUT_OF_RESOURCES No more generic range available. > + @retval EFI_UNSUPPORTED DMI configuration is locked, > + GenIO range conflicting with oth= er eSPI CS > +**/ > +STATIC > +EFI_STATUS > +LpcEspiGenIoRangeSetHelper ( > + IN UINT32 Address, > + IN UINT32 Length, > + IN SLAVE_ID_INDEX SlaveId > + ) > +{ > + EFI_STATUS Status; > + PCH_LPC_GEN_IO_RANGE_LIST GenIoRangeList; > + UINT32 RangeIndex; > + UINT32 Data32; > + UINT32 GenIoReg; > + UINT32 ListLength; > + > + // > + // Check if pasesed Address and Length meets all requirements > + // > + if(!IsLpcIoRangeValid (Address, Length) || (SlaveId >=3D SlaveId_Max))= { > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Read current Generic IO configuration > + // > + Status =3D LpcEspiGenIoRangeGetHelper (SlaveId, &GenIoRangeList); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Check if passed Generic IO range is already covered in current > configuration > + // > + if (IsRangeInList (Address, Length, &GenIoRangeList)) { > + return EFI_SUCCESS; > + } > + > + // > + // Check if passed Generic IO range conflicting with other eSPI CS dec= oding > + // > + if (IsRangeColliding (Address, Length, SlaveId)) { > + return EFI_UNSUPPORTED; > + } > + > + if (SlaveId =3D=3D SlaveEspiCS1) { > + GenIoReg =3D R_ESPI_CFG_CS1GIR1; > + ListLength =3D ESPI_CS1_GEN_IO_RANGE_MAX; > + } else { > + GenIoReg =3D R_LPC_CFG_GEN1_DEC; > + ListLength =3D PCH_LPC_GEN_IO_RANGE_MAX; > + } > + > + RangeIndex =3D ListLength; > + // > + // Check if there is an empty Generic IO range register > + // > + if (FindEmptyGenIoRange (&GenIoRangeList, ListLength, &RangeIndex) =3D= =3D > FALSE) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + // > + // Program decoding in DMI and LPC/eSPI registers > + // > + if (SlaveId =3D=3D SlaveEspiCS1) { > + ASSERT (RangeIndex =3D=3D 0); > + Status =3D PchDmiSetEspiCs1GenIoRange (Address, Length); > + } else { > + Status =3D PchDmiSetLpcGenIoRange (Address, Length, RangeIndex); > + } > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Program LPC/eSPI generic IO range register accordingly. > + // > + Data32 =3D (UINT32) (((Length - 1) << 16) & B_LPC_CFG_GENX_DEC_IODRA)= ; > + Data32 |=3D (UINT32) Address; > + Data32 |=3D B_LPC_CFG_GENX_DEC_EN; > + > + // > + // Program LPC/eSPI PCI Offset 84h ~ 93h (LPC, eSPI CS0#) or A4h (eSPI= CS1#) > of Mask, Address, and Enable. > + // > + PciSegmentWrite32 ( > + LpcPciBase () + GenIoReg + RangeIndex * 4, > + Data32 > + ); > + > + return Status; > +} > + > +/** > + Set PCH LPC/eSPI generic IO range. > + For generic IO range, the base address must align to 4 and less than 0= xFFFF, > and the length must be power of 2 > + and less than or equal to 256. Moreover, the address must be length al= igned. > + This function basically checks the address and length, which should no= t > overlap with all other generic ranges. > + If no more generic range register available, it returns out of resourc= e error. > + This cycle decoding is also required on DMI side > + Some IO ranges below 0x100 have fixed target. The target might be > ITSS,RTC,LPC,PMC or terminated inside P2SB > + but all predefined and can't be changed. IO range below 0x100 will be > rejected in this function except below ranges: > + 0x00-0x1F, > + 0x44-0x4B, > + 0x54-0x5F, > + 0x68-0x6F, > + 0x80-0x8F, > + 0xC0-0xFF > + Steps of programming generic IO range: > + 1. Program LPC/eSPI PCI Offset 84h ~ 93h of Mask, Address, and Enable. > + 2. Program LPC/eSPI Generic IO Range in DMI > + > + @param[in] Address Address for generic IO range bas= e > address. > + @param[in] Length Length of generic IO range. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address or length > passed. > + @retval EFI_OUT_OF_RESOURCES No more generic range available. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchLpcGenIoRangeSet ( > + IN UINT16 Address, > + IN UINTN Length > + ) > +{ > + return LpcEspiGenIoRangeSetHelper ((UINT32)Address, (UINT32)Length, > SlaveLpcEspiCS0); > +} > + > +/** > + Set PCH eSPI CS1# generic IO range decoding. > + > + Steps of programming generic IO range: > + 1. Program eSPI PCI Offset A4h (eSPI CS1#) of Mask, Address, and Enabl= e. > + 2. Program eSPI Generic IO Range in DMI > + > + @param[in] Address Address for generic IO range dec= oding. > + @param[in] Length Length of generic IO range. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address or length > passed. > + @retval EFI_OUT_OF_RESOURCES No more generic range available. > + @retval EFI_UNSUPPORTED eSPI secondary slave not support= ed > +**/ > +EFI_STATUS > +PchEspiCs1GenIoRangeSet ( > + IN UINT16 Address, > + IN UINTN Length > + ) > +{ > + if (!IsEspiSecondSlaveSupported ()) { > + return EFI_UNSUPPORTED; > + } > + > + return LpcEspiGenIoRangeSetHelper ((UINT32)Address, (UINT32)Length, > SlaveEspiCS1); > +} > + > +/** > + Get PCH LPC/eSPI generic IO range list. > + This function returns a list of base address, length, and enable for a= ll > LPC/eSPI generic IO range registers. > + > + @param[out] LpcGenIoRangeList Return all LPC/eSPI generic IO r= ange > register status. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address passed. > +**/ > +EFI_STATUS > +PchLpcGenIoRangeGet ( > + OUT PCH_LPC_GEN_IO_RANGE_LIST *LpcGenIoRangeList > + ) > +{ > + return LpcEspiGenIoRangeGetHelper (SlaveLpcEspiCS0, > LpcGenIoRangeList); > +} > + > +/** > + Get PCH eSPI CS1# generic IO range list. > + This function returns a list of base address, length, and enable for a= ll eSPI > CS1# generic IO range registers. > + > + @param[out] GenIoRangeList eSPI generic IO range registers. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address passed. > + @retval EFI_UNSUPPORTED eSPI secondary slave not support= ed > +**/ > +EFI_STATUS > +PchEspiCs1GenIoRangeGet ( > + OUT PCH_LPC_GEN_IO_RANGE_LIST *GenIoRangeList > + ) > +{ > + if (!IsEspiSecondSlaveSupported ()) { > + return EFI_UNSUPPORTED; > + } > + > + return LpcEspiGenIoRangeGetHelper (SlaveEspiCS1, GenIoRangeList); > +} > + > +/** > + Set PCH LPC/eSPI and eSPI CS1# memory range decoding. > + This cycle decoding is required to be set on DMI side > + Programming steps: > + 1. Program LPC/eSPI PCI Offset 98h (LPC, eSPI CS0#) or A8h (eSPI CS1#)= [0] to > [0] to disable memory decoding first before changing base address. > + 2. Program LPC/eSPI PCI Offset 98h (LPC, eSPI CS0#) or A8h (eSPI CS1#)= [31:16, > 0] to [Address, 1]. > + 3. Program LPC/eSPI Memory Range in DMI > + > + @param[in] Address Address for memory for decoding. > + @param[in] RangeIndex Slave ID (refer to SLAVE_ID_INDE= X) > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address or length > passed. > +**/ > +EFI_STATUS > +LpcEspiMemRangeSetHelper ( > + IN UINT32 Address, > + IN SLAVE_ID_INDEX SlaveId > + ) > +{ > + UINT64 LpcBase; > + EFI_STATUS Status; > + UINT32 GenMemReg; > + UINT32 MemRangeAddr; > + > + if (((Address & (~B_LPC_CFG_LGMR_MA)) !=3D 0) || (SlaveId >=3D SlaveId= _Max)) > { > + DEBUG ((DEBUG_ERROR, "PchLpcEspiMemRangeSet Error. Invalid Address: > %x or invalid SlaveId\n", Address)); > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + > + LpcBase =3D LpcPciBase (); > + > + MemRangeAddr =3D ~Address; > + if (SlaveId =3D=3D SlaveEspiCS1) { > + GenMemReg =3D R_ESPI_CFG_CS1GMR1; > + // Memory Range already decoded for LPC/eSPI? > + Status =3D PchLpcMemRangeGet (&MemRangeAddr); > + if (MemRangeAddr !=3D Address) { > + Status =3D PchDmiSetEspiCs1MemRange (Address); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + } > + } else { > + GenMemReg =3D R_LPC_CFG_LGMR; > + // Memory Range already decoded for eSPI CS1? > + Status =3D PchEspiCs1MemRangeGet (&MemRangeAddr); > + if (MemRangeAddr !=3D Address) { > + Status =3D PchDmiSetLpcMemRange (Address); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + } > + } > + > + // > + // Program LPC/eSPI PCI Offset 98h (LPC, eSPI CS0#) or A8h (eSPI CS1#)= [0] to > [0] to disable memory decoding first before changing base address. > + // > + PciSegmentAnd32 ( > + LpcBase + GenMemReg, > + (UINT32) ~B_LPC_CFG_LGMR_LMRD_EN > + ); > + // > + // Program LPC/eSPI PCI Offset 98h (LPC, eSPI CS0#) or A8h (eSPI CS1#)= [31:16, > 0] to [Address, 1]. > + // > + PciSegmentWrite32 ( > + LpcBase + GenMemReg, > + (Address | B_LPC_CFG_LGMR_LMRD_EN) > + ); > + > + return Status; > +} > + > +/** > + Set PCH LPC/eSPI memory range decoding. > + This cycle decoding is required to be set on DMI side > + Programming steps: > + 1. Program LPC PCI Offset 98h [0] to [0] to disable memory decoding fi= rst > before changing base address. > + 2. Program LPC PCI Offset 98h [31:16, 0] to [Address, 1]. > + 3. Program LPC Memory Range in DMI > + > + @param[in] Address Address for memory base address. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address or length > passed. > + @retval EFI_OUT_OF_RESOURCES No more generic range available. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchLpcMemRangeSet ( > + IN UINT32 Address > + ) > +{ > + return LpcEspiMemRangeSetHelper (Address, SlaveLpcEspiCS0); > +} > + > +/** > + Set PCH eSPI CS1# memory range decoding. > + This cycle decoding is required to be set on DMI side > + Programming steps: > + 1. Program eSPI PCI Offset A8h (eSPI CS1#) [0] to [0] to disable memor= y > decoding first before changing base address. > + 2. Program eSPI PCI Offset A8h (eSPI CS1#) [31:16, 0] to [Address, 1]. > + 3. Program eSPI Memory Range in DMI > + > + @param[in] Address Address for memory for decoding. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address or length > passed. > + @retval EFI_UNSUPPORTED eSPI secondary slave not support= ed > +**/ > +EFI_STATUS > +PchEspiCs1MemRangeSet ( > + IN UINT32 Address > + ) > +{ > + if (!IsEspiSecondSlaveSupported ()) { > + return EFI_UNSUPPORTED; > + } > + > + return LpcEspiMemRangeSetHelper (Address, SlaveEspiCS1); > +} > + > +/** > + @deprecated. Keep this for backward compatibility. > + It's replaced by PchEspiCs1MemRangeSet. > +**/ > +EFI_STATUS > +PchEspiMemRange2Set ( > + IN UINT32 Address > + ) > +{ > + return PchEspiCs1MemRangeSet (Address); > +} > + > +/** > + Get PCH LPC/eSPI and eSPI CS1# memory range decoding address. > + > + @param[in] SlaveId Slave ID (refer to SLAVE_ID_INDE= X) > + @param[out] Address Address of LPC/eSPI or eSPI CS1# > memory decoding base address. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address passed. > + @retval EFI_UNSUPPORTED eSPI secondary slave not support= ed > +**/ > +EFI_STATUS > +LpcEspiMemRangeGetHelper ( > + IN SLAVE_ID_INDEX SlaveId, > + OUT UINT32 *Address > + ) > +{ > + UINT32 GenMemReg; > + > + if ((Address =3D=3D NULL) || (SlaveId >=3D SlaveId_Max)) { > + DEBUG ((DEBUG_ERROR, "PchLpcEspiMemRangeGet Error. Invalid pointer > or SlaveId.\n")); > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + > + if (SlaveId =3D=3D SlaveEspiCS1) { > + GenMemReg =3D R_ESPI_CFG_CS1GMR1; > + } else { > + GenMemReg =3D R_LPC_CFG_LGMR; > + } > + *Address =3D PciSegmentRead32 (LpcPciBase () + GenMemReg) & > B_LPC_CFG_LGMR_MA; > + return EFI_SUCCESS; > +} > + > +/** > + Get PCH LPC/eSPI memory range decoding address. > + > + @param[out] Address Address of LPC/eSPI memory decod= ing > base address. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address passed. > +**/ > +EFI_STATUS > +PchLpcMemRangeGet ( > + OUT UINT32 *Address > + ) > +{ > + return LpcEspiMemRangeGetHelper (SlaveLpcEspiCS0, Address); > +} > + > +/** > + Get PCH eSPI CS1# memory range decoding address. > + > + @param[out] Address Address of eSPI CS1# memory deco= ding > base address. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid base address passed. > + @retval EFI_UNSUPPORTED eSPI secondary slave not support= ed > +**/ > +EFI_STATUS > +PchEspiCs1MemRangeGet ( > + OUT UINT32 *Address > + ) > +{ > + if (!IsEspiSecondSlaveSupported ()) { > + return EFI_UNSUPPORTED; > + } > + > + return LpcEspiMemRangeGetHelper (SlaveEspiCS1, Address); > +} > + > +/** > + Set PCH BIOS range deocding. > + This will check General Control and Status bit 10 (GCS.BBS) to identif= y SPI or > LPC/eSPI and program BDE register accordingly. > + Please check EDS for detail of BiosDecodeEnable bit definition. > + bit 15: F8-FF Enable > + bit 14: F0-F8 Enable > + bit 13: E8-EF Enable > + bit 12: E0-E8 Enable > + bit 11: D8-DF Enable > + bit 10: D0-D7 Enable > + bit 9: C8-CF Enable > + bit 8: C0-C7 Enable > + bit 7: Legacy F Segment Enable > + bit 6: Legacy E Segment Enable > + bit 5: Reserved > + bit 4: Reserved > + bit 3: 70-7F Enable > + bit 2: 60-6F Enable > + bit 1: 50-5F Enable > + bit 0: 40-4F Enable > + This cycle decoding is also required in DMI > + Programming steps: > + 1. if GCS.BBS is 0 (SPI), program SPI offset D8h to BiosDecodeEnable. > + if GCS.BBS is 1 (LPC/eSPi), program LPC offset D8h to BiosDecodeEna= ble. > + 2. program LPC BIOS Decode Enable in DMI > + > + @param[in] BiosDecodeEnable Bios decode enable setting. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchBiosDecodeEnableSet ( > + IN UINT16 BiosDecodeEnable > + ) > +{ > + UINT64 BaseAddr; > + EFI_STATUS Status; > + > + Status =3D PchDmiSetBiosDecodeEnable (BiosDecodeEnable); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + > + // > + // Check Boot BIOS Strap in DMI > + // > + if (PchDmiIsBootBiosStrapSetForSpi ()) { > + BaseAddr =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_SPI, > + PCI_FUNCTION_NUMBER_PCH_SPI, > + 0 > + ); > + // > + // Read SPI CFG cycle before write SPI CFG cycle > + PciSegmentRead16 (BaseAddr + R_SPI_CFG_BDE); > + // > + // If SPI, Program SPI offset D8h to BiosDecodeEnable. > + // > + PciSegmentWrite16 (BaseAddr + R_SPI_CFG_BDE, BiosDecodeEnable); > + } else { > + BaseAddr =3D LpcPciBase (); > + // > + // If LPC/eSPi, program LPC offset D8h to BiosDecodeEnable. > + // > + PciSegmentWrite16 (BaseAddr + R_LPC_CFG_BDE, BiosDecodeEnable); > + } > + > + return Status; > +} > + > +/** > + Set PCH LPC/eSPI IO decode ranges. > + Program LPC/eSPI I/O Decode Ranges in DMI to the same value programmed > in LPC/eSPI PCI offset 80h. > + Please check EDS for detail of LPC/eSPI IO decode ranges bit definitio= n. > + Bit 12: FDD range > + Bit 9:8: LPT range > + Bit 6:4: ComB range > + Bit 2:0: ComA range > + > + @param[in] LpcIoDecodeRanges LPC/eSPI IO decode ranges bit > settings. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchLpcIoDecodeRangesSet ( > + IN UINT16 LpcIoDecodeRanges > + ) > +{ > + UINT64 LpcBaseAddr; > + EFI_STATUS Status; > + > + // > + // Note: Inside this function, don't use debug print since it's could = used > before debug print ready. > + // > + > + LpcBaseAddr =3D LpcPciBase (); > + > + // > + // check if setting is identical > + // > + if (LpcIoDecodeRanges =3D=3D PciSegmentRead16 (LpcBaseAddr + > R_LPC_CFG_IOD)) { > + return EFI_SUCCESS; > + } > + > + Status =3D PchDmiSetLpcIoDecodeRanges (LpcIoDecodeRanges); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + > + // > + // program LPC/eSPI PCI offset 80h. > + // > + PciSegmentWrite16 (LpcBaseAddr + R_LPC_CFG_IOD, LpcIoDecodeRanges); > + > + return Status; > +} > + > +/** > + Set PCH LPC/eSPI and eSPI CS1# IO enable decoding. > + Setup I/O Enables in DMI to the same value program in LPC/eSPI PCI off= set > 82h (LPC, eSPI CS0#) or A0h (eSPI CS1#). > + Note: Bit[15:10] of the source decode register is Read-Only. The IO ra= nge > indicated by the Enables field > + in LPC/eSPI PCI offset 82h[13:10] or A0h[13:10] is always forwarded by= DMI > to subtractive agent for handling. > + Please check EDS for detail of Lpc/eSPI IO decode ranges bit definitio= n. > + > + @param[in] IoEnableDecoding LPC/eSPI IO enable decoding bit > settings. > + @param[in] SlaveId Slave ID (refer to SLAVE_ID_INDE= X) > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMI configuration is locked > +**/ > +EFI_STATUS > +LpcEspiIoEnableDecodingSetHelper ( > + IN UINT16 IoEnableDecoding, > + IN SLAVE_ID_INDEX SlaveId > + ) > +{ > + UINT64 LpcBaseAddr; > + EFI_STATUS Status; > + UINT16 Cs1IoEnableDecodingOrg; > + UINT16 Cs0IoEnableDecodingOrg; > + UINT16 IoEnableDecodingMerged; > + > + LpcBaseAddr =3D LpcPciBase (); > + > + Cs0IoEnableDecodingOrg =3D PciSegmentRead16 (LpcBaseAddr + > R_LPC_CFG_IOE); > + > + if (IsEspiSecondSlaveSupported ()) { > + Cs1IoEnableDecodingOrg =3D PciSegmentRead16 (LpcBaseAddr + > R_ESPI_CFG_CS1IORE); > + } else { > + Cs1IoEnableDecodingOrg =3D 0; > + } > + > + if (SlaveId =3D=3D SlaveEspiCS1) { > + if (IoEnableDecoding =3D=3D Cs1IoEnableDecodingOrg) { > + return EFI_SUCCESS; > + } else { > + IoEnableDecodingMerged =3D (Cs0IoEnableDecodingOrg | > IoEnableDecoding); > + } > + } else { > + if ((IoEnableDecoding | Cs1IoEnableDecodingOrg) =3D=3D > Cs0IoEnableDecodingOrg) { > + return EFI_SUCCESS; > + } else { > + IoEnableDecodingMerged =3D (Cs1IoEnableDecodingOrg | > IoEnableDecoding); > + } > + } > + > + Status =3D PchDmiSetLpcIoEnable (IoEnableDecodingMerged); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + > + // > + // program PCI offset 82h for LPC/eSPI. > + // > + PciSegmentWrite16 (LpcBaseAddr + R_LPC_CFG_IOE, > IoEnableDecodingMerged); > + > + if (SlaveId =3D=3D SlaveEspiCS1) { > + // > + // For eSPI CS1# device program eSPI PCI offset A0h. > + // > + PciSegmentWrite16 (LpcBaseAddr + R_ESPI_CFG_CS1IORE, > IoEnableDecoding); > + } > + > + return Status; > +} > + > + > +/** > + Set PCH LPC and eSPI CS0# IO enable decoding. > + Setup I/O Enables in DMI to the same value program in LPC/eSPI PCI off= set > 82h. > + Note: Bit[15:10] of the source decode register is Read-Only. The IO ra= nge > indicated by the Enables field > + in LPC/eSPI PCI offset 82h[13:10] is always forwarded by DMI to subtra= ctive > agent for handling. > + Please check EDS for detail of LPC/eSPI IO decode ranges bit definitio= n. > + > + @param[in] LpcIoEnableDecoding LPC IO enable decoding bit setti= ngs. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMIC.SRL is set. > +**/ > +EFI_STATUS > +PchLpcIoEnableDecodingSet ( > + IN UINT16 LpcIoEnableDecoding > + ) > +{ > + return LpcEspiIoEnableDecodingSetHelper (LpcIoEnableDecoding, > SlaveLpcEspiCS0); > +} > + > +/** > + Set PCH eSPI CS1# IO enable decoding. > + Setup I/O Enables in DMI to the same value program in eSPI PCI offset = A0h > (eSPI CS1#). > + Note: Bit[15:10] of the source decode register is Read-Only. The IO ra= nge > indicated by the Enables field > + in eSPI PCI offset A0h[13:10] is always forwarded by DMI to subtractiv= e agent > for handling. > + Please check EDS for detail of eSPI IO decode ranges bit definition. > + > + @param[in] IoEnableDecoding eSPI IO enable decoding bit sett= ings. > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_UNSUPPORTED DMI configuration is locked > +**/ > +EFI_STATUS > +PchEspiCs1IoEnableDecodingSet ( > + IN UINT16 IoEnableDecoding > + ) > +{ > + if (!IsEspiSecondSlaveSupported ()) { > + return EFI_UNSUPPORTED; > + } > + > + return LpcEspiIoEnableDecodingSetHelper (IoEnableDecoding, > SlaveEspiCS1); > +} > + > +/** > + Set PCH IO port 80h cycle decoding to PCIE root port. > + System BIOS is likely to do this very soon after reset before PCI bus > enumeration. > + This cycle decoding is allowed to set when DMI is unlocked > + > + @param[in] RpNumber PCIE root port physical number. > + > + @retval EFI_SUCCESS Successfully completed. > +**/ > +EFI_STATUS > +PchIoPort80DecodeSet ( > + IN UINTN RpNumber > + ) > +{ > + EFI_STATUS Status; > + > + Status =3D PchDmiSetIoPort80Decode (RpNumber); > + ASSERT_EFI_ERROR (Status); > + > + return Status; > +} > + > +/** > + Get IO APIC registers base address. > + > + @param[out] IoApicBase Buffer of IO APIC register addre= ss > + > + @retval EFI_SUCCESS Successfully completed. > +**/ > +EFI_STATUS > +PchIoApicBaseGet ( > + OUT UINT32 *IoApicBase > + ) > +{ > + *IoApicBase =3D PcdGet32 (PcdIoApicBaseAddress); > + return EFI_SUCCESS; > +} > + > +/** > + Get HPET base address. > + > + @param[out] HpetBase Buffer of HPET base address > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_INVALID_PARAMETER Invalid offset passed. > +**/ > +EFI_STATUS > +PchHpetBaseGet ( > + OUT UINT32 *HpetBase > + ) > +{ > + if (HpetBase =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "PchHpetBaseGet Error. Invalid pointer.\n")); > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + > + *HpetBase =3D PcdGet32 (PcdSiHpetBaseAddress); > + return EFI_SUCCESS; > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchE > spiLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchE > spiLib.c > new file mode 100644 > index 0000000000..1bbecc71ed > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchEspiLib/PchE > spiLib.c > @@ -0,0 +1,505 @@ > +/** @file > + This file contains routines for eSPI > + > + 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 > + > +#define CHANNEL_RESET_TIMEOUT 100 ///< Channel reset timeout in > us after which to report error > +#define SLAVE_CHANNELS_MAX 7 ///< Max number of channels > + > +// > +// eSPI Slave registers > +// > +#define R_ESPI_SLAVE_GENCAP 0x08 ///< General Capabil= ities > and Configurations > +#define B_ESPI_SLAVE_GENCAP_SUPPCHAN 0xFF ///< Channels > supported bit mask > +#define R_ESPI_SLAVE_CHACAP_BASE 0x10 ///< Base address > from which channel Cap and Conf registers start on slave > +#define S_ESPI_SLAVE_CHACAP_OFFSET 0x10 ///< Offset for each > channel from base > +#define B_ESPI_SLAVE_CHACAP_CHEN BIT0 ///< Slave Channel > enable bit > +#define B_ESPI_SLAVE_CHACAP_CHRDY BIT1 ///< Slave Channel > ready bit > + > +/** > + Checks if second slave capability is enabled > + > + @retval TRUE There's second slave > + @retval FALSE There's no second slave > +**/ > +BOOLEAN > +IsEspiSecondSlaveSupported ( > + VOID > + ) > +{ > + return (IsPchH () && ((PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_SOFTSTRAP= S) > & R_ESPI_PCR_SOFTSTRAPS_CS1_EN) !=3D 0)); > +} > + > +/** > + Checks in slave General Capabilities register if it supports channel w= ith > requested number > + > + @param[in] SlaveId Id of slave to check > + @param[in] ChannelNumber Number of channel of which to check > + > + @retval TRUE Channel with requested number is supported by slave > device > + @retval FALSE Channel with requested number is not supported by sl= ave > device > +**/ > +BOOLEAN > +IsEspiSlaveChannelSupported ( > + UINT8 SlaveId, > + UINT8 ChannelNumber > + ) > +{ > + EFI_STATUS Status; > + UINT32 Data32; > + UINT8 SupportedChannels; > + > + Status =3D PchEspiSlaveGetConfig (SlaveId, R_ESPI_SLAVE_GENCAP, &Data3= 2); > + if (EFI_ERROR (Status)) { > + return FALSE; > + } > + SupportedChannels =3D (UINT8) (Data32 & > B_ESPI_SLAVE_GENCAP_SUPPCHAN); > + > + DEBUG ((DEBUG_INFO, "Slave %d supported channels 0x%4X\n", SlaveId, > SupportedChannels)); > + > + if (ChannelNumber > SLAVE_CHANNELS_MAX || !(SupportedChannels & > (BIT0 << ChannelNumber))) { > + // Incorrect channel number was specified. Either exceeded max or Sl= ave > doesn't support that channel. > + return FALSE; > + } > + > + return TRUE; > +} > + > +/** > + Is eSPI enabled in strap. > + > + @retval TRUE Espi is enabled in strap > + @retval FALSE Espi is disabled in strap > +**/ > +BOOLEAN > +IsEspiEnabled ( > + VOID > + ) > +{ > + return (PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_CFG_VAL) & > B_ESPI_PCR_CFG_VAL_ESPI_EN) !=3D 0; > +} > + > +/** > + eSPI helper function to clear slave configuration register status > + > + @retval EFI_SUCCESS Write to private config space succeed > + @retval others Read / Write failed > +**/ > +STATIC > +VOID > +EspiClearScrs ( > + VOID > + ) > +{ > + PchPcrAndThenOr32 ( > + PID_ESPISPI, > + R_ESPI_PCR_SLV_CFG_REG_CTL, > + (UINT32) ~0, > + B_ESPI_PCR_SLV_CFG_REG_CTL_SCRS > + ); > +} > + > +/** > + eSPI helper function to poll slave configuration register enable for 0 > + and to check for slave configuration register status > + > + @retval EFI_SUCCESS Enable bit is zero and no error in status bi= ts > + @retval EFI_DEVICE_ERROR Error in SCRS > + @retval others Read / Write to private config space failed > +**/ > +STATIC > +EFI_STATUS > +EspiPollScreAndCheckScrs ( > + VOID > + ) > +{ > + UINT32 ScrStat; > + > + do { > + ScrStat =3D PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_SLV_CFG_REG_CTL); > + } while ((ScrStat & B_ESPI_PCR_SLV_CFG_REG_CTL_SCRE) !=3D 0); > + > + ScrStat =3D (ScrStat & B_ESPI_PCR_SLV_CFG_REG_CTL_SCRS) >> > N_ESPI_PCR_SLV_CFG_REG_CTL_SCRS; > + if (ScrStat !=3D V_ESPI_PCR_SLV_CFG_REG_CTL_SCRS_NOERR) { > + DEBUG ((DEBUG_ERROR, "eSPI slave config register status (error) is %= x \n", > ScrStat)); > + return EFI_DEVICE_ERROR; > + } > + return EFI_SUCCESS; > +} > + > +typedef enum { > + EspiSlaveOperationConfigRead, > + EspiSlaveOperationConfigWrite, > + EspiSlaveOperationStatusRead, > + EspiSlaveOperationInBandReset > +} ESPI_SLAVE_OPERATION; > + > +/** > + Helper library to do all the operations regards to eSPI slave > + > + @param[in] SlaveId eSPI Slave ID > + @param[in] SlaveAddress Slave address to be put in > R_ESPI_PCR_SLV_CFG_REG_CTL[11:0] > + @param[in] SlaveOperation Based on ESPI_SLAVE_OPERATION > + @param[in,out] Data > + > + @retval EFI_SUCCESS Operation succeed > + @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 i= s > used in PCH_LP > + @retval EFI_INVALID_PARAMETER Slave configuration register address > exceed maximum allowed > + @retval EFI_INVALID_PARAMETER Slave configuration register address is > not DWord aligned > + @retval EFI_ACCESS_DENIED eSPI Slave write to address range 0 to 0= x7FF > has been locked > + @retval EFI_DEVICE_ERROR Error in SCRS during polling stage of > operation > +**/ > +STATIC > +EFI_STATUS > +EspiSlaveOperationHelper ( > + IN UINT32 SlaveId, > + IN UINT32 SlaveAddress, > + IN ESPI_SLAVE_OPERATION SlaveOperation, > + IN OUT UINT32 *Data > + ) > +{ > + EFI_STATUS Status; > + UINT32 Data32; > + > + // > + // Check the SlaveId is 0 or 1 > + // > + if (SlaveId >=3D PCH_MAX_ESPI_SLAVES) { > + DEBUG ((DEBUG_ERROR, "eSPI Slave ID of %d or more is not accepted \n= ", > PCH_MAX_ESPI_SLAVES)); > + return EFI_INVALID_PARAMETER; > + } > + // > + // Check if SlaveId 1 is used, it is a PCH_H > + // > + if ((SlaveId =3D=3D 1) && (IsPchLp ())) { > + DEBUG ((DEBUG_ERROR, "eSPI Slave ID of 1 is only available on PCH_H > \n")); > + return EFI_INVALID_PARAMETER; > + } > + // > + // Check the address is not more then 0xFFF > + // > + if (SlaveAddress > B_ESPI_PCR_SLV_CFG_REG_CTL_SCRA) { > + DEBUG ((DEBUG_ERROR, "eSPI Slave address must be less than 0x%x \n", > (B_ESPI_PCR_SLV_CFG_REG_CTL_SCRA + 1))); > + return EFI_INVALID_PARAMETER; > + } > + // > + // Check the address is DWord aligned > + // > + if ((SlaveAddress & 0x3) !=3D 0) { > + DEBUG ((DEBUG_ERROR, "eSPI Slave address must be DWord aligned \n"))= ; > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Check if write is allowed > + // > + if ((SlaveOperation =3D=3D EspiSlaveOperationConfigWrite) && > + (SlaveAddress <=3D 0x7FF)) { > + > + // > + // If the SLCRR is not set in corresponding slave, we will check the= lock bit > + // > + Data32 =3D PchPcrRead32 (PID_ESPISPI, (UINT16) (R_ESPI_PCR_LNKERR_SL= V0 > + (SlaveId * S_ESPI_PCR_LNKERR_SLV0))); > + if ((Data32 & B_ESPI_PCR_LNKERR_SLV0_SLCRR) =3D=3D 0) { > + > + Data32 =3D PchPcrRead32 (PID_ESPISPI, (UINT16) > R_ESPI_PCR_SLV_CFG_REG_CTL); > + if ((Data32 & B_ESPI_PCR_SLV_CFG_REG_CTL_SBLCL) !=3D 0) { > + DEBUG ((DEBUG_ERROR, "eSPI Slave write to address range 0 to 0x7= FF > has been locked \n")); > + return EFI_ACCESS_DENIED; > + } > + } > + } > + > + // > + // Input check done, now go through all the processes > + // > + EspiClearScrs (); > + > + if (SlaveOperation =3D=3D EspiSlaveOperationConfigWrite) { > + PchPcrWrite32 ( > + PID_ESPISPI, > + (UINT16) R_ESPI_PCR_SLV_CFG_REG_DATA, > + *Data > + ); > + } > + > + PchPcrAndThenOr32 ( > + PID_ESPISPI, > + (UINT16) R_ESPI_PCR_SLV_CFG_REG_CTL, > + (UINT32) ~(B_ESPI_PCR_SLV_CFG_REG_CTL_SID | > B_ESPI_PCR_SLV_CFG_REG_CTL_SCRT | > B_ESPI_PCR_SLV_CFG_REG_CTL_SCRA), > + (B_ESPI_PCR_SLV_CFG_REG_CTL_SCRE | > + (SlaveId << N_ESPI_PCR_SLV_CFG_REG_CTL_SID) | > + (((UINT32) SlaveOperation) << N_ESPI_PCR_SLV_CFG_REG_CTL_SCRT) | > + SlaveAddress > + ) > + ); > + > + Status =3D EspiPollScreAndCheckScrs (); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if ((SlaveOperation =3D=3D EspiSlaveOperationConfigRead) || (SlaveOper= ation > =3D=3D EspiSlaveOperationStatusRead)) { > + Data32 =3D PchPcrRead32 ( > + PID_ESPISPI, > + (UINT16) R_ESPI_PCR_SLV_CFG_REG_DATA > + ); > + if (SlaveOperation =3D=3D EspiSlaveOperationStatusRead) { > + *Data =3D Data32 & 0xFFFF; > + } else { > + *Data =3D Data32; > + } > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Get configuration from eSPI slave > + > + @param[in] SlaveId eSPI slave ID > + @param[in] SlaveAddress Slave Configuration Register Address > + @param[out] OutData Configuration data read > + > + @retval EFI_SUCCESS Operation succeed > + @retval EFI_INVALID_PARAMETER Slave ID is not supported > + @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 i= s > used in PCH_LP > + @retval EFI_INVALID_PARAMETER Slave configuration register address > exceed maximum allowed > + @retval EFI_INVALID_PARAMETER Slave configuration register address is > not DWord aligned > + @retval EFI_DEVICE_ERROR Error in SCRS during polling stage of > operation > +**/ > +EFI_STATUS > +PchEspiSlaveGetConfig ( > + IN UINT32 SlaveId, > + IN UINT32 SlaveAddress, > + OUT UINT32 *OutData > + ) > +{ > + // > + // 1. Clear status from previous transaction by writing 111b to status= in SCRS, > PCR[eSPI] + 4000h [30:28] > + // 2. Program SLV_CFG_REG_CTL with the right value (Bit[31]=3D01, Bit > [20:19]=3D, Bit [17:16] =3D 00b, Bit[11:0] =3D . > + // 3. Poll the SCRE (PCR[eSPI] +4000h [31]) to be set back to 0 > + // 4. Check the transaction status in SCRS (bits [30:28]) > + // 5. Read SLV_CFG_REG_DATA. > + // > + return EspiSlaveOperationHelper (SlaveId, SlaveAddress, > EspiSlaveOperationConfigRead, OutData); > +} > + > +/** > + Set eSPI slave configuration > + > + Note: A Set_Configuration must always be followed by a Get_Configurati= on > in order to ensure > + that the internal state of the eSPI-MC is consistent with the Slave's = register > settings. > + > + @param[in] SlaveId eSPI slave ID > + @param[in] SlaveAddress Slave Configuration Register Address > + @param[in] InData Configuration data to write > + > + @retval EFI_SUCCESS Operation succeed > + @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 i= s > used in PCH_LP > + @retval EFI_INVALID_PARAMETER Slave configuration register address > exceed maximum allowed > + @retval EFI_INVALID_PARAMETER Slave configuration register address is > not DWord aligned > + @retval EFI_ACCESS_DENIED eSPI Slave write to address range 0 to 0= x7FF > has been locked > + @retval EFI_DEVICE_ERROR Error in SCRS during polling stage of > operation > +**/ > +EFI_STATUS > +PchEspiSlaveSetConfig ( > + IN UINT32 SlaveId, > + IN UINT32 SlaveAddress, > + IN UINT32 InData > + ) > +{ > + EFI_STATUS Status; > + UINT32 Data32; > + > + // > + // 1. Clear status from previous transaction by writing 111b to status= in SCRS, > PCR[eSPI] + 4000h [30:28] > + // 2. Program SLV_CFG_REG_DATA with the write value. > + // 3. Program SLV_CFG_REG_CTL with the right value (Bit[31]=3D01, Bit > [20:19]=3D, Bit [17:16] =3D 01b, Bit[11:0] =3D . > + // 4. Poll the SCRE (PCR[eSPI] +4000h [31]) to be set back to 0 > + // 5. Check the transaction status in SCRS (bits [30:28]) > + // > + Status =3D EspiSlaveOperationHelper (SlaveId, SlaveAddress, > EspiSlaveOperationConfigWrite, &InData); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + Status =3D PchEspiSlaveGetConfig (SlaveId, SlaveAddress, &Data32); > + return Status; > +} > + > +/** > + Get status from eSPI slave > + > + @param[in] SlaveId eSPI slave ID > + @param[out] OutData Configuration data read > + > + @retval EFI_SUCCESS Operation succeed > + @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 i= s > used in PCH_LP > + @retval EFI_DEVICE_ERROR Error in SCRS during polling stage of > operation > +**/ > +EFI_STATUS > +PchEspiSlaveGetStatus ( > + IN UINT32 SlaveId, > + OUT UINT16 *OutData > + ) > +{ > + EFI_STATUS Status; > + UINT32 TempOutData; > + > + TempOutData =3D 0; > + > + // > + // 1. Clear status from previous transaction by writing 111b to status= in SCRS, > PCR[eSPI] + 4000h [30:28] > + // 2. Program SLV_CFG_REG_CTL with the right value (Bit[31]=3D01, Bit > [20:19]=3D, Bit [17:16] =3D 10b, Bit[11:0] =3D . > + // 3. Poll the SCRE (PCR[eSPI] +4000h [31]) to be set back to 0 > + // 4. Check the transaction status in SCRS (bits [30:28]) > + // 5. Read SLV_CFG_REG_DATA [15:0]. > + // > + Status =3D EspiSlaveOperationHelper (SlaveId, 0, > EspiSlaveOperationStatusRead, &TempOutData); > + *OutData =3D (UINT16) TempOutData; > + > + return Status; > +} > + > +/** > + eSPI slave in-band reset > + > + @param[in] SlaveId eSPI slave ID > + > + @retval EFI_SUCCESS Operation succeed > + @retval EFI_INVALID_PARAMETER Slave ID is not supported or SlaveId 1 i= s > used in PCH_LP > + @retval EFI_DEVICE_ERROR Error in SCRS during polling stage of > operation > +**/ > +EFI_STATUS > +PchEspiSlaveInBandReset ( > + IN UINT32 SlaveId > + ) > +{ > + // > + // 1. Clear status from previous transaction by writing 111b to status= in SCRS, > PCR[eSPI] + 4000h [30:28] > + // 2. Program SLV_CFG_REG_CTL with the right value (Bit[31]=3D01, Bit > [20:19]=3D, Bit [17:16] =3D 11b). > + // 3. Poll the SCRE (PCR[eSPI] +4000h [31]) to be set back to 0 > + // 4. Check the transaction status in SCRS (bits [30:28]) > + // > + return EspiSlaveOperationHelper (SlaveId, 0, > EspiSlaveOperationInBandReset, NULL); > +} > + > +/** > + eSPI Slave channel reset helper function > + > + @param[in] SlaveId eSPI slave ID > + @param[in] ChannelNumber Number of channel to reset > + > + @retval EFI_SUCCESS Operation succeeded > + @retval EFI_UNSUPPORTED Slave doesn't support that channel or > invalid number specified > + @retval EFI_TIMEOUT Operation has timeouted > +**/ > +EFI_STATUS > +PchEspiSlaveChannelReset ( > + IN UINT8 SlaveId, > + IN UINT8 ChannelNumber > + ) > +{ > + UINT8 Timeout; > + UINT32 Data32; > + UINT32 SlaveChannelAddress; > + BOOLEAN SlaveBmeSet; > + EFI_STATUS Status; > + > + DEBUG ((DEBUG_INFO, "eSPI slave %d channel %d reset\n", SlaveId, > ChannelNumber)); > + > + Timeout =3D CHANNEL_RESET_TIMEOUT; > + SlaveBmeSet =3D FALSE; > + > + if (!IsEspiSlaveChannelSupported (SlaveId, ChannelNumber)) { > + // Incorrect channel number was specified. Either exceeded max or Sl= ave > doesn't support that channel. > + DEBUG ((DEBUG_ERROR, "Channel %d is not valid channel number for > slave %d!\n", ChannelNumber, SlaveId)); > + return EFI_UNSUPPORTED; > + } > + > + // Calculating slave channel address > + SlaveChannelAddress =3D R_ESPI_SLAVE_CHACAP_BASE + > (S_ESPI_SLAVE_CHACAP_OFFSET * ChannelNumber); > + > + // If we're resetting Peripheral Channel then we need to disable Bus > Mastering first and reenable after reset > + if (ChannelNumber =3D=3D 0) { > + Status =3D PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Dat= a32); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + if ((Data32 & B_ESPI_SLAVE_BME) !=3D 0) { > + Data32 &=3D ~(B_ESPI_SLAVE_BME); > + Status =3D PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Da= ta32); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + SlaveBmeSet =3D TRUE; > + } > + } > + > + // Disable channel > + Status =3D PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data3= 2); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + Data32 &=3D ~(B_ESPI_SLAVE_CHACAP_CHEN); > + Status =3D PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32= ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + // Enable channel > + Status =3D PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Data3= 2); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + Data32 |=3D B_ESPI_SLAVE_CHACAP_CHEN; > + Status =3D PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data32= ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + DEBUG ((DEBUG_INFO, "Waiting for Channel Ready bit\n")); > + // Wait until channel is ready by polling Channel Ready bit > + while (((Data32 & B_ESPI_SLAVE_CHACAP_CHRDY) =3D=3D 0) && (Timeout > 0= )) { > + Status =3D PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Dat= a32); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + MicroSecondDelay (1); > + --Timeout; > + } > + > + if (Timeout =3D=3D 0) { > + // The waiting for channel to be ready has timed out > + DEBUG ((DEBUG_ERROR, "The operation of channel %d reset for slave %d > has timed out!\n", ChannelNumber, SlaveId)); > + return EFI_TIMEOUT; > + } > + > + if (ChannelNumber =3D=3D 0 && SlaveBmeSet) { > + Status =3D PchEspiSlaveGetConfig (SlaveId, SlaveChannelAddress, &Dat= a32); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + Data32 |=3D B_ESPI_SLAVE_BME; > + Status =3D PchEspiSlaveSetConfig (SlaveId, SlaveChannelAddress, Data= 32); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + } > + > + return EFI_SUCCESS; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchG > beLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchG > beLib.c > new file mode 100644 > index 0000000000..652a47ebaf > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchGbeLib/PchG > beLib.c > @@ -0,0 +1,82 @@ > +/** @file > + PCH Gbe Library. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + 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 > + > +/** > + Check whether GbE region is valid > + Check SPI region directly since GbE might be disabled in SW. > + > + @retval TRUE Gbe Region is valid > + @retval FALSE Gbe Region is invalid > +**/ > +BOOLEAN > +PchIsGbeRegionValid ( > + VOID > + ) > +{ > + UINT32 SpiBar; > + SpiBar =3D PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_SPI, > + PCI_FUNCTION_NUMBER_PCH_SPI, > + R_SPI_CFG_BAR0)) & ~B_SPI_CFG_BAR0_MASK; > + ASSERT (SpiBar !=3D 0); > + if (MmioRead32 (SpiBar + R_SPI_MEM_FREG3_GBE) !=3D > B_SPI_MEM_FREGX_BASE_MASK) { > + return TRUE; > + } > + return FALSE; > +} > + > + > +/** > + Check whether LAN controller is enabled in the platform. > + > + @retval TRUE GbE is enabled > + @retval FALSE GbE is disabled > +**/ > +BOOLEAN > +PchIsGbePresent ( > + VOID > + ) > +{ > + // > + // Check PCH Support > + // > + if (!PchIsGbeSupported ()) { > + return FALSE; > + } > + // > + // Check PMC strap/fuse > + // > + if (!PmcIsGbeSupported ()) { > + return FALSE; > + } > + // > + // Check GbE NVM > + // > + if (PchIsGbeRegionValid () =3D=3D FALSE) { > + return FALSE; > + } > + return TRUE; > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/Pch > HsioLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/Pch > HsioLib.c > new file mode 100644 > index 0000000000..2be8e8ed49 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchHsioLib/Pch > HsioLib.c > @@ -0,0 +1,127 @@ > +/** @file > + PCH HSIO Library. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** > + The function returns the Port Id and lane owner for the specified lane > + > + @param[in] PhyMode Phymode that needs to be checked > + @param[out] PortId Common Lane End Point ID > + @param[out] LaneOwner Lane Owner > + > + @retval EFI_SUCCESS Read success > + @retval EFI_INVALID_PARAMETER Invalid lane number > +**/ > +EFI_STATUS > +EFIAPI > +PchGetLaneInfo ( > + IN UINT32 LaneNum, > + OUT UINT8 *PortId, > + OUT UINT8 *LaneOwner > + ) > +{ > + return EFI_SUCCESS; > +} > + > +/** > + Determine the lane number of a specified port > + > + @param[out] LaneNum GBE Lane Number > + > + @retval EFI_SUCCESS Lane number valid. > + @retval EFI_UNSUPPORTED Incorrect input device port > +**/ > +EFI_STATUS > +PchGetGbeLaneNum ( > + UINT8 *LaneNum > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + Determine the lane number of a specified port > + > + @param[in] Usb3LaneIndex USB3 Lane Index > + @param[out] LaneNum Lane Number > + > + @retval EFI_SUCCESS Lane number valid. > + @retval EFI_UNSUPPORTED Incorrect input device port > +**/ > +EFI_STATUS > +PchGetUsb3LaneNum ( > + UINT32 Usb3LaneIndex, > + UINT8 *LaneNum > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + Determine the lane number of a specified port > + > + @param[in] SataLaneIndex Sata Lane Index > + @param[out] LaneNum Lane Number > + > + @retval EFI_SUCCESS Lane number valid. > + @retval EFI_UNSUPPORTED Incorrect input device port > +**/ > +EFI_STATUS > +PchGetSataLaneNum ( > + UINT32 SataLaneIndex, > + UINT8 *LaneNum > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + Determine the lane number of a specified port > + > + @param[in] PcieLaneIndex PCIE Root Port Lane Index > + @param[out] LaneNum Lane Number > + > + @retval EFI_SUCCESS Lane number valid. > + @retval EFI_UNSUPPORTED Incorrect input device port > +**/ > +EFI_STATUS > +PchGetPcieLaneNum ( > + UINT32 PcieLaneIndex, > + UINT8 *LaneNum > + ) > +{ > + > + return EFI_UNSUPPORTED; > +} > + > +/** > + Get HSIO lane representation needed to perform any operation on the la= ne. > + > + @param[in] LaneIndex Number of the HSIO lane > + @param[out] HsioLane HSIO lane representation > +**/ > +VOID > +HsioGetLane ( > + IN UINT8 LaneIndex, > + OUT HSIO_LANE *HsioLane > + ) > +{ > + > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI= n > foLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI > nfoLib.c > new file mode 100644 > index 0000000000..7c3ade49b6 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI > nfoLib.c > @@ -0,0 +1,272 @@ > +/** @file > + Pch information library. > + > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + 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 "PchInfoLibPrivate.h" > +#include > +#include > +#include > +#include > + > +/** > + Return LPC Device Id > + > + @retval PCH_LPC_DEVICE_ID PCH Lpc Device ID > +**/ > +UINT16 > +PchGetLpcDid ( > + VOID > + ) > +{ > + UINT64 LpcBaseAddress; > + > + LpcBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_LPC, > + PCI_FUNCTION_NUMBER_PCH_LPC, > + 0 > + ); > + > + return PciSegmentRead16 (LpcBaseAddress + PCI_DEVICE_ID_OFFSET); > +} > + > +/** > + Return Pch Series > + > + @retval PCH_SERIES Pch Series > +**/ > +PCH_SERIES > +PchSeries ( > + VOID > + ) > +{ > + PCH_SERIES PchSer; > + static PCH_SERIES PchSeries =3D PCH_UNKNOWN_SERIES; > + > + if (PchSeries !=3D PCH_UNKNOWN_SERIES) { > + return PchSeries; > + } > + > + PchSer =3D PchSeriesFromLpcDid (PchGetLpcDid ()); > + > + PchSeries =3D PchSer; > + > + return PchSer; > +} > + > +/** > + Return Pch stepping type > + > + @retval PCH_STEPPING Pch stepping type > +**/ > +PCH_STEPPING > +PchStepping ( > + VOID > + ) > +{ > + UINT8 RevId; > + UINT64 LpcBaseAddress; > + static PCH_STEPPING PchStepping =3D PCH_STEPPING_MAX; > + > + if (PchStepping !=3D PCH_STEPPING_MAX) { > + return PchStepping; > + } > + > + LpcBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_LPC, > + PCI_FUNCTION_NUMBER_PCH_LPC, > + 0 > + ); > + RevId =3D PciSegmentRead8 (LpcBaseAddress + PCI_REVISION_ID_OFFSET); > + > + PchStepping =3D RevId; > + > + return RevId; > +} > + > +/** > + Determine if PCH is supported > + > + @retval TRUE PCH is supported > + @retval FALSE PCH is not supported > +**/ > +BOOLEAN > +IsPchSupported ( > + VOID > + ) > +{ > + UINT16 LpcDeviceId; > + UINT16 LpcVendorId; > + UINT64 LpcBaseAddress; > + > + LpcBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_LPC, > + PCI_FUNCTION_NUMBER_PCH_LPC, > + 0 > + ); > + > + LpcDeviceId =3D PciSegmentRead16 (LpcBaseAddress + > PCI_DEVICE_ID_OFFSET); > + LpcVendorId =3D PciSegmentRead16 (LpcBaseAddress + > PCI_VENDOR_ID_OFFSET); > + > + /// > + /// Verify that this is a supported chipset > + /// > + if ((LpcVendorId =3D=3D V_LPC_CFG_VENDOR_ID) && (PchSeries () !=3D > PCH_UNKNOWN_SERIES)) { > + return TRUE; > + } else { > + DEBUG ((DEBUG_ERROR, "PCH code doesn't support the LpcDeviceId: > 0x%04x!\n", LpcDeviceId)); > + return FALSE; > + } > +} > + > +/** > + Check if this is PCH LP series > + > + @retval TRUE It's PCH LP series > + @retval FALSE It's not PCH LP series > +**/ > +BOOLEAN > +IsPchLp ( > + VOID > + ) > +{ > + return (PchSeries () =3D=3D PCH_LP); > +} > + > +/** > + Check if this is PCH H series > + > + @retval TRUE It's PCH H series > + @retval FALSE It's not PCH H series > +**/ > +BOOLEAN > +IsPchH ( > + VOID > + ) > +{ > + return (PchSeries () =3D=3D PCH_H); > +} > + > +/** > + Check if this is CDF PCH generation > + > + @retval TRUE It's CDF PCH > + @retval FALSE It's not CDF PCH > +**/ > +BOOLEAN > +IsCdfPch ( > + VOID > + ) > +{ > + return (PchGeneration () =3D=3D CDF_PCH); > +} > + > +/** > + Check if this is PCH generation > + > + @retval TRUE It's CNL PCH > + @retval FALSE It's not CNL PCH > +**/ > +BOOLEAN > +IsCnlPch ( > + VOID > + ) > +{ > + return (PchGeneration () =3D=3D CNL_PCH); > +} > + > +/** > + Get PCH stepping ASCII string. > + Function determines major and minor stepping versions and writes them > into a buffer. > + The return string is zero terminated > + > + @param [out] Buffer Output buffer of string > + @param [in] BufferSize Buffer size. > + Must not be less then > PCH_STEPPING_STR_LENGTH_MAX > + > + @retval EFI_SUCCESS String copied successfully > + @retval EFI_INVALID_PARAMETER The stepping is not supported, o= r > parameters are NULL > + @retval EFI_BUFFER_TOO_SMALL Input buffer size is too small > +**/ > +EFI_STATUS > +PchGetSteppingStr ( > + OUT CHAR8 *Buffer, > + IN UINT32 BufferSize > + ) > +{ > + PCH_STEPPING PchStep; > + > + PchStep =3D PchStepping (); > + > + if ((Buffer =3D=3D NULL) || (BufferSize =3D=3D 0)) { > + return EFI_INVALID_PARAMETER; > + } > + if (BufferSize < PCH_STEPPING_STR_LENGTH_MAX) { > + return EFI_BUFFER_TOO_SMALL; > + } > + > + AsciiSPrint (Buffer, BufferSize, "%c%c", 'A' + (PchStep >> 4), '0' + (= PchStep & > 0xF)); > + > + return EFI_SUCCESS; > +} > + > +/** > + Get PCH Sku ASCII string > + The return string is zero terminated. > + > + @retval Static ASCII string of PCH Sku > +**/ > +CHAR8* > +PchGetSkuStr ( > + VOID > + ) > +{ > + UINTN Index; > + UINT16 LpcDid; > + > + LpcDid =3D PchGetLpcDid (); > + > + for (Index =3D 0; mSkuStrs[Index].Id !=3D 0xFFFF; Index++) { > + if (LpcDid =3D=3D mSkuStrs[Index].Id) { > + return mSkuStrs[Index].String; > + } > + } > + > + return "Undefined SKU"; > +} > + > +/** > + Get Pch Maximum Pcie Controller Number > + > + @retval Pch Maximum Pcie Root Port Number > +**/ > +UINT8 > +GetPchMaxPcieControllerNum ( > + VOID > + ) > +{ > + return GetPchMaxPciePortNum () / PCH_PCIE_CONTROLLER_PORTS; > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI= n > foLibClient.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI > nfoLibClient.c > new file mode 100644 > index 0000000000..7b09a2dbb9 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI > nfoLibClient.c > @@ -0,0 +1,87 @@ > +/** @file > + Common Pch information library for Client PCH silicon. > + > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > + > +/** > + Get Pch Maximum Pcie Clock Number > + > + @retval Pch Maximum Pcie Clock Number > +**/ > +UINT8 > +GetPchMaxPcieClockNum ( > + VOID > + ) > +{ > + if (IsPchH ()) { > + return 16; > + } else { > + return 6; > + } > +} > + > +/** > + Get Pch Maximum Serial IO controllers number > + > + @retval Pch Maximum Serial IO controllers number > +**/ > +UINT8 > +GetPchMaxSerialIoControllersNum ( > + VOID > + ) > +{ > + return 12; > +} > + > +/** > + Get Pch Maximum Serial IO I2C controllers number > + > + @retval Pch Maximum Serial IO I2C controllers number > +**/ > +UINT8 > +GetPchMaxSerialIoI2cControllersNum ( > + VOID > + ) > +{ > + if (IsPchH ()) { > + return 4; > + } else { > + return 6; > + } > +} > + > +/** > + Get Pch Maximum Serial IO SPI controllers number > + > + @retval Pch Maximum Serial IO SPI controllers number > +**/ > +UINT8 > +GetPchMaxSerialIoSpiControllersNum ( > + VOID > + ) > +{ > + return 3; > +} > + > +/** > + Get Pch Maximum Serial IO UART controllers number > + > + @retval Pch Maximum Serial IO UART controllers number > +**/ > +UINT8 > +GetPchMaxSerialIoUartControllersNum ( > + VOID > + ) > +{ > + return 3; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI= n > foLibCnl.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI > nfoLibCnl.c > new file mode 100644 > index 0000000000..431b1470c2 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchInfoLib/PchI > nfoLibCnl.c > @@ -0,0 +1,386 @@ > +/** @file > + Pch information library. > + > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include "PchInfoLibPrivate.h" > +#include > +#include > + > +/** > + Determine Pch Series based on Device Id > + > + @param[in] LpcDeviceId Lpc Device Id > + > + @retval PCH_SERIES Pch Series > +**/ > +PCH_SERIES > +PchSeriesFromLpcDid ( > + IN UINT16 LpcDeviceId > + ) > +{ > + switch (LpcDeviceId & B_LPC_CFG_DID) { > + > + case V_LPC_CFG_DID_CNL_H: > + return PCH_H; > + > + case V_LPC_CFG_DID_CNL_LP: > + return PCH_LP; > + > + default: > + return PCH_UNKNOWN_SERIES; > + } > +} > + > +/** > + Return Pch Generation > + > + @retval PCH_GENERATION Pch Generation > +**/ > +PCH_GENERATION > +PchGeneration ( > + VOID > + ) > +{ > + return CNL_PCH; > +} > + > +/** > + Check if this is Server PCH > + > + @retval TRUE It's a Server PCH > + @retval FALSE It's not a Server PCH > +**/ > +BOOLEAN > +IsPchServer ( > + VOID > + ) > +{ > + return FALSE; > +} > + > +/** > + Get RST mode supported by the silicon > + > + @retval RST_MODE RST mode supported by silicon > +**/ > +RST_MODE > +PchGetSupportedRstMode ( > + VOID > + ) > +{ > + switch (PchGetLpcDid ()) { > + > + case V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_4: > + case V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A303_SKU: > + return RstUnsupported; > + break; > + > + default: > + return RstPremium; > + break; > + } > +} > + > +/** > + Check if this is Server SKU > + > + @retval TRUE It's PCH Server SKU > + @retval FALSE It's not PCH Server SKU > +**/ > +BOOLEAN > +IsPchServerSku ( > + VOID > + ) > +{ > + UINT16 LpcDid; > + > + LpcDid =3D PchGetLpcDid (); > + > + if (LpcDid =3D=3D V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A309_SKU) { > + return TRUE; > + } else { > + return FALSE; > + } > +} > + > +/** > + Get PCH series ASCII string. > + > + @retval PCH Series string > +**/ > +CHAR8* > +PchGetSeriesStr ( > + VOID > + ) > +{ > + switch (PchSeries ()) { > + > + case PCH_LP: > + return "CNL PCH-LP"; > + > + case PCH_H: > + return "CNL PCH-H"; > + > + default: > + return NULL; > + } > +} > + > +GLOBAL_REMOVE_IF_UNREFERENCED > +struct PCH_SKU_STRING mSkuStrs[] =3D { > + // > + // PCH LP Mobile LPC Device IDs > + // > + {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_SUPER_SKU, "Super SKU"}, > + {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_0, "(U) Super SKU"}, > + {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_1, "Super SKU (locked)"}, > + {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_2, "(Y) Premium SKU"}, > + {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_3, "(U) Premium SKU"}, > + {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_4, "(U) Base/Mainstream SKU"}, > + {V_CNL_PCH_LP_LPC_CFG_DEVICE_ID_MB_5, "(Y) Super SKU"}, > + // > + // PCH H LPC Device IDs > + // > + {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A300_SKU, "CNL PCH-H SKU A300"}, > + {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A303_SKU, "H310"}, > + {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A304_SKU, "H370"}, > + {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A305_SKU, "Z390"}, > + {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A306_SKU, "Q370"}, > + {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A309_SKU, "C246"}, > + {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30A_SKU, "C242"}, > + {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30B_SKU, "X399"}, > + {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30C_SKU, "QM370"}, > + {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30D_SKU, "HM370"}, > + {V_CNL_PCH_H_LPC_CFG_DEVICE_ID_A30E_SKU, "CM246"}, > + {0xFFFF, NULL} > +}; > + > +/** > + Check whether integrated LAN controller is supported by PCH Series. > + > + @retval TRUE GbE is supported in current PCH > + @retval FALSE GbE is not supported on current PCH > +**/ > +BOOLEAN > +PchIsGbeSupported ( > + VOID > + ) > +{ > + return TRUE; > +} > + > +/** > + Get Pch Maximum Pcie Root Port Number > + > + @retval Pch Maximum Pcie Root Port Number > +**/ > +UINT8 > +GetPchMaxPciePortNum ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return 16; > + } else { > + return 24; > + } > +} > + > +/** > + Get Pch Usb2 Maximum Physical Port Number > + > + @retval Pch Usb2 Maximum Physical Port Number > +**/ > +UINT8 > +GetPchUsb2MaxPhysicalPortNum ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return 10; > + } else { > + return 14; > + } > +} > + > +/** > + Get Pch Maximum Usb2 Port Number of XHCI Controller > + > + @retval Pch Maximum Usb2 Port Number of XHCI Controller > +**/ > +UINT8 > +GetPchXhciMaxUsb2PortNum ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return 12; > + } else { > + return 16; > + } > +} > + > +/** > + Get Pch Maximum Usb3 Port Number of XHCI Controller > + > + @retval Pch Maximum Usb3 Port Number of XHCI Controller > +**/ > +UINT8 > +GetPchXhciMaxUsb3PortNum ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return 6; > + } else { > + return 10; > + } > +} > + > +/** > + Check if given Display Audio Link T-Mode is supported > + > + @param[in] Tmode T-mode support to be checked > + > + @retval TRUE T-mode supported > + @retval FALSE T-mode not supported > +**/ > +BOOLEAN > +IsAudioIDispTmodeSupported ( > + IN PCH_HDAUDIO_IDISP_TMODE Tmode > + ) > +{ > + // > + // iDisplay Audio Link T-mode support per PCH Generation/Series: > + // 1. 1T - CNP-LP > + // 2. 2T - CNP-LP/H (default) > + // > + switch (Tmode) { > + case PchHdaIDispMode1T: > + return IsPchLp (); > + case PchHdaIDispMode2T: > + return TRUE; > + case PchHdaIDispMode4T: > + case PchHdaIDispMode8T: > + case PchHdaIDispMode16T: > + default: > + return FALSE; > + } > +} > + > +/** > + Gets the maximum number of UFS controller supported by this chipset. > + > + @return Number of supported UFS controllers > +**/ > +UINT8 > +PchGetMaxUfsNum ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return 1; > + } else { > + return 0; > + } > +} > + > +/** > + Check if this chipset supports eMMC controller > + > + @retval BOOLEAN TRUE if supported, FALSE otherwise > +**/ > +BOOLEAN > +IsPchEmmcSupported ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return TRUE; > + } > + > + return FALSE; > +} > + > +/** > + Check if this chipset supports SD controller > + > + @retval BOOLEAN TRUE if supported, FALSE otherwise > +**/ > +BOOLEAN > +IsPchSdCardSupported ( > + VOID > + ) > +{ > + return TRUE; > +} > + > +/** > + Check if this chipset supports UFS controller > + > + @retval BOOLEAN TRUE if supported, FALSE otherwise > +**/ > +BOOLEAN > +IsPchUfsSupported ( > + VOID > + ) > +{ > + if (IsPchLp ()) { > + return TRUE; > + } > + > + return FALSE; > +} > + > +/** > + Check if link between PCH and CPU is an P-DMI > + > + @retval TRUE P-DMI link > + @retval FALSE Not an P-DMI link > +**/ > +BOOLEAN > +IsPchWithPdmi ( > + VOID > + ) > +{ > + return IsPchH (); > +} > + > +/** > + Check if link between PCH and CPU is an OP-DMI > + > + @retval TRUE OP-DMI link > + @retval FALSE Not an OP-DMI link > +**/ > +BOOLEAN > +IsPchWithOpdmi ( > + VOID > + ) > +{ > + return !IsPchH (); > +} > + > +/** > + Check if link between PCH and CPU is an F-DMI > + > + @retval TRUE F-DMI link > + @retval FALSE Not an F-DMI link > +**/ > +BOOLEAN > +IsPchWithFdmi ( > + VOID > + ) > +{ > + return FALSE; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/Pc > hPcieRpLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/Pc > hPcieRpLib.c > new file mode 100644 > index 0000000000..9997c3612b > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcieRpLib/Pc > hPcieRpLib.c > @@ -0,0 +1,183 @@ > +/** @file > + PCH PCIE root port library. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + 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 > + > +GLOBAL_REMOVE_IF_UNREFERENCED CONST PCH_PCIE_CONTROLLER_INFO > mPchPcieControllerInfo[] =3D { > + { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, PID_SPA, 0 }, > + { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_1, PID_SPB, 4 }, > + { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, PID_SPC, 8 }, > + { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_2, PID_SPD, 12 }, > + { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, PID_SPE, 16 }, // PCH-H only > + { PCI_DEVICE_NUMBER_PCH_PCIE_DEVICE_3, PID_SPF, 20 } // PCH-H only > +}; > +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 > mPchPcieControllerInfoSize =3D sizeof (mPchPcieControllerInfo) / sizeof > (mPchPcieControllerInfo[0]); > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 > mPchLpRstPcieStorageSupportedPort[] =3D { > + RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, > RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, // > RP1..RP4 > + RST_PCIE_STORAGE_CR_1, RST_PCIE_STORAGE_CR_1, > RST_PCIE_STORAGE_CR_1, RST_PCIE_STORAGE_CR_1, // RP5..RP8 > + RST_PCIE_STORAGE_CR_2, RST_PCIE_STORAGE_CR_2, > RST_PCIE_STORAGE_CR_2, RST_PCIE_STORAGE_CR_2, // RP9..RP12 > + RST_PCIE_STORAGE_CR_3, RST_PCIE_STORAGE_CR_3, > RST_PCIE_STORAGE_CR_3, RST_PCIE_STORAGE_CR_3 // > RP13..RP16 > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 > mPchHRstPcieStorageSupportedPort[] =3D { > + RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, > RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, // > RP1..RP4 > + RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, > RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, // > RP5..RP8 > + RST_PCIE_STORAGE_CR_1, RST_PCIE_STORAGE_CR_1, > RST_PCIE_STORAGE_CR_1, RST_PCIE_STORAGE_CR_1, // RP9..RP12 > + RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, > RST_PCIE_STORAGE_CR_INVALID, RST_PCIE_STORAGE_CR_INVALID, // > RP13..RP16 > + RST_PCIE_STORAGE_CR_3, RST_PCIE_STORAGE_CR_3, > RST_PCIE_STORAGE_CR_3, RST_PCIE_STORAGE_CR_3, // > RP17..RP20 > + RST_PCIE_STORAGE_CR_2, RST_PCIE_STORAGE_CR_2, > RST_PCIE_STORAGE_CR_2, RST_PCIE_STORAGE_CR_2 // > RP21..RP24 > +}; > + > +/** > + Get Pch Pcie Root Port Device and Function Number by Root Port physica= l > Number > + > + @param[in] RpNumber Root port physical number. (0-based) > + @param[out] RpDev Return corresponding root port devic= e > number. > + @param[out] RpFun Return corresponding root port funct= ion > number. > + > + @retval EFI_SUCCESS Root port device and function is ret= rieved > + @retval EFI_INVALID_PARAMETER RpNumber is invalid > +**/ > +EFI_STATUS > +EFIAPI > +GetPchPcieRpDevFun ( > + IN UINTN RpNumber, > + OUT UINTN *RpDev, > + OUT UINTN *RpFun > + ) > +{ > + UINTN Index; > + UINTN FuncIndex; > + UINT32 PciePcd; > + > + if (RpNumber >=3D GetPchMaxPciePortNum ()) { > + DEBUG ((DEBUG_ERROR, "GetPchPcieRpDevFun invalid RpNumber %x", > RpNumber)); > + ASSERT (FALSE); > + return EFI_INVALID_PARAMETER; > + } > + > + Index =3D RpNumber / PCH_PCIE_CONTROLLER_PORTS; > + FuncIndex =3D RpNumber - mPchPcieControllerInfo[Index].RpNumBase; > + *RpDev =3D mPchPcieControllerInfo[Index].DevNum; > + PciePcd =3D PchPcrRead32 (mPchPcieControllerInfo[Index].Pid, > R_SPX_PCR_PCD); > + *RpFun =3D (PciePcd >> (FuncIndex * S_SPX_PCR_PCD_RP_FIELD)) & > B_SPX_PCR_PCD_RP1FN; > + > + return EFI_SUCCESS; > +} > + > +/** > + Get Root Port physical Number by Pch Pcie Root Port Device and Functio= n > Number > + > + @param[in] RpDev Root port device number. > + @param[in] RpFun Root port function number. > + @param[out] RpNumber Return corresponding physical Root > Port index (0-based) > + > + @retval EFI_SUCCESS Physical root port is retrieved > +**/ > +EFI_STATUS > +EFIAPI > +GetPchPcieRpNumber ( > + IN UINTN RpDev, > + IN UINTN RpFun, > + OUT UINTN *RpNumber > + ) > +{ > + UINT64 RpBase; > + > + RpBase =3D PCI_SEGMENT_LIB_ADDRESS > (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, > RpDev, RpFun, 0); > + *RpNumber =3D (PciSegmentRead32 (RpBase + R_PCH_PCIE_CFG_LCAP) >> > N_PCH_PCIE_CFG_LCAP_PN) -1; > + return EFI_SUCCESS; > +} > + > +/** > + Gets pci segment base address of PCIe root port. > + > + @param RpIndex Root Port Index (0 based) > + @return PCIe port base address. > +**/ > +UINT64 > +PchPcieBase ( > + IN UINT32 RpIndex > + ) > +{ > + UINTN RpDevice; > + UINTN RpFunction; > + > + GetPchPcieRpDevFun (RpIndex, &RpDevice, &RpFunction); > + > + return PCI_SEGMENT_LIB_ADDRESS > (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, > (UINT32) RpDevice, (UINT32) RpFunction, 0); > +} > + > +/** > + Determines whether L0s is supported on current stepping. > + > + @return TRUE if L0s is supported, FALSE otherwise > +**/ > +BOOLEAN > +PchIsPcieL0sSupported ( > + VOID > + ) > +{ > + return TRUE; > +} > + > +/** > + Some early PCH steppings require Native ASPM to be disabled due to > hardware issues: > + - RxL0s exit causes recovery > + - Disabling PCIe L0s capability disables L1 > + Use this function to determine affected steppings. > + > + @return TRUE if Native ASPM is supported, FALSE otherwise > +**/ > +BOOLEAN > +PchIsPcieNativeAspmSupported ( > + VOID > + ) > +{ > + return PchIsPcieL0sSupported (); > +} > + > +/** > + Check the RST PCIe Storage Cycle Router number according to the root p= ort > number and PCH type > + > + @param[in] RootPortNum Root Port Number > + > + @return The RST PCIe Storage Cycle Router Number > +**/ > +UINT8 > +RstGetCycleRouterNumber ( > + IN UINT32 RootPortNum > + ) > +{ > + if (IsPchLp ()) { > + if (RootPortNum < ARRAY_SIZE (mPchLpRstPcieStorageSupportedPort)) { > + return mPchLpRstPcieStorageSupportedPort[RootPortNum]; > + } > + } else if (IsPchH ()) { > + if (RootPortNum < ARRAY_SIZE (mPchHRstPcieStorageSupportedPort)) { > + return mPchHRstPcieStorageSupportedPort[RootPortNum]; > + } > + } > + return RST_PCIE_STORAGE_CR_INVALID; > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPc > rLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPc > rLib.c > new file mode 100644 > index 0000000000..6f70733fe7 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPcrLib/PchPc > rLib.c > @@ -0,0 +1,279 @@ > +/** @file > + PCH PCR library. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#ifndef MDEPKG_NDEBUG > +/** > + Checks if the offset is valid for a given memory access width > + > + @param[in] Offset Offset of a register > + @param[in] Size Size of memory access in bytes > + > + @retval FALSE Offset is not valid for a given memory access > + @retval TRUE Offset is valid > +**/ > +STATIC > +BOOLEAN > +PchIsPcrOffsetValid ( > + IN UINT32 Offset, > + IN UINTN Size > + ) > +{ > + if (((Offset & (Size - 1)) !=3D 0) || (Offset > 0xFFFF)) { > + DEBUG ((DEBUG_ERROR, "PCR offset error. Invalid Offset: %x Size: %x"= , > Offset, Size)); > + return FALSE; > + } else { > + return TRUE; > + } > +} > +#endif > + > +/** > + Read PCR register. > + It returns PCR register and size in 4bytes. > + The Offset should not exceed 0xFFFF and must be aligned with size. > + > + @param[in] Pid Port ID > + @param[in] Offset Register offset of this Port ID > + > + @retval UINT32 PCR register value. > +**/ > +UINT32 > +PchPcrRead32 ( > + IN PCH_SBI_PID Pid, > + IN UINT32 Offset > + ) > +{ > +#ifndef MDEPKG_NDEBUG > + ASSERT (PchIsPcrOffsetValid (Offset, 4)); > +#endif > + return MmioRead32 (PCH_PCR_ADDRESS (Pid, Offset)); > +} > + > +/** > + Read PCR register. > + It returns PCR register and size in 2bytes. > + The Offset should not exceed 0xFFFF and must be aligned with size. > + > + @param[in] Pid Port ID > + @param[in] Offset Register offset of this Port ID > + > + @retval UINT16 PCR register value. > +**/ > +UINT16 > +PchPcrRead16 ( > + IN PCH_SBI_PID Pid, > + IN UINT32 Offset > + ) > +{ > +#ifndef MDEPKG_NDEBUG > + ASSERT (PchIsPcrOffsetValid (Offset, 2)); > +#endif > + return MmioRead16 (PCH_PCR_ADDRESS (Pid, Offset)); > +} > + > +/** > + Read PCR register. > + It returns PCR register and size in 1bytes. > + The Offset should not exceed 0xFFFF and must be aligned with size. > + > + @param[in] Pid Port ID > + @param[in] Offset Register offset of this Port ID > + > + @retval UINT8 PCR register value > +**/ > +UINT8 > +PchPcrRead8 ( > + IN PCH_SBI_PID Pid, > + IN UINT32 Offset > + ) > +{ > + return MmioRead8 (PCH_PCR_ADDRESS (Pid, Offset)); > +} > + > +/** > + Write PCR register. > + It programs PCR register and size in 4bytes. > + The Offset should not exceed 0xFFFF and must be aligned with size. > + > + @param[in] Pid Port ID > + @param[in] Offset Register offset of Port ID. > + @param[in] Data Input Data. Must be the same size as Size paramet= er. > + > + @retval UINT32 Value written to register > +**/ > +UINT32 > +PchPcrWrite32 ( > + IN PCH_SBI_PID Pid, > + IN UINT32 Offset, > + IN UINT32 Data > + ) > +{ > +#ifndef MDEPKG_NDEBUG > + ASSERT (PchIsPcrOffsetValid (Offset, 4)); > +#endif > + MmioWrite32 (PCH_PCR_ADDRESS (Pid, Offset), Data); > + > + return Data; > +} > + > +/** > + Write PCR register. > + It programs PCR register and size in 2bytes. > + The Offset should not exceed 0xFFFF and must be aligned with size. > + > + @param[in] Pid Port ID > + @param[in] Offset Register offset of Port ID. > + @param[in] Data Input Data. Must be the same size as Size paramet= er. > + > + @retval UINT16 Value written to register > +**/ > +UINT16 > +PchPcrWrite16 ( > + IN PCH_SBI_PID Pid, > + IN UINT32 Offset, > + IN UINT16 Data > + ) > +{ > +#ifndef MDEPKG_NDEBUG > + ASSERT (PchIsPcrOffsetValid (Offset, 2)); > +#endif > + MmioWrite16 (PCH_PCR_ADDRESS (Pid, Offset), Data); > + > + return Data; > +} > + > +/** > + Write PCR register. > + It programs PCR register and size in 1bytes. > + The Offset should not exceed 0xFFFF and must be aligned with size. > + > + @param[in] Pid Port ID > + @param[in] Offset Register offset of Port ID. > + @param[in] Data Input Data. Must be the same size as Size paramet= er. > + > + @retval UINT8 Value written to register > +**/ > +UINT8 > +PchPcrWrite8 ( > + IN PCH_SBI_PID Pid, > + IN UINT32 Offset, > + IN UINT8 Data > + ) > +{ > + MmioWrite8 (PCH_PCR_ADDRESS (Pid, Offset), Data); > + > + return Data; > +} > + > +/** > + Write PCR register. > + It programs PCR register and size in 4bytes. > + The Offset should not exceed 0xFFFF and must be aligned with size. > + > + @param[in] Pid Port ID > + @param[in] Offset Register offset of Port ID. > + @param[in] AndData AND Data. Must be the same size as Size parameter= . > + @param[in] OrData OR Data. Must be the same size as Size parameter. > + > + @retval UINT32 Value written to register > + > +**/ > +UINT32 > +PchPcrAndThenOr32 ( > + IN PCH_SBI_PID Pid, > + IN UINT32 Offset, > + IN UINT32 AndData, > + IN UINT32 OrData > + ) > +{ > + return PchPcrWrite32 (Pid, Offset, (PchPcrRead32 (Pid, Offset) & AndDa= ta) | > OrData); > +} > + > +/** > + Write PCR register and read back. > + The read back ensures the PCR cycle is completed before next operation= . > + It programs PCR register and size in 4bytes. > + The Offset should not exceed 0xFFFF and must be aligned with size. > + > + @param[in] Pid Port ID > + @param[in] Offset Register offset of Port ID. > + @param[in] AndData AND Data. Must be the same size as Size parameter= . > + @param[in] OrData OR Data. Must be the same size as Size parameter. > + > + @retval UINT32 Value read back from the register > +**/ > +UINT32 > +PchPcrAndThenOr32WithReadback ( > + IN PCH_SBI_PID Pid, > + IN UINT32 Offset, > + IN UINT32 AndData, > + IN UINT32 OrData > + ) > +{ > + PchPcrWrite32 (Pid, Offset, (PchPcrRead32 (Pid, Offset) & AndData) | > OrData); > + return PchPcrRead32 (Pid, Offset); > +} > + > +/** > + Write PCR register. > + It programs PCR register and size in 2bytes. > + The Offset should not exceed 0xFFFF and must be aligned with size. > + > + @param[in] Pid Port ID > + @param[in] Offset Register offset of Port ID. > + @param[in] AndData AND Data. Must be the same size as Size parameter= . > + @param[in] OrData OR Data. Must be the same size as Size parameter. > + > + @retval UINT16 Value written to register > + > +**/ > +UINT16 > +PchPcrAndThenOr16 ( > + IN PCH_SBI_PID Pid, > + IN UINT32 Offset, > + IN UINT16 AndData, > + IN UINT16 OrData > + ) > +{ > + return PchPcrWrite16 (Pid, Offset, (PchPcrRead16 (Pid, Offset) & AndDa= ta) | > OrData); > +} > + > +/** > + Write PCR register. > + It programs PCR register and size in 1bytes. > + The Offset should not exceed 0xFFFF and must be aligned with size. > + > + @param[in] Pid Port ID > + @param[in] Offset Register offset of Port ID. > + @param[in] AndData AND Data. Must be the same size as Size parameter= . > + @param[in] OrData OR Data. Must be the same size as Size parameter. > + > + @retval UINT8 Value written to register > + > +**/ > +UINT8 > +PchPcrAndThenOr8 ( > + IN PCH_SBI_PID Pid, > + IN UINT32 Offset, > + IN UINT8 AndData, > + IN UINT8 OrData > + ) > +{ > + return PchPcrWrite8 (Pid, Offset, (PchPcrRead8 (Pid, Offset) & AndData= ) | > OrData); > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchP > mcLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchP > mcLib.c > new file mode 100644 > index 0000000000..2654a76983 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchPmcLib/PchP > mcLib.c > @@ -0,0 +1,101 @@ > +/** @file > + PCH PMC Library. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** > + Query PCH to determine the Pm Status > + NOTE: > + It's matter when did platform code use this library, since some status= could > be cleared by write one clear. > + Therefore this funciton is not always return the same result in one bo= ot. > + It's suggested that platform code read this status in the beginning of= post. > + For the ColdBoot case, this function only returns one case of the cold= boot. > Some cold boot case might > + depends on the power cycle scenario and should check with different > condtion. > + > + @param[in] PmStatus - The Pch Pm Status to be probed > + > + @retval Return TRUE if Status querried is Valid or FALSE if otherwise > +**/ > +BOOLEAN > +GetPchPmStatus ( > + PCH_PM_STATUS PmStatus > + ) > +{ > + UINTN PmcRegBase; > + UINT32 GblRst0; > + > + PmcRegBase =3D MmPciBase ( > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_PMC, > + PCI_FUNCTION_NUMBER_PCH_PMC > + ); > + > + switch (PmStatus) { > + case WarmBoot: > + break; > + > + case PwrFlr: > + break; > + > + case PwrFlrSys: > + if (GblRst0 & BIT12) { > + return TRUE; > + } > + break; > + > + case PwrFlrPch: > + if (GblRst0 & BIT11) { > + return TRUE; > + } > + break; > + > + case ColdBoot: > + break; > + > + default: > + break; > + } > + > + return FALSE; > +} > + > +/** > + Funtion to check if Battery lost or CMOS cleared. > + > + @reval TRUE Battery is always present. > + @reval FALSE CMOS is cleared. > +**/ > +BOOLEAN > +EFIAPI > +PchIsRtcBatteryGood ( > + VOID > + ) > +{ > + UINTN PmcBaseAddress; > + > + // > + // Check if the CMOS battery is present > + // Checks RTC_PWR_STS bit in the GEN_PMCON_3 register > + // > + PmcBaseAddress =3D MmPciBase ( > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_PMC, > + PCI_FUNCTION_NUMBER_PCH_PMC > + ); > + return FALSE; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib > /PchSbiAccessLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib > /PchSbiAccessLib.c > new file mode 100644 > index 0000000000..43690e2409 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSbiAccessLib > /PchSbiAccessLib.c > @@ -0,0 +1,270 @@ > +/** @file > + PCH SBI access 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 > +#include > + > +/** > + Execute PCH SBI message > + Take care of that there is no lock protection when using SBI programmi= ng in > both POST time and SMI. > + It will clash with POST time SBI programming when SMI happen. > + Programmer MUST do the save and restore opration while using the > PchSbiExecution inside SMI > + to prevent from racing condition. > + This function will reveal P2SB and hide P2SB if it's originally hidden= . If more > than one SBI access > + needed, it's better to unhide the P2SB before calling and hide it back= after > done. > + > + When the return value is "EFI_SUCCESS", the "Response" do not need to = be > checked as it would have been > + SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this woul= d > provide additional information > + when needed. > + > + @param[in] Pid Port ID of the SBI message > + @param[in] Offset Offset of the SBI message > + @param[in] Opcode Opcode > + @param[in] Posted Posted message > + @param[in, out] Data32 Read/Write data > + @param[out] Response Response > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_DEVICE_ERROR Transaction fail > + @retval EFI_INVALID_PARAMETER Invalid parameter > + @retval EFI_TIMEOUT Timeout while waiting for respon= se > +**/ > +EFI_STATUS > +EFIAPI > +PchSbiExecution ( > + IN PCH_SBI_PID Pid, > + IN UINT64 Offset, > + IN PCH_SBI_OPCODE Opcode, > + IN BOOLEAN Posted, > + IN OUT UINT32 *Data32, > + OUT UINT8 *Response > + ) > +{ > + // > + // Check address valid > + // > + if (((UINT32) Offset & 0x3) !=3D 0) { > + // > + // Warning message for the address not DWORD alignment. > + // > + DEBUG ((DEBUG_INFO, "PchSbiExecution: Address is not DWORD > aligned.\n")); > + } > + > + return PchSbiExecutionEx ( Pid, > + Offset, > + Opcode, > + Posted, > + 0x000F, > + 0x0000, > + 0x0000, > + Data32, > + Response > + ); > +} > + > +/** > + Full function for executing PCH SBI message > + Take care of that there is no lock protection when using SBI programmi= ng in > both POST time and SMI. > + It will clash with POST time SBI programming when SMI happen. > + Programmer MUST do the save and restore opration while using the > PchSbiExecution inside SMI > + to prevent from racing condition. > + This function will reveal P2SB and hide P2SB if it's originally hidden= . If more > than one SBI access > + needed, it's better to unhide the P2SB before calling and hide it back= after > done. > + > + When the return value is "EFI_SUCCESS", the "Response" do not need to = be > checked as it would have been > + SBI_SUCCESS. If the return value is "EFI_DEVICE_ERROR", then this woul= d > provide additional information > + when needed. > + > + @param[in] Pid Port ID of the SBI message > + @param[in] Offset Offset of the SBI message > + @param[in] Opcode Opcode > + @param[in] Posted Posted message > + @param[in] Fbe First byte enable > + @param[in] Bar Bar > + @param[in] Fid Function ID > + @param[in, out] Data32 Read/Write data > + @param[out] Response Response > + > + @retval EFI_SUCCESS Successfully completed. > + @retval EFI_DEVICE_ERROR Transaction fail > + @retval EFI_INVALID_PARAMETER Invalid parameter > + @retval EFI_TIMEOUT Timeout while waiting for respon= se > +**/ > +EFI_STATUS > +EFIAPI > +PchSbiExecutionEx ( > + IN PCH_SBI_PID Pid, > + IN UINT64 Offset, > + IN PCH_SBI_OPCODE Opcode, > + IN BOOLEAN Posted, > + IN UINT16 Fbe, > + IN UINT16 Bar, > + IN UINT16 Fid, > + IN OUT UINT32 *Data32, > + OUT UINT8 *Response > + ) > +{ > + UINT64 P2sbBase; > + UINTN Timeout; > + UINT16 SbiStat; > + > + // > + // Check opcode valid > + // > + switch (Opcode) { > + case MemoryRead: > + case MemoryWrite: > + case PciConfigRead: > + case PciConfigWrite: > + case PrivateControlRead: > + case PrivateControlWrite: > + case GpioLockUnlock: > + break; > + default: > + return EFI_INVALID_PARAMETER; > + break; > + } > + > + P2sbBase =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_P2SB, > + PCI_FUNCTION_NUMBER_PCH_P2SB, > + 0 > + ); > + if (PciSegmentRead16 (P2sbBase + PCI_VENDOR_ID_OFFSET) =3D=3D 0xFFFF) = { > + ASSERT (FALSE); > + return EFI_DEVICE_ERROR; > + } > + /// > + /// BWG Section 2.2.1 > + /// 1. Poll P2SB PCI offset D8h[0] =3D 0b > + /// Make sure the previous opeartion is completed. > + /// > + Timeout =3D 0xFFFFFFF; > + while (Timeout > 0) { > + SbiStat =3D PciSegmentRead16 (P2sbBase + R_P2SB_CFG_SBISTAT); > + if ((SbiStat & B_P2SB_CFG_SBISTAT_INITRDY) =3D=3D 0) { > + break; > + } > + Timeout--; > + } > + if (Timeout =3D=3D 0) { > + return EFI_TIMEOUT; > + } > + // > + // Initial Response status > + // > + *Response =3D SBI_INVALID_RESPONSE; > + SbiStat =3D 0; > + /// > + /// 2. Write P2SB PCI offset D0h[31:0] with Address and Destination Po= rt ID > + /// > + PciSegmentWrite32 (P2sbBase + R_P2SB_CFG_SBIADDR, (UINT32) ((Pid << 24= ) > | (UINT16) Offset)); > + /// > + /// 3. Write P2SB PCI offset DCh[31:0] with extended address, which is > expected to be 0 in PCH. > + /// > + PciSegmentWrite32 (P2sbBase + R_P2SB_CFG_SBIEXTADDR, (UINT32) > RShiftU64 (Offset, 16)); > + /// > + /// 5. Set P2SB PCI offset D8h[15:8] =3D 00000110b for read > + /// Set P2SB PCI offset D8h[15:8] =3D 00000111b for write > + // > + // Set SBISTAT[15:8] to the opcode passed in > + // Set SBISTAT[7] to the posted passed in > + // > + PciSegmentAndThenOr16 ( > + (P2sbBase + R_P2SB_CFG_SBISTAT), > + (UINT16) ~(B_P2SB_CFG_SBISTAT_OPCODE | > B_P2SB_CFG_SBISTAT_POSTED), > + (UINT16) ((Opcode << 8) | (Posted << 7)) > + ); > + /// > + /// 6. Write P2SB PCI offset DAh[15:0] =3D F000h > + /// > + // > + // Set RID[15:0] =3D Fbe << 12 | Bar << 8 | Fid > + // > + PciSegmentWrite16 ( > + (P2sbBase + R_P2SB_CFG_SBIRID), > + (((Fbe & 0x000F) << 12) | ((Bar & 0x0007) << 8) | (Fid & 0x00FF)) > + ); > + > + switch (Opcode) { > + case MemoryWrite: > + case PciConfigWrite: > + case PrivateControlWrite: > + case GpioLockUnlock: > + /// > + /// 4. Write P2SB PCI offset D4h[31:0] with the intended data acco= rdingly > + /// > + PciSegmentWrite32 ((P2sbBase + R_P2SB_CFG_SBIDATA), *Data32); > + break; > + default: > + /// > + /// 4. Write P2SB PCI offset D4h[31:0] with dummy data such as 0, > + /// because all D0-DFh register range must be touched in PCH > + /// for a successful SBI transaction. > + /// > + PciSegmentWrite32 ((P2sbBase + R_P2SB_CFG_SBIDATA), 0); > + break; > + } > + /// > + /// 7. Set P2SB PCI offset D8h[0] =3D 1b, Poll P2SB PCI offset D8h[0] = =3D 0b > + /// > + // > + // Set SBISTAT[0] =3D 1b, trigger the SBI operation > + // > + PciSegmentOr16 (P2sbBase + R_P2SB_CFG_SBISTAT, (UINT16) > B_P2SB_CFG_SBISTAT_INITRDY); > + // > + // Poll SBISTAT[0] =3D 0b, Polling for Busy bit > + // > + Timeout =3D 0xFFFFFFF; > + while (Timeout > 0) { > + SbiStat =3D PciSegmentRead16 (P2sbBase + R_P2SB_CFG_SBISTAT); > + if ((SbiStat & B_P2SB_CFG_SBISTAT_INITRDY) =3D=3D 0) { > + break; > + } > + Timeout--; > + } > + if (Timeout =3D=3D 0) { > + // > + // If timeout, it's fatal error. > + // > + return EFI_TIMEOUT; > + } else { > + /// > + /// 8. Check if P2SB PCI offset D8h[2:1] =3D 00b for successful tran= saction > + /// > + *Response =3D (UINT8) ((SbiStat & B_P2SB_CFG_SBISTAT_RESPONSE) >> > N_P2SB_CFG_SBISTAT_RESPONSE); > + if (*Response =3D=3D SBI_SUCCESSFUL) { > + switch (Opcode) { > + case MemoryRead: > + case PciConfigRead: > + case PrivateControlRead: > + /// > + /// 9. Read P2SB PCI offset D4h[31:0] for SBI data > + /// > + *Data32 =3D PciSegmentRead32 (P2sbBase + R_P2SB_CFG_SBIDATA); > + break; > + default: > + break; > + } > + return EFI_SUCCESS; > + } else { > + return EFI_DEVICE_ERROR; > + } > + } > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/= P > chSerialIoLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/= P > chSerialIoLib.c > new file mode 100644 > index 0000000000..0e79d83a12 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/= P > chSerialIoLib.c > @@ -0,0 +1,516 @@ > +/** @file > + PCH Serial IO Lib implementation. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + 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 > +#include > +#include > + > +#define PCIEX_BAR_ADDR_MASK 0x0000007FFC000000 > + > +typedef struct { > + UINT32 Bar0; > + UINT32 Bar1; > +} SERIAL_IO_CONTROLLER_DESCRIPTOR; > + > +GLOBAL_REMOVE_IF_UNREFERENCED SERIAL_IO_CONTROLLER_DESCRIPTOR > mSerialIoAcpiAddress [PCH_MAX_SERIALIO_CONTROLLERS] =3D > +{ > + {PCH_SERIAL_IO_BASE_ADDRESS + 0x0000, > PCH_SERIAL_IO_BASE_ADDRESS + 0x1000}, > + {PCH_SERIAL_IO_BASE_ADDRESS + 0x2000, > PCH_SERIAL_IO_BASE_ADDRESS + 0x3000}, > + {PCH_SERIAL_IO_BASE_ADDRESS + 0x4000, > PCH_SERIAL_IO_BASE_ADDRESS + 0x5000}, > + {PCH_SERIAL_IO_BASE_ADDRESS + 0x6000, > PCH_SERIAL_IO_BASE_ADDRESS + 0x7000}, > + {PCH_SERIAL_IO_BASE_ADDRESS + 0x8000, > PCH_SERIAL_IO_BASE_ADDRESS + 0x9000}, > + {PCH_SERIAL_IO_BASE_ADDRESS + 0xA000, > PCH_SERIAL_IO_BASE_ADDRESS + 0xB000}, > + {PCH_SERIAL_IO_BASE_ADDRESS + 0xC000, > PCH_SERIAL_IO_BASE_ADDRESS + 0xD000}, > + {PCH_SERIAL_IO_BASE_ADDRESS + 0xE000, > PCH_SERIAL_IO_BASE_ADDRESS + 0xF000}, > + {PCH_SERIAL_IO_BASE_ADDRESS + 0x10000, > PCH_SERIAL_IO_BASE_ADDRESS + 0x11000}, > + {PCH_SERIAL_IO_BASE_ADDRESS + 0x12000, > PCH_SERIAL_IO_BASE_ADDRESS + 0x13000}, > + {PCH_SERIAL_IO_BASE_ADDRESS + 0x14000, > PCH_SERIAL_IO_BASE_ADDRESS + 0x15000}, > + {PCH_SERIAL_IO_BASE_ADDRESS + 0x16000, > PCH_SERIAL_IO_BASE_ADDRESS + 0x17000} > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchSerialIoPciCfgCtrAddr > [PCH_MAX_SERIALIO_CONTROLLERS] =3D > +{ > + R_SERIAL_IO_PCR_PCICFGCTRL1, > + R_SERIAL_IO_PCR_PCICFGCTRL2, > + R_SERIAL_IO_PCR_PCICFGCTRL3, > + R_SERIAL_IO_PCR_PCICFGCTRL4, > + R_SERIAL_IO_PCR_PCICFGCTRL5, > + R_SERIAL_IO_PCR_PCICFGCTRL6, > + R_SERIAL_IO_PCR_PCICFGCTRL13, > + R_SERIAL_IO_PCR_PCICFGCTRL14, > + R_SERIAL_IO_PCR_PCICFGCTRL9, > + R_SERIAL_IO_PCR_PCICFGCTRL10, > + R_SERIAL_IO_PCR_PCICFGCTRL11 > +}; > + > +/** > + Returns Serial IO Controller Type I2C, SPI or UART > + > + @param[in] Number Number of SerialIo controller > + > + @retval I2C, SPI or UART > + @retval UNKNOWN - in case if undefined controller > +**/ > +PCH_SERIAL_IO_CONTROLLER_TYPE > +GetSerialIoControllerType ( > + IN PCH_SERIAL_IO_CONTROLLER Controller > + ) > +{ > + if (Controller >=3D PchSerialIoIndexI2C0 && Controller <=3D GetMaxI2cN= umber > ()) { > + return SERIAL_IO_I2C; > + } else if (Controller >=3D PchSerialIoIndexSpi0 && Controller < > (PchSerialIoIndexSpi0 + GetPchMaxSerialIoSpiControllersNum ())) { > + return SERIAL_IO_SPI; > + } else if (Controller >=3D PchSerialIoIndexUart0 && Controller <=3D > PchSerialIoIndexUart2) { > + return SERIAL_IO_UART; > + } > + return SERIAL_IO_UNKNOWN; > +} > + > +/** > + Checks if given Serial IO Controller Function equals 0 > + > + @param[in] SerialIoNumber Serial IO device > + > + @retval TRUE if SerialIO Function is equ= al to 0 > + FALSE if Function is higher then= 0 > +**/ > +BOOLEAN > +IsSerialIoFunctionZero ( > + IN PCH_SERIAL_IO_CONTROLLER SerialIoNumber > + ) > +{ > + if (GetSerialIoFunctionNumber (SerialIoNumber) > 0) { > + return FALSE; > + } > + return TRUE; > +} > + > +/** > + Checks if given Serial IO Controller is enabled or not > + > + @param[in] DeviceNumber device number > + @param[in] FunctionNumber function number > + > + @retval TRUE TRUE if given serial io device i= s enabled. > + @retval FALSE FALSE if given serial io device = is disabled. > +**/ > +BOOLEAN > +IsSerialIoDeviceEnabled ( > + IN UINT8 DeviceNumber, > + IN UINT8 FunctionNumber > + ) > +{ > + if (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS > (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, > DeviceNumber, FunctionNumber, PCI_DEVICE_ID_OFFSET)) !=3D 0xFFFF) { > + return TRUE; > + } > + return FALSE; > +} > + > +/** > + Checks if given device corresponds to any of LPSS Devices > + > + @param[in] DeviceNumber device number > + @param[in] FunctionNumber function number > + > + @retval TRUE if SerialIO Device/Function= Number is > equal to any of LPSS devices > + FALSE Device/Function is not in = Serial IO scope > +**/ > +BOOLEAN > +IsSerialIoDevice ( > + IN UINT8 DeviceNumber, > + IN UINT8 FunctionNumber > + ) > +{ > + PCH_SERIAL_IO_CONTROLLER Controller; > + PCH_SERIAL_IO_CONTROLLER ControllerMax; > + > + ControllerMax =3D GetPchMaxSerialIoControllersNum (); > + > + for (Controller =3D 0; Controller < ControllerMax; Controller++) { > + if ((DeviceNumber =3D=3D GetSerialIoDeviceNumber (Controller)) && > + (FunctionNumber =3D=3D GetSerialIoFunctionNumber (Controller))) = { > + return TRUE; > + } > + } > + return FALSE; > +} > + > +/** > + Gets Pci Config control offset > + > + @param[in] DeviceNumber device number > + @param[in] FunctionNumber function number > + > + @retval CfgCtrAddr Offset of Pci config control > + 0 if Device and Function do not = correspond to > Serial IO > +**/ > +UINT16 > +GetSerialIoConfigControlOffset ( > + IN UINT8 DeviceNumber, > + IN UINT8 FunctionNumber > + ) > +{ > + PCH_SERIAL_IO_CONTROLLER Controller; > + PCH_SERIAL_IO_CONTROLLER ControllerMax; > + > + ControllerMax =3D GetPchMaxSerialIoControllersNum (); > + > + for (Controller =3D 0; Controller < ControllerMax; Controller++) { > + if ((DeviceNumber =3D=3D GetSerialIoDeviceNumber (Controller)) && > + (FunctionNumber =3D=3D GetSerialIoFunctionNumber (Controller))) = { > + return mPchSerialIoPciCfgCtrAddr[Controller]; > + } > + } > + > + return 0; > +} > + > +/** > + Checks if Device with given AcpiHid string is one of SerialIo controll= ers > + If yes, its number is returned through Number parameter, otherwise > Number is not updated > + > + @param[in] AcpiHid String > + @param[out] Number Number of SerialIo controller > + > + @retval TRUE yes it is a SerialIo controller > + @retval FALSE no it isn't a SerialIo controlle= r > +**/ > +BOOLEAN > +IsSerialIoAcpiHid ( > + IN CHAR8 *AcpiHid, > + OUT PCH_SERIAL_IO_CONTROLLER *Number > + ) > +{ > + PCH_SERIAL_IO_CONTROLLER Controller; > + PCH_SERIAL_IO_CONTROLLER ControllerMax; > + > + ControllerMax =3D GetPchMaxSerialIoControllersNum (); > + > + for (Controller =3D 0; Controller < ControllerMax; Controller++) { > + if (!AsciiStrCmp ((const CHAR8 *) AcpiHid, GetSerialIoAcpiHid(Contro= ller))) > { > + *Number =3D Controller; > + return TRUE; > + } > + } > + return FALSE; > +} > + > +/** > + Finds BAR values of SerialIo devices. > + SerialIo devices can be configured to not appear on PCI so traditional > method of reading BAR might not work. > + If the SerialIo device is in PCI mode, a request for BAR1 will return = its PCI CFG > space instead > + > + @param[in] SerialIoDevice Serial IO device > + @param[in] BarNumber 0=3DBAR0, 1=3DBAR1 > + > + @retval SerialIo Bar value > +**/ > +UINTN > +FindSerialIoBar ( > + IN PCH_SERIAL_IO_CONTROLLER SerialIoDevice, > + IN UINT8 BarNumber > + ) > +{ > + UINT64 Bar; > + UINT64 PcieBase; > + UINT64 PciSegBase; > + UINT16 VenId; > + UINT32 Device; > + UINT32 Function; > + > + Device =3D GetSerialIoDeviceNumber (SerialIoDevice); > + Function =3D GetSerialIoFunctionNumber (SerialIoDevice); > + > + PcieBase =3D PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, > SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_PCIEXBAR)); // S0:B0:D0:F0:R60 > + PcieBase =3D (PcieBase & PCIEX_BAR_ADDR_MASK) + LShiftU64 > (DEFAULT_PCI_BUS_NUMBER_PCH, 20) + LShiftU64 (Device, 15) + LShiftU64 > (Function, 12); > + > + PciSegBase =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + Device, > + Function, > + 0 > + ); > + > + VenId =3D PciSegmentRead16 (PciSegBase + PCI_VENDOR_ID_OFFSET) & > 0xFFFF; > + if (VenId =3D=3D V_PCH_INTEL_VENDOR_ID) { > + if (BarNumber =3D=3D 1) { > + return ((UINTN) PcieBase); > + } > + Bar =3D PciSegmentRead32 (PciSegBase + PCI_BASE_ADDRESSREG_OFFSET); > + // For 64-Bit Memory Space BARs ((BAR[x] & 0xFFFFFFF0) + ((BAR[x+1] = & > 0xFFFFFFFF) << 32) > + if ((Bar & B_PCI_BAR_MEMORY_TYPE_MASK) =3D=3D > B_PCI_BAR_MEMORY_TYPE_64) { > + Bar =3D (Bar & 0xFFFFF000) + (UINTN) ((UINT64) LShiftU64 > ((PciSegmentRead32 (PciSegBase + PCI_BASE_ADDRESSREG_OFFSET + 4) & > 0xFFFFFFFF), 32)); > + return (UINTN) Bar; > + } > + return (UINTN) (Bar & 0xFFFFF000); > + } > + //PCI mode failed? Try hardcoded addresses from ACPI > + if (BarNumber =3D=3D 0) { > + Bar =3D mSerialIoAcpiAddress[SerialIoDevice].Bar0; > + } else { > + Bar =3D mSerialIoAcpiAddress[SerialIoDevice].Bar1; > + } > + return (UINTN) Bar; > +} > + > +/** > + Get PSF_PORT for a given Serial IO Controller > + > + @param[in] Controller Serial IO controller number > +**/ > +STATIC > +PSF_PORT > +SerialIoPsfPort ( > + IN PCH_SERIAL_IO_CONTROLLER Controller > + ) > +{ > + switch (GetSerialIoControllerType (Controller)) { > + case SERIAL_IO_I2C: > + return PsfSerialIoI2cPort (Controller - PchSerialIoIndexI2C0); > + case SERIAL_IO_SPI: > + return PsfSerialIoSpiPort (Controller - PchSerialIoIndexSpi0); > + case SERIAL_IO_UART: > + return PsfSerialIoUartPort (Controller - PchSerialIoIndexUart0); > + case SERIAL_IO_UNKNOWN: > + default: > + return (PSF_PORT){0}; > + } > +} > + > +/** > + Configures Serial IO Controller > + > + @param[in] Controller Serial IO controller number > + @param[in] DeviceMode Device operation mode > + @param[in] PsfDisable Disable device at PSF level > + > + @retval None > +**/ > +VOID > +ConfigureSerialIoController ( > + IN PCH_SERIAL_IO_CONTROLLER Controller, > + IN PCH_SERIAL_IO_MODE DeviceMode, > + IN BOOLEAN PsfDisable > + ) > +{ > + UINT64 PciCfgBase; > + UINT32 Data32And; > + UINT32 Data32Or; > + UINT16 *SerialIoPciCfgCtrAddr; > + UINT8 Uart8BitLoop; > + > +/* > + Please do not add DEBUG message here because this routine is configuri= ng > SerialIoUart. > + Printing DEBUG message before SerialIoUart initialization may cause sy= stem > hang (in Debug build). > +*/ > + > + // > + // This is to prevent from overflow of array access. > + // > + if (Controller >=3D PCH_MAX_SERIALIO_CONTROLLERS) { > + return; > + } > + > + if (GetSerialIoControllerType (Controller) =3D=3D SERIAL_IO_UNKNOWN) { > + return; > + } > + > + PciCfgBase =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + GetSerialIoDeviceNumber (Controller), > + GetSerialIoFunctionNumber (Controller), > + 0 > + ); > + // > + // Do not modify a device that has already been disabled/hidden > + // > + if (PciSegmentRead16 (PciCfgBase + PCI_VENDOR_ID_OFFSET) !=3D > V_PCH_INTEL_VENDOR_ID) { > + return; > + } > + > + /// > + /// Step 0. set Bit 16,17,18. > + /// > + PciSegmentOr32 (PciCfgBase + R_SERIAL_IO_CFG_D0I3MAXDEVPG, BIT18 | > BIT17 | BIT16); > + > + SerialIoPciCfgCtrAddr =3D mPchSerialIoPciCfgCtrAddr; > + > + switch (DeviceMode) { > + case PchSerialIoDisabled: > + /// > + /// Step 1. Put device in D3 > + /// Step 2. Function Disable in PSF > + /// > + PciSegmentOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, BIT1 | > BIT0); > + > + if (PsfDisable) { > + PsfDisableDevice (SerialIoPsfPort (Controller)); > + } > + break; > + case PchSerialIoAcpi: > + case PchSerialIoHidden: > + /// > + /// reenable BAR1 in case it was disabled earlier > + /// Read back is needed to enforce the sideband and primary orderi= ng. > + /// > + PchPcrAndThenOr32WithReadback ( > + PID_SERIALIO, > + SerialIoPciCfgCtrAddr[Controller], > + (UINT32) ~(B_SERIAL_IO_PCR_PCICFGCTRL_BAR1_DIS), > + 0 > + ); > + PsfEnableDeviceBar (SerialIoPsfPort (Controller), BIT3 | BIT2); > + /// > + /// Step 1. Assign BAR0 > + /// Step 2. Assign BAR1 > + /// > + PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW, > mSerialIoAcpiAddress[Controller].Bar0); > + PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0x0); > + PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR1_LOW, > mSerialIoAcpiAddress[Controller].Bar1); > + PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR1_HIGH, 0x0); > + /// > + /// Step 3. Set Memory space Enable > + /// > + PciSegmentOr32 (PciCfgBase + PCI_COMMAND_OFFSET, > EFI_PCI_COMMAND_MEMORY_SPACE); > + /// > + /// Step 4. Disable device's PciCfg and enable ACPI interrupts > + /// Read back is needed to enforce the sideband and primar= y > ordering. > + /// > + PchPcrAndThenOr32WithReadback ( > + PID_SERIALIO, > + SerialIoPciCfgCtrAddr[Controller], > + ~0u, > + (B_SERIAL_IO_PCR_PCICFGCTRL_PCI_CFG_DIS | > B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_INTR_EN) > + ); > + /// > + /// Step 5. Disable device's PciCfg in PSF > + /// > + PsfHideDevice (SerialIoPsfPort (Controller)); > + /// > + /// get controller out of reset > + /// > + MmioOr32 ( > + mSerialIoAcpiAddress[Controller].Bar0 + > R_SERIAL_IO_MEM_PPR_RESETS, > + B_SERIAL_IO_MEM_PPR_RESETS_FUNC | > B_SERIAL_IO_MEM_PPR_RESETS_APB | > B_SERIAL_IO_MEM_PPR_RESETS_IDMA > + ); > + break; > + case PchSerialIoPci: > + // > + // Check If device is already initialized > + // > + if (PciSegmentRead32 (PciCfgBase + PCI_BASE_ADDRESSREG_OFFSET) & > 0xFFFFF000) { > + return; > + } > + /// > + /// reenable PciCfg in case it was disabled earlier > + /// Read back is needed to enforce the sideband and primary orderi= ng. > + /// > + PchPcrAndThenOr32WithReadback ( > + PID_SERIALIO, > + SerialIoPciCfgCtrAddr[Controller], > + (UINT32) ~(B_SERIAL_IO_PCR_PCICFGCTRL_PCI_CFG_DIS | > B_SERIAL_IO_PCR_PCICFGCTRL_ACPI_INTR_EN), > + 0 > + ); > + PsfUnhideDevice (SerialIoPsfPort (Controller)); > + /// > + /// Disable Bar1 > + /// Disable Bar1 in PSF > + /// Read back is needed to enforce the sideband and primary orderi= ng. > + /// > + PchPcrAndThenOr32WithReadback ( > + PID_SERIALIO, > + SerialIoPciCfgCtrAddr[Controller], > + ~0u, > + B_SERIAL_IO_PCR_PCICFGCTRL_BAR1_DIS > + ); > + PsfDisableDeviceBar (SerialIoPsfPort (Controller), BIT3 | BIT2); > + > + // > + // Assign BAR0 and Set Memory space Enable > + // > + PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW, > mSerialIoAcpiAddress[Controller].Bar0); > + PciSegmentWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0x0); > + PciSegmentOr32 (PciCfgBase + PCI_COMMAND_OFFSET, > EFI_PCI_COMMAND_MEMORY_SPACE); > + /// > + /// get controller out of reset > + /// > + MmioOr32 ( > + mSerialIoAcpiAddress[Controller].Bar0 + > R_SERIAL_IO_MEM_PPR_RESETS, > + B_SERIAL_IO_MEM_PPR_RESETS_FUNC | > B_SERIAL_IO_MEM_PPR_RESETS_APB | > B_SERIAL_IO_MEM_PPR_RESETS_IDMA > + ); > + break; > + default: > + return; > + } > + > + /// > + /// Step X. Program clock dividers for UARTs > + /// Step Y. Enable Byte addressing for UARTs in legacy mode > + /// > + if ((Controller >=3D PchSerialIoIndexUart0 && Controller <=3D > PchSerialIoIndexUart2) && (DeviceMode !=3D PchSerialIoDisabled)) { > + MmioWrite32 (mSerialIoAcpiAddress[Controller].Bar0 + > R_SERIAL_IO_MEM_PPR_CLK, > + (B_SERIAL_IO_MEM_PPR_CLK_UPDATE | > (V_SERIAL_IO_MEM_PPR_CLK_N_DIV << 16) | > + (V_SERIAL_IO_MEM_PPR_CLK_M_DIV << 1) | > B_SERIAL_IO_MEM_PPR_CLK_EN ) > + ); > + > + Data32And =3D (UINT32) > (~(B_SERIAL_IO_PCR_GPPRVRW7_UART0_BYTE_ADDR_EN << (Controller - > PchSerialIoIndexUart0))); > + Data32Or =3D 0x0; > + if (DeviceMode =3D=3D PchSerialIoHidden) { > + Data32Or =3D (B_SERIAL_IO_PCR_GPPRVRW7_UART0_BYTE_ADDR_EN << > (Controller - PchSerialIoIndexUart0)); > + } > + PchPcrAndThenOr32 (PID_SERIALIO, > R_SERIAL_IO_PCR_GPPRVRW7,Data32And,Data32Or); > + // > + // Dummy read after setting any of GPPRVRW7. > + // Required for UART 16550 8-bit Legacy mode to become active > + // > + MmioRead32 (mSerialIoAcpiAddress[Controller].Bar0 + > R_SERIAL_IO_MEM_PPR_CLK); > + // > + // Loop until Uart has successfuly moved to 8 bit mode > + // > + if (DeviceMode =3D=3D PchSerialIoHidden) { > + Uart8BitLoop =3D 10; > + while (Uart8BitLoop > 0) { > + if (DetectAccessMode (mSerialIoAcpiAddress[Controller].Bar0) =3D= =3D > AccessMode8bit) { > + return; > + } > + Uart8BitLoop--; > + } > + } > + } > + > + /// > + /// Step Z. Program I2C SDA hold registers > + /// > + if (Controller >=3D PchSerialIoIndexI2C0 && Controller <=3D GetMaxI2cN= umber > ()) { > + if (DeviceMode !=3D PchSerialIoDisabled) { > + MmioOr32 (mSerialIoAcpiAddress[Controller].Bar0 + > R_SERIAL_IO_MEM_I2C_SDA_HOLD, > V_SERIAL_IO_MEM_I2C_SDA_HOLD_VALUE); > + } > + } > + > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/= P > chSerialIoLibCnl.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/= P > chSerialIoLibCnl.c > new file mode 100644 > index 0000000000..28ccd626af > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoLib/= P > chSerialIoLibCnl.c > @@ -0,0 +1,181 @@ > +/** @file > + PCH Serial IO Lib implementation Cannon Lake specific. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + 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 "PchSerialIoLibInternal.h" > + > +GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 > mCnlAcpiHid[PCH_MAX_SERIALIO_CONTROLLERS][SERIALIO_HID_LENGTH] =3D > +{ > + "INT34B2", > + "INT34B3", > + "INT34B4", > + "INT34B5", > + "INT34B6", > + "INT34B7", > + "INT34B0", > + "INT34B1", > + "INT34BC", > + "INT34B8", > + "INT34B9", > + "INT34BA" > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mCnlPchLpSerialIoId > [PCH_MAX_SERIALIO_CONTROLLERS] =3D > +{ > + V_CNL_PCH_LP_SERIAL_IO_CFG_I2C0_DEVICE_ID, > + V_CNL_PCH_LP_SERIAL_IO_CFG_I2C1_DEVICE_ID, > + V_CNL_PCH_LP_SERIAL_IO_CFG_I2C2_DEVICE_ID, > + V_CNL_PCH_LP_SERIAL_IO_CFG_I2C3_DEVICE_ID, > + V_CNL_PCH_LP_SERIAL_IO_CFG_I2C4_DEVICE_ID, > + V_CNL_PCH_LP_SERIAL_IO_CFG_I2C5_DEVICE_ID, > + V_CNL_PCH_LP_SERIAL_IO_CFG_SPI0_DEVICE_ID, > + V_CNL_PCH_LP_SERIAL_IO_CFG_SPI1_DEVICE_ID, > + V_CNL_PCH_LP_SERIAL_IO_CFG_UART0_DEVICE_ID, > + V_CNL_PCH_LP_SERIAL_IO_CFG_UART1_DEVICE_ID, > + V_CNL_PCH_LP_SERIAL_IO_CFG_UART2_DEVICE_ID > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mCnlPchHSerialIoId > [PCH_MAX_SERIALIO_CONTROLLERS] =3D > +{ > + V_CNL_PCH_H_SERIAL_IO_CFG_I2C0_DEVICE_ID, > + V_CNL_PCH_H_SERIAL_IO_CFG_I2C1_DEVICE_ID, > + V_CNL_PCH_H_SERIAL_IO_CFG_I2C2_DEVICE_ID, > + V_CNL_PCH_H_SERIAL_IO_CFG_I2C3_DEVICE_ID, > + 0, > + 0, > + V_CNL_PCH_H_SERIAL_IO_CFG_SPI0_DEVICE_ID, > + V_CNL_PCH_H_SERIAL_IO_CFG_SPI1_DEVICE_ID, > + V_CNL_PCH_H_SERIAL_IO_CFG_UART0_DEVICE_ID, > + V_CNL_PCH_H_SERIAL_IO_CFG_UART1_DEVICE_ID, > + V_CNL_PCH_H_SERIAL_IO_CFG_UART2_DEVICE_ID > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED SERIAL_IO_BDF_NUMBERS > mSerialIoBdf [PCH_MAX_SERIALIO_CONTROLLERS] =3D > +{ > + {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C0, > PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C0}, > + {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C1, > PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C1}, > + {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C2, > PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C2}, > + {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C3, > PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C3}, > + {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C4, > PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C4}, > + {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C5, > PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C5}, > + {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI0, > PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI0}, > + {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI1, > PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI1}, > + {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART0, > PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART0}, > + {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART1, > PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART1}, > + {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART2, > PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART2} > +}; > + > + > +/** > + Returns index of the last i2c controller > + > + @param[in] Number Number of SerialIo controller > + > + @retval Index of I2C controller > +**/ > +PCH_SERIAL_IO_CONTROLLER > +GetMaxI2cNumber ( > + VOID > + ) > +{ > + if (IsPchH ()) { > + return PchSerialIoIndexI2C3; > + } else { > + return PchSerialIoIndexI2C5; > + } > +} > + > +/** > + Checks if Device with given PciDeviceId is one of SerialIo controllers > + If yes, its number is returned through Number parameter, otherwise > Number is not updated > + > + @param[in] PciDevId Device ID > + @param[out] Number Number of SerialIo controller > + > + @retval TRUE Yes it is a SerialIo controller > + @retval FALSE No it isn't a SerialIo controlle= r > +**/ > +BOOLEAN > +IsSerialIoPciDevId ( > + IN UINT16 PciDevId, > + OUT PCH_SERIAL_IO_CONTROLLER *Number > + ) > +{ > + PCH_SERIAL_IO_CONTROLLER Controller; > + > + for (Controller =3D 0; Controller < GetPchMaxSerialIoControllersNum ()= ; > Controller++) { > + if ((IsPchLp () && (PciDevId =3D=3D mCnlPchLpSerialIoId[Controller])= ) || > + (IsPchH () && (PciDevId =3D=3D mCnlPchHSerialIoId[Controller]))) > + { > + *Number =3D Controller; > + return TRUE; > + } > + } > + return FALSE; > +} > + > +/** > + Finds PCI Device Number of SerialIo devices. > + > + @param[in] SerialIoNumber Serial IO device > + > + @retval SerialIo device number > +**/ > +UINT8 > +GetSerialIoDeviceNumber ( > + IN PCH_SERIAL_IO_CONTROLLER SerialIoNumber > + ) > +{ > + return mSerialIoBdf[SerialIoNumber].DevNum; > +} > + > +/** > + Finds PCI Function Number of SerialIo devices. > + > + @param[in] SerialIoNumber Serial IO device > + > + @retval SerialIo funciton number > +**/ > +UINT8 > +GetSerialIoFunctionNumber ( > + IN PCH_SERIAL_IO_CONTROLLER SerialIoNumber > + ) > +{ > + return mSerialIoBdf[SerialIoNumber].FuncNum; > +} > + > +/** > + Returns string with AcpiHid assigned to selected SerialIo controller > + > + @param[in] Number Number of SerialIo controller > + > + @retval pointer to 8-byte string > +**/ > +CHAR8* > +GetSerialIoAcpiHid ( > + IN PCH_SERIAL_IO_CONTROLLER Number > + ) > +{ > + return mCnlAcpiHid[Number]; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUart= L > ib/PeiDxeSmmPchSerialIoUartLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUart= L > ib/PeiDxeSmmPchSerialIoUartLib.c > new file mode 100644 > index 0000000000..621a473cfa > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchSerialIoUart= L > ib/PeiDxeSmmPchSerialIoUartLib.c > @@ -0,0 +1,372 @@ > +/** @file > + PCH Serial IO UART Lib implementation. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define MAX_BAUD_RATE 115200 > + > +#define R_PCH_SERIAL_IO_8BIT_UART_RXBUF 0x00 > +#define R_PCH_SERIAL_IO_8BIT_UART_TXBUF 0x00 > +#define R_PCH_SERIAL_IO_8BIT_UART_BAUD_LOW 0x00 > +#define R_PCH_SERIAL_IO_8BIT_UART_BAUD_HIGH 0x01 > +#define R_PCH_SERIAL_IO_8BIT_UART_FCR 0x02 > +#define R_PCH_SERIAL_IO_8BIT_UART_IIR 0x02 > +#define R_PCH_SERIAL_IO_8BIT_UART_LCR 0x03 > +#define R_PCH_SERIAL_IO_8BIT_UART_MCR 0x04 > +#define R_PCH_SERIAL_IO_8BIT_UART_LSR 0x05 > +#define R_PCH_SERIAL_IO_8BIT_UART_USR 0x1F > +#define R_PCH_SERIAL_IO_32BIT_UART_CTR 0xFC //Component Type > Register contains identification code > +#define UART_COMPONENT_IDENTIFICATION_CODE 0x44570110 > + > +#define B_PCH_SERIAL_IO_UART_IIR_FIFOSE BIT7|BIT6 > +#define B_PCH_SERIAL_IO_UART_LSR_RXDA BIT0 > +#define B_PCH_SERIAL_IO_UART_LSR_BI BIT4 > +#define B_PCH_SERIAL_IO_UART_LSR_TXRDY BIT5 > +#define B_PCH_SERIAL_IO_UART_LCR_DLAB BIT7 > +#define B_PCH_SERIAL_IO_UART_FCR_FCR BIT0 > +#define B_PCH_SERIAL_IO_UART_MCR_RTS BIT1 > +#define B_PCH_SERIAL_IO_UART_MCR_AFCE BIT5 > +#define B_PCH_SERIAL_IO_UART_USR_TFNF BIT1 > + > +/** > + Returns UART's currently active access mode, 8 or 32 bit > + > + @param[in] MmioBase Base address of UART MMIO space > + > + @retval AccessMode8bit > + @retval AccessMode32bit > +**/ > +UART_ACCESS_MODE > +DetectAccessMode ( > + IN UINTN MmioBase > + ) > +{ > + if (MmioRead32 (MmioBase + R_PCH_SERIAL_IO_32BIT_UART_CTR) =3D=3D > UART_COMPONENT_IDENTIFICATION_CODE) { > + return AccessMode32bit; > + } else { > + return AccessMode8bit; > + } > +} > + > + > +/** > + Register access helper. Depending on SerialIO UART mode, > + its registers are aligned to 1 or 4 bytes and have 8 or 32bit size > + > + @param[in] AccessMode Selects between 8bit access to 1-byte align= ed > registers or 32bit access to 4-byte algined > + @param[in] BaseAddress Base address of UART MMIO space > + @param[in] Offset Register offset in 8bit mode > + @param[in] Data Data to be written > +**/ > +STATIC > +VOID > +WriteRegister ( > + IN UART_ACCESS_MODE AccessMode, > + IN UINTN BaseAddress, > + IN UINTN Offset, > + IN UINT8 Data > + ) > +{ > + if (AccessMode =3D=3D AccessMode32bit) { > + MmioWrite32 (BaseAddress + 4*Offset, Data); > + } else { > + MmioWrite8 (BaseAddress + Offset, Data); > + } > +} > + > +/** > + Register access helper. Depending on SerialIO UART mode, > + its registers are aligned to 1 or 4 bytes and have 8 or 32bit size > + > + @param[in] AccessMode Selects between 8bit access to 1-byte align= ed > registers or 32bit access to 4-byte algined > + @param[in] BaseAddress Base address of UART MMIO space > + @param[in] Offset Register offset in 8bit mode > + @retval retrieved register value, always 8bit regar= dless of > access mode > +**/ > +STATIC > +UINT8 > +ReadRegister ( > + IN UART_ACCESS_MODE AccessMode, > + IN UINTN BaseAddress, > + IN UINTN Offset > + ) > +{ > + if (AccessMode =3D=3D AccessMode32bit) { > + return (UINT8) (0xFF & MmioRead32 (BaseAddress + 4*Offset)); > + } else { > + return MmioRead8 (BaseAddress + Offset); > + } > +} > + > +/** > + SerialIo UART in PCI mode will become unavailable when PCI enumerator > + disables its memory space. This function re-enables it > + > + @param[in] UartNumber Selects Serial IO UART device (0-2) > +**/ > +STATIC > +VOID > +EnablePciMse ( > + IN UINT8 UartNumber > + ) > +{ > + UINTN CfgSpace; > + > + CfgSpace =3D FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 1); > + if (MmioRead16 (CfgSpace + PCI_VENDOR_ID_OFFSET) =3D=3D 0xFFFF) { > + return; > + } > + if ((MmioRead16 (CfgSpace + PCI_COMMAND_OFFSET) & > EFI_PCI_COMMAND_MEMORY_SPACE) !=3D > EFI_PCI_COMMAND_MEMORY_SPACE) { > + if ((MmioRead32 (CfgSpace + PCI_BASE_ADDRESSREG_OFFSET) & > 0xFFFFF000) !=3D 0x0 && > + (MmioRead32 (CfgSpace + PCI_BASE_ADDRESSREG_OFFSET) & > 0xFFFFF000) !=3D 0xFFFFF000 ) { > + MmioOr8 (CfgSpace + PCI_COMMAND_OFFSET, > EFI_PCI_COMMAND_MEMORY_SPACE); > + } > + } > +} > + > +/** > + Initialize selected SerialIo UART. > + This init function MUST be used prior any SerialIo UART functions to i= nit > serial io controller if platform is going use serialio UART as debug outp= ut. > + > + @param UartNumber Selects Serial IO UART device (0-2) > + @param FifoEnable When TRUE, enables 64-byte FIFOs. > + @param BaudRate Baud rate. > + @param LineControl Data length, parity, stop bits. > + @param HardwareFlowControl Automated hardware flow control. If > TRUE, hardware automatically checks CTS when sending data, and sets RTS > when receiving data. > +**/ > +VOID > +EFIAPI > +PchSerialIoUartInit ( > + UINT8 UartNumber, > + BOOLEAN FifoEnable, > + UINT32 BaudRate, > + UINT8 LineControl, > + BOOLEAN HardwareFlowControl > + ) > +{ > + UINTN Base; > + UINTN Divisor; > + UART_ACCESS_MODE AccessMode; > + > + Base =3D FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0); > + if ((Base & 0xFFFFFF00) =3D=3D 0x0 || (Base & 0xFFFFF000) =3D=3D 0xFFF= FF000) { > + // > + // Base is not programmed, skip it. > + // > + return; > + } > + EnablePciMse (UartNumber); > + AccessMode =3D DetectAccessMode (Base); > + > + Divisor =3D MAX_BAUD_RATE / BaudRate; > + > + // > + // Configure baud rate > + // > + WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LCR, > B_PCH_SERIAL_IO_UART_LCR_DLAB); > + WriteRegister (AccessMode, Base, > R_PCH_SERIAL_IO_8BIT_UART_BAUD_HIGH, (UINT8) (Divisor >> 8)); > + WriteRegister (AccessMode, Base, > R_PCH_SERIAL_IO_8BIT_UART_BAUD_LOW, (UINT8) (Divisor & 0xff)); > + // > + // Configure Line control and switch back to bank 0 > + // > + WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LCR, > LineControl & 0x1F); > + // > + // Enable and reset FIFOs > + // > + WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_FCR, > FifoEnable?B_PCH_SERIAL_IO_UART_FCR_FCR:0 ); > + // > + // Put Modem Control Register(MCR) into its reset state of 0x00. > + // > + WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_MCR, > B_PCH_SERIAL_IO_UART_MCR_RTS | > (HardwareFlowControl?B_PCH_SERIAL_IO_UART_MCR_AFCE:0)); > +} > + > +/** > + Write data to serial device. > + > + If the buffer is NULL, then return 0; > + if NumberOfBytes is zero, then return 0. > + > + @param UartNumber Selects Serial IO UART device (0-2) > + @param Buffer Point of data buffer which need to be writed. > + @param NumberOfBytes Number of output bytes which are cached in > Buffer. > + > + @retval Actual number of bytes writed to serial devic= e. > +**/ > +UINTN > +EFIAPI > +PchSerialIoUartOut ( > + IN UINT8 UartNumber, > + IN UINT8 *Buffer, > + IN UINTN NumberOfBytes > + ) > +{ > + UINTN BytesLeft; > + UINTN Base; > + UART_ACCESS_MODE AccessMode; > + > + if (NULL =3D=3D Buffer) { > + return 0; > + } > + > + Base =3D FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0); > + // > + // Sanity checks to avoid infinite loop when trying to print through > uninitialized UART > + // > + if ((Base & 0xFFFFFF00) =3D=3D 0x0 || (Base & 0xFFFFF000) =3D=3D 0xFFF= FF000) { > + return 0; > + } > + EnablePciMse (UartNumber); > + AccessMode =3D DetectAccessMode (Base); > + > + if (ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_USR) =3D= =3D > 0xFF) { > + return 0; > + } > + > + BytesLeft =3D NumberOfBytes; > + > + while (BytesLeft !=3D 0) { > + // > + // Write data while there's room in TXFIFO. If HW Flow Control was e= nabled, > it happens automatically on hardware level. > + // > + if (ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_USR) > & B_PCH_SERIAL_IO_UART_USR_TFNF) { > + WriteRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_TXBUF, > *Buffer); > + Buffer++; > + BytesLeft--; > + } > + } > + > + return NumberOfBytes; > +} > + > +/* > + Read data from serial device and save the datas in buffer. > + > + If the buffer is NULL, then return 0; > + if NumberOfBytes is zero, then return 0. > + > + @param UartNumber Selects Serial IO UART device (0-2) > + @param Buffer Point of data buffer which need to be wri= ted. > + @param NumberOfBytes Number of output bytes which are cached > in Buffer. > + @param WaitUntilBufferFull When TRUE, function waits until whole > buffer is filled. When FALSE, function returns as soon as no new characte= rs are > available. > + > + @retval Actual number of bytes raed to serial dev= ice. > + > +**/ > +UINTN > +EFIAPI > +PchSerialIoUartIn ( > + IN UINT8 UartNumber, > + OUT UINT8 *Buffer, > + IN UINTN NumberOfBytes, > + IN BOOLEAN WaitUntilBufferFull > + ) > +{ > + UINTN BytesReceived; > + UINTN Base; > + UART_ACCESS_MODE AccessMode; > + UINT8 Lsr; > + UINT8 Byte; > + > + if (NULL =3D=3D Buffer) { > + return 0; > + } > + > + Base =3D FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0); > + // > + // Sanity checks to avoid infinite loop when trying to print through > uninitialized UART > + // > + if ((Base & 0xFFFFFF00) =3D=3D 0x0 || (Base & 0xFFFFF000) =3D=3D 0xFFF= FF000) { > + return 0; > + } > + EnablePciMse (UartNumber); > + AccessMode =3D DetectAccessMode (Base); > + > + BytesReceived =3D 0; > + > + while (BytesReceived !=3D NumberOfBytes) { > + // > + // Read the line status register > + // > + Lsr =3D ReadRegister(AccessMode, Base, > R_PCH_SERIAL_IO_8BIT_UART_LSR); > + > + // > + // If there is data in the RX buffer, read it. > + // > + if ((Lsr & B_PCH_SERIAL_IO_UART_LSR_RXDA) !=3D 0) { > + Byte =3D ReadRegister (AccessMode, Base, > R_PCH_SERIAL_IO_8BIT_UART_RXBUF); > + // > + // Check if the break interrupt bit is set. If set, the byte read = from the > + // RX buffer is invalid and should be ignored. If not set, copy th= e byte into > + // the receive buffer. > + // > + if ((Lsr & B_PCH_SERIAL_IO_UART_LSR_BI) =3D=3D 0) { > + *Buffer =3D Byte; > + Buffer++; > + BytesReceived++; > + } > + } else { > + if (!WaitUntilBufferFull) { > + // > + // If there's no data and function shouldn't wait, exit early > + // > + return BytesReceived; > + } > + } > + } > + return BytesReceived; > +} > + > +/** > + Polls a serial device to see if there is any data waiting to be read. > + > + Polls a serial device to see if there is any data waiting to be read. > + If there is data waiting to be read from the serial device, then TRUE = is > returned. > + If there is no data waiting to be read from the serial device, then FA= LSE is > returned. > + > + @param UartNumber Selects Serial IO UART device (0-2) > + > + @retval TRUE Data is waiting to be read from the serial de= vice. > + @retval FALSE There is no data waiting to be read from the = serial > device. > + > +**/ > +BOOLEAN > +EFIAPI > +PchSerialIoUartPoll ( > + IN UINT8 UartNumber > + ) > +{ > + UINTN Base; > + UART_ACCESS_MODE AccessMode; > + > + Base =3D FindSerialIoBar (UartNumber + PchSerialIoIndexUart0, 0); > + // > + // Sanity checks to avoid infinite loop when trying to print through > uninitialized UART > + // > + if ((Base & 0xFFFFFF00) =3D=3D 0x0 || (Base & 0xFFFFF000) =3D=3D 0xFFF= FF000) { > + return 0; > + } > + EnablePciMse (UartNumber); > + AccessMode =3D DetectAccessMode (Base); > + > + // > + // Read the serial port status > + // > + if ((ReadRegister (AccessMode, Base, R_PCH_SERIAL_IO_8BIT_UART_LSR) & > B_PCH_SERIAL_IO_UART_LSR_RXDA) !=3D 0) { > + return TRUE; > + } > + return FALSE; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommo > nLib/WdtCommon.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommo > nLib/WdtCommon.c > new file mode 100644 > index 0000000000..679dcae0ab > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPchWdtCommo > nLib/WdtCommon.c > @@ -0,0 +1,242 @@ > +/** @file > + Library that contains common parts of WdtPei and WdtDxe. Not a > standalone module. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mAllowExpectedReset =3D 0; > + > +/** > + Reads LPC bridge to get Watchdog Timer address > + > + > + @retval UINT32 Watchdog's address > +**/ > +UINT32 > +WdtGetAddress ( > + VOID > + ) > +{ > + return PmcGetAcpiBase () + R_ACPI_IO_OC_WDT_CTL; > +} > + > +/** > + Reloads WDT with new timeout value and starts it. Also sets Unexpected > Reset bit, which > + causes the next reset to be treated as watchdog expiration - unless > AllowKnownReset() > + function was called too. > + > + @param[in] TimeoutValue Time in seconds before WDT times out. > Supported range =3D 1 - 1024. > + > + @retval EFI_SUCCESS if everything's OK > + @retval EFI_INVALID_PARAMETER if TimeoutValue parameter is wrong > +**/ > +EFI_STATUS > +EFIAPI > +WdtReloadAndStart ( > + IN UINT32 TimeoutValue > + ) > +{ > + UINT32 Readback; > + > + DEBUG ((DEBUG_INFO, "\n(Wdt) ReloadAndStartTimer(%d)\n", > TimeoutValue)); > + > + if ((TimeoutValue > B_ACPI_IO_OC_WDT_CTL_TOV_MASK) || > (TimeoutValue =3D=3D 0)) { > + return EFI_INVALID_PARAMETER; > + } > + > + Readback =3D IoRead32 (WdtGetAddress ()); > + Readback |=3D (B_ACPI_IO_OC_WDT_CTL_EN | > B_ACPI_IO_OC_WDT_CTL_FORCE_ALL | B_ACPI_IO_OC_WDT_CTL_ICCSURV); > + if (mAllowExpectedReset =3D=3D 0) { > + Readback |=3D B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS; > + } > + > + if (PcdGetBool (PcdOcEnableWdtforDebug) =3D=3D FALSE) { > + /// > + /// WDT will not be turned on. This is to prevent platform reboots > triggered > + /// by WDT expiration, which can be expected when processor is halte= d for > debugging > + /// > + Readback &=3D ~(B_ACPI_IO_OC_WDT_CTL_EN | > B_ACPI_IO_OC_WDT_CTL_FORCE_ALL | > B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS); > + DEBUG ((DEBUG_INFO, "(Wdt) Wdt disabled in Debug BIOS\n")); > + } > + > + Readback &=3D ~(B_ACPI_IO_OC_WDT_CTL_TOV_MASK); > + Readback |=3D ((TimeoutValue - 1) & B_ACPI_IO_OC_WDT_CTL_TOV_MASK); > + IoWrite32 (WdtGetAddress (), Readback); > + Readback |=3D B_ACPI_IO_OC_WDT_CTL_RLD; > + IoWrite32 (WdtGetAddress (), Readback); > + return EFI_SUCCESS; > +} > + > +/** > + Disables WDT timer. > + > + > +**/ > +VOID > +EFIAPI > +WdtDisable ( > + VOID > + ) > +{ > + UINT32 Readback; > + > + DEBUG ((DEBUG_INFO, "(Wdt) DisableTimer\n")); > + > + Readback =3D IoRead32 (WdtGetAddress ()); > + Readback &=3D ~(B_ACPI_IO_OC_WDT_CTL_EN | > B_ACPI_IO_OC_WDT_CTL_FORCE_ALL | > B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS); > + IoWrite32 (WdtGetAddress (), Readback); > +} > + > +/** > + Returns WDT failure status. > + > + > + @retval V_ACPI_IO_OC_WDT_CTL_STATUS_FAILURE If there was WDT > expiration or unexpected reset > + @retval V_ACPI_IO_OC_WDT_CTL_STATUS_OK Otherwise > +**/ > +UINT8 > +EFIAPI > +WdtCheckStatus ( > + VOID > + ) > +{ > + UINT32 Readback; > + > + DEBUG ((DEBUG_INFO, "(Wdt) CheckTimerStatus\n")); > + > + Readback =3D IoRead32 (WdtGetAddress ()); > + > + DEBUG ((DEBUG_INFO, "(Wdt) Readback =3D (%x)\n", Readback)); > + > + if (Readback & B_ACPI_IO_OC_WDT_CTL_FAILURE_STS) { > + DEBUG ((DEBUG_INFO, "(Wdt) Status =3D FAILURE\n")); > + return V_ACPI_IO_OC_WDT_CTL_STATUS_FAILURE; > + } else { > + return V_ACPI_IO_OC_WDT_CTL_STATUS_OK; > + } > +} > + > +/** > + Normally, each reboot performed while watchdog runs is considered a > failure. > + This function allows platform to perform expected reboots with WDT > running, > + without being interpreted as failures. > + In DXE phase, it is enough to call this function any time before reset= . > + In PEI phase, between calling this function and performing reset, > ReloadAndStart() > + must not be called. > + > + > +**/ > +VOID > +EFIAPI > +WdtAllowKnownReset ( > + VOID > + ) > +{ > + UINT32 Readback; > + > + DEBUG ((DEBUG_INFO, "(Wdt) AllowKnownReset\n")); > + > + mAllowExpectedReset =3D 1; > + > + Readback =3D IoRead32 (WdtGetAddress ()); > + Readback &=3D ~(B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS | > B_ACPI_IO_OC_WDT_CTL_FORCE_ALL); > + IoWrite32 (WdtGetAddress (), Readback); > +} > + > +/** > + Returns information if WDT coverage for the duration of BIOS execution > + was requested by an OS application > + > + > + @retval TRUE if WDT was requested > + @retval FALSE if WDT was not requested > +**/ > +UINT8 > +EFIAPI > +IsWdtRequired ( > + VOID > + ) > +{ > + UINT32 Readback; > + > + DEBUG ((DEBUG_INFO, "(Wdt) IsWdtRequired")); > + > + Readback =3D IoRead32 (WdtGetAddress ()); > + > + > + if ((Readback & B_ACPI_IO_OC_WDT_CTL_AFTER_POST) !=3D 0) { > + DEBUG ((DEBUG_INFO, " - yes\n")); > + return TRUE; > + } else { > + DEBUG ((DEBUG_INFO, " - no\n")); > + return FALSE; > + } > + > +} > + > +/** > + Returns WDT enabled/disabled status. > + > + > + @retval TRUE if WDT is enabled > + @retval FALSE if WDT is disabled > +**/ > +UINT8 > +EFIAPI > +IsWdtEnabled ( > + VOID > + ) > +{ > + UINT32 Readback; > + > + DEBUG ((DEBUG_INFO, "(Wdt) IsWdtEnabled")); > + > + Readback =3D IoRead32 (WdtGetAddress ()); > + > + > + if ((Readback & B_ACPI_IO_OC_WDT_CTL_EN) !=3D 0) { > + DEBUG ((DEBUG_INFO, " - yes\n")); > + return TRUE; > + } else { > + DEBUG ((DEBUG_INFO, " - no\n")); > + return FALSE; > + } > + > +} > + > +/** > + Returns WDT locked status. > + > + > + @retval TRUE if WDT is locked > + @retval FALSE if WDT is unlocked > +**/ > +UINT8 > +EFIAPI > +IsWdtLocked ( > + VOID > + ) > +{ > + UINT32 Readback; > + > + DEBUG ((DEBUG_INFO, "(Wdt) IsWdtLocked")); > + > + Readback =3D IoRead32 (WdtGetAddress ()); > + > + > + if ((Readback & B_ACPI_IO_OC_WDT_CTL_LCK) !=3D 0) { > + DEBUG ((DEBUG_INFO, " - yes\n")); > + return TRUE; > + } else { > + DEBUG ((DEBUG_INFO, " - no\n")); > + return FALSE; > + } > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c > new file mode 100644 > index 0000000000..8e026b3ab6 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmPmcLib/PmcLib.c > @@ -0,0 +1,330 @@ > +/** @file > + PCH PMC Library. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + 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 > + > +/** > + Get PCH ACPI base address. > + > + @retval Address Address of PWRM base address. > +**/ > +UINT16 > +PmcGetAcpiBase ( > + VOID > + ) > +{ > + return PcdGet16 (PcdAcpiBaseAddress); > +} > + > +/** > + Get PCH PWRM base address. > + > + @retval Address Address of PWRM base address. > +**/ > +UINT32 > +PmcGetPwrmBase ( > + VOID > + ) > +{ > + return PCH_PWRM_BASE_ADDRESS; > +} > + > +/** > + This function enables Power Button SMI > +**/ > +VOID > +PmcEnablePowerButtonSmi ( > + VOID > + ) > +{ > + IoOr16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_EN, > B_ACPI_IO_PM1_EN_PWRBTN); > +} > + > +/** > + This function disables Power Button SMI > +**/ > +VOID > +PmcDisablePowerButtonSmi ( > + VOID > + ) > +{ > + IoAnd16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_EN, > (UINT16)~B_ACPI_IO_PM1_EN_PWRBTN); > +} > + > +/** > + This function reads PM Timer Count driven by 3.579545 MHz clock > + > + @retval PM Timer Count > +**/ > +UINT32 > +PmcGetTimerCount ( > + VOID > + ) > +{ > + return IoRead32 (PmcGetAcpiBase () + R_ACPI_IO_PM1_TMR) & > B_ACPI_IO_PM1_TMR_VAL; > +} > + > +/** > + Get Sleep Type that platform has waken from > + > + @retval SleepType Sleep Type > +**/ > +PMC_SLEEP_STATE > +PmcGetSleepTypeAfterWake ( > + VOID > + ) > +{ > + UINT16 AcpiBase; > + UINT32 PmconA; > + > + AcpiBase =3D PmcGetAcpiBase (); > + PmconA =3D MmioRead32 (PmcGetPwrmBase () + > R_PMC_PWRM_GEN_PMCON_A); > + > + DEBUG ((DEBUG_INFO, "PWRM_PMCON_A =3D 0x%x\n", PmconA)); > + > + // > + // If Global Reset Status, Power Failure. Host Reset Status bits are s= et, return > S5 State > + // > + if ((PmconA & (B_PMC_PWRM_GEN_PMCON_A_GBL_RST_STS | > B_PMC_PWRM_GEN_PMCON_A_PWR_FLR | > B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS)) !=3D 0) { > + return PmcNotASleepState; > + } > + > + if (IoRead16 (AcpiBase + R_ACPI_IO_PM1_STS) & B_ACPI_IO_PM1_STS_WAK) > { > + switch (IoRead16 (AcpiBase + R_ACPI_IO_PM1_CNT) & > B_ACPI_IO_PM1_CNT_SLP_TYP) { > + case V_ACPI_IO_PM1_CNT_S0: > + return PmcInS0State; > + > + case V_ACPI_IO_PM1_CNT_S1: > + return PmcS1SleepState; > + > + case V_ACPI_IO_PM1_CNT_S3: > + return PmcS3SleepState; > + > + case V_ACPI_IO_PM1_CNT_S4: > + return PmcS4SleepState; > + > + case V_ACPI_IO_PM1_CNT_S5: > + return PmcS5SleepState; > + > + default: > + ASSERT (FALSE); > + return PmcUndefinedState; > + } > + } else { > + return PmcNotASleepState; > + } > +} > + > +/** > + Clear PMC Wake Status > +**/ > +VOID > +PmcClearWakeStatus ( > + VOID > + ) > +{ > + IoWrite16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_STS, > B_ACPI_IO_PM1_STS_WAK); > +} > + > +/** > + Check if platform boots after shutdown caused by power button override > event > + > + @retval TRUE Power Button Override occurred in last system boot > + @retval FALSE Power Button Override didn't occur > +**/ > +BOOLEAN > +PmcIsPowerButtonOverrideDetected ( > + VOID > + ) > +{ > + return ((IoRead16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_STS) & > B_ACPI_IO_PM1_STS_PRBTNOR) !=3D 0); > +} > + > +/** > + This function checks if RTC Power Failure occurred by > + reading RTC_PWR_FLR bit > + > + @retval RTC Power Failure state: TRUE - Battery is always present. > + FALSE - CMOS is cleared. > +**/ > +BOOLEAN > +PmcIsRtcBatteryGood ( > + VOID > + ) > +{ > + return ((MmioRead8 (PmcGetPwrmBase () + > R_PMC_PWRM_GEN_PMCON_B) & > B_PMC_PWRM_GEN_PMCON_B_RTC_PWR_STS) =3D=3D 0); > +} > + > +/** > + This function checks if Power Failure occurred by > + reading PWR_FLR bit > + > + @retval Power Failure state > +**/ > +BOOLEAN > +PmcIsPowerFailureDetected ( > + VOID > + ) > +{ > + return ((MmioRead16 (PmcGetPwrmBase () + > R_PMC_PWRM_GEN_PMCON_A) & > B_PMC_PWRM_GEN_PMCON_A_PWR_FLR) !=3D 0); > +} > + > +/** > + This function checks if RTC Power Failure occurred by > + reading SUS_PWR_FLR bit > + > + @retval SUS Power Failure state > +**/ > +BOOLEAN > +PmcIsSusPowerFailureDetected ( > + VOID > + ) > +{ > + return ((MmioRead32 (PmcGetPwrmBase () + > R_PMC_PWRM_GEN_PMCON_B) & > B_PMC_PWRM_GEN_PMCON_A_SUS_PWR_FLR) !=3D 0); > +} > + > +/** > + This function clears Power Failure status (PWR_FLR) > +**/ > +VOID > +PmcClearPowerFailureStatus ( > + VOID > + ) > +{ > + // > + // Write 1 to clear PWR_FLR > + // Avoid clearing other W1C bits > + // > + MmioAndThenOr8 ( > + PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 1, > + (UINT8) ~(B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS >> 8), > + B_PMC_PWRM_GEN_PMCON_A_PWR_FLR >> 8 > + ); > +} > + > +/** > + This function clears Global Reset status (GBL_RST_STS) > +**/ > +VOID > +PmcClearGlobalResetStatus ( > + VOID > + ) > +{ > + // > + // Write 1 to clear GBL_RST_STS > + // Avoid clearing other W1C bits > + // > + MmioAndThenOr8 ( > + PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 3, > + (UINT8) ~0, > + B_PMC_PWRM_GEN_PMCON_A_GBL_RST_STS >> 24 > + ); > +} > + > +/** > + This function clears Host Reset status (HOST_RST_STS) > +**/ > +VOID > +PmcClearHostResetStatus ( > + VOID > + ) > +{ > + // > + // Write 1 to clear HOST_RST_STS > + // Avoid clearing other W1C bits > + // > + MmioAndThenOr8 ( > + PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 1, > + (UINT8) ~(B_PMC_PWRM_GEN_PMCON_A_PWR_FLR >> 8), > + B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS >> 8 > + ); > +} > + > +/** > + This function clears SUS Power Failure status (SUS_PWR_FLR) > +**/ > +VOID > +PmcClearSusPowerFailureStatus ( > + VOID > + ) > +{ > + // > + // BIOS clears this bit by writing a '1' to it. > + // Take care of other fields, so we don't clear them accidentally. > + // > + MmioAndThenOr8 ( > + PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 2, > + (UINT8) ~(B_PMC_PWRM_GEN_PMCON_A_MS4V >> 16), > + B_PMC_PWRM_GEN_PMCON_A_SUS_PWR_FLR >> 16 > + ); > +} > + > +/** > + This function sets state to which platform will get after power is rea= pplied > + > + @param[in] PowerStateAfterG3 0: S0 state (boot) > + 1: S5/S4 State > +**/ > +VOID > +PmcSetPlatformStateAfterPowerFailure ( > + IN UINT8 PowerStateAfterG3 > + ) > +{ > + UINT32 PchPwrmBase; > + > + PchPwrmBase =3D PmcGetPwrmBase (); > + > + if (PowerStateAfterG3) { > + MmioOr8 (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_A, > B_PMC_PWRM_GEN_PMCON_A_AFTERG3_EN); > + } else { > + MmioAnd8 (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_A, > (UINT8)~B_PMC_PWRM_GEN_PMCON_A_AFTERG3_EN); > + } > +} > + > +/** > + This function checks if SMI Lock is set > + > + @retval SMI Lock state > +**/ > +BOOLEAN > +PmcIsSmiLockSet ( > + VOID > + ) > +{ > + return ((MmioRead8 ((UINTN) (PmcGetPwrmBase () + > R_PMC_PWRM_GEN_PMCON_B)) & > B_PMC_PWRM_GEN_PMCON_B_SMI_LOCK) !=3D 0); > +} > + > +/** > + Check global SMI enable is set > + > + @retval TRUE Global SMI enable is set > + FALSE Global SMI enable is not set > +**/ > +BOOLEAN > +PmcIsGblSmiEn ( > + VOID > + ) > +{ > + return !!(IoRead32 (PmcGetAcpiBase () + R_ACPI_IO_SMI_EN) & > B_ACPI_IO_SMI_EN_GBL_SMI); > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib= . > c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib= . > c > new file mode 100644 > index 0000000000..05557931c2 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib= . > c > @@ -0,0 +1,41 @@ > +/** @file > + Pch SATA library. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +/** > + Get SATA controller address that can be passed to the PCI Segment Libr= ary > functions. > + > + @param[in] SataCtrlIndex SATA controller index > + > + @retval SATA controller address in PCI Segment Library representation > +**/ > +UINT64 > +GetSataRegBase ( > + IN UINT32 SataCtrlIndex > + ) > +{ > + ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ()); > + > + return PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + GetSataPcieDeviceNum (SataCtrlIndex), > + GetSataPcieFunctionNum (SataCtrlIndex), > + 0 > + ); > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib= C > df.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib > Cdf.c > new file mode 100644 > index 0000000000..5cec818dd6 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib > Cdf.c > @@ -0,0 +1,101 @@ > +/** @file > + Pch SATA library for CedarFork SouthCluster. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** > + Get Maximum Sata Controller Number > + > + @param[in] None > + > + @retval Maximum Sata Controller Number > +**/ > +UINT8 > +GetPchMaxSataControllerNum ( > + VOID > + ) > +{ > + return 3; > +} > + > +/** > + Get Pch Maximum Sata Port Number > + > + @param[in] SataCtrlIndex SATA controller index > + > + @retval Pch Maximum Sata Port Number > +**/ > +UINT8 > +GetPchMaxSataPortNum ( > + IN UINT8 SataCtrlIndex > + ) > +{ > + ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ()); > + > + return 8; > +} > + > +/** > + Get SATA controller PCIe Device Number > + > + @param[in] SataCtrlIndex SATA controller index > + > + @retval SATA controller PCIe Device Number > +**/ > +UINT8 > +GetSataPcieDeviceNum ( > + IN UINT8 SataCtrlIndex > + ) > +{ > + ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ()); > + > + if (SataCtrlIndex =3D=3D SATA_1_CONTROLLER_INDEX) { > + return PCI_DEVICE_NUMBER_CDF_PCH_SATA_1; > + } else if (SataCtrlIndex =3D=3D SATA_2_CONTROLLER_INDEX) { > + return PCI_DEVICE_NUMBER_CDF_PCH_SATA_2; > + } else if (SataCtrlIndex =3D=3D SATA_3_CONTROLLER_INDEX) { > + return PCI_DEVICE_NUMBER_CDF_PCH_SATA_3; > + } else { > + ASSERT (FALSE); > + return 0; > + } > +} > + > +/** > + Get SATA controller PCIe Function Number > + > + @param[in] SataCtrlIndex SATA controller index > + > + @retval SATA controller PCIe Function Number > +**/ > +UINT8 > +GetSataPcieFunctionNum ( > + IN UINT8 SataCtrlIndex > + ) > +{ > + ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ()); > + > + if (SataCtrlIndex =3D=3D SATA_1_CONTROLLER_INDEX) { > + return PCI_FUNCTION_NUMBER_CDF_PCH_SATA_1; > + } else if (SataCtrlIndex =3D=3D SATA_2_CONTROLLER_INDEX) { > + return PCI_FUNCTION_NUMBER_CDF_PCH_SATA_2; > + } else if (SataCtrlIndex =3D=3D SATA_3_CONTROLLER_INDEX) { > + return PCI_FUNCTION_NUMBER_CDF_PCH_SATA_3; > + } else { > + ASSERT (FALSE); > + return 0; > + } > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib= C > nl.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib > Cnl.c > new file mode 100644 > index 0000000000..0eca692a74 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmSataLib/SataLib > Cnl.c > @@ -0,0 +1,88 @@ > +/** @file > + Pch SATA library. > + All function in this library is available for PEI, DXE, and SMM, > + But do not support UEFI RUNTIME environment call. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** > + Get Maximum Sata Controller Number > + > + @param[in] None > + > + @retval Maximum Sata Controller Number > +**/ > +UINT8 > +GetPchMaxSataControllerNum ( > + VOID > + ) > +{ > + return 1; > +} > + > +/** > + Get Pch Maximum Sata Port Number > + > + @param[in] SataCtrlIndex SATA controller index > + > + @retval Pch Maximum Sata Port Number > +**/ > +UINT8 > +GetPchMaxSataPortNum ( > + IN UINT32 SataCtrlIndex > + ) > +{ > + ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ()); > + > + if (IsPchLp ()) { > + return 3; > + } else { > + return 8; > + } > +} > + > +/** > + Get SATA controller PCIe Device Number > + > + @param[in] SataCtrlIndex SATA controller index > + > + @retval SATA controller PCIe Device Number > +**/ > +UINT8 > +GetSataPcieDeviceNum ( > + IN UINT32 SataCtrlIndex > + ) > +{ > + ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ()); > + > + return PCI_DEVICE_NUMBER_PCH_SATA; > +} > + > +/** > + Get SATA controller PCIe Function Number > + > + @param[in] SataCtrlIndex SATA controller index > + > + @retval SATA controller PCIe Function Number > +**/ > +UINT8 > +GetSataPcieFunctionNum ( > + IN UINT32 SataCtrlIndex > + ) > +{ > + ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ()); > + > + return PCI_FUNCTION_NUMBER_PCH_SATA; > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.= c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.= c > new file mode 100644 > index 0000000000..22f6fb215f > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLib/PeiOcWdtLib.= c > @@ -0,0 +1,130 @@ > +/** @file > + The PEI Library Implements OcWdt Support. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +static WDT_PPI mWdtPpi =3D { > + WdtReloadAndStart, > + WdtCheckStatus, > + WdtDisable, > + WdtAllowKnownReset, > + IsWdtRequired, > + IsWdtEnabled > +}; > + > +static EFI_PEI_PPI_DESCRIPTOR mInstallWdtPpi =3D { > + (EFI_PEI_PPI_DESCRIPTOR_PPI | > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), > + &gWdtPpiGuid, > + &mWdtPpi > +}; > + > +/** > + Reads PCH registers to check if platform wakes from S3/S4 > + > + @retval TRUE if platfrom wakes from S3/S4 > + @retval FALSE otherwise > +**/ > +BOOLEAN > +IsWakeFromS3S4 ( > + VOID > + ) > +{ > + PMC_SLEEP_STATE SleepType; > + > + SleepType =3D PmcGetSleepTypeAfterWake (); > + if ((SleepType =3D=3D PmcS3SleepState) || (SleepType =3D=3D PmcS4Sleep= State)) { > + return TRUE; > + } > + > + return FALSE; > + > +} > + > +/** > + Check for unexpected reset. > + If there was an unexpected reset, enforces WDT expiration. > +**/ > +VOID > +OcWdtResetCheck ( > + VOID > + ) > +{ > + UINT32 Readback; > + > + Readback =3D IoRead32 (WdtGetAddress ()); > + DEBUG ((DEBUG_INFO, "(WDT) OcWdtResetCheck()\n")); > + > + /// > + /// If there was a WDT expiration, set Failure Status and clear timeou= t status > bits > + /// Timeout status bits are cleared by writing '1' > + /// > + if (Readback & (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | > B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS)) { > + DEBUG ((DEBUG_ERROR, "(WDT) Expiration detected.\n", Readback)); > + Readback |=3D B_ACPI_IO_OC_WDT_CTL_FAILURE_STS; > + Readback |=3D (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | > B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS); > + Readback &=3D ~(B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS); > + } else { > + /// > + /// If there was unexpected reset but no WDT expiration and no resum= e > from S3/S4, > + /// clear unexpected reset status and enforce expiration. This is to= inform > Firmware > + /// which has no access to unexpected reset status bit, that somethi= ng > went wrong. > + /// > + if ((Readback & B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS) > && !IsWakeFromS3S4()) { > + if (PcdGetBool (PcdOcEnableWdtforDebug)) { > + DEBUG ((DEBUG_ERROR, "(WDT) Unexpected reset detected and > ignored.\n")); > + Readback &=3D ~(B_ACPI_IO_OC_WDT_CTL_FAILURE_STS | > B_ACPI_IO_OC_WDT_CTL_UNXP_RESET_STS); > + Readback |=3D (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | > B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS); > + } else { > + DEBUG ((DEBUG_ERROR, "(WDT) Unexpected reset detected. Enforcing > Wdt expiration.\n")); > + WdtReloadAndStart (1); > + /// > + /// wait for reboot caused by WDT expiration > + /// > + CpuDeadLoop (); > + } > + } else { > + /// > + /// No WDT expiration and no unexpected reset - clear Failure stat= us > + /// > + DEBUG ((DEBUG_INFO, "(WDT) Status OK.\n", Readback)); > + Readback &=3D ~(B_ACPI_IO_OC_WDT_CTL_FAILURE_STS); > + Readback |=3D (B_ACPI_IO_OC_WDT_CTL_ICCSURV_STS | > B_ACPI_IO_OC_WDT_CTL_NO_ICCSURV_STS); > + } > + } > + > + IoWrite32 (WdtGetAddress (), Readback); > + > + return; > +} > + > +/** > + This function install WDT PPI > + > + @retval EFI_STATUS Results of the installation of the WDT PPI > +**/ > +EFI_STATUS > +EFIAPI > +OcWdtInit ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + > + Status =3D PeiServicesInstallPpi (&mInstallWdtPpi); > + ASSERT_EFI_ERROR (Status); > + > + return Status; > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdt > LibNull.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdt > LibNull.c > new file mode 100644 > index 0000000000..182218ffcf > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiOcWdtLibNull/PeiOcWdt > LibNull.c > @@ -0,0 +1,23 @@ > +/** @file > + The Null PEI Library Implements OcWdt Support. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > + > +/** > + This function install WDT PPI > + > + @retval EFI_STATUS Results of the installation of the WDT PPI > +**/ > +EFI_STATUS > +EFIAPI > +OcWdtInit ( > + VOID > + ) > +{ > + return EFI_SUCCESS; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMe= m > PrintPolicy.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMe= m > PrintPolicy.c > new file mode 100644 > index 0000000000..bd1e2711da > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPreMe= m > PrintPolicy.c > @@ -0,0 +1,307 @@ > +/** @file > + Print whole PCH_PREMEM_POLICY_PPI > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "PeiPchPolicyLibrary.h" > + > +/** > + Print PCH_GENERAL_PREMEM_CONFIG and serial out. > + > + @param[in] PchGeneralPreMemConfig Pointer to a > PCH_GENERAL_PREMEM_CONFIG that provides the platform setting > + > +**/ > +VOID > +PchPrintGeneralPreMemConfig ( > + IN CONST PCH_GENERAL_PREMEM_CONFIG *PchGeneralPreMemConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH General PreMem Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, " Port80Route=3D %x\n", > PchGeneralPreMemConfig->Port80Route)); > +} > + > +/** > + Print PCH_DCI_PREMEM_CONFIG and serial out. > + > + @param[in] DciPreMemConfig Pointer to a > PCH_DCI_PREMEM_CONFIG that provides the platform setting > + > +**/ > +VOID > +PchPrintDciPreMemConfig ( > + IN CONST PCH_DCI_PREMEM_CONFIG *DciPreMemConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH DCI PreMem Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, "PlatformDebugConsent =3D %x\n", > DciPreMemConfig->PlatformDebugConsent)); > + DEBUG ((DEBUG_INFO, "DciUsb3TypecUfpDbg =3D %x\n", > DciPreMemConfig->DciUsb3TypecUfpDbg)); > +} > + > +/** > + Print PCH_WDT_PREMEM_CONFIG and serial out. > + > + @param[in] WdtPreMemConfig Pointer to a > PCH_WDT_PREMEM_CONFIG that provides the platform setting > + > +**/ > +VOID > +PchPrintWdtPreMemConfig ( > + IN CONST PCH_WDT_PREMEM_CONFIG *WdtPreMemConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH WDT PreMem Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, "DisableAndLock=3D %x\n", > WdtPreMemConfig->DisableAndLock)); > +} > + > +/** > + Print PCH_TRACE_HUB_CONFIG and serial out. > + > + @param[in] TraceHubConfig Pointer to a > PCH_TRACE_HUB_CONFIG that provides the platform setting > + > +**/ > +VOID > +PchPrintTraceHubPreMemConfig ( > + IN CONST PCH_TRACE_HUB_PREMEM_CONFIG > *PchTraceHubPreMemConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH TraceHub PreMem Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, "EnableMode=3D %x\n", > PchTraceHubPreMemConfig->EnableMode)); > + DEBUG ((DEBUG_INFO, "MemReg0Size=3D %x\n", > PchTraceHubPreMemConfig->MemReg0Size)); > + DEBUG ((DEBUG_INFO, "MemReg1Size=3D %x\n", > PchTraceHubPreMemConfig->MemReg1Size)); > +} > + > +/** > + Print PCH_SMBUS_CONFIG and serial out. > + > + @param[in] SmbusConfig Pointer to a PCH_SMBUS_CONFIG that > provides the platform setting > + > +**/ > +VOID > +PchPrintSmbusPreMemConfig ( > + IN CONST PCH_SMBUS_PREMEM_CONFIG *SmbusPreMemConfig > + ) > +{ > + UINT32 Index; > + > + DEBUG ((DEBUG_INFO, "------------------ PCH SMBUS PreMem Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, " Enable=3D %x\n", SmbusPreMemConfig->Enable)); > + DEBUG ((DEBUG_INFO, " ArpEnable=3D %x\n", > SmbusPreMemConfig->ArpEnable)); > + DEBUG ((DEBUG_INFO, " DynamicPowerGating=3D %x\n", > SmbusPreMemConfig->DynamicPowerGating)); > + DEBUG ((DEBUG_INFO, " SpdWriteDisable=3D %x\n", > SmbusPreMemConfig->SpdWriteDisable)); > + DEBUG ((DEBUG_INFO, " SmbAlertEnable=3D %x\n", > SmbusPreMemConfig->SmbAlertEnable)); > + DEBUG ((DEBUG_INFO, " SmbusIoBase=3D %x\n", > SmbusPreMemConfig->SmbusIoBase)); > + DEBUG ((DEBUG_INFO, " NumRsvdSmbusAddresses=3D %x\n", > SmbusPreMemConfig->NumRsvdSmbusAddresses)); > + DEBUG ((DEBUG_INFO, " RsvdSmbusAddressTable=3D {")); > + for (Index =3D 0; Index < SmbusPreMemConfig->NumRsvdSmbusAddresses; > ++Index) { > + DEBUG ((DEBUG_INFO, " %02xh", > SmbusPreMemConfig->RsvdSmbusAddressTable[Index])); > + } > + DEBUG ((DEBUG_INFO, " }\n")); > +} > + > +/** > + Print PCH_LPC_PREMEM_CONFIG and serial out. > + > + @param[in] LpcPreMemConfig Pointer to a > PCH_LPC_PREMEM_CONFIG that provides the platform setting > + > +**/ > +VOID > +PchPrintLpcPreMemConfig ( > + IN CONST PCH_LPC_PREMEM_CONFIG *LpcPreMemConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH LPC PreMem Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, "EnhancePort8xhDecoding=3D %x\n", > LpcPreMemConfig->EnhancePort8xhDecoding)); > +} > + > +/** > + Print PCH_HSIO_PCIE_PREMEM_CONFIG and serial out. > + > + @param[in] HsioPciePreMemConfig Pointer to a > PCH_HSIO_PCIE_PREMEM_CONFIG that provides the platform setting > + > +**/ > +VOID > +PchPrintHsioPciePreMemConfig ( > + IN CONST PCH_HSIO_PCIE_PREMEM_CONFIG *HsioPciePreMemConfig > + ) > +{ > + UINT32 Index; > + > + DEBUG ((DEBUG_INFO, "------------------ HSIO PCIE PreMem Config > ------------------\n")); > + for (Index =3D 0; Index < GetPchMaxPciePortNum (); Index++) { > + DEBUG ((DEBUG_INFO, " RootPort[%d] HsioRxSetCtleEnable=3D %x\n", Ind= ex, > HsioPciePreMemConfig->Lane[Index].HsioRxSetCtleEnable)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] HsioRxSetCtle=3D %x\n", Index, > HsioPciePreMemConfig->Lane[Index].HsioRxSetCtle)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] > HsioTxGen1DownscaleAmpEnable=3D %x\n", Index, > HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmpEnable)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DownscaleAmp=3D %x\n", > Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen1DownscaleAmp)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] > HsioTxGen2DownscaleAmpEnable=3D %x\n", Index, > HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmpEnable)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DownscaleAmp=3D %x\n", > Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DownscaleAmp)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] > HsioTxGen3DownscaleAmpEnable=3D %x\n", Index, > HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmpEnable)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen3DownscaleAmp=3D %x\n", > Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen3DownscaleAmp)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DeEmphEnable=3D %x\n", > Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmphEnable)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen1DeEmph=3D %x\n", Index, > HsioPciePreMemConfig->Lane[Index].HsioTxGen1DeEmph)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph3p5Enable=3D > %x\n", Index, > HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5Enable)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph3p5=3D %x\n", > Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph3p5)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph6p0Enable=3D > %x\n", Index, > HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0Enable)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] HsioTxGen2DeEmph6p0=3D %x\n", > Index, HsioPciePreMemConfig->Lane[Index].HsioTxGen2DeEmph6p0)); > + } > +} > + > +/** > + Print PCH_HSIO_SATA_PREMEM_CONFIG and serial out. > + > + @param[in] SataCtrlIndex SATA controller index > + @param[in] HsioSataPreMemConfig Pointer to a > PCH_HSIO_SATA_PREMEM_CONFIG that provides the platform setting > +**/ > +VOID > +PchPrintHsioSataPreMemConfig ( > + IN UINT8 SataCtrlIndex, > + IN CONST PCH_HSIO_SATA_PREMEM_CONFIG *HsioSataPreMemConfig > + ) > +{ > + UINT32 Index; > + > + DEBUG ((DEBUG_INFO, "---------------- HSIO SATA PreMem Config for > controller %d ----------------\n", SataCtrlIndex)); > + for (Index =3D 0; Index < GetPchMaxSataPortNum (SataCtrlIndex); Index+= +) { > + DEBUG ((DEBUG_INFO, " PortSettings[%d] > HsioRxGen1EqBoostMagEnable=3D %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMagEnable)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen1EqBoostMag=3D > %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioRxGen1EqBoostMag)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] > HsioRxGen2EqBoostMagEnable=3D %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMagEnable)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen2EqBoostMag=3D > %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioRxGen2EqBoostMag)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] > HsioRxGen3EqBoostMagEnable=3D %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMagEnable)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioRxGen3EqBoostMag=3D > %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioRxGen3EqBoostMag)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] > HsioTxGen1DownscaleAmpEnable=3D %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmpEnable) > ); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DownscaleAmp=3D > %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DownscaleAmp)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] > HsioTxGen2DownscaleAmpEnable=3D %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmpEnable) > ); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DownscaleAmp=3D > %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DownscaleAmp)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] > HsioTxGen3DownscaleAmpEnable=3D %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmpEnable) > ); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DownscaleAmp=3D > %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DownscaleAmp)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DeEmphEnable=3D > %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmphEnable)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen1DeEmph=3D %x\n", > Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen1DeEmph)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DeEmphEnable=3D > %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmphEnable)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen2DeEmph=3D %x\n", > Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen2DeEmph)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DeEmphEnable=3D > %x\n", Index, > HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmphEnable)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] HsioTxGen3DeEmph=3D %x\n", > Index, HsioSataPreMemConfig->PortLane[Index].HsioTxGen3DeEmph)); > + } > +} > + > +/** > + Print PCH_PCIE_RP_PREMEM_CONFIG and serial out. > + > + @param[in] PcieRpPreMemConfig Pointer to a > PCH_PCIE_RP_PREMEM_CONFIG that provides the platform setting > + > +**/ > +VOID > +PchPrintPcieRpPreMemConfig ( > + IN CONST PCH_PCIE_RP_PREMEM_CONFIG *PcieRpPreMemConfig > + ) > +{ > + UINT32 Index; > + DEBUG ((DEBUG_INFO, "------------------ PCH PCIe RP PreMem Config > ------------------\n")); > + > + for (Index =3D 0; Index < GetPchMaxPciePortNum (); Index++) { > + DEBUG ((DEBUG_INFO, " Port[%d] RpEnabled=3D %x\n", Index, > (PcieRpPreMemConfig->RpEnabledMask & (UINT32) (1 << Index)) !=3D 0 )); > + } > + DEBUG ((DEBUG_INFO, " PcieImrEnabled=3D %x\n", > PcieRpPreMemConfig->PcieImrEnabled)); > + DEBUG ((DEBUG_INFO, " PcieImrSize=3D %d MB\n", > PcieRpPreMemConfig->PcieImrSize)); > + DEBUG ((DEBUG_INFO, " ImrRpSelection=3D %d\n", > PcieRpPreMemConfig->ImrRpSelection)); > +} > + > +/** > + Print PCH_HDAUDIO_PREMEM_CONFIG and serial out. > + > + @param[in] LpcPreMemConfig Pointer to a > PCH_HDAUDIO_PREMEM_CONFIG that provides the platform setting > + > +**/ > +VOID > +PchPrintHdAudioPreMemConfig ( > + IN CONST PCH_HDAUDIO_PREMEM_CONFIG *HdaPreMemConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ HD Audio PreMem Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, " Enable=3D %x\n", HdaPreMemConfig->Enable)); > +} > + > +/** > + Print PCH_ISH_PREMEM_CONFIG and serial out. > + > + @param[in] IshPreMemConfig Pointer to a > PCH_ISH_PREMEM_CONFIG that provides the platform setting > + > +**/ > +VOID > +PchPrintIshPreMemConfig ( > + IN CONST PCH_ISH_PREMEM_CONFIG *IshPreMemConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ ISH PreMem Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, " Enable=3D %x\n", IshPreMemConfig->Enable)); > +} > + > + > +/** > + Print whole PCH_POLICY_PPI and serial out. > + > + @param[in] SiPreMemPolicyPpi The RC PREMEM Policy PPI instance > + > +**/ > +VOID > +EFIAPI > +PchPreMemPrintPolicyPpi ( > + IN SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi > + ) > +{ > + DEBUG_CODE_BEGIN (); > + EFI_STATUS Status; > + PCH_GENERAL_PREMEM_CONFIG *PchGeneralPreMemConfig; > + PCH_DCI_PREMEM_CONFIG *DciPreMemConfig; > + PCH_WDT_PREMEM_CONFIG *WdtPreMemConfig; > + PCH_TRACE_HUB_PREMEM_CONFIG *PchTraceHubPreMemConfig; > + PCH_SMBUS_PREMEM_CONFIG *SmbusPreMemConfig; > + PCH_LPC_PREMEM_CONFIG *LpcPreMemConfig; > + PCH_HSIO_PCIE_PREMEM_CONFIG *HsioPciePreMemConfig; > + PCH_HSIO_SATA_PREMEM_CONFIG *HsioSataPreMemConfig; > + PCH_PCIE_RP_PREMEM_CONFIG *PcieRpPreMemConfig; > + PCH_HDAUDIO_PREMEM_CONFIG *HdaPreMemConfig; > + PCH_ISH_PREMEM_CONFIG *IshPreMemConfig; > + UINT8 SataCtrlIndex; > + > + Status =3D GetConfigBlock ((VOID *) SiPreMemPolicyPpi, > &gPchGeneralPreMemConfigGuid, (VOID *) &PchGeneralPreMemConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPreMemPolicyPpi, > &gDciPreMemConfigGuid, (VOID *) &DciPreMemConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPreMemPolicyPpi, > &gWatchDogPreMemConfigGuid, (VOID *) &WdtPreMemConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPreMemPolicyPpi, > &gPchTraceHubPreMemConfigGuid, (VOID *) &PchTraceHubPreMemConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPreMemPolicyPpi, > &gSmbusPreMemConfigGuid, (VOID *) &SmbusPreMemConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPreMemPolicyPpi, > &gLpcPreMemConfigGuid, (VOID *) &LpcPreMemConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPreMemPolicyPpi, > &gHsioPciePreMemConfigGuid, (VOID *) &HsioPciePreMemConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPreMemPolicyPpi, > &gPcieRpPreMemConfigGuid, (VOID *) &PcieRpPreMemConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPreMemPolicyPpi, > &gHdAudioPreMemConfigGuid, (VOID *) &HdaPreMemConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPreMemPolicyPpi, > &gIshPreMemConfigGuid, (VOID *) &IshPreMemConfig); > + ASSERT_EFI_ERROR (Status); > + DEBUG ((DEBUG_INFO, "------------------------ PCH Print PreMemPolicy S= tart > ------------------------\n")); > + DEBUG ((DEBUG_INFO, " Revision=3D %x\n", > SiPreMemPolicyPpi->TableHeader.Header.Revision)); > + > + PchPrintGeneralPreMemConfig (PchGeneralPreMemConfig); > + PchPrintDciPreMemConfig (DciPreMemConfig); > + PchPrintWdtPreMemConfig (WdtPreMemConfig); > + PchPrintTraceHubPreMemConfig (PchTraceHubPreMemConfig); > + PchPrintSmbusPreMemConfig (SmbusPreMemConfig); > + PchPrintLpcPreMemConfig (LpcPreMemConfig); > + PchPrintHsioPciePreMemConfig (HsioPciePreMemConfig); > + for (SataCtrlIndex =3D 0; SataCtrlIndex < GetPchMaxSataControllerNum (= ); > SataCtrlIndex++) { > + HsioSataPreMemConfig =3D GetPchHsioSataPreMemConfig > (SiPreMemPolicyPpi, SataCtrlIndex); > + PchPrintHsioSataPreMemConfig (SataCtrlIndex, HsioSataPreMemConfig); > + } > + PchPrintPcieRpPreMemConfig (PcieRpPreMemConfig); > + PchPrintHdAudioPreMemConfig (HdaPreMemConfig); > + PchPrintIshPreMemConfig (IshPreMemConfig); > + > + DEBUG ((DEBUG_INFO, "------------------------ PCH Print PreMemPolicy E= nd > --------------------------\n")); > + DEBUG_CODE_END (); > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrint= Poli > cy.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrint= Poli > cy.c > new file mode 100644 > index 0000000000..d9005b50ef > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PchPrint= Poli > cy.c > @@ -0,0 +1,778 @@ > +/** @file > + Print whole PCH_POLICY_PPI > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "PeiPchPolicyLibrary.h" > +#include > + > +/** > + Print USB_CONFIG and serial out. > + > + @param[in] UsbConfig Pointer to a USB_CONFIG that provides the > platform setting > + > +**/ > +VOID > +PchPrintUsbConfig ( > + IN CONST USB_CONFIG *UsbConfig > + ) > +{ > + UINT32 Index; > + > + DEBUG ((DEBUG_INFO, "------------------ PCH USB Config ---------------= ---\n")); > + DEBUG ((DEBUG_INFO, " EnableComplianceMode =3D %x\n", > UsbConfig->EnableComplianceMode)); > + DEBUG ((DEBUG_INFO, " PdoProgramming =3D %x\n", > UsbConfig->PdoProgramming)); > + DEBUG ((DEBUG_INFO, " OverCurrentEnable =3D %x\n", > UsbConfig->OverCurrentEnable)); > + DEBUG ((DEBUG_INFO, " XhciOcLock =3D %x\n", > UsbConfig->XhciOcLock)); > + DEBUG ((DEBUG_INFO, " Usb2PhySusPgEnable =3D %x\n", > UsbConfig->Usb2PhySusPgEnable)); > + > + for (Index =3D 0; Index < GetPchUsb2MaxPhysicalPortNum (); Index++) { > + DEBUG ((DEBUG_INFO, " PortUsb20[%d].Enabled =3D %x\n", Index, > UsbConfig->PortUsb20[Index].Enable)); > + DEBUG ((DEBUG_INFO, " PortUsb20[%d].OverCurrentPin =3D OC%x\n", Inde= x, > UsbConfig->PortUsb20[Index].OverCurrentPin)); > + DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Petxiset =3D %x\n", Index, > UsbConfig->PortUsb20[Index].Afe.Petxiset)); > + DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Txiset =3D %x\n", Index, > UsbConfig->PortUsb20[Index].Afe.Txiset)); > + DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Predeemp =3D %x\n", Index, > UsbConfig->PortUsb20[Index].Afe.Predeemp)); > + DEBUG ((DEBUG_INFO, " PortUsb20[%d].Afe.Pehalfbit =3D %x\n", Index, > UsbConfig->PortUsb20[Index].Afe.Pehalfbit)); > + } > + > + for (Index =3D 0; Index < GetPchXhciMaxUsb3PortNum (); Index++) { > + DEBUG ((DEBUG_INFO, " PortUsb30[%d] Enabled =3D %x\= n", > Index, UsbConfig->PortUsb30[Index].Enable)); > + DEBUG ((DEBUG_INFO, " PortUsb30[%d].OverCurrentPin =3D > OC%x\n", Index, UsbConfig->PortUsb30[Index].OverCurrentPin)); > + DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDeEmphEnable =3D > %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDeEmphEnable)); > + DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDeEmph =3D %x\= n", > Index, UsbConfig->PortUsb30[Index].HsioTxDeEmph)); > + DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDownscaleAmpEnable =3D > %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDownscaleAmpEnable)); > + DEBUG ((DEBUG_INFO, " PortUsb30[%d].HsioTxDownscaleAmp =3D > %x\n", Index, UsbConfig->PortUsb30[Index].HsioTxDownscaleAmp)); > + > + DEBUG ((DEBUG_INFO, " > PortUsb30HsioRx[%d].HsioCtrlAdaptOffsetCfgEnable =3D %x\n", Index, > UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfgEnable)); > + DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioCtrlAdaptOffsetCfg > =3D %x\n", Index, > UsbConfig->PortUsb30HsioRx[Index].HsioCtrlAdaptOffsetCfg)); > + DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelNEnable > =3D %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelNEnable)= ); > + DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelN > =3D %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelN)); > + DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelPEnable > =3D %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelPEnable)= ); > + DEBUG ((DEBUG_INFO, " PortUsb30HsioRx[%d].HsioFilterSelP > =3D %x\n", Index, UsbConfig->PortUsb30HsioRx[Index].HsioFilterSelP)); > + DEBUG ((DEBUG_INFO, " > PortUsb30HsioRx[%d].HsioOlfpsCfgPullUpDwnResEnable =3D %x\n", Index, > UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnResEnable)); > + DEBUG ((DEBUG_INFO, " > PortUsb30HsioRx[%d].HsioOlfpsCfgPullUpDwnRes =3D %x\n", Index, > UsbConfig->PortUsb30HsioRx[Index].HsioOlfpsCfgPullUpDwnRes)); > + } > + > + DEBUG ((DEBUG_INFO, " XdciConfig.Enable=3D %x\n", > UsbConfig->XdciConfig.Enable)); > + > +} > + > +/** > + Print PCH_PCIE_CONFIG and serial out. > + > + @param[in] PcieConfig Pointer to a PCH_PCIE_CONFIG that provid= es > the platform setting > + > +**/ > +VOID > +PchPrintPcieConfig ( > + IN CONST PCH_PCIE_CONFIG *PcieConfig > + ) > +{ > + UINT32 Index; > + > + DEBUG ((DEBUG_INFO, "------------------ PCH PCIE Config --------------= ----\n")); > + for (Index =3D 0; Index < GetPchMaxPciePortNum (); Index++) { > + DEBUG ((DEBUG_INFO, " RootPort[%d] HotPlug=3D %x\n", Index, > PcieConfig->RootPort[Index].HotPlug)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] PmSci=3D %x\n", Index, > PcieConfig->RootPort[Index].PmSci)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] ExtSync=3D %x\n", Index, > PcieConfig->RootPort[Index].ExtSync)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] ClkReqDetect=3D %x\n", Index, > PcieConfig->RootPort[Index].ClkReqDetect)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] UnsupportedRequestReport=3D > %x\n", Index, PcieConfig->RootPort[Index].UnsupportedRequestReport)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] FatalErrorReport=3D %x\n", Index, > PcieConfig->RootPort[Index].FatalErrorReport)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] NoFatalErrorReport=3D %x\n", Inde= x, > PcieConfig->RootPort[Index].NoFatalErrorReport)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] CorrectableErrorReport=3D %x\n", > Index, PcieConfig->RootPort[Index].CorrectableErrorReport)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] SystemErrorOnFatalError=3D %x\n", > Index, PcieConfig->RootPort[Index].SystemErrorOnFatalError)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] SystemErrorOnNonFatalError=3D > %x\n", Index, PcieConfig->RootPort[Index].SystemErrorOnNonFatalError)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] SystemErrorOnCorrectableError=3D > %x\n", Index, PcieConfig->RootPort[Index].SystemErrorOnCorrectableError))= ; > + DEBUG ((DEBUG_INFO, " RootPort[%d] MaxPayload=3D %x\n", Index, > PcieConfig->RootPort[Index].MaxPayload)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] SlotImplemented=3D %x\n", Index, > PcieConfig->RootPort[Index].SlotImplemented)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] AcsEnabled=3D %x\n", Index, > PcieConfig->RootPort[Index].AcsEnabled)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] PtmEnabled=3D %x\n", Index, > PcieConfig->RootPort[Index].PtmEnabled)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] AdvancedErrorReporting=3D %x\n", > Index, PcieConfig->RootPort[Index].AdvancedErrorReporting)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] TransmitterHalfSwing=3D %x\n", > Index, PcieConfig->RootPort[Index].TransmitterHalfSwing)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] PcieSpeed=3D %x\n", Index, > PcieConfig->RootPort[Index].PcieSpeed)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] Gen3EqPh3Method=3D %x\n", Index, > PcieConfig->RootPort[Index].Gen3EqPh3Method)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] PhysicalSlotNumber=3D %x\n", Inde= x, > PcieConfig->RootPort[Index].PhysicalSlotNumber)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] CompletionTimeout=3D %x\n", Index= , > PcieConfig->RootPort[Index].CompletionTimeout)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] Aspm=3D %x\n", Index, > PcieConfig->RootPort[Index].Aspm)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] L1Substates=3D %x\n", Index, > PcieConfig->RootPort[Index].L1Substates)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] LtrEnable=3D %x\n", Index, > PcieConfig->RootPort[Index].LtrEnable)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] LtrConfigLock=3D %x\n", Index, > PcieConfig->RootPort[Index].LtrConfigLock)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] LtrMaxSnoopLatency=3D %x\n", > Index, PcieConfig->RootPort[Index].LtrMaxSnoopLatency)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] LtrMaxNoSnoopLatency=3D %x\n", > Index, PcieConfig->RootPort[Index].LtrMaxNoSnoopLatency)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] SnoopLatencyOverrideMode=3D > %x\n", Index, PcieConfig->RootPort[Index].SnoopLatencyOverrideMode)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] SnoopLatencyOverrideMultiplier=3D > %x\n", Index, PcieConfig->RootPort[Index].SnoopLatencyOverrideMultiplier)= ); > + DEBUG ((DEBUG_INFO, " RootPort[%d] SnoopLatencyOverrideValue=3D > %x\n", Index, PcieConfig->RootPort[Index].SnoopLatencyOverrideValue)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] NonSnoopLatencyOverrideMode=3D > %x\n", Index, PcieConfig->RootPort[Index].NonSnoopLatencyOverrideMode)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] > NonSnoopLatencyOverrideMultiplier=3D %x\n", Index, > PcieConfig->RootPort[Index].NonSnoopLatencyOverrideMultiplier)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] NonSnoopLatencyOverrideValue=3D > %x\n", Index, PcieConfig->RootPort[Index].NonSnoopLatencyOverrideValue)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] ForceLtrOverride=3D %x\n", Index, > PcieConfig->RootPort[Index].ForceLtrOverride)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] DetectTimeoutMs=3D %x\n", Index, > PcieConfig->RootPort[Index].DetectTimeoutMs)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] SlotPowerLimitScale=3D %x\n", Ind= ex, > PcieConfig->RootPort[Index].SlotPowerLimitScale)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] SlotPowerLimitValue=3D %x\n", Ind= ex, > PcieConfig->RootPort[Index].SlotPowerLimitValue)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] Uptp=3D %x\n", Index, > PcieConfig->RootPort[Index].Uptp)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] Dptp=3D %x\n", Index, > PcieConfig->RootPort[Index].Dptp)); > + DEBUG ((DEBUG_INFO, " RootPort[%d] EnableCpm=3D %x\n", Index, > PcieConfig->RootPort[Index].EnableCpm)); > + > + } > + for (Index =3D 0; Index < GetPchMaxPcieClockNum (); Index++) { > + DEBUG ((DEBUG_INFO, " Clock[%d] Usage=3D %x\n", Index, > PcieConfig->PcieClock[Index].Usage)); > + DEBUG ((DEBUG_INFO, " Clock[%d] ClkReq=3D %x\n", Index, > PcieConfig->PcieClock[Index].ClkReq)); > + } > + for (Index =3D 0; Index < PCH_PCIE_SWEQ_COEFFS_MAX; Index++) { > + DEBUG ((DEBUG_INFO, " SwEqCoeffCm[%d] =3D %x\n", Index, > PcieConfig->SwEqCoeffList[Index].Cm)); > + DEBUG ((DEBUG_INFO, " SwEqCoeffCp[%d] =3D %x\n", Index, > PcieConfig->SwEqCoeffList[Index].Cp)); > + } > + DEBUG ((DEBUG_INFO, " EnablePort8xhDecode=3D %x\n", > PcieConfig->EnablePort8xhDecode)); > + DEBUG ((DEBUG_INFO, " PchPciePort8xhDecodePortIndex=3D %x\n", > PcieConfig->PchPciePort8xhDecodePortIndex)); > + DEBUG ((DEBUG_INFO, " DisableRootPortClockGating=3D %x\n", > PcieConfig->DisableRootPortClockGating)); > + DEBUG ((DEBUG_INFO, " EnablePeerMemoryWrite=3D %x\n", > PcieConfig->EnablePeerMemoryWrite)); > + DEBUG ((DEBUG_INFO, " ComplianceTestMode=3D %x\n", > PcieConfig->ComplianceTestMode)); > + DEBUG ((DEBUG_INFO, " RpFunctionSwap=3D %x\n", > PcieConfig->RpFunctionSwap)); > + DEBUG ((DEBUG_INFO, " PcieDeviceOverrideTablePtr=3D %x\n", > PcieConfig->PcieDeviceOverrideTablePtr)); > +} > + > +/** > + Print PCH_SATA_CONFIG and serial out. > + > + @param[in] SataCtrlIndex SATA controller index > + @param[in] SataConfig Pointer to a PCH_SATA_CONFIG that provid= es > the platform setting > + > +**/ > +VOID > +PchPrintSataConfig ( > + IN UINT32 SataCtrlIndex, > + IN CONST PCH_SATA_CONFIG *SataConfig > + ) > +{ > + UINT32 Index; > + > + DEBUG ((DEBUG_INFO, "--------------- PCH SATA Config for controller %d > -----------\n", SataCtrlIndex)); > + DEBUG ((DEBUG_INFO, " Enable=3D %x\n", SataConfig->Enable)); > + DEBUG ((DEBUG_INFO, " SataMode=3D %x\n", SataConfig->SataMode)); > + > + for (Index =3D 0; Index < GetPchMaxSataPortNum (SataCtrlIndex); Index+= +) { > + DEBUG ((DEBUG_INFO, " PortSettings[%d] Enabled=3D %x\n", Index, > SataConfig->PortSettings[Index].Enable)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] HotPlug=3D %x\n", Index, > SataConfig->PortSettings[Index].HotPlug)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] InterlockSw=3D %x\n", Index, > SataConfig->PortSettings[Index].InterlockSw)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] External=3D %x\n", Index, > SataConfig->PortSettings[Index].External)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] SpinUp=3D %x\n", Index, > SataConfig->PortSettings[Index].SpinUp)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] SolidStateDrive=3D %x\n", Ind= ex, > SataConfig->PortSettings[Index].SolidStateDrive)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] DevSlp=3D %x\n", Index, > SataConfig->PortSettings[Index].DevSlp)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] EnableDitoConfig=3D %x\n", In= dex, > SataConfig->PortSettings[Index].EnableDitoConfig)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] DmVal=3D %x\n", Index, > SataConfig->PortSettings[Index].DmVal)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] DitoVal=3D %x\n", Index, > SataConfig->PortSettings[Index].DitoVal)); > + DEBUG ((DEBUG_INFO, " PortSettings[%d] ZpOdd=3D %x\n", Index, > SataConfig->PortSettings[Index].ZpOdd)); > + } > + > + DEBUG ((DEBUG_INFO, " RaidDeviceId=3D %x\n", > SataConfig->Rst.RaidDeviceId)); > + DEBUG ((DEBUG_INFO, " Sata interrupt mode =3D %x\n", > SataConfig->Rst.SataRstInterrupt)); > + DEBUG ((DEBUG_INFO, " Raid0=3D %x\n", SataConfig->Rst.Raid0)); > + DEBUG ((DEBUG_INFO, " Raid1=3D %x\n", SataConfig->Rst.Raid1)); > + DEBUG ((DEBUG_INFO, " Raid10=3D %x\n", SataConfig->Rst.Raid10)); > + DEBUG ((DEBUG_INFO, " Raid5=3D %x\n", SataConfig->Rst.Raid5)); > + DEBUG ((DEBUG_INFO, " Irrt=3D %x\n", SataConfig->Rst.Irrt)); > + DEBUG ((DEBUG_INFO, " OromUiBanner=3D %x\n", > SataConfig->Rst.OromUiBanner)); > + DEBUG ((DEBUG_INFO, " OromUiDelay=3D %x\n", > SataConfig->Rst.OromUiDelay)); > + DEBUG ((DEBUG_INFO, " HddUnlock=3D %x\n", SataConfig->Rst.HddUnlock)); > + DEBUG ((DEBUG_INFO, " LedLocate=3D %x\n", SataConfig->Rst.LedLocate)); > + DEBUG ((DEBUG_INFO, " IrrtOnly=3D %x\n", SataConfig->Rst.IrrtOnly)); > + DEBUG ((DEBUG_INFO, " SmartStorage=3D %x\n", > SataConfig->Rst.SmartStorage)); > + DEBUG ((DEBUG_INFO, " LegacyOrom=3D %x\n", > SataConfig->Rst.LegacyOrom)); > + DEBUG ((DEBUG_INFO, " OptaneMemory=3D %x\n", > SataConfig->Rst.OptaneMemory)); > + DEBUG ((DEBUG_INFO, " CpuAttachedStorage=3D %x\n", > SataConfig->Rst.CpuAttachedStorage)); > + > + DEBUG ((DEBUG_INFO, " SpeedSupport=3D %x\n", SataConfig->SpeedLimit)); > + DEBUG ((DEBUG_INFO, " EsataSpeedLimit=3D %x\n", > SataConfig->EsataSpeedLimit)); > + DEBUG ((DEBUG_INFO, " LedEnable=3D %x\n", SataConfig->LedEnable)); > + DEBUG ((DEBUG_INFO, " TestMode=3D %x\n", SataConfig->TestMode)); > + DEBUG ((DEBUG_INFO, " SalpSupport=3D %x\n", SataConfig->SalpSupport)); > + DEBUG ((DEBUG_INFO, " PwrOptEnable=3D %x\n", > SataConfig->PwrOptEnable)); > + > + for (Index =3D 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) { > + DEBUG ((DEBUG_INFO, " RstPcieStorageRemap[%d].Enable = =3D > %x\n", Index, SataConfig->RstPcieStorageRemap[Index].Enable)); > + DEBUG ((DEBUG_INFO, " RstPcieStorageRemap[%d].RstPcieStoragePort > =3D %x\n", Index, > SataConfig->RstPcieStorageRemap[Index].RstPcieStoragePort)); > + DEBUG ((DEBUG_INFO, " RstPcieStorageRemap[%d].DeviceResetDelay > =3D %x\n", Index, SataConfig->RstPcieStorageRemap[Index].DeviceResetDelay= )); > + } > + DEBUG ((DEBUG_INFO, " ThermalThrottling P0T1M %x\n", > SataConfig->ThermalThrottling.P0T1M)); > + DEBUG ((DEBUG_INFO, " ThermalThrottling P0T2M %x\n", > SataConfig->ThermalThrottling.P0T2M)); > + DEBUG ((DEBUG_INFO, " ThermalThrottling P0T3M %x\n", > SataConfig->ThermalThrottling.P0T3M)); > + DEBUG ((DEBUG_INFO, " ThermalThrottling P0TDisp %x\n", > SataConfig->ThermalThrottling.P0TDisp)); > + DEBUG ((DEBUG_INFO, " ThermalThrottling P0Tinact %x\n", > SataConfig->ThermalThrottling.P0Tinact)); > + DEBUG ((DEBUG_INFO, " ThermalThrottling P0TDispFinit %x\n", > SataConfig->ThermalThrottling.P0TDispFinit)); > + DEBUG ((DEBUG_INFO, " ThermalThrottling P1T1M %x\n", > SataConfig->ThermalThrottling.P1T1M)); > + DEBUG ((DEBUG_INFO, " ThermalThrottling P1T2M %x\n", > SataConfig->ThermalThrottling.P1T2M)); > + DEBUG ((DEBUG_INFO, " ThermalThrottling P1T3M %x\n", > SataConfig->ThermalThrottling.P1T3M)); > + DEBUG ((DEBUG_INFO, " ThermalThrottling P1TDisp %x\n", > SataConfig->ThermalThrottling.P1TDisp)); > + DEBUG ((DEBUG_INFO, " ThermalThrottling P1Tinact %x\n", > SataConfig->ThermalThrottling.P1Tinact)); > + DEBUG ((DEBUG_INFO, " ThermalThrottling P1TDispFinit %x\n", > SataConfig->ThermalThrottling.P1TDispFinit)); > + DEBUG ((DEBUG_INFO, " ThermalThrottling SuggestedSetting %x\n", > SataConfig->ThermalThrottling.SuggestedSetting)); > +} > + > +/** > + Print PCH_IOAPIC_CONFIG and serial out. > + > + @param[in] IoApicConfig Pointer to a PCH_IOAPIC_CONFIG that > provides the platform setting > + > +**/ > +VOID > +PchPrintIoApicConfig ( > + IN CONST PCH_IOAPIC_CONFIG *IoApicConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH IOAPIC Config ------------= ------\n")); > + DEBUG ((DEBUG_INFO, " IoApicEntry24_119=3D %x\n", > IoApicConfig->IoApicEntry24_119)); > + DEBUG ((DEBUG_INFO, " Enable8254ClockGating=3D %x\n", > IoApicConfig->Enable8254ClockGating)); > + DEBUG ((DEBUG_INFO, " Enable8254ClockGatingOnS3=3D %x\n", > IoApicConfig->Enable8254ClockGatingOnS3)); > + DEBUG ((DEBUG_INFO, " IoApicId=3D %x\n", IoApicConfig->IoApicId)); > +} > + > +/** > + Print PCH_LOCK_DOWN_CONFIG and serial out. > + > + @param[in] LockDownConfig Pointer to a PCH_LOCK_DOWN_CONFIG > that provides the platform setting > + > +**/ > +VOID > +PchPrintLockDownConfig ( > + IN CONST PCH_LOCK_DOWN_CONFIG *LockDownConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH Lock Down Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, " GlobalSmi=3D %x\n", LockDownConfig->GlobalSmi)); > + DEBUG ((DEBUG_INFO, " BiosInterface=3D %x\n", > LockDownConfig->BiosInterface)); > + DEBUG ((DEBUG_INFO, " RtcMemoryLock=3D %x\n", > LockDownConfig->RtcMemoryLock)); > + DEBUG ((DEBUG_INFO, " BiosLock=3D %x\n", LockDownConfig->BiosLock)); > + DEBUG ((DEBUG_INFO, " UnlockGpioPads=3D %x\n", > LockDownConfig->UnlockGpioPads)); > +} > + > +/** > + Print PCH_HDAUDIO_CONFIG and serial out. > + > + @param[in] HdaConfig Pointer to a PCH_HDAUDIO_CONFIG that > provides the platform setting > + > +**/ > +VOID > +PchPrintHdAudioConfig ( > + IN CONST PCH_HDAUDIO_CONFIG *HdaConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH HD-Audio Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, " DSP Enable =3D %x\n", > HdaConfig->DspEnable)); > + DEBUG ((DEBUG_INFO, " DSP UAA Compliance =3D %x\n", > HdaConfig->DspUaaCompliance)); > + DEBUG ((DEBUG_INFO, " iDisp Codec Disconnect =3D %x\n", > HdaConfig->IDispCodecDisconnect)); > + DEBUG ((DEBUG_INFO, " Pme =3D %x\n", HdaConfig->P= me)); > + DEBUG ((DEBUG_INFO, " Codec Sx Wake Capability =3D %x\n", > HdaConfig->CodecSxWakeCapability)); > + DEBUG ((DEBUG_INFO, " VC Type =3D %x\n", > HdaConfig->VcType)); > + DEBUG ((DEBUG_INFO, " HD-A Link Frequency =3D %x\n", > HdaConfig->HdAudioLinkFrequency)); > + DEBUG ((DEBUG_INFO, " iDisp Link Frequency =3D %x\n", > HdaConfig->IDispLinkFrequency)); > + DEBUG ((DEBUG_INFO, " iDisp Link T-Mode =3D %x\n", > HdaConfig->IDispLinkTmode)); > + DEBUG ((DEBUG_INFO, " Audio Link: HDA Link =3D %x\n", > HdaConfig->AudioLinkHda)); > + DEBUG ((DEBUG_INFO, " Audio Link: DMIC#0 =3D %x\n", > HdaConfig->AudioLinkDmic0)); > + DEBUG ((DEBUG_INFO, " Audio Link: DMIC#1 =3D %x\n", > HdaConfig->AudioLinkDmic1)); > + DEBUG ((DEBUG_INFO, " Audio Link: SSP#0 =3D %x\n", > HdaConfig->AudioLinkSsp0)); > + DEBUG ((DEBUG_INFO, " Audio Link: SSP#1 =3D %x\n", > HdaConfig->AudioLinkSsp1)); > + DEBUG ((DEBUG_INFO, " Audio Link: SSP#2 =3D %x\n", > HdaConfig->AudioLinkSsp1)); > + DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#1 =3D %x\n", > HdaConfig->AudioLinkSndw1)); > + DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#2 =3D %x\n", > HdaConfig->AudioLinkSndw2)); > + DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#3 =3D %x\n", > HdaConfig->AudioLinkSndw3)); > + DEBUG ((DEBUG_INFO, " Audio Link: SoundWire#4 =3D %x\n", > HdaConfig->AudioLinkSndw4)); > + DEBUG ((DEBUG_INFO, " SoundWire Buffer RCOMP =3D %x\n", > HdaConfig->SndwBufferRcomp)); > + DEBUG ((DEBUG_INFO, " ResetWaitTimer =3D %x\n", > HdaConfig->ResetWaitTimer)); > + DEBUG ((DEBUG_INFO, " VerbTableEntryNum =3D %x\n", > HdaConfig->VerbTableEntryNum)); > + DEBUG ((DEBUG_INFO, " VerbTablePtr =3D %x\n", > HdaConfig->VerbTablePtr)); > +} > + > +/** > + Print PCH_PM_CONFIG and serial out. > + > + @param[in] PmConfig Pointer to a PCH_PM_CONFIG that provides > the platform setting > + > +**/ > +VOID > +PchPrintPmConfig ( > + IN CONST PCH_PM_CONFIG *PmConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH PM Config ----------------= --\n")); > + > + DEBUG ((DEBUG_INFO, " WakeConfig PmeB0S5Dis =3D %x\n", > PmConfig->WakeConfig.PmeB0S5Dis)); > + DEBUG ((DEBUG_INFO, " WakeConfig WolEnableOverride =3D %x\n", > PmConfig->WakeConfig.WolEnableOverride)); > + DEBUG ((DEBUG_INFO, " WakeConfig LanWakeFromDeepSx =3D %x\n", > PmConfig->WakeConfig.LanWakeFromDeepSx)); > + DEBUG ((DEBUG_INFO, " WakeConfig PcieWakeFromDeepSx =3D %x\n", > PmConfig->WakeConfig.PcieWakeFromDeepSx)); > + DEBUG ((DEBUG_INFO, " WakeConfig WoWlanEnable =3D %x\n", > PmConfig->WakeConfig.WoWlanEnable)); > + DEBUG ((DEBUG_INFO, " WakeConfig WoWlanDeepSxEnable =3D %x\n", > PmConfig->WakeConfig.WoWlanDeepSxEnable)); > + > + DEBUG ((DEBUG_INFO, " PchDeepSxPol =3D %x\n", > PmConfig->PchDeepSxPol)); > + DEBUG ((DEBUG_INFO, " PchSlpS3MinAssert =3D %x\n", > PmConfig->PchSlpS3MinAssert)); > + DEBUG ((DEBUG_INFO, " PchSlpS4MinAssert =3D %x\n", > PmConfig->PchSlpS4MinAssert)); > + DEBUG ((DEBUG_INFO, " PchSlpSusMinAssert =3D %x\n", > PmConfig->PchSlpSusMinAssert)); > + DEBUG ((DEBUG_INFO, " PchSlpAMinAssert =3D %x\n", > PmConfig->PchSlpAMinAssert)); > + DEBUG ((DEBUG_INFO, " LpcClockRun =3D %x\n", > PmConfig->LpcClockRun)); > + DEBUG ((DEBUG_INFO, " SlpStrchSusUp =3D %x\n", > PmConfig->SlpStrchSusUp)); > + DEBUG ((DEBUG_INFO, " SlpLanLowDc =3D %x\n", > PmConfig->SlpLanLowDc)); > + DEBUG ((DEBUG_INFO, " PwrBtnOverridePeriod =3D %x\n", > PmConfig->PwrBtnOverridePeriod)); > + DEBUG ((DEBUG_INFO, " DisableEnergyReport =3D %x\n", > PmConfig->DisableEnergyReport)); > + DEBUG ((DEBUG_INFO, " DisableDsxAcPresentPulldown =3D %x\n", > PmConfig->DisableDsxAcPresentPulldown)); > + DEBUG ((DEBUG_INFO, " PchPwrCycDur =3D %x\n", > PmConfig->PchPwrCycDur)); > + DEBUG ((DEBUG_INFO, " PciePllSsc =3D %x\n", > PmConfig->PciePllSsc)); > + DEBUG ((DEBUG_INFO, " DisableNativePowerButton =3D %x\n", > PmConfig->DisableNativePowerButton)); > + DEBUG ((DEBUG_INFO, " SlpS0Enabled =3D %x\n", > PmConfig->SlpS0Enable)); > + DEBUG ((DEBUG_INFO, " MeWakeSts =3D %x\n", > PmConfig->MeWakeSts)); > + DEBUG ((DEBUG_INFO, " WolOvrWkSts =3D %x\n", > PmConfig->WolOvrWkSts)); > + DEBUG ((DEBUG_INFO, " EnableTcoTimer =3D %x\n", > PmConfig->EnableTcoTimer)); > + DEBUG ((DEBUG_INFO, " VrAlert =3D %x\n", > PmConfig->VrAlert)); > + DEBUG ((DEBUG_INFO, " PowerButtonDebounce =3D %x\n", > PmConfig->PowerButtonDebounce)); > + DEBUG ((DEBUG_INFO, " SlpS0VmRuntimeControl =3D %x\n", > PmConfig->SlpS0VmRuntimeControl)); > + DEBUG ((DEBUG_INFO, " SlpS0Vm070VSupport =3D %x\n", > PmConfig->SlpS0Vm070VSupport)); > + DEBUG ((DEBUG_INFO, " SlpS0Vm075VSupport =3D %x\n", > PmConfig->SlpS0Vm075VSupport)); > + DEBUG ((DEBUG_INFO, " SlpS0Override =3D %x\n", > PmConfig->SlpS0Override)); > + DEBUG ((DEBUG_INFO, " SlpS0DisQForDebug =3D %x\n", > PmConfig->SlpS0DisQForDebug)); > + DEBUG ((DEBUG_INFO, " PsOnEnable =3D %x\n", > PmConfig->PsOnEnable)); > + DEBUG ((DEBUG_INFO, " CpuC10GatePinEnable =3D %x\n", > PmConfig->CpuC10GatePinEnable)); > + DEBUG ((DEBUG_INFO, " PmcDbgMsgEn =3D %x\n", > PmConfig->PmcDbgMsgEn)); > + DEBUG ((DEBUG_INFO, " ModPhySusPgEnable =3D %x\n", > PmConfig->ModPhySusPgEnable)); > + DEBUG ((DEBUG_INFO, " SlpS0WithGbeSupport =3D %x\n", > PmConfig->SlpS0WithGbeSupport)); > +} > + > +/** > + Print PCH_DMI_CONFIG and serial out. > + > + @param[in] DmiConfig Pointer to a PCH_DMI_CONFIG that provides > the platform setting > + > +**/ > +VOID > +PchPrintDmiConfig ( > + IN CONST PCH_DMI_CONFIG *DmiConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH DMI Config ---------------= ---\n")); > + DEBUG ((DEBUG_INFO, " PwrOptEnable=3D %x\n", > DmiConfig->PwrOptEnable)); > + DEBUG ((DEBUG_INFO, " DmiAspmCtrl=3D %x\n", DmiConfig->DmiAspmCtrl)); > +} > +/** > + Print PCH_LPC_SIRQ_CONFIG and serial out. > + > + @param[in] SerialIrqConfig Pointer to a PCH_LPC_SIRQ_CONFIG th= at > provides the platform setting > + > +**/ > +VOID > +PchPrintSerialIrqConfig ( > + IN CONST PCH_LPC_SIRQ_CONFIG *SerialIrqConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH LPC SIRQ Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, " SirqEnable=3D %x\n", SerialIrqConfig->SirqEnable= )); > + DEBUG ((DEBUG_INFO, " SirqMode=3D %x\n", SerialIrqConfig->SirqMode)); > + DEBUG ((DEBUG_INFO, " StartFramePulse=3D %x\n", > SerialIrqConfig->StartFramePulse)); > +} > +/** > + Print PCH_THERMAL_CONFIG and serial out. > + > + @param[in] ThermalConfig Pointer to a PCH_THERMAL_CONFIG that > provides the platform setting > + > +**/ > +VOID > +PchPrintThermalConfig ( > + IN CONST PCH_THERMAL_CONFIG *ThermalConfig > + ) > +{ > + UINTN Index; > + > + DEBUG ((DEBUG_INFO, "------------------ PCH Thermal Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, " TsmicLock=3D %x\n", ThermalConfig->TsmicLock)); > + DEBUG ((DEBUG_INFO, " TTLevels T0Level %x centigrade degree\n", > ThermalConfig->TTLevels.T0Level)); > + DEBUG ((DEBUG_INFO, " TTLevels T1Level %x centigrade degree\n", > ThermalConfig->TTLevels.T1Level)); > + DEBUG ((DEBUG_INFO, " TTLevels T2Level %x centigrade degree\n", > ThermalConfig->TTLevels.T2Level)); > + DEBUG ((DEBUG_INFO, " TTLevels TTEnable %x\n", > ThermalConfig->TTLevels.TTEnable)); > + DEBUG ((DEBUG_INFO, " TTLevels TTState13Enable %x\n", > ThermalConfig->TTLevels.TTState13Enable)); > + DEBUG ((DEBUG_INFO, " TTLevels TTLock %x\n", > ThermalConfig->TTLevels.TTLock)); > + DEBUG ((DEBUG_INFO, " TTLevels SuggestedSetting %x\n", > ThermalConfig->TTLevels.SuggestedSetting)); > + DEBUG ((DEBUG_INFO, " TTLevels PchCrossThrottling %x\n", > ThermalConfig->TTLevels.PchCrossThrottling)); > + > + DEBUG ((DEBUG_INFO, " DmiHaAWC DmiTsawEn %x\n", > ThermalConfig->DmiHaAWC.DmiTsawEn)); > + DEBUG ((DEBUG_INFO, " DmiHaAWC TS0TW %x\n", > ThermalConfig->DmiHaAWC.TS0TW)); > + DEBUG ((DEBUG_INFO, " DmiHaAWC TS1TW %x\n", > ThermalConfig->DmiHaAWC.TS1TW)); > + DEBUG ((DEBUG_INFO, " DmiHaAWC TS2TW %x\n", > ThermalConfig->DmiHaAWC.TS2TW)); > + DEBUG ((DEBUG_INFO, " DmiHaAWC TS3TW %x\n", > ThermalConfig->DmiHaAWC.TS3TW)); > + DEBUG ((DEBUG_INFO, " DmiHaAWC SuggestedSetting %x\n", > ThermalConfig->DmiHaAWC.SuggestedSetting)); > + > + DEBUG ((DEBUG_INFO, " MemoryThrottling Enable=3D %x\n", > ThermalConfig->MemoryThrottling.Enable)); > + for (Index =3D 0; Index < MaxTsGpioPin; Index++) { > + DEBUG ((DEBUG_INFO, " MemoryThrottling TsGpioPinSetting > PmsyncEnable=3D %x\n", > ThermalConfig->MemoryThrottling.TsGpioPinSetting[Index].PmsyncEnable)); > + DEBUG ((DEBUG_INFO, " MemoryThrottling TsGpioPinSetting > C0TransmitEnable=3D %x\n", > ThermalConfig->MemoryThrottling.TsGpioPinSetting[Index].C0TransmitEnabl > e)); > + DEBUG ((DEBUG_INFO, " MemoryThrottling TsGpioPinSetting > PinSelection=3D %x\n", > ThermalConfig->MemoryThrottling.TsGpioPinSetting[Index].PinSelection)); > + } > + DEBUG ((DEBUG_INFO, " PchHotEnable =3D %x\n", > ThermalConfig->PchHotEnable)); > + DEBUG ((DEBUG_INFO, " PchHotLevel =3D %x\n", > ThermalConfig->PchHotLevel)); > +} > + > +/** > + Print PCH_GENERAL_CONFIG and serial out. > + > + @param[in] PchGeneralConfig Pointer to a PCH_GENERAL_CONFIG that > provides the platform setting > + > +**/ > +VOID > +PchPrintGeneralConfig ( > + IN CONST PCH_GENERAL_CONFIG *PchGeneralConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH General Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, " Crid=3D %x\n", PchGeneralConfig->Crid)); > + DEBUG ((DEBUG_INFO, " LegacyIoLowLatency =3D %x\n", > PchGeneralConfig->LegacyIoLowLatency)); > +} > + > +/** > + Print PCH_LAN_CONFIG and serial out. > + > + @param[in] LanConfig Pointer to a PCH_LAN_CONFIG that provides > the platform setting > + > +**/ > +VOID > +PchPrintLanConfig ( > + IN CONST PCH_LAN_CONFIG *LanConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH LAN Config ---------------= ---\n")); > + DEBUG ((DEBUG_INFO, " Enable=3D %x\n", LanConfig->Enable)); > + DEBUG ((DEBUG_INFO, " LtrEnable=3D %x\n", LanConfig->LtrEnable)); > +} > + > +/** > + Print PCH_SERIAL_IO_CONFIG and serial out. > + > + @param[in] SerialIoConfig Pointer to a PCH_SERIAL_IO_CONFIG th= at > provides the platform setting > + > +**/ > +VOID > +PchPrintSerialIoConfig ( > + IN CONST PCH_SERIAL_IO_CONFIG *SerialIoConfig > + ) > +{ > + UINTN Index; > +#ifndef MDEPKG_NDEBUG > + static UINT8 DeviceName[PCH_MAX_SERIALIO_CONTROLLERS][5] =3D > {"I2C0","I2C1","I2C2","I2C3","I2C4","I2C5","SPI0","SPI1","SPI2","UA00","U= A01" > ,"UA02"}; > +#endif > + > + DEBUG ((DEBUG_INFO, "------------------ PCH Serial IO Config > ------------------\n")); > + DEBUG_CODE_BEGIN (); > + for (Index =3D 0; Index < GetPchMaxSerialIoControllersNum (); Index++)= { > + DEBUG ((DEBUG_INFO, " SerialIoController %a: Mode 0x%x\n", > DeviceName[Index], SerialIoConfig->DevMode[Index])); > + } > + DEBUG_CODE_END (); > + for (Index =3D 0; Index < GetPchMaxSerialIoSpiControllersNum (); Index= ++) { > + DEBUG ((DEBUG_INFO, " SpiCsPolarity[%d] =3D 0x%x\n", Index, > SerialIoConfig->SpiCsPolarity[Index])); > + } > + for (Index =3D 0; Index < GetPchMaxSerialIoUartControllersNum (); Inde= x++) { > + DEBUG ((DEBUG_INFO, " UartHwFlowCtrl[%d] =3D 0x%x\n", Index, > SerialIoConfig->UartHwFlowCtrl[Index])); > + } > + for (Index =3D 0; Index < GetPchMaxSerialIoI2cControllersNum (); Index= ++) { > + DEBUG ((DEBUG_INFO, " I2cPadsTermination[%d] =3D 0x%x\n", Index, > SerialIoConfig->I2cPadsTermination[Index])); > + } > + DEBUG ((DEBUG_INFO, " DebugUartNumber =3D 0x%x\n", > SerialIoConfig->DebugUartNumber)); > + DEBUG ((DEBUG_INFO, " EnableDebugUartAfterPost =3D 0x%x\n", > SerialIoConfig->EnableDebugUartAfterPost)); > + DEBUG ((DEBUG_INFO, " Uart0PinMuxing =3D 0x%x\n", > SerialIoConfig->Uart0PinMuxing)); > +} > + > +/** > + Print PCH_INTERRUPT_CONFIG and serial out > + > + @param[in] InterruptConfig Pointer to Interrupt Configuration > structure > + > +**/ > +VOID > +PchPrintInterruptConfig ( > + IN CONST PCH_INTERRUPT_CONFIG *InterruptConfig > + ) > +{ > + UINTN Index; > + // > + // Print interrupt information > + // > + DEBUG ((DEBUG_INFO, "------------------ PCH Interrupt Config > ------------------\n")); > + DEBUG ((DEBUG_INFO, " Interrupt assignment:\n")); > + DEBUG ((DEBUG_INFO, " Dxx:Fx INTx IRQ\n")); > + for (Index =3D 0; Index < InterruptConfig->NumOfDevIntConfig; Index++)= { > + DEBUG ((DEBUG_INFO, " D%02d:F%d %d %03d\n", > + InterruptConfig->DevIntConfig[Index].Device, > + InterruptConfig->DevIntConfig[Index].Function, > + InterruptConfig->DevIntConfig[Index].IntX, > + InterruptConfig->DevIntConfig[Index].Irq)); > + } > + DEBUG ((DEBUG_INFO, " Legacy PIC interrupt routing:\n")); > + DEBUG ((DEBUG_INFO, " PIRQx IRQx\n")); > + for (Index =3D 0; Index < PCH_MAX_PXRC_CONFIG; Index++) { > + DEBUG ((DEBUG_INFO, " PIRQ%c -> IRQ%d\n", Index + 65, > InterruptConfig->PxRcConfig[Index])); > + } > + DEBUG ((DEBUG_INFO, " Other interrupt configuration:\n")); > + DEBUG ((DEBUG_INFO, " GpioIrqRoute=3D %d\n", > InterruptConfig->GpioIrqRoute)); > + DEBUG ((DEBUG_INFO, " SciIrqSelect=3D %d\n", > InterruptConfig->SciIrqSelect)); > + DEBUG ((DEBUG_INFO, " TcoIrqEnable=3D %d\n", > InterruptConfig->TcoIrqEnable)); > + DEBUG ((DEBUG_INFO, " TcoIrqSelect=3D %d\n", > InterruptConfig->TcoIrqSelect)); > +} > + > +/** > + Print PCH_SCS_CONFIG and serial out. > + > + @param[in] ScsConfig Pointer to a PCH_SCS_CONFIG that provides > the platform setting > + > +**/ > +VOID > +PchPrintScsConfig ( > + IN CONST PCH_SCS_CONFIG *ScsConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH SCS Config ---------------= ---\n")); > + DEBUG ((DEBUG_INFO, " ScsEmmcEnabled =3D %x\n", > ScsConfig->ScsEmmcEnabled)); > + DEBUG ((DEBUG_INFO, " ScsSdcardEnabled =3D %x\n", > ScsConfig->ScsSdcardEnabled)); > + DEBUG ((DEBUG_INFO, " SdCardPowerEnableActiveHigh =3D %x\n", > ScsConfig->SdCardPowerEnableActiveHigh)); > + DEBUG ((DEBUG_INFO, " ScsUfsEnabled =3D %x\n", > ScsConfig->ScsUfsEnabled)); > + DEBUG ((DEBUG_INFO, " ScsEmmcHs400Enabled =3D %x\n", > ScsConfig->ScsEmmcHs400Enabled)); > + DEBUG ((DEBUG_INFO, " ScsEmmcHs400TuningRequired =3D %x\n", > ScsConfig->ScsEmmcHs400TuningRequired)); > + DEBUG ((DEBUG_INFO, " ScsEmmcHs400DllDataValid =3D %x\n", > ScsConfig->ScsEmmcHs400DllDataValid)); > + DEBUG ((DEBUG_INFO, " ScsEmmcHs400RxStrobeDll1 =3D %x\n", > ScsConfig->ScsEmmcHs400RxStrobeDll1)); > + DEBUG ((DEBUG_INFO, " ScsEmmcHs400TxDataDll =3D %x\n", > ScsConfig->ScsEmmcHs400TxDataDll)); > + DEBUG ((DEBUG_INFO, " ScsEmmcHs400DriverStrength =3D %x\n", > ScsConfig->ScsEmmcHs400DriverStrength)); > +} > + > +/** > + Print PCH_ISH_CONFIG and serial out. > + > + @param[in] IshConfig Pointer to a PCH_ISH_CONFIG that provides > the platform setting > + > +**/ > +VOID > +PchPrintIshConfig ( > + IN CONST PCH_ISH_CONFIG *IshConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH ISH Config ---------------= ---\n")); > + DEBUG ((DEBUG_INFO, " SPI GPIO Assigned =3D %x\n", > IshConfig->SpiGpioAssign)); > + DEBUG ((DEBUG_INFO, " UART0 GPIO Assigned =3D %x\n", > IshConfig->Uart0GpioAssign)); > + DEBUG ((DEBUG_INFO, " UART1 GPIO Assigned =3D %x\n", > IshConfig->Uart1GpioAssign)); > + DEBUG ((DEBUG_INFO, " I2C0 GPIO Assigned =3D %x\n", > IshConfig->I2c0GpioAssign)); > + DEBUG ((DEBUG_INFO, " I2C1 GPIO Assigned =3D %x\n", > IshConfig->I2c1GpioAssign)); > + DEBUG ((DEBUG_INFO, " I2C2 GPIO Assigned =3D %x\n", > IshConfig->I2c2GpioAssign)); > + DEBUG ((DEBUG_INFO, " GP_0 GPIO Assigned =3D %x\n", > IshConfig->Gp0GpioAssign)); > + DEBUG ((DEBUG_INFO, " GP_1 GPIO Assigned =3D %x\n", > IshConfig->Gp1GpioAssign)); > + DEBUG ((DEBUG_INFO, " GP_2 GPIO Assigned =3D %x\n", > IshConfig->Gp2GpioAssign)); > + DEBUG ((DEBUG_INFO, " GP_3 GPIO Assigned =3D %x\n", > IshConfig->Gp3GpioAssign)); > + DEBUG ((DEBUG_INFO, " GP_4 GPIO Assigned =3D %x\n", > IshConfig->Gp4GpioAssign)); > + DEBUG ((DEBUG_INFO, " GP_5 GPIO Assigned =3D %x\n", > IshConfig->Gp5GpioAssign)); > + DEBUG ((DEBUG_INFO, " GP_6 GPIO Assigned =3D %x\n", > IshConfig->Gp6GpioAssign)); > + DEBUG ((DEBUG_INFO, " GP_7 GPIO Assigned =3D %x\n", > IshConfig->Gp7GpioAssign)); > +} > + > +/** > + Print PCH_FLASH_PROTECTION_CONFIG and serial out. > + > + @param[in] FlashProtectConfig Pointer to a > PCH_FLASH_PROTECTION_CONFIG that provides the platform setting > + > +**/ > +VOID > +PchPrintFlashProtectionConfig ( > + IN CONST PCH_FLASH_PROTECTION_CONFIG *FlashProtectConfig > + ) > +{ > + UINT32 Index; > + > + DEBUG ((DEBUG_INFO, "------------------ PCH Flash Protection Config > ------------------\n")); > + for (Index =3D 0; Index < PCH_FLASH_PROTECTED_RANGES; ++Index) { > + DEBUG ((DEBUG_INFO, " WriteProtectionEnable[%d] =3D %x\n", Index, > FlashProtectConfig->ProtectRange[Index].WriteProtectionEnable)); > + DEBUG ((DEBUG_INFO, " ReadProtectionEnable[%d] =3D %x\n", Index, > FlashProtectConfig->ProtectRange[Index].ReadProtectionEnable)); > + DEBUG ((DEBUG_INFO, " ProtectedRangeLimit[%d] =3D %x\n", Index, > FlashProtectConfig->ProtectRange[Index].ProtectedRangeLimit)); > + DEBUG ((DEBUG_INFO, " ProtectedRangeBase[%d] =3D %x\n", Index, > FlashProtectConfig->ProtectRange[Index].ProtectedRangeBase)); > + } > +} > + > +/** > + Print PCH_P2SB_CONFIG and serial out. > + > + @param[in] P2sbConfig Pointer to a PCH_P2SB_CONFIG tha= t > provides the platform setting > + > +**/ > +VOID > +PchPrintP2sbConfig ( > + IN CONST PCH_P2SB_CONFIG *P2sbConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH P2SB Config --------------= ----\n")); > + DEBUG ((DEBUG_INFO, "SbAccessUnlock=3D %x\n", > P2sbConfig->SbAccessUnlock)); > +} > + > +/** > + Print PCH_ESPI_CONFIG. > + > + @param[in] EspiConfig Pointer to a PCH_ESPI_CONFIG that provid= es > the eSPI setting > + > +**/ > +VOID > +PchPrintEspiConfig ( > + IN CONST PCH_ESPI_CONFIG *EspiConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH eSPI Config --------------= ----\n")); > + DEBUG ((DEBUG_INFO, " LGMR Enable %x\n", EspiConfig->LgmrEnable)); > + DEBUG ((DEBUG_INFO, " BME for Master and Slave Enabled %x\n", > EspiConfig->BmeMasterSlaveEnabled)); > +} > + > +/** > + Print PCH_CNVI_CONFIG. > + > + @param[in] CnviConfig Pointer to a PCH_CNVI_CONFIG that provid= es > the CNVi settings > + > +**/ > +VOID > +PchPrintCnviConfig ( > + IN CONST PCH_CNVI_CONFIG *CnviConfig > + ) > +{ > + DEBUG ((DEBUG_INFO, "------------------ PCH CNVi Config --------------= ----\n")); > + DEBUG ((DEBUG_INFO, "CNVi Mode =3D %x\n", CnviConfig->Mode)); > + DEBUG ((DEBUG_INFO, "CNVi MfUart1 type =3D %x\n", > CnviConfig->MfUart1Type)); > +} > + > +/** > + Print PCH_HSIO_CONFIG. > + > + @param[in] HsioConfig Pointer to a PCH_HSIO_CONFIG that provid= es > the eSPI setting > + > +**/ > +VOID > +PchPrintHsioConfig ( > + IN CONST PCH_HSIO_CONFIG *HsioConfig > + ) > +{ > + PCH_HSIO_VER_INFO *BiosChipsetInitVerInfoPtr; > + DEBUG ((DEBUG_INFO, "------------------ PCH HSIO Config --------------= ----\n")); > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary Pointer =3D %x\n", > HsioConfig->ChipsetInitBinPtr)); > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary Length =3D %x\n", > HsioConfig->ChipsetInitBinLen)); > + BiosChipsetInitVerInfoPtr =3D (PCH_HSIO_VER_INFO *) > HsioConfig->ChipsetInitBinPtr; > + if (HsioConfig->ChipsetInitBinPtr && HsioConfig->ChipsetInitBinLen) { > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary Base CRC =3D %x\n= ", > BiosChipsetInitVerInfoPtr->BaseCrc)); > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary OEM CRC =3D %x\n= ", > BiosChipsetInitVerInfoPtr->OemCrc)); > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary SUS CRC =3D %x\n= ", > BiosChipsetInitVerInfoPtr->SusCrc)); > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary Version =3D %x\n= ", > BiosChipsetInitVerInfoPtr->Version)); > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary Product =3D %x\n= ", > BiosChipsetInitVerInfoPtr->Product)); > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary Metal Layer =3D %x\n= ", > BiosChipsetInitVerInfoPtr->MetalLayer)); > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary Base Layer =3D %x\n= ", > BiosChipsetInitVerInfoPtr->BaseLayer)); > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary OEM Version =3D %x\n= ", > BiosChipsetInitVerInfoPtr->OemVersion)); > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary Debug Mode =3D %x\n= ", > BiosChipsetInitVerInfoPtr->DebugMode)); > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary OEM CRC Valid =3D %x\n= ", > BiosChipsetInitVerInfoPtr->OemCrcValid)); > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary SUS CRC Valid =3D %x\n= ", > BiosChipsetInitVerInfoPtr->SusCrcValid)); > + DEBUG ((DEBUG_INFO, " ChipsetInit Binary Base CRC Valid =3D %x\n= ", > BiosChipsetInitVerInfoPtr->BaseCrcValid)); > + } > +} > + > +/** > + Print whole PCH config blocks and serial out. > + > + @param[in] SiPolicyPpi The RC Policy PPI instance > + > +**/ > +VOID > +EFIAPI > +PchPrintPolicyPpi ( > + IN SI_POLICY_PPI *SiPolicyPpi > + ) > +{ > +DEBUG_CODE_BEGIN(); > + EFI_STATUS Status; > + PCH_GENERAL_CONFIG *PchGeneralConfig; > + PCH_PCIE_CONFIG *PcieRpConfig; > + PCH_SATA_CONFIG *SataConfig; > + PCH_IOAPIC_CONFIG *IoApicConfig; > + PCH_DMI_CONFIG *DmiConfig; > + PCH_FLASH_PROTECTION_CONFIG *FlashProtectionConfig; > + PCH_HDAUDIO_CONFIG *HdAudioConfig; > + PCH_INTERRUPT_CONFIG *InterruptConfig; > + PCH_ISH_CONFIG *IshConfig; > + PCH_LAN_CONFIG *LanConfig; > + PCH_P2SB_CONFIG *P2sbConfig; > + PCH_LOCK_DOWN_CONFIG *LockDownConfig; > + PCH_PM_CONFIG *PmConfig; > + PCH_SCS_CONFIG *ScsConfig; > + PCH_SERIAL_IO_CONFIG *SerialIoConfig; > + PCH_LPC_SIRQ_CONFIG *SerialIrqConfig; > + PCH_THERMAL_CONFIG *ThermalConfig; > + USB_CONFIG *UsbConfig; > + PCH_ESPI_CONFIG *EspiConfig; > + PCH_CNVI_CONFIG *CnviConfig; > + PCH_HSIO_CONFIG *HsioConfig; > + UINT32 SataCtrlIndex; > + > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gPchGeneralConfigGui= d, > (VOID *) &PchGeneralConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gPcieRpConfigGuid, (= VOID *) > &PcieRpConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gIoApicConfigGuid, (= VOID *) > &IoApicConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gDmiConfigGuid, (VOI= D *) > &DmiConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gFlashProtectionConf= igGuid, > (VOID *) &FlashProtectionConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gHdAudioConfigGuid, = (VOID > *) &HdAudioConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gInterruptConfigGuid= , (VOID > *) &InterruptConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gIshConfigGuid, (VOI= D *) > &IshConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gLanConfigGuid, (VOI= D *) > &LanConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gLockDownConfigGuid, > (VOID *) &LockDownConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gP2sbConfigGuid, (VO= ID *) > &P2sbConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gPmConfigGuid, (VOID= *) > &PmConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gScsConfigGuid, (VOI= D *) > &ScsConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gSerialIoConfigGuid,= (VOID *) > &SerialIoConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gSerialIrqConfigGuid= , (VOID > *) &SerialIrqConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gThermalConfigGuid, = (VOID > *) &ThermalConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gUsbConfigGuid, (VOI= D *) > &UsbConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gEspiConfigGuid, (VO= ID *) > &EspiConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gCnviConfigGuid, (VO= ID *) > &CnviConfig); > + ASSERT_EFI_ERROR (Status); > + Status =3D GetConfigBlock ((VOID *) SiPolicyPpi, &gHsioConfigGuid, (VO= ID *) > &HsioConfig); > + ASSERT_EFI_ERROR (Status); > + > + DEBUG ((DEBUG_INFO, "------------------------ PCH Print Policy Start > ------------------------\n")); > + DEBUG ((DEBUG_INFO, " Revision=3D %x\n", > SiPolicyPpi->TableHeader.Header.Revision)); > + > + PchPrintGeneralConfig (PchGeneralConfig); > + PchPrintPcieConfig (PcieRpConfig); > + for (SataCtrlIndex =3D 0; SataCtrlIndex < GetPchMaxSataControllerNum (= ); > SataCtrlIndex++) { > + SataConfig =3D GetPchSataConfig (SiPolicyPpi, SataCtrlIndex); > + PchPrintSataConfig (SataCtrlIndex, SataConfig); > + } > + PchPrintUsbConfig (UsbConfig); > + PchPrintIoApicConfig (IoApicConfig); > + PchPrintHdAudioConfig (HdAudioConfig); > + PchPrintLanConfig (LanConfig); > + PchPrintLockDownConfig (LockDownConfig); > + PchPrintThermalConfig (ThermalConfig); > + PchPrintPmConfig (PmConfig); > + PchPrintDmiConfig (DmiConfig); > + PchPrintSerialIrqConfig (SerialIrqConfig); > + PchPrintSerialIoConfig (SerialIoConfig); > + PchPrintInterruptConfig (InterruptConfig); > + PchPrintScsConfig (ScsConfig); > + PchPrintIshConfig (IshConfig); > + PchPrintFlashProtectionConfig (FlashProtectionConfig); > + PchPrintP2sbConfig (P2sbConfig); > + PchPrintEspiConfig (EspiConfig); > + PchPrintCnviConfig (CnviConfig); > + PchPrintHsioConfig (HsioConfig); > + > + DEBUG ((DEBUG_INFO, "------------------------ PCH Print Platform Proto= col End > --------------------------\n")); > +DEBUG_CODE_END(); > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPo= lic > yLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPo= lic > yLib.c > new file mode 100644 > index 0000000000..2a1da20667 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPo= lic > yLib.c > @@ -0,0 +1,739 @@ > +/** @file > + This file is PeiPchPolicy library. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "PeiPchPolicyLibrary.h" > +#include > +#include > +#include > + > +/** > + mPxRcConfig[] table contains data for 8259 routing (how PIRQx is mappe= d to > IRQy). > + This information is used by systems which choose to use legacy PIC > + interrupt controller. Only IRQ3-7,9-12,14,15 are valid. Values from th= is table > + will be programmed into ITSS.PxRC registers. > +**/ > +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPxRcConfig[] =3D { > + 11, // PARC: PIRQA -> IRQ11 > + 10, // PBRC: PIRQB -> IRQ10 > + 11, // PCRC: PIRQC -> IRQ11 > + 11, // PDRC: PIRQD -> IRQ11 > + 11, // PERC: PIRQE -> IRQ11 > + 11, // PFRC: PIRQF -> IRQ11 > + 11, // PGRC: PIRQG -> IRQ11 > + 11 // PHRC: PIRQH -> IRQ11 > +}; > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadPchGeneralConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_GENERAL_CONFIG *PchGeneralConfig; > + PchGeneralConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "PchGeneralConfig->Header.GuidHob.Name =3D > %g\n", &PchGeneralConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "PchGeneralConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > PchGeneralConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + PCH general configuration > + ********************************/ > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadPcieRpConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + UINTN Index; > + PCH_PCIE_CONFIG *PcieRpConfig; > + > + PcieRpConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "PcieRpConfig->Header.GuidHob.Name =3D %g\n", > &PcieRpConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "PcieRpConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > PcieRpConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + PCI Express related settings > + ********************************/ > + PcieRpConfig->RpFunctionSwap =3D TRUE; > + > + for (Index =3D 0; Index < GetPchMaxPciePortNum (); Index++) { > + PcieRpConfig->RootPort[Index].Aspm =3D > PchPcieAspmAutoConfig; > + PcieRpConfig->RootPort[Index].PmSci =3D TRUE; > + PcieRpConfig->RootPort[Index].AcsEnabled =3D TRUE; > + PcieRpConfig->RootPort[Index].PtmEnabled =3D TRUE; > + PcieRpConfig->RootPort[Index].DpcEnabled =3D TRUE; > + PcieRpConfig->RootPort[Index].RpDpcExtensionsEnabled =3D TRUE; > + PcieRpConfig->RootPort[Index].MaxPayload =3D > PchPcieMaxPayload256; > + PcieRpConfig->RootPort[Index].SlotImplemented =3D TRUE; > + PcieRpConfig->RootPort[Index].PhysicalSlotNumber =3D (UINT8) Ind= ex; > + PcieRpConfig->RootPort[Index].L1Substates =3D > PchPcieL1SubstatesL1_1_2; > + PcieRpConfig->RootPort[Index].EnableCpm =3D TRUE; > + PcieRpConfig->RootPort[Index].Gen3EqPh3Method =3D > PchPcieEqHardware; > + > + // > + // PCIe LTR Configuration. > + // > + PcieRpConfig->RootPort[Index].LtrEnable =3D TRUE; > + > + PcieRpConfig->RootPort[Index].LtrMaxSnoopLatency =3D 0= x1003; > + PcieRpConfig->RootPort[Index].LtrMaxNoSnoopLatency =3D > 0x1003; > + > + PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMode =3D= 2; > + PcieRpConfig->RootPort[Index].SnoopLatencyOverrideMultiplier =3D= 2; > + PcieRpConfig->RootPort[Index].SnoopLatencyOverrideValue =3D= 60; > + PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMode =3D > 2; > + PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideMultiplier =3D > 2; > + PcieRpConfig->RootPort[Index].NonSnoopLatencyOverrideValue =3D > 60; > + > + PcieRpConfig->RootPort[Index].Uptp =3D= 5; > + PcieRpConfig->RootPort[Index].Dptp =3D= 7; > + > + PcieRpConfig->EqPh3LaneParam[Index].Cm =3D= 6; > + PcieRpConfig->EqPh3LaneParam[Index].Cp =3D= 2; > + } > + > + PcieRpConfig->SwEqCoeffList[0].Cm =3D 4; > + PcieRpConfig->SwEqCoeffList[0].Cp =3D 8; > + PcieRpConfig->SwEqCoeffList[1].Cm =3D 6; > + PcieRpConfig->SwEqCoeffList[1].Cp =3D 2; > + PcieRpConfig->SwEqCoeffList[2].Cm =3D 8; > + PcieRpConfig->SwEqCoeffList[2].Cp =3D 6; > + PcieRpConfig->SwEqCoeffList[3].Cm =3D 10; > + PcieRpConfig->SwEqCoeffList[3].Cp =3D 8; > + PcieRpConfig->SwEqCoeffList[4].Cm =3D 12; > + PcieRpConfig->SwEqCoeffList[4].Cp =3D 2; > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadSataConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + UINTN PortIndex; > + UINTN Index; > + UINT32 SataCtrlIndex; > + PCH_SATA_CONFIG *SataConfig; > + > + SataConfig =3D (PCH_SATA_CONFIG *)ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "SataConfig->Header.GuidHob.Name =3D %g\n", > &SataConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, "SataConfig->Header.GuidHob.Header.HobLength =3D > 0x%x\n", SataConfig->Header.GuidHob.Header.HobLength)); > + > + for (SataCtrlIndex =3D 0; SataCtrlIndex < GetPchMaxSataControllerNum (= ); > SataCtrlIndex++, SataConfig++) { > + /******************************** > + SATA related settings > + ********************************/ > + SataConfig->Enable =3D TRUE; > + SataConfig->SalpSupport =3D TRUE; > + SataConfig->SataMode =3D PchSataModeAhci; > + > + for (PortIndex =3D 0; PortIndex < GetPchMaxSataPortNum (SataCtrlInde= x); > PortIndex++) { > + SataConfig->PortSettings[PortIndex].Enable =3D TRUE; > + SataConfig->PortSettings[PortIndex].DmVal =3D 15; > + SataConfig->PortSettings[PortIndex].DitoVal =3D 625; > + } > + > + SataConfig->Rst.Raid0 =3D TRUE; > + SataConfig->Rst.Raid1 =3D TRUE; > + SataConfig->Rst.Raid10 =3D TRUE; > + SataConfig->Rst.Raid5 =3D TRUE; > + SataConfig->Rst.Irrt =3D TRUE; > + SataConfig->Rst.OromUiBanner =3D TRUE; > + SataConfig->Rst.OromUiDelay =3D PchSataOromDelay2sec; > + SataConfig->Rst.HddUnlock =3D TRUE; > + SataConfig->Rst.LedLocate =3D TRUE; > + SataConfig->Rst.IrrtOnly =3D TRUE; > + SataConfig->Rst.SmartStorage =3D TRUE; > + SataConfig->Rst.OptaneMemory =3D TRUE; > + SataConfig->Rst.CpuAttachedStorage =3D TRUE; > + > + for (Index =3D 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) { > + SataConfig->RstPcieStorageRemap[Index].DeviceResetDelay = =3D > 100; > + } > + > + SataConfig->PwrOptEnable =3D TRUE; > + SataConfig->ThermalThrottling.SuggestedSetting =3D TRUE; > + } > +} > + > +/** > + Get Sata Config Policy > + > + @param[in] SiPolicy The RC Policy PPI instance > + @param[in] SataCtrlIndex SATA controller index > + > + @retval SataConfig Pointer to Sata Config Policy > +**/ > +PCH_SATA_CONFIG * > +GetPchSataConfig ( > + IN SI_POLICY_PPI *SiPolicy, > + IN UINT32 SataCtrlIndex > + ) > +{ > + PCH_SATA_CONFIG *SataConfig; > + EFI_STATUS Status; > + > + ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ()); > + > + Status =3D GetConfigBlock ((VOID *) SiPolicy, &gSataConfigGuid, (VOID = *) > &SataConfig); > + ASSERT_EFI_ERROR (Status); > + > + SataConfig +=3D SataCtrlIndex; > + > + return SataConfig; > +} > + > +/** > + Load Config block default > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadIoApicConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_IOAPIC_CONFIG *IoApicConfig; > + IoApicConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "IoApicConfig->Header.GuidHob.Name =3D %g\n", > &IoApicConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, "IoApicConfig->Header.GuidHob.Header.HobLength > =3D 0x%x\n", IoApicConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + Io Apic configuration > + ********************************/ > + IoApicConfig->IoApicId =3D 0x02; > + IoApicConfig->IoApicEntry24_119 =3D TRUE; > + IoApicConfig->Enable8254ClockGating =3D TRUE; > + IoApicConfig->Enable8254ClockGatingOnS3 =3D TRUE; > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadDmiConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_DMI_CONFIG *DmiConfig; > + DmiConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "DmiConfig->Header.GuidHob.Name =3D %g\n", > &DmiConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, "DmiConfig->Header.GuidHob.Header.HobLength =3D > 0x%x\n", DmiConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + DMI related settings > + ********************************/ > + DmiConfig->DmiAspmCtrl =3D PchPcieAspmAutoConfig; > +} > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadFlashProtectionConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_FLASH_PROTECTION_CONFIG *FlashProtectionConfig; > + FlashProtectionConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "FlashProtectionConfig->Header.GuidHob.Name =3D > %g\n", &FlashProtectionConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "FlashProtectionConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > FlashProtectionConfig->Header.GuidHob.Header.HobLength)); > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadHdAudioConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_HDAUDIO_CONFIG *HdAudioConfig; > + HdAudioConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "HdAudioConfig->Header.GuidHob.Name =3D %g\n", > &HdAudioConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "HdAudioConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > HdAudioConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + HD-Audio configuration > + ********************************/ > + HdAudioConfig->DspEnable =3D TRUE; > + HdAudioConfig->HdAudioLinkFrequency =3D PchHdaLinkFreq24MHz; > + HdAudioConfig->IDispLinkFrequency =3D PchHdaLinkFreq96MHz; > + HdAudioConfig->IDispLinkTmode =3D PchHdaIDispMode2T; > + HdAudioConfig->ResetWaitTimer =3D 600; // Must be at least 521us= (25 > frames) > + HdAudioConfig->AudioLinkHda =3D TRUE; > + HdAudioConfig->AudioLinkDmic0 =3D TRUE; > + HdAudioConfig->AudioLinkDmic1 =3D TRUE; > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadInterruptConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_INTERRUPT_CONFIG *InterruptConfig; > + InterruptConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "InterruptConfig->Header.GuidHob.Name =3D %g\n", > &InterruptConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "InterruptConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > InterruptConfig->Header.GuidHob.Header.HobLength)); > + > + LoadDeviceInterruptConfig (InterruptConfig); > + > + ASSERT ((sizeof (mPxRcConfig) / sizeof (UINT8)) <=3D > PCH_MAX_PXRC_CONFIG); > + CopyMem ( > + InterruptConfig->PxRcConfig, > + mPxRcConfig, > + sizeof (mPxRcConfig) > + ); > + > + InterruptConfig->GpioIrqRoute =3D 14; > + InterruptConfig->SciIrqSelect =3D 9; > + InterruptConfig->TcoIrqSelect =3D 9; > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadIshConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_ISH_CONFIG *IshConfig; > + IshConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "IshConfig->Header.GuidHob.Name =3D %g\n", > &IshConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, "IshConfig->Header.GuidHob.Header.HobLength =3D > 0x%x\n", IshConfig->Header.GuidHob.Header.HobLength)); > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadLanConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_LAN_CONFIG *LanConfig; > + UINT16 LpcDid; > + > + LanConfig =3D ConfigBlockPointer; > + LpcDid =3D PchGetLpcDid (); > + > + DEBUG ((DEBUG_INFO, "LanConfig->Header.GuidHob.Name =3D %g\n", > &LanConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, "LanConfig->Header.GuidHob.Header.HobLength =3D > 0x%x\n", LanConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + Lan configuration > + ********************************/ > + LanConfig->Enable =3D TRUE; > + LanConfig->LtrEnable =3D TRUE; > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadLockDownConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_LOCK_DOWN_CONFIG *LockDownConfig; > + LockDownConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "LockDownConfig->Header.GuidHob.Name =3D %g\n", > &LockDownConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "LockDownConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > LockDownConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + Lockdown configuration > + ********************************/ > + LockDownConfig->GlobalSmi =3D TRUE; > + LockDownConfig->BiosInterface =3D TRUE; > + LockDownConfig->RtcMemoryLock =3D TRUE; > + LockDownConfig->BiosLock =3D TRUE; > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadP2sbConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_P2SB_CONFIG *P2sbConfig; > + P2sbConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "P2sbConfig->Header.GuidHob.Name =3D %g\n", > &P2sbConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, "P2sbConfig->Header.GuidHob.Header.HobLength =3D > 0x%x\n", P2sbConfig->Header.GuidHob.Header.HobLength)); > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadPmConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_PM_CONFIG *PmConfig; > + PmConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "PmConfig->Header.GuidHob.Name =3D %g\n", > &PmConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, "PmConfig->Header.GuidHob.Header.HobLength =3D > 0x%x\n", PmConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + MiscPm Configuration > + ********************************/ > + PmConfig->MeWakeSts =3D TRUE; > + PmConfig->WolOvrWkSts =3D TRUE; > + > + PmConfig->WakeConfig.WolEnableOverride =3D TRUE; > + PmConfig->WakeConfig.LanWakeFromDeepSx =3D TRUE; > + > + PmConfig->PchSlpS3MinAssert =3D PchSlpS350ms; > + PmConfig->PchSlpS4MinAssert =3D PchSlpS41s; > + PmConfig->PchSlpSusMinAssert =3D PchSlpSus4s; > + PmConfig->PchSlpAMinAssert =3D PchSlpA2s; > + > + PmConfig->SlpLanLowDc =3D TRUE; > + PmConfig->PciePllSsc =3D 0xFF; > + PmConfig->LpcClockRun =3D TRUE; > + PmConfig->SlpS0Enable =3D TRUE; > + PmConfig->CpuC10GatePinEnable =3D TRUE; > + if (IsWhlCpu () && (GetCpuStepping () =3D=3D EnumCflV0)) { > + PmConfig->SlpS0WithGbeSupport =3D FALSE; > + } else { > + PmConfig->SlpS0WithGbeSupport =3D TRUE; > + } > + > + if (IsPchLp ()) { > + PmConfig->ModPhySusPgEnable =3D TRUE; > + } > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadScsConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_SCS_CONFIG *ScsConfig; > + ScsConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "ScsConfig->Header.GuidHob.Name =3D %g\n", > &ScsConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, "ScsConfig->Header.GuidHob.Header.HobLength =3D > 0x%x\n", ScsConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + SCS Configuration > + ********************************/ > + ScsConfig->ScsEmmcEnabled =3D IsPchLp () ? TRUE : FALSE; // eMMC pre= sent > on PCH-LP only > + ScsConfig->ScsEmmcHs400DriverStrength =3D DriverStrength40Ohm; > + //Enable Sd Card controller for Non-Desktop sku platforms > + if (GetCpuSku () !=3D EnumCpuTrad) { > + ScsConfig->ScsSdcardEnabled =3D TRUE; > + } > + ScsConfig->SdCardPowerEnableActiveHigh =3D TRUE; > + ScsConfig->ScsUfsEnabled =3D TRUE; > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadSerialIoConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + UINTN Index; > + PCH_SERIAL_IO_CONFIG *SerialIoConfig; > + SerialIoConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "SerialIoConfig->Header.GuidHob.Name =3D %g\n", > &SerialIoConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "SerialIoConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > SerialIoConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + SerialIo Configuration > + ********************************/ > + for (Index =3D 0; Index < GetPchMaxSerialIoControllersNum (); Index++)= { > + SerialIoConfig->DevMode[Index] =3D PchSerialIoPci; > + } > + SerialIoConfig->DebugUartNumber =3D PcdGet8 > (PcdSerialIoUartNumber); > +} > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadSerialIrqConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_LPC_SIRQ_CONFIG *SerialIrqConfig; > + SerialIrqConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "SerialIrqConfig->Header.GuidHob.Name =3D %g\n", > &SerialIrqConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "SerialIrqConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > SerialIrqConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + Serial IRQ Configuration > + ********************************/ > + SerialIrqConfig->SirqEnable =3D TRUE; > + SerialIrqConfig->SirqMode =3D PchQuietMode; > + SerialIrqConfig->StartFramePulse =3D PchSfpw4Clk; > +} > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadThermalConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_THERMAL_CONFIG *ThermalConfig; > + ThermalConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "ThermalConfig->Header.GuidHob.Name =3D %g\n", > &ThermalConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "ThermalConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > ThermalConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + Thermal configuration. > + ********************************/ > + ThermalConfig->TsmicLock =3D TRUE; > + ThermalConfig->PchHotLevel =3D 0x154; > + ThermalConfig->TTLevels.SuggestedSetting =3D TRUE; > + ThermalConfig->TTLevels.PchCrossThrottling =3D TRUE; > + ThermalConfig->DmiHaAWC.SuggestedSetting =3D TRUE; > + > + > ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioC].PmsyncEnable > =3D TRUE; > + > ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioC].C0TransmitEn > able =3D TRUE; > + > ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioD].PmsyncEnable > =3D TRUE; > + > ThermalConfig->MemoryThrottling.TsGpioPinSetting[TsGpioD].C0TransmitEn > able =3D TRUE; > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadUsbConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + UINTN PortIndex; > + USB_CONFIG *UsbConfig; > + UsbConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "UsbConfig->Header.GuidHob.Name =3D %g\n", > &UsbConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, "UsbConfig->Header.GuidHob.Header.HobLength =3D > 0x%x\n", UsbConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + USB related configuration > + ********************************/ > + for (PortIndex =3D 0; PortIndex < GetPchXhciMaxUsb2PortNum (); PortInd= ex++) > { > + UsbConfig->PortUsb20[PortIndex].Enable =3D TRUE; > + } > + > + for (PortIndex =3D 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortInd= ex++) > { > + UsbConfig->PortUsb30[PortIndex].Enable =3D TRUE; > + } > + > + // > + // BIOS should program PDO in PEI phase by default > + // > + UsbConfig->PdoProgramming =3D TRUE; > + > + // > + // Default values of USB2 AFE settings. > + // > + UsbConfig->Usb2PhySusPgEnable =3D TRUE; > + for (PortIndex =3D 0; PortIndex < GetPchXhciMaxUsb2PortNum (); PortInd= ex++) > { > + UsbConfig->PortUsb20[PortIndex].Afe.Petxiset =3D 3; > + UsbConfig->PortUsb20[PortIndex].Afe.Txiset =3D 2; > + UsbConfig->PortUsb20[PortIndex].Afe.Predeemp =3D 1; > + UsbConfig->PortUsb20[PortIndex].Afe.Pehalfbit =3D 1; > + } > + > + for (PortIndex =3D 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortInd= ex++) > { > + UsbConfig->PortUsb30HsioRx[PortIndex].HsioOlfpsCfgPullUpDwnRes =3D 3= ; > + } > + > + UsbConfig->XhciOcLock =3D TRUE; > + > + // > + // xDCI configuration > + // > + UsbConfig->XdciConfig.Enable =3D FALSE; > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadEspiConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_ESPI_CONFIG *EspiConfig; > + EspiConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "EspiConfig->Header.GuidHob.Name =3D %g\n", > &EspiConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, "EspiConfig->Header.GuidHob.Header.HobLength =3D > 0x%x\n", EspiConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + Espi configuration. > + ********************************/ > + EspiConfig->BmeMasterSlaveEnabled =3D TRUE; > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadCnviConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_CNVI_CONFIG *CnviConfig; > + CnviConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "CnviConfig->Header.GuidHob.Name =3D %g\n", > &CnviConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, "CnviConfig->Header.GuidHob.Header.HobLength =3D > 0x%x\n", CnviConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + Cnvi configuration. > + ********************************/ > + CnviConfig->Mode =3D CnviModeAuto; // Automatic detection > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadHsioConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_HSIO_CONFIG *HsioConfig; > + HsioConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "HsioConfig->Header.GuidHob.Name =3D %g\n", > &HsioConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, "HsioConfig->Header.GuidHob.Header.HobLength =3D > 0x%x\n", HsioConfig->Header.GuidHob.Header.HobLength)); > +} > + > +GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY > mPchIpBlocks [] =3D { > + {&gPchGeneralConfigGuid, sizeof (PCH_GENERAL_CONFIG), > PCH_GENERAL_CONFIG_REVISION, LoadPchGeneralConfigDefault}, > + {&gPcieRpConfigGuid, sizeof (PCH_PCIE_CONFIG), > PCIE_RP_CONFIG_REVISION, LoadPcieRpConfigDefault}, > + {&gSataConfigGuid, sizeof (PCH_SATA_CONFIG), > SATA_CONFIG_REVISION, LoadSataConfigDefault}, > + {&gIoApicConfigGuid, sizeof (PCH_IOAPIC_CONFIG), > IOAPIC_CONFIG_REVISION, LoadIoApicConfigDefault}, > + {&gDmiConfigGuid, sizeof (PCH_DMI_CONFIG), > DMI_CONFIG_REVISION, LoadDmiConfigDefault}, > + {&gFlashProtectionConfigGuid, sizeof (PCH_FLASH_PROTECTION_CONFIG), > FLASH_PROTECTION_CONFIG_REVISION, LoadFlashProtectionConfigDefault}, > + {&gHdAudioConfigGuid, sizeof (PCH_HDAUDIO_CONFIG), > HDAUDIO_CONFIG_REVISION, LoadHdAudioConfigDefault}, > + {&gInterruptConfigGuid, sizeof (PCH_INTERRUPT_CONFIG), > INTERRUPT_CONFIG_REVISION, LoadInterruptConfigDefault}, > + {&gIshConfigGuid, sizeof (PCH_ISH_CONFIG), > ISH_CONFIG_REVISION, LoadIshConfigDefault}, > + {&gLanConfigGuid, sizeof (PCH_LAN_CONFIG), > LAN_CONFIG_REVISION, LoadLanConfigDefault}, > + {&gLockDownConfigGuid, sizeof (PCH_LOCK_DOWN_CONFIG), > LOCK_DOWN_CONFIG_REVISION, LoadLockDownConfigDefault}, > + {&gP2sbConfigGuid, sizeof (PCH_P2SB_CONFIG), > P2SB_CONFIG_REVISION, LoadP2sbConfigDefault}, > + {&gPmConfigGuid, sizeof (PCH_PM_CONFIG), > PM_CONFIG_REVISION, LoadPmConfigDefault}, > + {&gScsConfigGuid, sizeof (PCH_SCS_CONFIG), > SCS_CONFIG_REVISION, LoadScsConfigDefault}, > + {&gSerialIoConfigGuid, sizeof (PCH_SERIAL_IO_CONFIG), > SERIAL_IO_CONFIG_REVISION, LoadSerialIoConfigDefault}, > + {&gSerialIrqConfigGuid, sizeof (PCH_LPC_SIRQ_CONFIG), > SERIAL_IRQ_CONFIG_REVISION, LoadSerialIrqConfigDefault}, > + {&gThermalConfigGuid, sizeof (PCH_THERMAL_CONFIG), > THERMAL_CONFIG_REVISION, LoadThermalConfigDefault}, > + {&gUsbConfigGuid, sizeof (USB_CONFIG), > USB_CONFIG_REVISION, LoadUsbConfigDefault}, > + {&gEspiConfigGuid, sizeof (PCH_ESPI_CONFIG), > ESPI_CONFIG_REVISION, LoadEspiConfigDefault}, > + {&gCnviConfigGuid, sizeof (PCH_CNVI_CONFIG), > CNVI_CONFIG_REVISION, LoadCnviConfigDefault}, > + {&gHsioConfigGuid, sizeof (PCH_HSIO_CONFIG), > HSIO_CONFIG_REVISION, LoadHsioConfigDefault}, > +}; > + > +/** > + Get PCH config block table total size. > + > + @retval Size of PCH config block table > +**/ > +UINT16 > +EFIAPI > +PchGetConfigBlockTotalSize ( > + VOID > + ) > +{ > + return GetComponentConfigBlockTotalSize (&mPchIpBlocks[0], sizeof > (mPchIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY)); > +} > + > +/** > + PchAddConfigBlocks add all PCH config blocks. > + > + @param[in] ConfigBlockTableAddress The pointer to add PCH config > blocks > + > + @retval EFI_SUCCESS The policy default is initialize= d. > + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create > buffer > +**/ > +EFI_STATUS > +EFIAPI > +PchAddConfigBlocks ( > + IN VOID *ConfigBlockTableAddress > + ) > +{ > + DEBUG ((DEBUG_INFO, "PCH AddConfigBlocks\n")); > + > + return AddComponentConfigBlocks (ConfigBlockTableAddress, > &mPchIpBlocks[0], sizeof (mPchIpBlocks) / sizeof > (COMPONENT_BLOCK_ENTRY)); > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPo= lic > yLibCnl.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPo= lic > yLibCnl.c > new file mode 100644 > index 0000000000..d19692ff2c > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPo= lic > yLibCnl.c > @@ -0,0 +1,169 @@ > +/** @file > + This file is PeiPchPolicy library Cannon Lake specific. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "PeiPchPolicyLibrary.h" > +#include > +#include > + > +/** > + mDevIntConfig[] table contains data on INTx and IRQ for each device. > + IRQ value for devices which use ITSS INTx->PIRQx mapping need to be se= t in > a way > + that for each multifunctional Dxx:Fy same interrupt pins must map to t= he > same IRQ. > + Those IRQ values will be used to update ITSS.PIRx register. > + In APIC relationship between PIRQs and IRQs is: > + PIRQA -> IRQ16 > + PIRQB -> IRQ17 > + PIRQC -> IRQ18 > + PIRQD -> IRQ19 > + PIRQE -> IRQ20 > + PIRQF -> IRQ21 > + PIRQG -> IRQ22 > + PIRQH -> IRQ23 > + > + Devices which use INTx->PIRQy mapping are: cAVS(in PCI mode), SMBus, G= bE, > TraceHub, PCIe, > + SATA, HECI, IDE-R, KT Redirection, xHCI, Thermal Subsystem, Camera IO = Host > Controller > + > + PCI Express Root Ports mapping should be programmed only with values a= s > in below table (D27/28/29) > + otherwise _PRT methods in ACPI for RootPorts would require additional > patching as > + PCIe Endpoint Device Interrupt is further subjected to INTx to PIRQy > Mapping > + > + Configured IRQ values are not used if an OS chooses to be in PIC inste= ad of > APIC mode > +**/ > +GLOBAL_REMOVE_IF_UNREFERENCED PCH_DEVICE_INTERRUPT_CONFIG > mDevIntConfig[] =3D { > +// {31, 0, PchNoInt, 0}, // LPC/eSPI Interface, doesn't use interrupts > +// {31, 1, PchNoInt, 0}, // P2SB, doesn't use interrupts > +// {31, 2, PchNoInt, 0}, // PMC , doesn't use interrupts > + {31, 3, PchIntA, 16}, // cAVS(Audio, Voice, Speach), INTA is default, > programmed in PciCfgSpace 3Dh > + {31, 4, PchIntA, 16}, // SMBus Controller, no default value, programme= d in > PciCfgSpace 3Dh > +// {31, 5, PchNoInt, 0}, // SPI , doesn't use interrupts > + {31, 7, PchIntA, 16}, // TraceHub, INTA is default, RO register > + {30, 0, PchIntA, 20}, // SerialIo: UART #0, INTA is default, programme= d in > PCR[SERIALIO] + PCICFGCTRL[7] > + {30, 1, PchIntB, 21}, // SerialIo: UART #1, INTA is default, programme= d in > PCR[SERIALIO] + PCICFGCTRL[8] > + {30, 2, PchIntC, 22}, // SerialIo: SPI #0, INTA is default, programmed= in > PCR[SERIALIO] + PCICFGCTRL[10] > + {30, 3, PchIntD, 23}, // SerialIo: SPI #1, INTA is default, programmed= in > PCR[SERIALIO] + PCICFGCTRL[11] > + {28, 0, PchIntA, 16}, // PCI Express Port 1, INT is default, programme= d in > PciCfgSpace + FCh > + {28, 1, PchIntB, 17}, // PCI Express Port 2, INT is default, programme= d in > PciCfgSpace + FCh > + {28, 2, PchIntC, 18}, // PCI Express Port 3, INT is default, programme= d in > PciCfgSpace + FCh > + {28, 3, PchIntD, 19}, // PCI Express Port 4, INT is default, programme= d in > PciCfgSpace + FCh > + {28, 4, PchIntA, 16}, // PCI Express Port 5, INT is default, programme= d in > PciCfgSpace + FCh > + {28, 5, PchIntB, 17}, // PCI Express Port 6, INT is default, programme= d in > PciCfgSpace + FCh > + {28, 6, PchIntC, 18}, // PCI Express Port 7, INT is default, programme= d in > PciCfgSpace + FCh > + {28, 7, PchIntD, 19}, // PCI Express Port 8, INT is default, programme= d in > PciCfgSpace + FCh > + {25, 2, PchIntC, 34}, // SerialIo UART Controller #2, INTA is default, > programmed in PCR[SERIALIO] + PCICFGCTRL[9] > +// {24, 0, 0, 0}, // Reserved (used by RST PCIe Storage Cycle Router) > + {23, 0, PchIntA, 16}, // SATA Controller, INTA is default, programmed = in > PciCfgSpace + 3Dh > + {22, 0, PchIntA, 16}, // CSME: HECI #1 > + {22, 1, PchIntB, 17}, // CSME: HECI #2 > + {22, 4, PchIntA, 16}, // CSME: HECI #3 > +// {22, 7, PchNoInt, 0}, // CSME: WLAN > + {21, 0, PchIntA, 16}, // SerialIo I2C Controller #0, INTA is default, > programmed in PCR[SERIALIO] + PCICFGCTRL[1] > + {21, 1, PchIntB, 17}, // SerialIo I2C Controller #1, INTA is default, = programmed > in PCR[SERIALIO] + PCICFGCTRL[2] > + {21, 2, PchIntC, 18}, // SerialIo I2C Controller #2, INTA is default, = programmed > in PCR[SERIALIO] + PCICFGCTRL[3] > + {21, 3, PchIntD, 19}, // SerialIo I2C Controller #3, INTA is default, = programmed > in PCR[SERIALIO] + PCICFGCTRL[4] > + {20, 0, PchIntA, 16}, // USB 3.0 xHCI Controller, no default value, > programmed in PciCfgSpace 3Dh > + {20, 1, PchIntB, 17}, // USB Device Controller (OTG) > + //{20, 2, PchNoInt, 0}, // Shared SRAM, no interrupts > + {20, 3, PchIntA, 16}, // CNVi WiFir > +// {20, 4, 0, 0}, // TraceHub Phantom (ACPI) Function > + {20, 5, PchIntD, 19}, // SCS: SDCard > +// {18, 0, PchNoInt, 0}, // CSME: KVMcc, doesn't use interrupts > +// {18, 1, PchNoInt, 0}, // CSME: Clink, doesn't use interrupts > +// {18, 2, PchNoInt, 0}, // CSME: PMT, doesn't use interrupts > +// {18, 3, 0, 0}, // CSME: CSE UMA > +// {18, 4, 0, 0} // CSME: fTPM DMA > + {18, 5, PchIntA, 16} // SCS: UFS > +}; > + > +// > +// mCnlPchLpOnlyDevIntConfig[] table contains data on INTx and IRQ for > devices that exist on PCH-LP > +// > +GLOBAL_REMOVE_IF_UNREFERENCED PCH_DEVICE_INTERRUPT_CONFIG > mPchLpOnlyDevIntConfig[] =3D { > + {31, 6, PchIntA, 16}, // GbE Controller, INTA is default, programmed i= n > PciCfgSpace 3Dh > + {29, 0, PchIntA, 16}, // PCI Express Port 9, INT is default, programme= d in > PciCfgSpace + FCh > + {29, 1, PchIntB, 17}, // PCI Express Port 10, INT is default, programm= ed in > PciCfgSpace + FCh > + {29, 2, PchIntC, 18}, // PCI Express Port 11, INT is default, programm= ed in > PciCfgSpace + FCh > + {29, 3, PchIntD, 19}, // PCI Express Port 12, INT is default, programm= ed in > PciCfgSpace + FCh > + {29, 4, PchIntA, 16}, // PCI Express Port 13, INT is default, programm= ed in > PciCfgSpace + FCh > + {29, 5, PchIntB, 17}, // PCI Express Port 14, INT is default, programm= ed in > PciCfgSpace + FCh > + {29, 6, PchIntC, 18}, // PCI Express Port 15, INT is default, programm= ed in > PciCfgSpace + FCh > + {29, 7, PchIntD, 19}, // PCI Express Port 16, INT is default, programm= ed in > PciCfgSpace + FCh > + {26, 0, PchIntA, 16}, // SCS: eMMC > + {25, 0, PchIntA, 32}, // SerialIo I2C Controller #4, INTA is default, > programmed in PCR[SERIALIO] + PCICFGCTRL[5] > + {25, 1, PchIntB, 33}, // SerialIo I2C Controller #5, INTA is default, = programmed > in PCR[SERIALIO] + PCICFGCTRL[6] > + {22, 2, PchIntC, 18}, // CSME: IDE-Redirection (IDE-R) > + {22, 3, PchIntD, 19}, // CSME: Keyboard and Text (KT) Redirection > + {19, 0, PchIntA, 20}, // Integrated Sensor Hub > + {18, 0, PchIntA, 16}, // Thermal Subsystem > + {18, 6, PchIntB, 24} // SerialIo: SPI #2, INTA is default, programmed= in > PCR[SERIALIO] + PCICFGCTRL[12] > +}; > + > +// > +// mPchHOnlyDevIntConfig[] table contains data on INTx and IRQ for devic= es > that exist on PCH-H > +// > +GLOBAL_REMOVE_IF_UNREFERENCED PCH_DEVICE_INTERRUPT_CONFIG > mPchHOnlyDevIntConfig[] =3D { > + {31, 6, PchIntA, 16}, // GbE Controller, INTA is default, programmed i= n > PciCfgSpace 3Dh > + {29, 0, PchIntA, 16}, // PCI Express Port 9, INT is default, programme= d in > PciCfgSpace + FCh > + {29, 1, PchIntB, 17}, // PCI Express Port 10, INT is default, programm= ed in > PciCfgSpace + FCh > + {29, 2, PchIntC, 18}, // PCI Express Port 11, INT is default, programm= ed in > PciCfgSpace + FCh > + {29, 3, PchIntD, 19}, // PCI Express Port 12, INT is default, programm= ed in > PciCfgSpace + FCh > + {29, 4, PchIntA, 16}, // PCI Express Port 13, INT is default, programm= ed in > PciCfgSpace + FCh > + {29, 5, PchIntB, 17}, // PCI Express Port 14, INT is default, programm= ed in > PciCfgSpace + FCh > + {29, 6, PchIntC, 18}, // PCI Express Port 15, INT is default, programm= ed in > PciCfgSpace + FCh > + {29, 7, PchIntD, 19}, // PCI Express Port 16, INT is default, programm= ed in > PciCfgSpace + FCh > + {27, 0, PchIntA, 16}, // PCI Express Port 17, INT is default, programm= ed in > PciCfgSpace + FCh > + {27, 1, PchIntB, 17}, // PCI Express Port 18, INT is default, programm= ed in > PciCfgSpace + FCh > + {27, 2, PchIntC, 18}, // PCI Express Port 19, INT is default, programm= ed in > PciCfgSpace + FCh > + {27, 3, PchIntD, 19}, // PCI Express Port 20, INT is default, programm= ed in > PciCfgSpace + FCh > + {27, 4, PchIntA, 16}, // PCI Express Port 21 > + {27, 5, PchIntB, 17}, // PCI Express Port 22 > + {27, 6, PchIntC, 18}, // PCI Express Port 23 > + {27, 7, PchIntD, 19}, // PCI Express Port 24 > + {22, 2, PchIntC, 18}, // CSME: IDE-Redirection (IDE-R) > + {22, 3, PchIntD, 19}, // CSME: Keyboard and Text (KT) Redirection > + {19, 0, PchIntA, 20}, // Integrated Sensor Hub > + {18, 0, PchIntA, 16}, // Thermal Subsystem > + {18, 6, PchIntB, 24} // SerialIo: SPI #2, INTA is default, programmed= in > PCR[SERIALIO] + PCICFGCTRL[12] > +}; > + > +/** > + Adds interrupt configuration for device > + > + @param[in/out] InterruptConfig Pointer to interrupt config > +**/ > +VOID > +LoadDeviceInterruptConfig ( > + IN OUT PCH_INTERRUPT_CONFIG *InterruptConfig > + ) > +{ > + UINT8 IntConfigTableEntries; > + > + IntConfigTableEntries =3D ARRAY_SIZE (mDevIntConfig); > + ASSERT (IntConfigTableEntries <=3D PCH_MAX_DEVICE_INTERRUPT_CONFIG); > + InterruptConfig->NumOfDevIntConfig =3D IntConfigTableEntries; > + CopyMem ( > + InterruptConfig->DevIntConfig, > + mDevIntConfig, > + sizeof (mDevIntConfig) > + ); > + > + if (IsPchLp ()) { > + CopyMem ( > + > &(InterruptConfig->DevIntConfig[InterruptConfig->NumOfDevIntConfig]), > + mPchLpOnlyDevIntConfig, > + sizeof (mPchLpOnlyDevIntConfig) > + ); > + InterruptConfig->NumOfDevIntConfig +=3D ARRAY_SIZE > (mPchLpOnlyDevIntConfig); > + } else if (IsPchH ()) { > + CopyMem ( > + > &(InterruptConfig->DevIntConfig[InterruptConfig->NumOfDevIntConfig]), > + mPchHOnlyDevIntConfig, > + sizeof (mPchHOnlyDevIntConfig) > + ); > + InterruptConfig->NumOfDevIntConfig +=3D ARRAY_SIZE > (mPchHOnlyDevIntConfig); > + } > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPr= eM > emPolicyLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPr= eM > emPolicyLib.c > new file mode 100644 > index 0000000000..dfab5d29c2 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchPolicyLib/PeiPchPr= eM > emPolicyLib.c > @@ -0,0 +1,318 @@ > +/** @file > + This file is PeiPchPreMemPolicy library. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include "PeiPchPolicyLibrary.h" > +#include > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadPchGeneralPreMemConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_GENERAL_PREMEM_CONFIG *PchGeneralPreMemConfig; > + PchGeneralPreMemConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, > "PchGeneralPreMemConfig->Header.GuidHob.Name =3D %g\n", > &PchGeneralPreMemConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "PchGeneralPreMemConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > PchGeneralPreMemConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + PCH general premem configuration > + ********************************/ > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadDciPreMemConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_DCI_PREMEM_CONFIG *DciPreMemConfig; > + DciPreMemConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "DciPreMemConfig->Header.GuidHob.Name =3D > %g\n", &DciPreMemConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "DciPreMemConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > DciPreMemConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + DCI Configuration > + ********************************/ > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadWatchDogPreMemConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_WDT_PREMEM_CONFIG *WdtPreMemConfig; > + WdtPreMemConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "WdtPreMemConfig->Header.GuidHob.Name =3D > %g\n", &WdtPreMemConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "WdtPreMemConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > WdtPreMemConfig->Header.GuidHob.Header.HobLength)); > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadPchTraceHubPreMemConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_TRACE_HUB_PREMEM_CONFIG *PchTraceHubPreMemConfig; > + PchTraceHubPreMemConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, > "PchTraceHubPreMemConfig->Header.GuidHob.Name =3D %g\n", > &PchTraceHubPreMemConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "PchTraceHubPreMemConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > PchTraceHubPreMemConfig->Header.GuidHob.Header.HobLength)); > +} > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mSmbusRsvdAddresses[] =3D { > + 0xA0, > + 0xA2, > + 0xA4, > + 0xA6 > +}; > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadSmbusPreMemConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_SMBUS_PREMEM_CONFIG *SmbusPreMemConfig; > + SmbusPreMemConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "SmbusPreMemConfig->Header.GuidHob.Name =3D > %g\n", &SmbusPreMemConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "SmbusPreMemConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > SmbusPreMemConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + SMBus configuration > + ********************************/ > + SmbusPreMemConfig->Enable =3D TRUE; > + SmbusPreMemConfig->DynamicPowerGating =3D TRUE; > + SmbusPreMemConfig->SpdWriteDisable =3D TRUE; > + SmbusPreMemConfig->SmbusIoBase =3D PcdGet16 > (PcdSmbusBaseAddress); > + ASSERT (sizeof (mSmbusRsvdAddresses) <=3D > PCH_MAX_SMBUS_RESERVED_ADDRESS); > + SmbusPreMemConfig->NumRsvdSmbusAddresses =3D sizeof > (mSmbusRsvdAddresses); > + CopyMem ( > + SmbusPreMemConfig->RsvdSmbusAddressTable, > + mSmbusRsvdAddresses, > + sizeof (mSmbusRsvdAddresses) > + ); > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadLpcPreMemConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_LPC_PREMEM_CONFIG *LpcPreMemConfig; > + LpcPreMemConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "LpcPreMemConfig->Header.GuidHob.Name =3D > %g\n", &LpcPreMemConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "LpcPreMemConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > LpcPreMemConfig->Header.GuidHob.Header.HobLength)); > + > + /******************************** > + LPC Configuration > + ********************************/ > + LpcPreMemConfig->EnhancePort8xhDecoding =3D TRUE; > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadHsioPciePreMemConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_HSIO_PCIE_PREMEM_CONFIG *HsioPciePreMemConfig; > + HsioPciePreMemConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "HsioPciePreMemConfig->Header.GuidHob.Name =3D > %g\n", &HsioPciePreMemConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "HsioPciePreMemConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > HsioPciePreMemConfig->Header.GuidHob.Header.HobLength)); > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadHsioSataPreMemConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_HSIO_SATA_PREMEM_CONFIG *HsioSataPreMemConfig; > + HsioSataPreMemConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "HsioSataPreMemConfig->Header.GuidHob.Name =3D > %g\n", &HsioSataPreMemConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "HsioSataPreMemConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > HsioSataPreMemConfig->Header.GuidHob.Header.HobLength)); > +} > + > +/** > + Get Hsio Sata Pre Mem Config Policy > + > + @param[in] SiPolicy The RC Policy PPI instance > + @param[in] SataCtrlIndex SATA controller index > + > + @retval Pointer to Hsio Sata Pre Mem Config Policy > +**/ > +PCH_HSIO_SATA_PREMEM_CONFIG * > +GetPchHsioSataPreMemConfig ( > + IN SI_PREMEM_POLICY_PPI *SiPreMemPolicy, > + IN UINT32 SataCtrlIndex > + ) > +{ > + PCH_HSIO_SATA_PREMEM_CONFIG *HsioSataPreMemConfig; > + EFI_STATUS Status; > + > + ASSERT (SataCtrlIndex < GetPchMaxSataControllerNum ()); > + > + Status =3D GetConfigBlock ((VOID *) SiPreMemPolicy, > &gHsioSataPreMemConfigGuid, (VOID *) &HsioSataPreMemConfig); > + ASSERT_EFI_ERROR (Status); > + > + HsioSataPreMemConfig +=3D SataCtrlIndex; > + > + return HsioSataPreMemConfig; > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadPcieRpPreMemConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_PCIE_RP_PREMEM_CONFIG *PcieRpPreMemConfig; > + UINT32 RpIndex; > + > + PcieRpPreMemConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Name =3D > %g\n", &PcieRpPreMemConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "PcieRpPreMemConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > PcieRpPreMemConfig->Header.GuidHob.Header.HobLength)); > + > + for (RpIndex =3D 0; RpIndex < GetPchMaxPciePortNum (); RpIndex ++) { > + PcieRpPreMemConfig->RpEnabledMask |=3D (UINT32) (1 << RpIndex); > + } > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadHdAudioPreMemConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_HDAUDIO_PREMEM_CONFIG *HdaPreMemConfig; > + HdaPreMemConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Name =3D > %g\n", &HdaPreMemConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "PcieRpPreMemConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > HdaPreMemConfig->Header.GuidHob.Header.HobLength)); > + HdaPreMemConfig->Enable =3D 1; > +} > + > +/** > + Load Config block default > + > + @param[in] ConfigBlockPointer Pointer to config block > +**/ > +VOID > +LoadIshPreMemConfigDefault ( > + IN VOID *ConfigBlockPointer > + ) > +{ > + PCH_ISH_PREMEM_CONFIG *IshPreMemConfig; > + IshPreMemConfig =3D ConfigBlockPointer; > + > + DEBUG ((DEBUG_INFO, "PcieRpPreMemConfig->Header.GuidHob.Name =3D > %g\n", &IshPreMemConfig->Header.GuidHob.Name)); > + DEBUG ((DEBUG_INFO, > "PcieRpPreMemConfig->Header.GuidHob.Header.HobLength =3D 0x%x\n", > IshPreMemConfig->Header.GuidHob.Header.HobLength)); > + //Enable ISH controller for Non-Desktop sku platforms > + if (GetCpuSku () !=3D EnumCpuTrad) { > + IshPreMemConfig->Enable =3D TRUE; > + } > +} > + > + > +GLOBAL_REMOVE_IF_UNREFERENCED COMPONENT_BLOCK_ENTRY > mPchIpBlocksPreMem [] =3D { > + {&gPchGeneralPreMemConfigGuid, sizeof > (PCH_GENERAL_PREMEM_CONFIG), > PCH_GENERAL_PREMEM_CONFIG_REVISION, > LoadPchGeneralPreMemConfigDefault}, > + {&gDciPreMemConfigGuid, sizeof (PCH_DCI_PREMEM_CONFIG), > DCI_PREMEM_CONFIG_REVISION, LoadDciPreMemConfigDefault}, > + {&gWatchDogPreMemConfigGuid, sizeof > (PCH_WDT_PREMEM_CONFIG), > WATCH_DOG_PREMEM_CONFIG_REVISION, > LoadWatchDogPreMemConfigDefault}, > + {&gPchTraceHubPreMemConfigGuid, sizeof > (PCH_TRACE_HUB_PREMEM_CONFIG), > PCH_TRACEHUB_PREMEM_CONFIG_REVISION, > LoadPchTraceHubPreMemConfigDefault}, > + {&gSmbusPreMemConfigGuid, sizeof > (PCH_SMBUS_PREMEM_CONFIG), SMBUS_PREMEM_CONFIG_REVISION, > LoadSmbusPreMemConfigDefault}, > + {&gLpcPreMemConfigGuid, sizeof (PCH_LPC_PREMEM_CONFIG), > LPC_PREMEM_CONFIG_REVISION, LoadLpcPreMemConfigDefault}, > + {&gHsioPciePreMemConfigGuid, sizeof > (PCH_HSIO_PCIE_PREMEM_CONFIG), > HSIO_PCIE_PREMEM_CONFIG_REVISION, > LoadHsioPciePreMemConfigDefault}, > + {&gHsioSataPreMemConfigGuid, sizeof > (PCH_HSIO_SATA_PREMEM_CONFIG), > HSIO_SATA_PREMEM_CONFIG_REVISION, > LoadHsioSataPreMemConfigDefault}, > + {&gPcieRpPreMemConfigGuid, sizeof > (PCH_PCIE_RP_PREMEM_CONFIG), PCIE_RP_PREMEM_CONFIG_REVISION, > LoadPcieRpPreMemConfigDefault}, > + {&gHdAudioPreMemConfigGuid, sizeof > (PCH_HDAUDIO_PREMEM_CONFIG), > HDAUDIO_PREMEM_CONFIG_REVISION, > LoadHdAudioPreMemConfigDefault}, > + {&gIshPreMemConfigGuid, sizeof (PCH_ISH_PREMEM_CONFIG), > ISH_PREMEM_CONFIG_REVISION, LoadIshPreMemConfigDefault}, > +}; > + > +/** > + Get PCH PREMEM config block table total size. > + > + @retval Size of PCH PREMEM config block = table > +**/ > +UINT16 > +EFIAPI > +PchGetPreMemConfigBlockTotalSize ( > + VOID > + ) > +{ > + return GetComponentConfigBlockTotalSize (&mPchIpBlocksPreMem[0], > sizeof (mPchIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY)); > +} > + > +/** > + PchAddPreMemConfigBlocks add all PCH PREMEM config blocks. > + > + @param[in] ConfigBlockTableAddress The pointer to add PCH PREMEM > config blocks > + > + @retval EFI_SUCCESS The policy default is initialize= d. > + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create > buffer > +**/ > +EFI_STATUS > +EFIAPI > +PchAddPreMemConfigBlocks ( > + IN VOID *ConfigBlockTableAddress > + ) > +{ > + DEBUG ((DEBUG_INFO, "PCH AddPreMemConfigBlocks\n")); > + > + return AddComponentConfigBlocks (ConfigBlockTableAddress, > &mPchIpBlocksPreMem[0], sizeof (mPchIpBlocksPreMem) / sizeof > (COMPONENT_BLOCK_ENTRY)); > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.= c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.= c > new file mode 100644 > index 0000000000..2210344462 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiPchResetLib/PchReset.= c > @@ -0,0 +1,109 @@ > +/** @file > + PCH RESET PEIM DRIVER. > + > + Copyright (c) 2019 Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > + > +/** > + Resets the entire platform. > + > + @param[in] ResetType UEFI defined reset type. > + @param[in] ResetStatus The status code for the reset. > + @param[in] DataSize The size of ResetData in bytes. > + @param[in] ResetData Optional element used to introduce a > platform specific reset. > + The exact type of the reset is defined= by the > EFI_GUID that follows > + the Null-terminated Unicode string. > + > +**/ > +VOID > +EFIAPI > +ResetSystem ( > + IN EFI_RESET_TYPE ResetType, > + IN EFI_STATUS ResetStatus, > + IN UINTN DataSize, > + IN VOID *ResetData OPTIONAL > + ) > +{ > + switch (ResetType) { > + case EfiResetWarm: > + ResetWarm (); > + break; > + > + case EfiResetCold: > + ResetCold (); > + break; > + > + case EfiResetShutdown: > + ResetShutdown (); > + return; > + > + case EfiResetPlatformSpecific: > + ResetPlatformSpecific (DataSize, ResetData); > + return; > + > + default: > + return; > + } > + > + // > + // Given we should have reset getting here would be bad > + // > + ASSERT (FALSE); > + CpuDeadLoop(); > +} > + > +/** > + Initialize PCH Reset APIs > + > + @retval EFI_SUCCESS APIs are installed successfully > + @retval EFI_OUT_OF_RESOURCES Can't allocate pool > +**/ > +EFI_STATUS > +EFIAPI > +PchInitializeReset ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + EFI_PEI_RESET2_PPI *EfiPeiReset2Ppi; > + EFI_PEI_PPI_DESCRIPTOR *EfiPeiReset2Descriptor; > + > + DEBUG ((DEBUG_INFO, "PchInitializeReset() Start\n")); > + > + > + EfiPeiReset2Descriptor =3D (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool > (sizeof (EFI_PEI_PPI_DESCRIPTOR)); > + EfiPeiReset2Ppi =3D (EFI_PEI_RESET2_PPI *) AllocateZeroPool (sizeof > (EFI_PEI_RESET2_PPI)); > + if ((EfiPeiReset2Descriptor =3D=3D NULL) || > + (EfiPeiReset2Ppi =3D=3D NULL)) { > + ASSERT (FALSE); > + return EFI_OUT_OF_RESOURCES; > + } > + > + /// > + /// Initialize the EFI Reset2 ppi instance > + /// > + EfiPeiReset2Ppi->ResetSystem =3D ResetSystem; > + > + EfiPeiReset2Descriptor->Flags =3D EFI_PEI_PPI_DESCRIPTOR_PPI | > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; > + EfiPeiReset2Descriptor->Guid =3D &gEfiPeiReset2PpiGuid; > + EfiPeiReset2Descriptor->Ppi =3D EfiPeiReset2Ppi; > + > + Status =3D PeiServicesInstallPpi (EfiPeiReset2Descriptor); > + ASSERT_EFI_ERROR (Status); > + > + DEBUG ((DEBUG_INFO, "PchInitializeReset() End\n")); > + > + return Status; > +} > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiRes= et > SystemLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiRes= et > SystemLib.c > new file mode 100644 > index 0000000000..58f2d86103 > --- /dev/null > +++ > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiResetSystemLib/PeiRes= et > SystemLib.c > @@ -0,0 +1,257 @@ > +/** @file > + System reset library services. > + > + 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 > + > +/** > + Dump reset message for debug build readability > +**/ > +VOID > +DumpResetMessage ( > + VOID > + ) > +{ > + DEBUG_CODE_BEGIN (); > + UINTN Index; > + // > + // ****************************** > + // ** SYSTEM REBOOT !!! ** > + // ****************************** > + // > + for (Index =3D 0; Index < 30; Index++) { > + DEBUG ((DEBUG_INFO, "*")); > + } > + DEBUG ((DEBUG_INFO, "\n** SYSTEM REBOOT !!! **\n")); > + for (Index =3D 0; Index < 30; Index++) { > + DEBUG ((DEBUG_INFO, "*")); > + } > + DEBUG ((DEBUG_INFO, "\n")); > + DEBUG_CODE_END (); > +} > +/** > + Execute call back function for Pch Reset. > + > + @param[in] ResetType Reset Types which includes GlobalReset= . > + @param[in] ResetTypeGuid Pointer to an EFI_GUID, which is the R= eset > Type Guid. > +**/ > +VOID > +PchResetCallback ( > + IN EFI_RESET_TYPE ResetType, > + IN EFI_GUID *ResetTypeGuid > + ) > +{ > + EFI_STATUS Status; > + UINTN Instance; > + PCH_RESET_CALLBACK_PPI *PchResetCallbackPpi; > + > + Instance =3D 0; > + do { > + Status =3D PeiServicesLocatePpi ( > + &gPchResetCallbackPpiGuid, > + Instance, > + NULL, > + (VOID **) &PchResetCallbackPpi > + ); > + > + switch (Status) { > + case EFI_SUCCESS: > + PchResetCallbackPpi->ResetCallback (ResetType, ResetTypeGuid); > + break; > + case EFI_NOT_FOUND: > + break; > + default: > + ASSERT_EFI_ERROR (Status); > + break; > + } > + ++Instance; > + } while (Status =3D=3D EFI_SUCCESS); > +} > + > +/** > + Calling this function causes a system-wide reset. This sets > + all circuitry within the system to its initial state. This type of res= et > + is asynchronous to system operation and operates without regard to > + cycle boundaries. > + > + System reset should not return, if it returns, it means the system doe= s > + not support cold reset. > +**/ > +VOID > +EFIAPI > +ResetCold ( > + VOID > + ) > +{ > + // > + // Loop through callback functions of PchResetCallback PPI > + // > + PchResetCallback (EfiResetCold, NULL); > + DumpResetMessage (); > + > + IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET); > +} > + > +/** > + Calling this function causes a system-wide initialization. The process= ors > + are set to their initial state, and pending cycles are not corrupted. > + > + System reset should not return, if it returns, it means the system doe= s > + not support warm reset. > +**/ > +VOID > +EFIAPI > +ResetWarm ( > + VOID > + ) > +{ > + // > + // Loop through callback functions of PchResetCallback PPI > + // > + PchResetCallback (EfiResetWarm, NULL); > + DumpResetMessage (); > + > + IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_HARDRESET); > +} > + > +/** > + Calling this function causes the system to enter a power state equival= ent > + to the ACPI G2/S5 or G3 states. > + > + System shutdown should not return, if it returns, it means the system = does > + not support shut down reset. > +**/ > +VOID > +EFIAPI > +ResetShutdown ( > + VOID > + ) > +{ > + UINT16 ABase; > + UINT32 Data32; > + > + // > + // Loop through callback functions of PchResetCallback PPI > + // > + PchResetCallback (EfiResetShutdown, NULL); > + > + ABase =3D PmcGetAcpiBase (); > + /// > + /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up the > system from S5 > + /// > + IoWrite32 ((UINTN) (ABase + R_ACPI_IO_GPE0_EN_127_96), 0); > + > + /// > + /// Secondly, PwrSts register must be cleared > + /// > + /// Write a "1" to bit[8] of power button status register at > + /// (PM_BASE + PM1_STS_OFFSET) to clear this bit > + /// > + IoWrite16 ((UINTN) (ABase + R_ACPI_IO_PM1_STS), > B_ACPI_IO_PM1_STS_PWRBTN); > + > + /// > + /// Finally, transform system into S5 sleep state > + /// > + Data32 =3D IoRead32 ((UINTN) (ABase + R_ACPI_IO_PM1_CNT)); > + > + Data32 =3D (UINT32) ((Data32 &~(B_ACPI_IO_PM1_CNT_SLP_TYP + > B_ACPI_IO_PM1_CNT_SLP_EN)) | V_ACPI_IO_PM1_CNT_S5); > + > + IoWrite32 ((UINTN) (ABase + R_ACPI_IO_PM1_CNT), Data32); > + > + Data32 =3D Data32 | B_ACPI_IO_PM1_CNT_SLP_EN; > + > + DumpResetMessage (); > + > + IoWrite32 ((UINTN) (ABase + R_ACPI_IO_PM1_CNT), Data32); > + > + return; > +} > + > +/** > + Internal function to execute the required HECI command for GlobalReset= , > + if failed will use PCH Reest. > + > +**/ > +STATIC > +VOID > +PchGlobalReset ( > + VOID > + ) > +{ > + // > + // Loop through callback functions of PchResetCallback PPI > + // > + PchResetCallback (EfiResetPlatformSpecific, &gPchGlobalResetGuid); > + > + // > + // PCH BIOS Spec Section 4.6 GPIO Reset Requirement > + // > + PmcEnableCf9GlobalReset (); > + > + DumpResetMessage (); > + > + IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET); > +} > + > +/** > + Calling this function causes the system to enter a power state for pla= tform > specific. > + > + @param[in] DataSize The size of ResetData in bytes. > + @param[in] ResetData Optional element used to introduce a > platform specific reset. > + The exact type of the reset is defined= by the > EFI_GUID that follows > + the Null-terminated Unicode string. > + > +**/ > +VOID > +EFIAPI > +ResetPlatformSpecific ( > + IN UINTN DataSize, > + IN VOID *ResetData OPTIONAL > + ) > +{ > + EFI_GUID *GuidPtr; > + > + if (ResetData =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "[PeiResetSystemLib] ResetData is not > available.\n")); > + return; > + } > + GuidPtr =3D (EFI_GUID *) ((UINT8 *) ResetData + DataSize - sizeof (EFI= _GUID)); > + if (CompareGuid (GuidPtr, &gPchGlobalResetGuid)) { > + PchGlobalReset(); > + } else { > + return; > + } > +} > + > +/** > + Calling this function causes the system to enter a power state for cap= sule > update. > + > + Reset update should not return, if it returns, it means the system doe= s > + not support capsule update. > + > +**/ > +VOID > +EFIAPI > +EnterS3WithImmediateWake ( > + VOID > + ) > +{ > + ASSERT (FALSE); > +} > + > diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/Pch= Spi.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c > new file mode 100644 > index 0000000000..1a5db7f24a > --- /dev/null > +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiSpiLib/PchSpi.c > @@ -0,0 +1,217 @@ > +/** @file > + PCH SPI PEI Library implements the SPI Host Controller Compatibility > Interface. > + > + 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 > + > +typedef struct { > + EFI_PEI_PPI_DESCRIPTOR PpiDescriptor; > + SPI_INSTANCE SpiInstance; > +} PEI_SPI_INSTANCE; > + > +/** > + PCI Enumeratuion is not done till later in DXE > + Initlialize SPI BAR0 to a default value till enumeration is done > + also enable memory space decoding for SPI > + > +**/ > +VOID > +InitSpiBar0 ( > + VOID > + ) > +{ > + UINT64 PchSpiBase; > + PchSpiBase =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_SPI, > + PCI_FUNCTION_NUMBER_PCH_SPI, > + 0 > + ); > + PciSegmentAnd8 (PchSpiBase + PCI_COMMAND_OFFSET, (UINT8) > ~EFI_PCI_COMMAND_MEMORY_SPACE); > + PciSegmentWrite32 (PchSpiBase + R_SPI_CFG_BAR0, > PCH_SPI_BASE_ADDRESS); > + PciSegmentOr8 (PchSpiBase + PCI_COMMAND_OFFSET, > EFI_PCI_COMMAND_MEMORY_SPACE); > +} > + > +/** > + This function Initial SPI services > + > + @retval EFI_STATUS Results of the installation of the SPI services > +**/ > +EFI_STATUS > +EFIAPI > +SpiServiceInit ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + PEI_SPI_INSTANCE *PeiSpiInstance; > + SPI_INSTANCE *SpiInstance; > + PCH_SPI_PPI *SpiPpi; > + > + Status =3D PeiServicesLocatePpi ( > + &gPchSpiPpiGuid, > + 0, > + NULL, > + (VOID **)&SpiPpi > + ); > + > + if (Status !=3D EFI_SUCCESS) { > + DEBUG ((DEBUG_INFO, "SpiServiceInit() Start\n")); > + > + // > + // PCI Enumeratuion is not done till later in DXE > + // Initlialize SPI BAR0 to a default value till enumeration is done > + // also enable memory space decoding for SPI > + // > + InitSpiBar0 (); > + > + PeiSpiInstance =3D (PEI_SPI_INSTANCE *) AllocateZeroPool (sizeof > (PEI_SPI_INSTANCE)); > + if (NULL =3D=3D PeiSpiInstance) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + SpiInstance =3D &(PeiSpiInstance->SpiInstance); > + SpiProtocolConstructor (SpiInstance); > + > + PeiSpiInstance->PpiDescriptor.Flags =3D EFI_PEI_PPI_DESCRIPTOR_PPI | > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; > + PeiSpiInstance->PpiDescriptor.Guid =3D &gPchSpiPpiGuid; > + PeiSpiInstance->PpiDescriptor.Ppi =3D &(SpiInstance->SpiProtocol); > + > + /// > + /// Install the SPI PPI > + /// > + DEBUG ((DEBUG_INFO, "SPI PPI Installed\n")); > + Status =3D PeiServicesInstallPpi (&PeiSpiInstance->PpiDescriptor); > + ASSERT_EFI_ERROR (Status); > + > + DEBUG ((DEBUG_INFO, "SpiServiceInit() End\n")); > + } > + else { > + DEBUG ((DEBUG_INFO, "SPI PPI already installed\n")); > + } > + return Status; > +} > + > +/** > + Acquire pch spi mmio address. > + > + @param[in] SpiInstance Pointer to SpiInstance to initialize > + > + @retval PchSpiBar0 return SPI MMIO address > +**/ > +UINTN > +AcquireSpiBar0 ( > + IN SPI_INSTANCE *SpiInstance > + ) > +{ > + return PciSegmentRead32 (SpiInstance->PchSpiBase + R_SPI_CFG_BAR0) & > ~(B_SPI_CFG_BAR0_MASK); > +} > + > +/** > + Release pch spi mmio address. Do nothing. > + > + @param[in] SpiInstance Pointer to SpiInstance to initialize > + > + @retval None > +**/ > +VOID > +ReleaseSpiBar0 ( > + IN SPI_INSTANCE *SpiInstance > + ) > +{ > +} > + > +/** > + This function is a hook for Spi to disable BIOS Write Protect > + > + @retval EFI_SUCCESS The protocol instance was properly > initialized > + @retval EFI_ACCESS_DENIED The BIOS Region can only be updated in > SMM phase > + > +**/ > +EFI_STATUS > +EFIAPI > +DisableBiosWriteProtect ( > + VOID > + ) > +{ > + UINT64 SpiBaseAddress; > + > + SpiBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_SPI, > + PCI_FUNCTION_NUMBER_PCH_SPI, > + 0 > + ); > + if ((PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC) & > B_SPI_CFG_BC_EISS) !=3D 0) { > + return EFI_ACCESS_DENIED; > + } > + /// > + /// Enable the access to the BIOS space for both read and write cycles > + /// > + PciSegmentOr8 ( > + SpiBaseAddress + R_SPI_CFG_BC, > + B_SPI_CFG_BC_WPD > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + This function is a hook for Spi to enable BIOS Write Protect > + > + > +**/ > +VOID > +EFIAPI > +EnableBiosWriteProtect ( > + VOID > + ) > +{ > + UINT64 SpiBaseAddress; > + > + SpiBaseAddress =3D PCI_SEGMENT_LIB_ADDRESS ( > + DEFAULT_PCI_SEGMENT_NUMBER_PCH, > + DEFAULT_PCI_BUS_NUMBER_PCH, > + PCI_DEVICE_NUMBER_PCH_SPI, > + PCI_FUNCTION_NUMBER_PCH_SPI, > + 0 > + ); > + /// > + /// Disable the access to the BIOS space for write cycles > + /// > + PciSegmentAnd8 ( > + SpiBaseAddress + R_SPI_CFG_BC, > + (UINT8) (~B_SPI_CFG_BC_WPD) > + ); > +} > + > +/** > + Check if it's granted to do flash write. > + > + @retval TRUE It's secure to do flash write. > + @retval FALSE It's not secure to do flash write. > +**/ > +BOOLEAN > +IsSpiFlashWriteGranted ( > + VOID > + ) > +{ > + return TRUE; > +} > -- > 2.16.2.windows.1