public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Chiu, Chasel" <chasel.chiu@intel.com>
To: "Kubacki, Michael A" <michael.a.kubacki@intel.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Chaganty, Rangasai V" <rangasai.v.chaganty@intel.com>,
	"Desimone, Nathaniel L" <nathaniel.l.desimone@intel.com>,
	"Gao, Liming" <liming.gao@intel.com>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>,
	"Sinha, Ankit" <ankit.sinha@intel.com>
Subject: Re: [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base library instances
Date: Sat, 17 Aug 2019 01:13:14 +0000	[thread overview]
Message-ID: <3C3EFB470A303B4AB093197B6777CCEC50462341@PGSMSX111.gar.corp.intel.com> (raw)
In-Reply-To: <20190817001603.30632-18-michael.a.kubacki@intel.com>

Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>


> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Saturday, August 17, 2019 8:16 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Sinha, Ankit
> <ankit.sinha@intel.com>
> Subject: [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add
> Base library instances
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
> 
> Adds PCH Base library class instances.
> 
> * BaseResetSystemLib
> * BaseSmbusLib
> 
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
> ---
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseRes
> etSystemLib.inf |  38 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.
> inf             |  39 +
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseRes
> etSystemLib.c   | 153 +++
> 
> Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.
> c               | 993 ++++++++++++++++++++
>  4 files changed, 1223 insertions(+)
> 
> 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. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = BaseResetSystemLib
> +FILE_GUID = D4FF05AA-3C7D-4B8A-A1EE-AA5EFA0B1732
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +UEFI_SPECIFICATION_VERSION = 2.00
> +LIBRARY_CLASS = ResetSystemLib
> +CONSTRUCTOR = BaseResetSystemLibConstructor # # The following
> +information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = 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. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = BaseSmbusLib
> +FILE_GUID = 5C4D0430-F81B-42D3-BB88-4A6CD2796FF8
> +VERSION_STRING = 1.0
> +MODULE_TYPE = BASE
> +LIBRARY_CLASS = SmbusLib
> +CONSTRUCTOR = BaseSmbusLibConstructor
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = 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. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#include <Uefi.h>
> +#include <Library/IoLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/ResetSystemLib.h>
> +#include <Library/PmcLib.h>
> +#include <Register/PchRegsLpc.h>
> +#include <Register/PchRegsPmc.h>
> +
> +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 = mBaseResetSystemABase;
> +  if (ABase == 0) {
> +    ABase = 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 = IoRead32 (ABase + R_ACPI_IO_PM1_CNT);
> +
> +  Data32 = (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 = 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 platform
> 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 capsule
> 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 instance.
> +
> +  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for
> now.
> +**/
> +EFI_STATUS
> +EFIAPI
> +BaseResetSystemLibConstructor (
> +  VOID
> +  )
> +{
> +  mBaseResetSystemABase = 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. <BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#include <Base.h>
> +#include <Library/SmbusLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Register/PchRegs.h>
> +#include <Register/PchRegsSmbus.h>
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED UINT16           mSmbusIoBase = 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 != 0) {
> +    return mSmbusIoBase;
> +  }
> +
> +  SmbusPciBase = 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 = (UINT16) PciSegmentRead32 (SmbusPciBase +
> + R_SMBUS_CFG_BASE);
> +
> +  //
> +  // Make sure that the IO port base address has been properly set.
> +  //
> +  if ((IoPortBaseAddress == 0) || (IoPortBaseAddress == 0xFFFF)) {
> +    ASSERT (FALSE);
> +    return 0;
> +  }
> +
> +  IoPortBaseAddress &= B_SMBUS_CFG_BASE_BAR;  mSmbusIoBase =
> + 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 = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HSTS);  if
> + ((HostStatus & B_SMBUS_IO_IUS) != 0) {
> +    return RETURN_TIMEOUT;
> +  } else if ((HostStatus & B_SMBUS_IO_HBSY) != 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 status
> 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 SMBUS
> 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.  Device errors are
> +                                  a result of a transaction collision, illegal command
> field,
> +                                  unclaimed cycle (host initiated), or bus 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 = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HSTS);  }
> + while ((HostStatus & (B_SMBUS_IO_INTR | B_SMBUS_IO_ERROR |
> + B_SMBUS_IO_BYTE_DONE_STS)) == 0);
> +
> +  if ((HostStatus & B_SMBUS_IO_ERROR) == 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 = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_AUXS);  if
> + ((AuxiliaryStatus & B_SMBUS_IO_CRCE) != 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 returned
> 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 NULL.
> +
> +  @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 = InternalGetSmbusIoPortBaseAddress ();
> +
> +  //
> +  // Try to acquire the ownership of SMBUS.
> +  //
> +  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);  if
> + (RETURN_ERROR (ReturnStatus)) {
> +    goto Done;
> +  }
> +  //
> +  // Set the appropriate Host Control Register and auxiliary Control Register.
> +  //
> +  AuxiliaryControl = 0;
> +  if (SMBUS_LIB_PEC (SmBusAddress)) {
> +    AuxiliaryControl |= 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 = InternalSmBusStart (IoPortBaseAddress, HostControl);
> + //  // Read value from Host Data 0 and Host Data 1 Registers.
> +  //
> +  Value = (UINT16)(IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HD1) << 8);
> + Value = (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 != NULL) {
> +    *Status = 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 returned
> 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 NULL.
> +
> +**/
> +VOID
> +EFIAPI
> +SmBusQuickRead (
> +  IN  UINTN                     SmBusAddress,
> +  OUT RETURN_STATUS             *Status       OPTIONAL
> +  )
> +{
> +  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
> +  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if (SMBUS_LIB_PEC (SmBusAddress)           ||
> +    (SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
> +    (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +    (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = 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 returned
> 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 NULL.
> +
> +**/
> +VOID
> +EFIAPI
> +SmBusQuickWrite (
> +  IN  UINTN                     SmBusAddress,
> +  OUT RETURN_STATUS             *Status       OPTIONAL
> +  )
> +{
> +  ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
> +  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if (SMBUS_LIB_PEC (SmBusAddress)           ||
> +    (SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
> +    (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +    (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = 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 returned
> 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 NULL.
> +
> +  @retval The byte received from the SMBUS.
> +
> +**/
> +UINT8
> +EFIAPI
> +SmBusReceiveByte (
> +  IN  UINTN          SmBusAddress,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = 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 returned
> 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 NULL.
> +
> +  @retval The parameter of Value.
> +
> +**/
> +UINT8
> +EFIAPI
> +SmBusSendByte (
> +  IN  UINTN          SmBusAddress,
> +  IN  UINT8          Value,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)  == 0);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_COMMAND (SmBusAddress)  != 0) ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = 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 returned
> 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 NULL.
> +
> +  @retval The byte read from the SMBUS.
> +
> +**/
> +UINT8
> +EFIAPI
> +SmBusReadDataByte (
> +  IN  UINTN          SmBusAddress,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = 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 returned
> 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 NULL.
> +
> +  @retval The parameter of Value.
> +
> +**/
> +UINT8
> +EFIAPI
> +SmBusWriteDataByte (
> +  IN  UINTN          SmBusAddress,
> +  IN  UINT8          Value,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = 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 returned
> 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 NULL.
> +
> +  @retval The byte read from the SMBUS.
> +
> +**/
> +UINT16
> +EFIAPI
> +SmBusReadDataWord (
> +  IN  UINTN          SmBusAddress,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = 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 returned
> 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 NULL.
> +
> +  @retval The parameter of Value.
> +
> +**/
> +UINT16
> +EFIAPI
> +SmBusWriteDataWord (
> +  IN  UINTN          SmBusAddress,
> +  IN  UINT16         Value,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = 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 by
> 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 returned
> 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 NULL.
> +
> +  @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)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = 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 larger
> than 32-bytes.
> +  If Status is not NULL, then the status of the executed command is returned
> 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 from the
> SMBUS.
> +  @param[out] Status          Return status for the executed command.
> +                              This is an optional parameter and may be NULL.
> +
> +  @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 = InternalGetSmbusIoPortBaseAddress ();
> +
> +  BytesCount = SMBUS_LIB_LENGTH (SmBusAddress);
> +
> +  //
> +  // Try to acquire the ownership of SMBUS.
> +  //
> +  ReturnStatus = InternalSmBusAcquire (IoPortBaseAddress);  if
> + (RETURN_ERROR (ReturnStatus)) {
> +    goto Done;
> +  }
> +  //
> +  // Set the appropriate Host Control Register and auxiliary Control Register.
> +  //
> +  AuxiliaryControl = B_SMBUS_IO_E32B;
> +  if (SMBUS_LIB_PEC (SmBusAddress)) {
> +    AuxiliaryControl |= 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 != 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 = 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 = InternalSmBusStart (IoPortBaseAddress, HostControl);
> + if (RETURN_ERROR (ReturnStatus)) {
> +    goto Done;
> +  }
> +
> +  if (ReadBuffer != NULL) {
> +    //
> +    // Read the number of block from host block data byte register.
> +    //
> +    BytesCount = IoRead8 (IoPortBaseAddress + R_SMBUS_IO_HD0);
> +    //
> +    // Write data block from Host Block Data Register.
> +    //
> +    for (Index = 0; Index < BytesCount; Index++) {
> +      ReadBuffer[Index] = 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 != NULL) {
> +    *Status = 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 larger
> than 32-bytes.
> +  If Status is not NULL, then the status of the executed command is returned
> 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 read from
> the SMBUS.
> +  @param[out] Status        Return status for the executed command.
> +                            This is an optional parameter and may be NULL.
> +
> +  @retval The number of bytes read.
> +
> +**/
> +UINTN
> +EFIAPI
> +SmBusReadBlock (
> +  IN  UINTN          SmBusAddress,
> +  OUT VOID           *Buffer,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (Buffer != NULL);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   == 0);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((Buffer == NULL)                         ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   != 0) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = 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 returned
> 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 read from
> the SMBUS.
> +  @param[out] Status        Return status for the executed command.
> +                            This is an optional parameter and may be NULL.
> +
> +  @retval The number of bytes written.
> +
> +**/
> +UINTN
> +EFIAPI
> +SmBusWriteBlock (
> +  IN  UINTN          SmBusAddress,
> +  OUT VOID           *Buffer,
> +  OUT RETURN_STATUS  *Status        OPTIONAL
> +  )
> +{
> +  ASSERT (Buffer != NULL);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   >= 1);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   <= 32);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((Buffer == NULL)                         ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   == 0) ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   > 32) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = 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 returned
> in Status.
> +  It is the caller's responsibility to make sure ReadBuffer 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 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 the
> 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 NULL.
> +
> +  @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 != NULL);
> +  ASSERT (ReadBuffer  != NULL);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   >= 1);
> +  ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)   <= 32);
> +  ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
> +
> +  if ((WriteBuffer == NULL)                    ||
> +      (ReadBuffer  == NULL)                    ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   == 0) ||
> +      (SMBUS_LIB_LENGTH (SmBusAddress)   > 32) ||
> +      (SMBUS_LIB_RESERVED (SmBusAddress) != 0))  {
> +    if (Status != NULL) {
> +      *Status = 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 instance.
> +
> +  @retval     EFI_SUCCESS       The function always return EFI_SUCCESS for
> now.
> +**/
> +RETURN_STATUS
> +EFIAPI
> +BaseSmbusLibConstructor (
> +  VOID
> +  )
> +{
> +  UINT64    SmbusPciBase;
> +  UINT16    IoPortBaseAddress;
> +
> +  //
> +  // Init mSmbusIoBase variable.
> +  //
> +  SmbusPciBase = 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 = (UINT16) PciSegmentRead32 (SmbusPciBase +
> + R_SMBUS_CFG_BASE);
> +
> +  if ((IoPortBaseAddress != 0) && (IoPortBaseAddress != 0xFFFF)) {
> +    mSmbusIoBase = IoPortBaseAddress & B_SMBUS_CFG_BASE_BAR;  }
> +
> +  return RETURN_SUCCESS;
> +}
> --
> 2.16.2.windows.1


  parent reply	other threads:[~2019-08-17  1:13 UTC|newest]

Thread overview: 121+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-17  0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  1:18   ` Chaganty, Rangasai V
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  6:58   ` Chaganty, Rangasai V
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  7:04   ` Chaganty, Rangasai V
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:08   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:09   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol " Kubacki, Michael A
2019-08-17  0:51   ` Nate DeSimone
2019-08-17  1:10   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:12   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel [this message]
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private " Kubacki, Michael A
2019-08-17  0:52   ` Nate DeSimone
2019-08-17  1:13   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add " Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:14   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers Kubacki, Michael A
2019-08-17  0:53   ` Nate DeSimone
2019-08-17  1:15   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-19 18:09   ` Sinha, Ankit
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17  0:15 ` [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: " Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:17   ` Chiu, Chasel
2019-08-17 20:08   ` Chaganty, Rangasai V
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:17   ` Chiu, Chasel
2019-08-17  7:50   ` Chaganty, Rangasai V
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:16   ` Chiu, Chasel
2019-08-17 20:11   ` Chaganty, Rangasai V
2019-08-17  0:16 ` [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation Kubacki, Michael A
2019-08-17  0:54   ` Nate DeSimone
2019-08-17  1:17   ` Chiu, Chasel
2019-08-17 20:00   ` Chaganty, Rangasai V
2019-08-19 18:14 ` [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Sinha, Ankit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3C3EFB470A303B4AB093197B6777CCEC50462341@PGSMSX111.gar.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox