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.126, mailfrom: chasel.chiu@intel.com) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by groups.io with SMTP; Fri, 16 Aug 2019 18:13:18 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Aug 2019 18:13:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,395,1559545200"; d="scan'208";a="377593622" Received: from pgsmsx101.gar.corp.intel.com ([10.221.44.78]) by fmsmga006.fm.intel.com with ESMTP; 16 Aug 2019 18:13:16 -0700 Received: from pgsmsx111.gar.corp.intel.com ([169.254.2.22]) by PGSMSX101.gar.corp.intel.com ([169.254.1.232]) with mapi id 14.03.0439.000; Sat, 17 Aug 2019 09:13:15 +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 17/37] CoffeelakeSiliconPkg/Pch: Add Base library instances Thread-Topic: [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base library instances Thread-Index: AQHVVJEYEPxcUv0/U06faLDwYoL1J6b+iLkQ Date: Sat, 17 Aug 2019 01:13:14 +0000 Message-ID: <3C3EFB470A303B4AB093197B6777CCEC50462341@PGSMSX111.gar.corp.intel.com> References: <20190817001603.30632-1-michael.a.kubacki@intel.com> <20190817001603.30632-18-michael.a.kubacki@intel.com> In-Reply-To: <20190817001603.30632-18-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: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMDJlMGZlNTQtZDIwNS00ZjEzLTk2ZjQtZjY3NzA5MGEyMDljIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiWEVrT3RIaTJKTDBPMnhmTVhhT1RqN2NQRGQxQTZUZlUyT0tvSDdxUTNjTVJOb29VTlF3ZmpTdUo5bk0zaVhLYSJ9 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 17/37] CoffeelakeSiliconPkg/Pch: Add > Base library instances >=20 > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D2082 >=20 > Adds PCH Base library class instances. >=20 > * BaseResetSystemLib > * BaseSmbusLib >=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/BaseResetSystemLib/BaseRes > etSystemLib.inf | 38 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib. > inf | 39 + >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseRes > etSystemLib.c | 153 +++ >=20 > Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib. > c | 993 ++++++++++++++++++++ > 4 files changed, 1223 insertions(+) >=20 > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseR > esetSystemLib.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseR > esetSystemLib.inf > new file mode 100644 > index 0000000000..8d68f2dd83 > --- /dev/null > +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/ > +++ BaseResetSystemLib.inf > @@ -0,0 +1,38 @@ > +## @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 BaseResetSystemLib > +FILE_GUID =3D D4FF05AA-3C7D-4B8A-A1EE-AA5EFA0B1732 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +UEFI_SPECIFICATION_VERSION =3D 2.00 > +LIBRARY_CLASS =3D ResetSystemLib > +CONSTRUCTOR =3D BaseResetSystemLibConstructor # # The following > +information is for reference only and not required by the build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 IPF > +# > + > +[LibraryClasses] > +IoLib > +DebugLib > +PmcLib > + > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > + > +[Sources] > +BaseResetSystemLib.c > + > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLi > b.inf > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLi > b.inf > new file mode 100644 > index 0000000000..f3388a2624 > --- /dev/null > +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSm > +++ busLib.inf > @@ -0,0 +1,39 @@ > +## @file > +# Component description file for PCH Smbus Library. > +# > +# SMBUS Library that layers on top of the I/O Library to directly # > +access a standard SMBUS host controller. > +# > +# Copyright (c) 2019 Intel Corporation. All rights reserved.
# # > +SPDX-License-Identifier: BSD-2-Clause-Patent # ## > + > +[Defines] > +INF_VERSION =3D 0x00010017 > +BASE_NAME =3D BaseSmbusLib > +FILE_GUID =3D 5C4D0430-F81B-42D3-BB88-4A6CD2796FF8 > +VERSION_STRING =3D 1.0 > +MODULE_TYPE =3D BASE > +LIBRARY_CLASS =3D SmbusLib > +CONSTRUCTOR =3D BaseSmbusLibConstructor > + > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC # > + > +[LibraryClasses] > +BaseLib > +DebugLib > +IoLib > +PciSegmentLib > + > +[Packages] > +MdePkg/MdePkg.dec > +CoffeelakeSiliconPkg/SiPkg.dec > + > +[Sources] > +BaseSmbusLib.c > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseR > esetSystemLib.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseR > esetSystemLib.c > new file mode 100644 > index 0000000000..a603f5e794 > --- /dev/null > +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/ > +++ BaseResetSystemLib.c > @@ -0,0 +1,153 @@ > +/** @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 > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 > mBaseResetSystemABase; > + > +/** > + Calling this function causes a system-wide reset. This sets > + all circuitry within the system to its initial state. This type of > +reset > + is asynchronous to system operation and operates without regard to > + cycle boundaries. > + > + System reset should not return, if it returns, it means the system > +does > + not support cold reset. > +**/ > +VOID > +EFIAPI > +ResetCold ( > + VOID > + ) > +{ > + IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET); } > + > +/** > + Calling this function causes a system-wide initialization. The > +processors > + are set to their initial state, and pending cycles are not corrupted. > + > + System reset should not return, if it returns, it means the system > +does > + not support warm reset. > +**/ > +VOID > +EFIAPI > +ResetWarm ( > + VOID > + ) > +{ > + IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_HARDRESET); } > + > +/** > + Calling this function causes the system to enter a power state > +equivalent > + 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; > + > + ABase =3D mBaseResetSystemABase; > + if (ABase =3D=3D 0) { > + ABase =3D PmcGetAcpiBase (); > + } > + /// > + /// Firstly, GPE0_EN should be disabled to avoid any GPI waking up > + the system from S5 /// > + IoWrite32 (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 (ABase + R_ACPI_IO_PM1_STS, B_ACPI_IO_PM1_STS_PWRBTN); > + > + /// > + /// Finally, transform system into S5 sleep state /// > + Data32 =3D IoRead32 (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 (ABase + R_ACPI_IO_PM1_CNT, Data32); > + > + Data32 =3D Data32 | B_ACPI_IO_PM1_CNT_SLP_EN; > + > + IoWrite32 (ABase + R_ACPI_IO_PM1_CNT, Data32); > + > + return; > +} > + > +/** > + 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 > + ) > +{ > + IoWrite8 (R_PCH_IO_RST_CNT, V_PCH_IO_RST_CNT_FULLRESET); } > + > +/** > + 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 > + does not support capsule update. > + > +**/ > +VOID > +EFIAPI > +EnterS3WithImmediateWake ( > + VOID > + ) > +{ > + ASSERT (FALSE); > +} > + > +/** > + The library constructuor. > + > + The function does the necessary initialization work for this library i= nstance. > + > + @retval EFI_SUCCESS The function always return EFI_SUCCESS f= or > now. > +**/ > +EFI_STATUS > +EFIAPI > +BaseResetSystemLibConstructor ( > + VOID > + ) > +{ > + mBaseResetSystemABase =3D PmcGetAcpiBase (); > + > + return EFI_SUCCESS; > +} > diff --git > a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLi > b.c > b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLi > b.c > new file mode 100644 > index 0000000000..3d6386d433 > --- /dev/null > +++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSm > +++ busLib.c > @@ -0,0 +1,993 @@ > +/** @file > + PCH SMBUS library implementation built upon I/O 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 > + > +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mSmbusIoBase =3D 0; > + > +/** > + Gets Io port base address of Smbus Host Controller. > + > + @retval The Io port base address of Smbus host controller. > + > +**/ > +UINT16 > +InternalGetSmbusIoPortBaseAddress ( > + VOID > + ) > +{ > + UINT64 SmbusPciBase; > + UINT16 IoPortBaseAddress; > + > + if (mSmbusIoBase !=3D 0) { > + return mSmbusIoBase; > + } > + > + SmbusPciBase =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 > + ); > + IoPortBaseAddress =3D (UINT16) PciSegmentRead32 (SmbusPciBase + > + R_SMBUS_CFG_BASE); > + > + // > + // Make sure that the IO port base address has been properly set. > + // > + if ((IoPortBaseAddress =3D=3D 0) || (IoPortBaseAddress =3D=3D 0xFFFF))= { > + ASSERT (FALSE); > + return 0; > + } > + > + IoPortBaseAddress &=3D B_SMBUS_CFG_BASE_BAR; mSmbusIoBase =3D > + IoPortBaseAddress; > + > + return IoPortBaseAddress; > +} > + > + > +/** > + Acquires the ownership of SMBUS. > + > + This internal function reads the host state register. > + If the SMBUS is not available, RETURN_TIMEOUT is returned; > + Otherwise, it performs some basic initializations and returns > + RETURN_SUCCESS. > + > + @param[in] IoPortBaseAddress The Io port base address of Smbus Host > controller. > + > + @retval RETURN_SUCCESS The SMBUS command was executed > successfully. > + @retval RETURN_TIMEOUT A timeout occurred while executing the > SMBUS command. > + > +**/ > +RETURN_STATUS > +InternalSmBusAcquire ( > + IN UINT16 IoPortBaseAddress > + ) > +{ > + UINT8 HostStatus; > + > + HostStatus =3D IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HSTS); if > + ((HostStatus & B_SMBUS_IO_IUS) !=3D 0) { > + return RETURN_TIMEOUT; > + } else if ((HostStatus & B_SMBUS_IO_HBSY) !=3D 0) { > + // > + // Clear host status register and exit. > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, > B_SMBUS_IO_HSTS_ALL); > + return RETURN_TIMEOUT; > + } > + // > + // Clear out any odd status information (Will Not Clear In Use). > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, HostStatus); > + > + return RETURN_SUCCESS; > +} > + > +/** > + Starts the SMBUS transaction and waits until the end. > + > + This internal function start the SMBUS transaction and waits until > + the transaction of SMBUS is over by polling the INTR bit of Host statu= s > register. > + If the SMBUS is not available, RETURN_TIMEOUT is returned; > + Otherwise, it performs some basic initializations and returns > + RETURN_SUCCESS. > + > + @param[in] IoPortBaseAddress The Io port base address of Smbus Host > controller. > + @param[in] HostControl The Host control command to start SMBU= S > transaction. > + > + @retval RETURN_SUCCESS The SMBUS command was executed > successfully. > + @retval RETURN_CRC_ERROR The checksum is not correct (PEC is > incorrect). > + @retval RETURN_DEVICE_ERROR The request was not completed > because a failure reflected > + in the Host Status Register bit. Devi= ce errors are > + a result of a transaction collision, i= llegal command > field, > + unclaimed cycle (host initiated), or b= us errors > (collisions). > + > +**/ > +RETURN_STATUS > +InternalSmBusStart ( > + IN UINT16 IoPortBaseAddress, > + IN UINT8 HostControl > + ) > +{ > + UINT8 HostStatus; > + UINT8 AuxiliaryStatus; > + > + // > + // Set Host Control Register (Initiate Operation, Interrupt disabled). > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HCTL, (UINT8)(HostControl + > + B_SMBUS_IO_START)); > + > + do { > + // > + // Poll INTR bit of Host Status Register. > + // > + HostStatus =3D IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HSTS); } > + while ((HostStatus & (B_SMBUS_IO_INTR | B_SMBUS_IO_ERROR | > + B_SMBUS_IO_BYTE_DONE_STS)) =3D=3D 0); > + > + if ((HostStatus & B_SMBUS_IO_ERROR) =3D=3D 0) { > + return RETURN_SUCCESS; > + } > + // > + // Clear error bits of Host Status Register. > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, B_SMBUS_IO_ERROR); > // > + // Read Auxiliary Status Register to judge CRC error. > + // > + AuxiliaryStatus =3D IoRead8 (IoPortBaseAddress + R_SMBUS_IO_AUXS); if > + ((AuxiliaryStatus & B_SMBUS_IO_CRCE) !=3D 0) { > + return RETURN_CRC_ERROR; > + } > + > + return RETURN_DEVICE_ERROR; > +} > + > +/** > + Executes an SMBUS quick, byte or word command. > + > + This internal function executes an SMBUS quick, byte or word commond. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + > + @param[in] HostControl The value of Host Control Register to set. > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[in] Value The byte/word write to the SMBUS. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be N= ULL. > + > + @retval The byte/word read from the SMBUS. > + > +**/ > +UINT16 > +InternalSmBusNonBlock ( > + IN UINT8 HostControl, > + IN UINTN SmBusAddress, > + IN UINT16 Value, > + OUT RETURN_STATUS *Status > + ) > +{ > + RETURN_STATUS ReturnStatus; > + UINT16 IoPortBaseAddress; > + UINT8 AuxiliaryControl; > + > + IoPortBaseAddress =3D InternalGetSmbusIoPortBaseAddress (); > + > + // > + // Try to acquire the ownership of SMBUS. > + // > + ReturnStatus =3D InternalSmBusAcquire (IoPortBaseAddress); if > + (RETURN_ERROR (ReturnStatus)) { > + goto Done; > + } > + // > + // Set the appropriate Host Control Register and auxiliary Control Reg= ister. > + // > + AuxiliaryControl =3D 0; > + if (SMBUS_LIB_PEC (SmBusAddress)) { > + AuxiliaryControl |=3D B_SMBUS_IO_AAC; } // // Set Host Commond > + Register. > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HCMD, (UINT8) > + SMBUS_LIB_COMMAND (SmBusAddress)); // // Write value to Host Data 0 > + and Host Data 1 Registers. > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HD0, (UINT8) Value); > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HD1, (UINT8) (Value >> 8)); > + // // Set Auxiliary Control Regiester. > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXC, AuxiliaryControl); // > + // Set SMBUS slave address for the device to send/receive from. > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_TSA, (UINT8) SmBusAddress); > + // // Start the SMBUS transaction and wait for the end. > + // > + ReturnStatus =3D InternalSmBusStart (IoPortBaseAddress, HostControl); > + // // Read value from Host Data 0 and Host Data 1 Registers. > + // > + Value =3D (UINT16)(IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HD1) << 8); > + Value =3D (UINT16)(Value | IoRead8 (IoPortBaseAddress + > + R_SMBUS_IO_HD0)); // // Clear Host Status Register and Auxiliary > + Status Register. > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, > B_SMBUS_IO_HSTS_ALL); > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXS, B_SMBUS_IO_CRCE); > + > +Done: > + if (Status !=3D NULL) { > + *Status =3D ReturnStatus; > + } > + > + return Value; > +} > + > +/** > + Executes an SMBUS quick read command. > + > + Executes an SMBUS quick read command on the SMBUS device specified by > SmBusAddress. > + Only the SMBUS slave address field of SmBusAddress is required. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + If PEC is set in SmBusAddress, then ASSERT(). > + If Command in SmBusAddress is not zero, then ASSERT(). > + If Length in SmBusAddress is not zero, then ASSERT(). > + If any reserved bits of SmBusAddress are set, then ASSERT(). > + > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be NUL= L. > + > +**/ > +VOID > +EFIAPI > +SmBusQuickRead ( > + IN UINTN SmBusAddress, > + OUT RETURN_STATUS *Status OPTIONAL > + ) > +{ > + ASSERT (!SMBUS_LIB_PEC (SmBusAddress)); > + ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) =3D=3D 0); > + > + if (SMBUS_LIB_PEC (SmBusAddress) || > + (SMBUS_LIB_COMMAND (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_LENGTH (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_RESERVED (SmBusAddress) !=3D 0)) { > + if (Status !=3D NULL) { > + *Status =3D RETURN_INVALID_PARAMETER; > + } > + return; > + } > + > + InternalSmBusNonBlock ( > + V_SMBUS_IO_SMB_CMD_QUICK, > + SmBusAddress | B_SMBUS_IO_READ, > + 0, > + Status > + ); > +} > + > +/** > + Executes an SMBUS quick write command. > + > + Executes an SMBUS quick write command on the SMBUS device specified by > SmBusAddress. > + Only the SMBUS slave address field of SmBusAddress is required. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + If PEC is set in SmBusAddress, then ASSERT(). > + If Command in SmBusAddress is not zero, then ASSERT(). > + If Length in SmBusAddress is not zero, then ASSERT(). > + If any reserved bits of SmBusAddress are set, then ASSERT(). > + > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be NUL= L. > + > +**/ > +VOID > +EFIAPI > +SmBusQuickWrite ( > + IN UINTN SmBusAddress, > + OUT RETURN_STATUS *Status OPTIONAL > + ) > +{ > + ASSERT (!SMBUS_LIB_PEC (SmBusAddress)); > + ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) =3D=3D 0); > + > + if (SMBUS_LIB_PEC (SmBusAddress) || > + (SMBUS_LIB_COMMAND (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_LENGTH (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_RESERVED (SmBusAddress) !=3D 0)) { > + if (Status !=3D NULL) { > + *Status =3D RETURN_INVALID_PARAMETER; > + } > + return; > + } > + > + InternalSmBusNonBlock ( > + V_SMBUS_IO_SMB_CMD_QUICK, > + SmBusAddress | B_SMBUS_IO_WRITE, > + 0, > + Status > + ); > +} > + > +/** > + Executes an SMBUS receive byte command. > + > + Executes an SMBUS receive byte command on the SMBUS device specified > by SmBusAddress. > + Only the SMBUS slave address field of SmBusAddress is required. > + The byte received from the SMBUS is returned. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + If Command in SmBusAddress is not zero, then ASSERT(). > + If Length in SmBusAddress is not zero, then ASSERT(). > + If any reserved bits of SmBusAddress are set, then ASSERT(). > + > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be NUL= L. > + > + @retval The byte received from the SMBUS. > + > +**/ > +UINT8 > +EFIAPI > +SmBusReceiveByte ( > + IN UINTN SmBusAddress, > + OUT RETURN_STATUS *Status OPTIONAL > + ) > +{ > + ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) =3D=3D 0); > + > + if ((SMBUS_LIB_COMMAND (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_LENGTH (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_RESERVED (SmBusAddress) !=3D 0)) { > + if (Status !=3D NULL) { > + *Status =3D RETURN_INVALID_PARAMETER; > + } > + return 0; > + } > + > + return (UINT8) InternalSmBusNonBlock ( > + V_SMBUS_IO_SMB_CMD_BYTE, > + SmBusAddress | B_SMBUS_IO_READ, > + 0, > + Status > + ); > +} > + > +/** > + Executes an SMBUS send byte command. > + > + Executes an SMBUS send byte command on the SMBUS device specified by > SmBusAddress. > + The byte specified by Value is sent. > + Only the SMBUS slave address field of SmBusAddress is required. Value= is > returned. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + If Command in SmBusAddress is not zero, then ASSERT(). > + If Length in SmBusAddress is not zero, then ASSERT(). > + If any reserved bits of SmBusAddress are set, then ASSERT(). > + > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[in] Value The 8-bit value to send. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be NUL= L. > + > + @retval The parameter of Value. > + > +**/ > +UINT8 > +EFIAPI > +SmBusSendByte ( > + IN UINTN SmBusAddress, > + IN UINT8 Value, > + OUT RETURN_STATUS *Status OPTIONAL > + ) > +{ > + ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) =3D=3D 0); > + > + if ((SMBUS_LIB_COMMAND (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_LENGTH (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_RESERVED (SmBusAddress) !=3D 0)) { > + if (Status !=3D NULL) { > + *Status =3D RETURN_INVALID_PARAMETER; > + } > + return 0; > + } > + > + return (UINT8) InternalSmBusNonBlock ( > + V_SMBUS_IO_SMB_CMD_BYTE, > + SmBusAddress | B_SMBUS_IO_WRITE, > + Value, > + Status > + ); > +} > + > +/** > + Executes an SMBUS read data byte command. > + > + Executes an SMBUS read data byte command on the SMBUS device specified > by SmBusAddress. > + Only the SMBUS slave address and SMBUS command fields of > SmBusAddress are required. > + The 8-bit value read from the SMBUS is returned. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + If Length in SmBusAddress is not zero, then ASSERT(). > + If any reserved bits of SmBusAddress are set, then ASSERT(). > + > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be N= ULL. > + > + @retval The byte read from the SMBUS. > + > +**/ > +UINT8 > +EFIAPI > +SmBusReadDataByte ( > + IN UINTN SmBusAddress, > + OUT RETURN_STATUS *Status OPTIONAL > + ) > +{ > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) =3D=3D 0); > + > + if ((SMBUS_LIB_LENGTH (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_RESERVED (SmBusAddress) !=3D 0)) { > + if (Status !=3D NULL) { > + *Status =3D RETURN_INVALID_PARAMETER; > + } > + return 0; > + } > + > + return (UINT8) InternalSmBusNonBlock ( > + V_SMBUS_IO_SMB_CMD_BYTE_DATA, > + SmBusAddress | B_SMBUS_IO_READ, > + 0, > + Status > + ); > +} > + > +/** > + Executes an SMBUS write data byte command. > + > + Executes an SMBUS write data byte command on the SMBUS device > specified by SmBusAddress. > + The 8-bit value specified by Value is written. > + Only the SMBUS slave address and SMBUS command fields of > SmBusAddress are required. > + Value is returned. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + If Length in SmBusAddress is not zero, then ASSERT(). > + If any reserved bits of SmBusAddress are set, then ASSERT(). > + > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[in] Value The 8-bit value to write. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be NUL= L. > + > + @retval The parameter of Value. > + > +**/ > +UINT8 > +EFIAPI > +SmBusWriteDataByte ( > + IN UINTN SmBusAddress, > + IN UINT8 Value, > + OUT RETURN_STATUS *Status OPTIONAL > + ) > +{ > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) =3D=3D 0); > + > + if ((SMBUS_LIB_LENGTH (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_RESERVED (SmBusAddress) !=3D 0)) { > + if (Status !=3D NULL) { > + *Status =3D RETURN_INVALID_PARAMETER; > + } > + return 0; > + } > + > + return (UINT8) InternalSmBusNonBlock ( > + V_SMBUS_IO_SMB_CMD_BYTE_DATA, > + SmBusAddress | B_SMBUS_IO_WRITE, > + Value, > + Status > + ); > +} > + > +/** > + Executes an SMBUS read data word command. > + > + Executes an SMBUS read data word command on the SMBUS device > specified by SmBusAddress. > + Only the SMBUS slave address and SMBUS command fields of > SmBusAddress are required. > + The 16-bit value read from the SMBUS is returned. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + If Length in SmBusAddress is not zero, then ASSERT(). > + If any reserved bits of SmBusAddress are set, then ASSERT(). > + > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be NUL= L. > + > + @retval The byte read from the SMBUS. > + > +**/ > +UINT16 > +EFIAPI > +SmBusReadDataWord ( > + IN UINTN SmBusAddress, > + OUT RETURN_STATUS *Status OPTIONAL > + ) > +{ > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) =3D=3D 0); > + > + if ((SMBUS_LIB_LENGTH (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_RESERVED (SmBusAddress) !=3D 0)) { > + if (Status !=3D NULL) { > + *Status =3D RETURN_INVALID_PARAMETER; > + } > + return 0; > + } > + > + return InternalSmBusNonBlock ( > + V_SMBUS_IO_SMB_CMD_WORD_DATA, > + SmBusAddress | B_SMBUS_IO_READ, > + 0, > + Status > + ); > +} > + > +/** > + Executes an SMBUS write data word command. > + > + Executes an SMBUS write data word command on the SMBUS device > specified by SmBusAddress. > + The 16-bit value specified by Value is written. > + Only the SMBUS slave address and SMBUS command fields of > SmBusAddress are required. > + Value is returned. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + If Length in SmBusAddress is not zero, then ASSERT(). > + If any reserved bits of SmBusAddress are set, then ASSERT(). > + > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[in] Value The 16-bit value to write. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be NUL= L. > + > + @retval The parameter of Value. > + > +**/ > +UINT16 > +EFIAPI > +SmBusWriteDataWord ( > + IN UINTN SmBusAddress, > + IN UINT16 Value, > + OUT RETURN_STATUS *Status OPTIONAL > + ) > +{ > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) =3D=3D 0); > + > + if ((SMBUS_LIB_LENGTH (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_RESERVED (SmBusAddress) !=3D 0)) { > + if (Status !=3D NULL) { > + *Status =3D RETURN_INVALID_PARAMETER; > + } > + return 0; > + } > + > + return InternalSmBusNonBlock ( > + V_SMBUS_IO_SMB_CMD_WORD_DATA, > + SmBusAddress | B_SMBUS_IO_WRITE, > + Value, > + Status > + ); > +} > + > +/** > + Executes an SMBUS process call command. > + > + Executes an SMBUS process call command on the SMBUS device specified b= y > SmBusAddress. > + The 16-bit value specified by Value is written. > + Only the SMBUS slave address and SMBUS command fields of > SmBusAddress are required. > + The 16-bit value returned by the process call command is returned. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + If Length in SmBusAddress is not zero, then ASSERT(). > + If any reserved bits of SmBusAddress are set, then ASSERT(). > + > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[in] Value The 16-bit value to write. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be NUL= L. > + > + @retval The 16-bit value returned by the process call command. > + > +**/ > +UINT16 > +EFIAPI > +SmBusProcessCall ( > + IN UINTN SmBusAddress, > + IN UINT16 Value, > + OUT RETURN_STATUS *Status OPTIONAL > + ) > +{ > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) =3D=3D 0); > + > + if ((SMBUS_LIB_LENGTH (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_RESERVED (SmBusAddress) !=3D 0)) { > + if (Status !=3D NULL) { > + *Status =3D RETURN_INVALID_PARAMETER; > + } > + return 0; > + } > + > + return InternalSmBusNonBlock ( > + V_SMBUS_IO_SMB_CMD_PROCESS_CALL, > + SmBusAddress | B_SMBUS_IO_WRITE, > + Value, > + Status > + ); > +} > + > +/** > + Executes an SMBUS block command. > + > + Executes an SMBUS block read, block write and block write-block read > + command on the SMBUS device specified by SmBusAddress. > + Bytes are read from the SMBUS and stored in Buffer. > + The number of bytes read is returned, and will never return a value la= rger > than 32-bytes. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + It is the caller's responsibility to make sure Buffer is large enough = for the > total number of bytes read. > + SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not > need to be any larger than 32 bytes. > + > + @param[in] HostControl The value of Host Control Register to set. > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[in] WriteBuffer Pointer to the buffer of bytes to write to= the > SMBUS. > + @param[out] ReadBuffer Pointer to the buffer of bytes to read fro= m the > SMBUS. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be N= ULL. > + > + @retval The number of bytes read from the SMBUS. > + > +**/ > +UINTN > +InternalSmBusBlock ( > + IN UINT8 HostControl, > + IN UINTN SmBusAddress, > + IN UINT8 *WriteBuffer, > + OUT UINT8 *ReadBuffer, > + OUT RETURN_STATUS *Status > + ) > +{ > + RETURN_STATUS ReturnStatus; > + UINTN Index; > + UINTN BytesCount; > + UINT16 IoPortBaseAddress; > + UINT8 AuxiliaryControl; > + > + IoPortBaseAddress =3D InternalGetSmbusIoPortBaseAddress (); > + > + BytesCount =3D SMBUS_LIB_LENGTH (SmBusAddress); > + > + // > + // Try to acquire the ownership of SMBUS. > + // > + ReturnStatus =3D InternalSmBusAcquire (IoPortBaseAddress); if > + (RETURN_ERROR (ReturnStatus)) { > + goto Done; > + } > + // > + // Set the appropriate Host Control Register and auxiliary Control Reg= ister. > + // > + AuxiliaryControl =3D B_SMBUS_IO_E32B; > + if (SMBUS_LIB_PEC (SmBusAddress)) { > + AuxiliaryControl |=3D B_SMBUS_IO_AAC; } // // Set Host Command > + Register. > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HCMD, (UINT8) > + SMBUS_LIB_COMMAND (SmBusAddress)); // // Set Auxiliary Control > + Regiester. > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXC, AuxiliaryControl); // > + // Clear byte pointer of 32-byte buffer. > + // > + IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HCTL); > + > + if (WriteBuffer !=3D NULL) { > + // > + // Write the number of block to Host Block Data Byte Register. > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HD0, (UINT8) BytesCount); > + // > + // Write data block to Host Block Data Register. > + // > + for (Index =3D 0; Index < BytesCount; Index++) { > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HBD, WriteBuffer[Index]); > + } > + } > + // > + // Set SMBUS slave address for the device to send/receive from. > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_TSA, (UINT8) SmBusAddress); > + // // Start the SMBUS transaction and wait for the end. > + // > + ReturnStatus =3D InternalSmBusStart (IoPortBaseAddress, HostControl); > + if (RETURN_ERROR (ReturnStatus)) { > + goto Done; > + } > + > + if (ReadBuffer !=3D NULL) { > + // > + // Read the number of block from host block data byte register. > + // > + BytesCount =3D IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HD0); > + // > + // Write data block from Host Block Data Register. > + // > + for (Index =3D 0; Index < BytesCount; Index++) { > + ReadBuffer[Index] =3D IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HBD)= ; > + } > + } > + > +Done: > + // > + // Clear Host Status Register and Auxiliary Status Register. > + // > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_HSTS, > B_SMBUS_IO_HSTS_ALL); > + IoWrite8 (IoPortBaseAddress + R_SMBUS_IO_AUXS, B_SMBUS_IO_CRCE); > + > + if (Status !=3D NULL) { > + *Status =3D ReturnStatus; > + } > + > + return BytesCount; > +} > + > +/** > + Executes an SMBUS read block command. > + > + Executes an SMBUS read block command on the SMBUS device specified by > SmBusAddress. > + Only the SMBUS slave address and SMBUS command fields of > SmBusAddress are required. > + Bytes are read from the SMBUS and stored in Buffer. > + The number of bytes read is returned, and will never return a value la= rger > than 32-bytes. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + It is the caller's responsibility to make sure Buffer is large enough = for the > total number of bytes read. > + SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not > need to be any larger than 32 bytes. > + If Length in SmBusAddress is not zero, then ASSERT(). > + If Buffer is NULL, then ASSERT(). > + If any reserved bits of SmBusAddress are set, then ASSERT(). > + > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[out] Buffer Pointer to the buffer to store the bytes rea= d from > the SMBUS. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be NUL= L. > + > + @retval The number of bytes read. > + > +**/ > +UINTN > +EFIAPI > +SmBusReadBlock ( > + IN UINTN SmBusAddress, > + OUT VOID *Buffer, > + OUT RETURN_STATUS *Status OPTIONAL > + ) > +{ > + ASSERT (Buffer !=3D NULL); > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) =3D=3D 0); > + ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) =3D=3D 0); > + > + if ((Buffer =3D=3D NULL) || > + (SMBUS_LIB_LENGTH (SmBusAddress) !=3D 0) || > + (SMBUS_LIB_RESERVED (SmBusAddress) !=3D 0)) { > + if (Status !=3D NULL) { > + *Status =3D RETURN_INVALID_PARAMETER; > + } > + return 0; > + } > + > + return InternalSmBusBlock ( > + V_SMBUS_IO_SMB_CMD_BLOCK, > + SmBusAddress | B_SMBUS_IO_READ, > + NULL, > + Buffer, > + Status > + ); > +} > + > +/** > + Executes an SMBUS write block command. > + > + Executes an SMBUS write block command on the SMBUS device specified by > SmBusAddress. > + The SMBUS slave address, SMBUS command, and SMBUS length fields of > SmBusAddress are required. > + Bytes are written to the SMBUS from Buffer. > + The number of bytes written is returned, and will never return a value= larger > than 32-bytes. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + If Length in SmBusAddress is zero or greater than 32, then ASSERT(). > + If Buffer is NULL, then ASSERT(). > + If any reserved bits of SmBusAddress are set, then ASSERT(). > + > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[out] Buffer Pointer to the buffer to store the bytes rea= d from > the SMBUS. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be NUL= L. > + > + @retval The number of bytes written. > + > +**/ > +UINTN > +EFIAPI > +SmBusWriteBlock ( > + IN UINTN SmBusAddress, > + OUT VOID *Buffer, > + OUT RETURN_STATUS *Status OPTIONAL > + ) > +{ > + ASSERT (Buffer !=3D NULL); > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >=3D 1); > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <=3D 32); > + ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) =3D=3D 0); > + > + if ((Buffer =3D=3D NULL) || > + (SMBUS_LIB_LENGTH (SmBusAddress) =3D=3D 0) || > + (SMBUS_LIB_LENGTH (SmBusAddress) > 32) || > + (SMBUS_LIB_RESERVED (SmBusAddress) !=3D 0)) { > + if (Status !=3D NULL) { > + *Status =3D RETURN_INVALID_PARAMETER; > + } > + return 0; > + } > + > + return InternalSmBusBlock ( > + V_SMBUS_IO_SMB_CMD_BLOCK, > + SmBusAddress | B_SMBUS_IO_WRITE, > + Buffer, > + NULL, > + Status > + ); > +} > + > +/** > + Executes an SMBUS block process call command. > + > + Executes an SMBUS block process call command on the SMBUS device > specified by SmBusAddress. > + The SMBUS slave address, SMBUS command, and SMBUS length fields of > SmBusAddress are required. > + Bytes are written to the SMBUS from WriteBuffer. Bytes are then read = from > the SMBUS into ReadBuffer. > + If Status is not NULL, then the status of the executed command is retu= rned > in Status. > + It is the caller's responsibility to make sure ReadBuffer is large eno= ugh for > the total number of bytes read. > + SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not > need to be any larger than 32 bytes. > + If Length in SmBusAddress is zero or greater than 32, then ASSERT(). > + If WriteBuffer is NULL, then ASSERT(). > + If ReadBuffer is NULL, then ASSERT(). > + If any reserved bits of SmBusAddress are set, then ASSERT(). > + > + @param[in] SmBusAddress Address that encodes the SMBUS Slave > Address, > + SMBUS Command, SMBUS Data Length, and PEC. > + @param[in] WriteBuffer Pointer to the buffer of bytes to write to t= he > SMBUS. > + @param[out] ReadBuffer Pointer to the buffer of bytes to read from = the > SMBUS. > + @param[out] Status Return status for the executed command. > + This is an optional parameter and may be NUL= L. > + > + @retval The number of bytes written. > + > +**/ > +UINTN > +EFIAPI > +SmBusBlockProcessCall ( > + IN UINTN SmBusAddress, > + IN VOID *WriteBuffer, > + OUT VOID *ReadBuffer, > + OUT RETURN_STATUS *Status OPTIONAL > + ) > +{ > + ASSERT (WriteBuffer !=3D NULL); > + ASSERT (ReadBuffer !=3D NULL); > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >=3D 1); > + ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <=3D 32); > + ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) =3D=3D 0); > + > + if ((WriteBuffer =3D=3D NULL) || > + (ReadBuffer =3D=3D NULL) || > + (SMBUS_LIB_LENGTH (SmBusAddress) =3D=3D 0) || > + (SMBUS_LIB_LENGTH (SmBusAddress) > 32) || > + (SMBUS_LIB_RESERVED (SmBusAddress) !=3D 0)) { > + if (Status !=3D NULL) { > + *Status =3D RETURN_INVALID_PARAMETER; > + } > + return 0; > + } > + > + return InternalSmBusBlock ( > + V_SMBUS_IO_SMB_CMD_BLOCK_PROCESS, > + SmBusAddress | B_SMBUS_IO_WRITE, > + WriteBuffer, > + ReadBuffer, > + Status > + ); > +} > + > +/** > + The library constructuor. > + > + The function does the necessary initialization work for this library i= nstance. > + > + @retval EFI_SUCCESS The function always return EFI_SUCCESS f= or > now. > +**/ > +RETURN_STATUS > +EFIAPI > +BaseSmbusLibConstructor ( > + VOID > + ) > +{ > + UINT64 SmbusPciBase; > + UINT16 IoPortBaseAddress; > + > + // > + // Init mSmbusIoBase variable. > + // > + SmbusPciBase =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 > + ); > + IoPortBaseAddress =3D (UINT16) PciSegmentRead32 (SmbusPciBase + > + R_SMBUS_CFG_BASE); > + > + if ((IoPortBaseAddress !=3D 0) && (IoPortBaseAddress !=3D 0xFFFF)) { > + mSmbusIoBase =3D IoPortBaseAddress & B_SMBUS_CFG_BASE_BAR; } > + > + return RETURN_SUCCESS; > +} > -- > 2.16.2.windows.1