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/BaseResetSystemLib.inf | 38 +
Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf | 39 +
Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.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/BaseResetSystemLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.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/BaseSmbusLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf
new file mode 100644
index 0000000000..f3388a2624
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.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/BaseResetSystemLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.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/BaseSmbusLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.c
new file mode 100644
index 0000000000..3d6386d433
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.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
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#45894): https://edk2.groups.io/g/devel/message/45894
Mute This Topic: https://groups.io/mt/32918186/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
-----Original Message-----
From: Kubacki, Michael A
Sent: Friday, August 16, 2019 5:16 PM
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/BaseResetSystemLib.inf | 38 +
Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.inf | 39 +
Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.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/BaseResetSystemLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.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/BaseSmbusLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.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/BaseResetSystemLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseResetSystemLib/BaseResetSystemLib.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/BaseSmbusLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/BaseSmbusLib/BaseSmbusLib.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
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#45933): https://edk2.groups.io/g/devel/message/45933
Mute This Topic: https://groups.io/mt/32918186/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
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
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#45981): https://edk2.groups.io/g/devel/message/45981
Mute This Topic: https://groups.io/mt/32918186/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2025 Red Hat, Inc.