From: "Nhi Pham via groups.io" <nhi=os.amperecomputing.com@groups.io>
To: devel@edk2.groups.io
Cc: quic_llindhol@quicinc.com, chuong@os.amperecomputing.com,
rebecca@os.amperecomputing.com, nhi@os.amperecomputing.com
Subject: [edk2-devel] [edk2-platforms][PATCH v2 3/5] AmpereAltraPkg: Add SmbusHc PEI and DXE drivers
Date: Wed, 7 Aug 2024 13:47:29 +0700 [thread overview]
Message-ID: <20240807064731.4049764-4-nhi@os.amperecomputing.com> (raw)
In-Reply-To: <20240807064731.4049764-1-nhi@os.amperecomputing.com>
This adds the implementation of SMBUS PPI and Protocol to produce SMBUS
interface in both PEI and DXE phases for use by IPMI SSIF.
Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcDxe.inf | 43 +++
Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcPei.inf | 43 +++
Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcCommon.h | 95 +++++++
Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcCommon.c | 261 ++++++++++++++++++
Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcDxe.c | 277 ++++++++++++++++++++
Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcPei.c | 263 +++++++++++++++++++
6 files changed, 982 insertions(+)
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcDxe.inf
new file mode 100644
index 000000000000..7e8c8176658e
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcDxe.inf
@@ -0,0 +1,43 @@
+## @file
+#
+# Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = SmbusHcDxe
+ FILE_GUID = A92C6874-B59E-49A7-957D-8511C9D8520E
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeSmbus
+
+[Sources]
+ SmbusHcCommon.c
+ SmbusHcDxe.c
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+ Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ GpioLib
+ I2cLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiSmbusHcProtocolGuid # PRODUCES
+
+[Pcd]
+ gAmpereTokenSpaceGuid.PcdSmbusI2cBusNumber
+ gAmpereTokenSpaceGuid.PcdSmbusI2cBusSpeed
+
+[Depex]
+ TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcPei.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcPei.inf
new file mode 100644
index 000000000000..810a583feab3
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcPei.inf
@@ -0,0 +1,43 @@
+## @file
+#
+# Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = SmbusHcPeim
+ FILE_GUID = 1D770ACE-36E9-4B74-B548-4F423B60A26C
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeSmbusPeim
+
+[Sources]
+ SmbusHcCommon.c
+ SmbusHcPei.c
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+ Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ GpioLib
+ I2cLib
+ PeimEntryPoint
+ PeiServicesLib
+
+[Ppis]
+ gEfiPeiSmbus2PpiGuid # PRODUCES
+
+[Pcd]
+ gAmpereTokenSpaceGuid.PcdSmbusI2cBusNumber
+ gAmpereTokenSpaceGuid.PcdSmbusI2cBusSpeed
+
+[Depex]
+ TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcCommon.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcCommon.h
new file mode 100644
index 000000000000..db19d50b0f2a
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcCommon.h
@@ -0,0 +1,95 @@
+/** @file
+
+ Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SMBUS_HC_COMMON_LIB_H_
+#define SMBUS_HC_COMMON_LIB_H_
+
+#include <Library/PcdLib.h>
+#include <IndustryStandard/SmBus.h>
+#include <Uefi/UefiBaseType.h>
+
+//
+// I2C Based SMBus info
+//
+#define I2C_BUS_NUMBER (FixedPcdGet8 (PcdSmbusI2cBusNumber))
+#define I2C_BUS_SPEED (FixedPcdGet32 (PcdSmbusI2cBusSpeed))
+#define I2C_WRITE_ADDRESS(Addr) ((Addr) << 1 | 0)
+#define I2C_READ_ADDRESS(Addr) ((Addr) << 1 | 1)
+
+//
+// SMBus 2.0
+//
+#define SMBUS_MAX_BLOCK_LENGTH 0x20
+#define SMBUS_READ_TEMP_LENGTH (SMBUS_MAX_BLOCK_LENGTH + 2) // Length + 32 Bytes + PEC
+#define SMBUS_WRITE_TEMP_LENGTH (SMBUS_MAX_BLOCK_LENGTH + 3) // CMD + Length + 32 Bytes + PEC
+
+//
+// SMBus PEC
+//
+#define CRC8_POLYNOMINAL_KEY 0x107 // X^8 + X^2 + X + 1
+
+/**
+ Executes an SMBus operation to an SMBus controller. Returns when either the command has been
+ executed or an error is encountered in doing the operation.
+
+ The Execute() function provides a standard way to execute an operation as defined in the System
+ Management Bus (SMBus) Specification. The resulting transaction will be either that the SMBus
+ slave devices accept this transaction or that this function returns with error.
+
+ @param This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+ @param SlaveAddress The SMBus slave address of the device with which to communicate.
+ @param Command This command is transmitted by the SMBus host controller to the
+ SMBus slave device and the interpretation is SMBus slave device
+ specific. It can mean the offset to a list of functions inside an
+ SMBus slave device. Not all operations or slave devices support
+ this command's registers.
+ @param Operation Signifies which particular SMBus hardware protocol instance that
+ it will use to execute the SMBus transactions. This SMBus
+ hardware protocol is defined by the SMBus Specification and is
+ not related to EFI.
+ @param PecCheck Defines if Packet Error Code (PEC) checking is required for this
+ operation.
+ @param Length Signifies the number of bytes that this operation will do. The
+ maximum number of bytes can be revision specific and operation
+ specific. This field will contain the actual number of bytes that
+ are executed for this operation. Not all operations require this
+ argument.
+ @param Buffer Contains the value of data to execute to the SMBus slave device.
+ Not all operations require this argument. The length of this
+ buffer is identified by Length.
+
+ @retval EFI_SUCCESS The last data that was returned from the access matched the poll
+ exit criteria.
+ @retval EFI_CRC_ERROR Checksum is not correct (PEC is incorrect).
+ @retval EFI_TIMEOUT Timeout expired before the operation was completed. Timeout is
+ determined by the SMBus host controller device.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The request was not completed because a failure that was
+ 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).
+ @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.
+ @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+ and EfiSmbusQuickWrite. Length is outside the range of valid
+ values.
+ @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.
+ @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusHcCommonExecute (
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ );
+
+#endif /* SMBUS_HC_COMMON_LIB_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcCommon.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcCommon.c
new file mode 100644
index 000000000000..adce5c02cf95
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcCommon.c
@@ -0,0 +1,261 @@
+/** @file
+ SmbusHcCommon implement common api for SmbusHc
+
+ Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <Library/I2cLib.h>
+#include <Library/PcdLib.h>
+
+#include "SmbusHcCommon.h"
+
+/**
+ Incremental calculate Pec base on previous Pec value and CRC8 of data array
+ pointed to by Buffer
+
+ @param Pec Previous Pec
+ @param Buffer Pointer to data array
+ @param Length Array count
+
+ @retval Pec
+
+**/
+UINT8
+CalculatePec (
+ UINT8 Pec,
+ UINT8 *Buffer,
+ UINT32 Length
+ )
+{
+ UINT8 Offset, Index;
+
+ for (Offset = 0; Offset < Length; Offset++) {
+ Pec ^= Buffer[Offset];
+ for (Index = 0; Index < 8; Index++) {
+ if ((Pec & 0x80) != 0) {
+ Pec = (UINT8)((Pec << 1) ^ CRC8_POLYNOMINAL_KEY);
+ } else {
+ Pec <<= 1;
+ }
+ }
+ }
+
+ return Pec & 0xFF;
+}
+
+/**
+ Executes an SMBus operation to an SMBus controller. Returns when either the command has been
+ executed or an error is encountered in doing the operation.
+
+ The Execute() function provides a standard way to execute an operation as defined in the System
+ Management Bus (SMBus) Specification. The resulting transaction will be either that the SMBus
+ slave devices accept this transaction or that this function returns with error.
+
+ @param SlaveAddress The SMBus slave address of the device with which to communicate.
+ @param Command This command is transmitted by the SMBus host controller to the
+ SMBus slave device and the interpretation is SMBus slave device
+ specific. It can mean the offset to a list of functions inside an
+ SMBus slave device. Not all operations or slave devices support
+ this command's registers.
+ @param Operation Signifies which particular SMBus hardware protocol instance that
+ it will use to execute the SMBus transactions. This SMBus
+ hardware protocol is defined by the SMBus Specification and is
+ not related to EFI.
+ @param PecCheck Defines if Packet Error Code (PEC) checking is required for this
+ operation.
+ @param Length Signifies the number of bytes that this operation will do. The
+ maximum number of bytes can be revision specific and operation
+ specific. This field will contain the actual number of bytes that
+ are executed for this operation. Not all operations require this
+ argument.
+ @param Buffer Contains the value of data to execute to the SMBus slave device.
+ Not all operations require this argument. The length of this
+ buffer is identified by Length.
+
+ @retval EFI_SUCCESS The last data that was returned from the access matched the poll
+ exit criteria.
+ @retval EFI_CRC_ERROR Checksum is not correct (PEC is incorrect).
+ @retval EFI_TIMEOUT Timeout expired before the operation was completed. Timeout is
+ determined by the SMBus host controller device.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The request was not completed because a failure that was
+ 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).
+ @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.
+ @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+ and EfiSmbusQuickWrite. Length is outside the range of valid
+ values.
+ @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.
+ @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusHcCommonExecute (
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataLen, Idx;
+ UINT8 ReadTemp[SMBUS_READ_TEMP_LENGTH];
+ UINT8 WriteTemp[SMBUS_WRITE_TEMP_LENGTH];
+ UINT8 CrcTemp[10];
+ UINT8 Pec;
+
+ if ( ((Operation != EfiSmbusQuickRead) && (Operation != EfiSmbusQuickWrite))
+ && ((Length == NULL) || (Buffer == NULL)))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Switch to correct I2C bus and speed
+ //
+ Status = I2cProbe (I2C_BUS_NUMBER, I2C_BUS_SPEED, TRUE, PecCheck);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Process Operation
+ //
+ switch (Operation) {
+ case EfiSmbusWriteBlock:
+ if (*Length > SMBUS_MAX_BLOCK_LENGTH) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ WriteTemp[0] = Command;
+ WriteTemp[1] = *Length;
+ CopyMem (&WriteTemp[2], Buffer, *Length);
+ DataLen = *Length + 2;
+
+ //
+ // PEC handling
+ //
+ if (PecCheck) {
+ CrcTemp[0] = I2C_WRITE_ADDRESS (SlaveAddress.SmbusDeviceAddress);
+ Pec = CalculatePec (0, &CrcTemp[0], 1);
+ Pec = CalculatePec (Pec, WriteTemp, DataLen);
+ DEBUG ((DEBUG_VERBOSE, "\nWriteBlock PEC = 0x%x \n", Pec));
+ WriteTemp[DataLen] = Pec;
+ DataLen += 1;
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "W %d: ", DataLen));
+ for (Idx = 0; Idx < DataLen; Idx++) {
+ DEBUG ((DEBUG_VERBOSE, "0x%x ", WriteTemp[Idx]));
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "\n"));
+
+ Status = I2cWrite (
+ I2C_BUS_NUMBER,
+ SlaveAddress.SmbusDeviceAddress,
+ WriteTemp,
+ (UINT32 *)&DataLen
+ );
+ if (EFI_ERROR (Status)) {
+ if (Status != EFI_TIMEOUT) {
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+
+ break;
+
+ case EfiSmbusReadBlock:
+ WriteTemp[0] = Command;
+ DataLen = *Length + 2; // +1 byte for Data Length +1 byte for PEC
+ Status = I2cRead (
+ I2C_BUS_NUMBER,
+ SlaveAddress.SmbusDeviceAddress,
+ WriteTemp,
+ 1,
+ ReadTemp,
+ (UINT32 *)&DataLen
+ );
+ if (EFI_ERROR (Status)) {
+ if (Status != EFI_TIMEOUT) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ *Length = 0;
+ break;
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "R %d: ", DataLen));
+ for (Idx = 0; Idx < DataLen; Idx++) {
+ DEBUG ((DEBUG_VERBOSE, "0x%x ", ReadTemp[Idx]));
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "\n"));
+
+ DataLen = ReadTemp[0];
+
+ //
+ // PEC handling
+ //
+ if (PecCheck) {
+ CrcTemp[0] = I2C_WRITE_ADDRESS (SlaveAddress.SmbusDeviceAddress);
+ CrcTemp[1] = Command;
+ CrcTemp[2] = I2C_READ_ADDRESS (SlaveAddress.SmbusDeviceAddress);
+
+ Pec = CalculatePec (0, &CrcTemp[0], 3);
+ Pec = CalculatePec (Pec, ReadTemp, DataLen + 1);
+
+ if (Pec != ReadTemp[DataLen + 1]) {
+ DEBUG ((DEBUG_ERROR, "ReadBlock PEC cal = 0x%x != 0x%x\n", Pec, ReadTemp[DataLen + 1]));
+ return EFI_CRC_ERROR;
+ } else {
+ DEBUG ((DEBUG_VERBOSE, "ReadBlock PEC 0x%x\n", ReadTemp[DataLen + 1]));
+ }
+ }
+
+ if ((DataLen == 0) || (DataLen > SMBUS_MAX_BLOCK_LENGTH)) {
+ DEBUG ((DEBUG_ERROR, "%a: Invalid length = %d\n", __func__, DataLen));
+ *Length = 0;
+ Status = EFI_INVALID_PARAMETER;
+ } else if (DataLen > *Length) {
+ DEBUG ((DEBUG_ERROR, "%a: Buffer too small\n", __func__));
+ *Length = 0;
+ Status = EFI_BUFFER_TOO_SMALL;
+ } else {
+ *Length = DataLen;
+ CopyMem (Buffer, &ReadTemp[1], DataLen);
+ }
+
+ break;
+
+ case EfiSmbusQuickRead:
+ case EfiSmbusQuickWrite:
+ case EfiSmbusReceiveByte:
+ case EfiSmbusSendByte:
+ case EfiSmbusReadByte:
+ case EfiSmbusWriteByte:
+ case EfiSmbusReadWord:
+ case EfiSmbusWriteWord:
+ case EfiSmbusProcessCall:
+ case EfiSmbusBWBRProcessCall:
+ DEBUG ((DEBUG_ERROR, "%a: Unsupported command\n", __func__));
+ Status = EFI_UNSUPPORTED;
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ return Status;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcDxe.c
new file mode 100644
index 000000000000..49a16a2c3d7e
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcDxe.c
@@ -0,0 +1,277 @@
+/** SmbusHc protocol implementation follows SMBus 2.0 specification.
+
+ Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <Library/I2cLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/SmbusHc.h>
+
+#include "SmbusHcCommon.h"
+
+//
+// Handle to install SMBus Host Controller protocol.
+//
+EFI_HANDLE mSmbusHcHandle = NULL;
+
+/**
+ Executes an SMBus operation to an SMBus controller. Returns when either the command has been
+ executed or an error is encountered in doing the operation.
+
+ The Execute() function provides a standard way to execute an operation as defined in the System
+ Management Bus (SMBus) Specification. The resulting transaction will be either that the SMBus
+ slave devices accept this transaction or that this function returns with error.
+
+ @param This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+ @param SlaveAddress The SMBus slave address of the device with which to communicate.
+ @param Command This command is transmitted by the SMBus host controller to the
+ SMBus slave device and the interpretation is SMBus slave device
+ specific. It can mean the offset to a list of functions inside an
+ SMBus slave device. Not all operations or slave devices support
+ this command's registers.
+ @param Operation Signifies which particular SMBus hardware protocol instance that
+ it will use to execute the SMBus transactions. This SMBus
+ hardware protocol is defined by the SMBus Specification and is
+ not related to EFI.
+ @param PecCheck Defines if Packet Error Code (PEC) checking is required for this
+ operation.
+ @param Length Signifies the number of bytes that this operation will do. The
+ maximum number of bytes can be revision specific and operation
+ specific. This field will contain the actual number of bytes that
+ are executed for this operation. Not all operations require this
+ argument.
+ @param Buffer Contains the value of data to execute to the SMBus slave device.
+ Not all operations require this argument. The length of this
+ buffer is identified by Length.
+
+ @retval EFI_SUCCESS The last data that was returned from the access matched the poll
+ exit criteria.
+ @retval EFI_CRC_ERROR Checksum is not correct (PEC is incorrect).
+ @retval EFI_TIMEOUT Timeout expired before the operation was completed. Timeout is
+ determined by the SMBus host controller device.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The request was not completed because a failure that was
+ 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).
+ @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.
+ @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+ and EfiSmbusQuickWrite. Length is outside the range of valid
+ values.
+ @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.
+ @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusHcExecute (
+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ ASSERT (This != NULL);
+
+ OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+ Status = SmbusHcCommonExecute (SlaveAddress, Command, Operation, PecCheck, Length, Buffer);
+
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+/**
+
+ The SmbusHcArpDevice() function provides a standard way for a device driver to
+ enumerate the entire SMBus or specific devices on the bus.
+
+ @param This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+
+ @param ArpAll A Boolean expression that indicates if the
+ host drivers need to enumerate all the devices
+ or enumerate only the device that is
+ identified by SmbusUdid. If ArpAll is TRUE,
+ SmbusUdid and SlaveAddress are optional. If
+ ArpAll is FALSE, ArpDevice will enumerate
+ SmbusUdid and the address will be at
+ SlaveAddress.
+
+ @param SmbusUdid The Unique Device Identifier (UDID) that is
+ associated with this device. Type
+ EFI_SMBUS_UDID is defined in
+ EFI_PEI_SMBUS_PPI.ArpDevice() in the
+ Platform Initialization SMBus PPI
+ Specification.
+
+ @param SlaveAddress The SMBus slave address that is
+ associated with an SMBus UDID.
+
+ @retval EFI_SUCCESS The last data that was returned from the
+ access matched the poll exit criteria.
+
+ @retval EFI_CRC_ERROR Checksum is not correct (PEC is
+ incorrect).
+
+ @retval EFI_TIMEOUT Timeout expired before the operation was
+ completed. Timeout is determined by the
+ SMBus host controller device.
+
+ @retval EFI_OUT_OF_RESOURCES The request could not be
+ completed due to a lack of
+ resources.
+
+ @retval EFI_DEVICE_ERROR The request was not completed
+ because a failure was 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).
+
+ @retval EFI_UNSUPPORTED ArpDevice, GetArpMap, and Notify are
+ not implemented by this driver.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusHcArpDevice (
+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL
+ )
+{
+ //
+ // Not supported
+ //
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ The SmbusHcGetArpMap() function returns the mapping of all the SMBus devices
+ that were enumerated by the SMBus host driver.
+
+ @param This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+
+ @param Length Size of the buffer that contains the SMBus
+ device map.
+
+ @param SmbusDeviceMap The pointer to the device map as
+ enumerated by the SMBus controller
+ driver.
+
+ @retval EFI_SUCCESS The SMBus returned the current device map.
+
+ @retval EFI_UNSUPPORTED ArpDevice, GetArpMap, and Notify are
+ not implemented by this driver.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusHcGetArpMap (
+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ )
+{
+ //
+ // Not supported
+ //
+ return EFI_UNSUPPORTED;
+}
+
+/**
+
+ The SmbusHcNotify() function registers all the callback functions to
+ allow the bus driver to call these functions when the
+ SlaveAddress/Data pair happens.
+
+ @param This A pointer to the EFI_SMBUS_HC_PROTOCOL instance.
+
+ @param SlaveAddress Address that the host controller detects
+ as sending a message and calls all the registered function.
+
+ @param Data Data that the host controller detects as sending
+ message and calls all the registered function.
+
+
+ @param NotifyFunction The function to call when the bus
+ driver detects the SlaveAddress and
+ Data pair.
+
+ @retval EFI_SUCCESS NotifyFunction was registered.
+
+ @retval EFI_UNSUPPORTED ArpDevice, GetArpMap, and Notify are
+ not implemented by this driver.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusHcNotify (
+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ )
+{
+ //
+ // Not supported
+ //
+ return EFI_UNSUPPORTED;
+}
+
+//
+// Interface defintion of SMBUS Host Controller Protocol.
+//
+EFI_SMBUS_HC_PROTOCOL mSmbusHcProtocol = {
+ SmbusHcExecute,
+ SmbusHcArpDevice,
+ SmbusHcGetArpMap,
+ SmbusHcNotify
+};
+
+/**
+ SmbusHc driver entry point
+
+ @param[in] ImageHandle ImageHandle of this module
+ @param[in] SystemTable EFI System Table
+
+ @retval EFI_SUCCESS Driver initializes successfully
+ @retval Other values Some error occurred
+**/
+EFI_STATUS
+InitializeSmbus (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install Smbus protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mSmbusHcHandle,
+ &gEfiSmbusHcProtocolGuid,
+ &mSmbusHcProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcPei.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcPei.c
new file mode 100644
index 000000000000..39483a2a602a
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/SmbusHc/SmbusHcPei.c
@@ -0,0 +1,263 @@
+/** @file
+ SmbusHc protocol implementation follows SMBus 2.0 specification.
+
+ Copyright (c) 2024, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/Smbus2.h>
+
+#include "SmbusHcCommon.h"
+
+/**
+ Executes an SMBus operation to an SMBus controller. Returns when either the command has been
+ executed or an error is encountered in doing the operation.
+
+ The Execute() function provides a standard way to execute an operation as defined in the System
+ Management Bus (SMBus) Specification. The resulting transaction will be either that the SMBus
+ slave devices accept this transaction or that this function returns with error.
+
+ @param This A pointer to the EFI_PEI_SMBUS2_PPI instance.
+ @param SlaveAddress The SMBus slave address of the device with which to communicate.
+ @param Command This command is transmitted by the SMBus host controller to the
+ SMBus slave device and the interpretation is SMBus slave device
+ specific. It can mean the offset to a list of functions inside an
+ SMBus slave device. Not all operations or slave devices support
+ this command's registers.
+ @param Operation Signifies which particular SMBus hardware protocol instance that
+ it will use to execute the SMBus transactions. This SMBus
+ hardware protocol is defined by the SMBus Specification and is
+ not related to EFI.
+ @param PecCheck Defines if Packet Error Code (PEC) checking is required for this
+ operation.
+ @param Length Signifies the number of bytes that this operation will do. The
+ maximum number of bytes can be revision specific and operation
+ specific. This field will contain the actual number of bytes that
+ are executed for this operation. Not all operations require this
+ argument.
+ @param Buffer Contains the value of data to execute to the SMBus slave device.
+ Not all operations require this argument. The length of this
+ buffer is identified by Length.
+
+ @retval EFI_SUCCESS The last data that was returned from the access matched the poll
+ exit criteria.
+ @retval EFI_CRC_ERROR Checksum is not correct (PEC is incorrect).
+ @retval EFI_TIMEOUT Timeout expired before the operation was completed. Timeout is
+ determined by the SMBus host controller device.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_DEVICE_ERROR The request was not completed because a failure that was
+ 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).
+ @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.
+ @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead
+ and EfiSmbusQuickWrite. Length is outside the range of valid
+ values.
+ @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.
+ @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusHcExecute (
+ IN CONST EFI_PEI_SMBUS2_PPI *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ ASSERT (This != NULL);
+ return SmbusHcCommonExecute (SlaveAddress, Command, Operation, PecCheck, Length, Buffer);
+}
+
+/**
+
+ The SmbusHcArpDevice() function provides a standard way for a device driver to
+ enumerate the entire SMBus or specific devices on the bus.
+
+ @param This A pointer to the EFI_PEI_SMBUS2_PPI instance.
+
+ @param ArpAll A Boolean expression that indicates if the
+ host drivers need to enumerate all the devices
+ or enumerate only the device that is
+ identified by SmbusUdid. If ArpAll is TRUE,
+ SmbusUdid and SlaveAddress are optional. If
+ ArpAll is FALSE, ArpDevice will enumerate
+ SmbusUdid and the address will be at
+ SlaveAddress.
+
+ @param SmbusUdid The Unique Device Identifier (UDID) that is
+ associated with this device. Type
+ EFI_SMBUS_UDID is defined in
+ EFI_PEI_SMBUS_PPI.ArpDevice() in the
+ Platform Initialization SMBus PPI
+ Specification.
+
+ @param SlaveAddress The SMBus slave address that is
+ associated with an SMBus UDID.
+
+ @retval EFI_SUCCESS The last data that was returned from the
+ access matched the poll exit criteria.
+
+ @retval EFI_CRC_ERROR Checksum is not correct (PEC is
+ incorrect).
+
+ @retval EFI_TIMEOUT Timeout expired before the operation was
+ completed. Timeout is determined by the
+ SMBus host controller device.
+
+ @retval EFI_OUT_OF_RESOURCES The request could not be
+ completed due to a lack of
+ resources.
+
+ @retval EFI_DEVICE_ERROR The request was not completed
+ because a failure was 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).
+
+ @retval EFI_UNSUPPORTED ArpDevice, GetArpMap, and Notify are
+ not implemented by this driver.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusHcArpDevice (
+ IN CONST EFI_PEI_SMBUS2_PPI *This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL
+ )
+{
+ //
+ // Not supported
+ //
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ The SmbusHcGetArpMap() function returns the mapping of all the SMBus devices
+ that were enumerated by the SMBus host driver.
+
+ @param This A pointer to the EFI_PEI_SMBUS2_PPI instance.
+
+ @param Length Size of the buffer that contains the SMBus
+ device map.
+
+ @param SmbusDeviceMap The pointer to the device map as
+ enumerated by the SMBus controller
+ driver.
+
+ @retval EFI_SUCCESS The SMBus returned the current device map.
+
+ @retval EFI_UNSUPPORTED ArpDevice, GetArpMap, and Notify are
+ not implemented by this driver.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusHcGetArpMap (
+ IN CONST EFI_PEI_SMBUS2_PPI *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ )
+{
+ //
+ // Not supported
+ //
+ return EFI_UNSUPPORTED;
+}
+
+/**
+
+ The SmbusHcNotify() function registers all the callback functions to
+ allow the bus driver to call these functions when the
+ SlaveAddress/Data pair happens.
+
+ @param This A pointer to the EFI_PEI_SMBUS2_PPI instance.
+
+ @param SlaveAddress Address that the host controller detects
+ as sending a message and calls all the registered function.
+
+ @param Data Data that the host controller detects as sending
+ message and calls all the registered function.
+
+
+ @param NotifyFunction The function to call when the bus
+ driver detects the SlaveAddress and
+ Data pair.
+
+ @retval EFI_SUCCESS NotifyFunction was registered.
+
+ @retval EFI_UNSUPPORTED ArpDevice, GetArpMap, and Notify are
+ not implemented by this driver.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbusHcNotify (
+ IN CONST EFI_PEI_SMBUS2_PPI *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_PEI_SMBUS_NOTIFY2_FUNCTION NotifyFunction
+ )
+{
+ //
+ // Not supported
+ //
+ return EFI_UNSUPPORTED;
+}
+
+//
+// Interface defintion of SMBUS Host Controller Protocol.
+//
+EFI_PEI_SMBUS2_PPI mSmbusHcPpi = {
+ SmbusHcExecute,
+ SmbusHcArpDevice,
+ SmbusHcGetArpMap,
+ SmbusHcNotify
+};
+
+EFI_PEI_PPI_DESCRIPTOR gPpiSmbusHcPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiSmbus2PpiGuid,
+ &mSmbusHcPpi
+};
+
+/**
+ SmbusHc driver entry point
+
+ @param[in] ImageHandle ImageHandle of this module
+ @param[in] PeiServices An indirect pointer to the PEI Services Table
+ published by the PEI Foundation.
+
+ @retval EFI_SUCCESS Driver initializes successfully
+ @retval Other values Some error occurred
+**/
+EFI_STATUS
+EFIAPI
+InitializeSmbusPeim (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install Smbus Ppi
+ //
+ Status = PeiServicesInstallPpi (&gPpiSmbusHcPpiList);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
--
2.25.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#120264): https://edk2.groups.io/g/devel/message/120264
Mute This Topic: https://groups.io/mt/107765355/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2024-08-07 6:50 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-07 6:47 [edk2-devel] [edk2-platforms][PATCH v2 0/5] Add IPMI SSIF support Nhi Pham via groups.io
2024-08-07 6:47 ` [edk2-devel] [edk2-platforms][PATCH v2 1/5] AmpereAltraPkg/DwI2cLib: Add support for SMBUS+PEC operation Nhi Pham via groups.io
2024-08-07 6:47 ` [edk2-devel] [edk2-platforms][PATCH v2 2/5] AmpereSiliconPkg: Define PCDs for SMBUS and BMC Nhi Pham via groups.io
2024-08-07 6:47 ` Nhi Pham via groups.io [this message]
2024-08-07 6:47 ` [edk2-devel] [edk2-platforms][PATCH v2 4/5] JadePkg: Add PlatformBmcReadyLib to support BMC ready check Nhi Pham via groups.io
2024-08-07 6:47 ` [edk2-devel] [edk2-platforms][PATCH v2 5/5] Ampere/Jade: Enable IPMI SSIF Nhi Pham via groups.io
2024-08-07 7:16 ` [edk2-devel] [edk2-platforms][PATCH v2 0/5] Add IPMI SSIF support Chang, Abner via groups.io
2024-08-07 7:35 ` Nhi Pham via groups.io
2024-08-09 2:44 ` Chang, Abner via groups.io
2024-08-09 3:05 ` Nhi Pham via groups.io
2024-08-09 4:34 ` Chang, Abner via groups.io
2024-08-07 10:23 ` Leif Lindholm
2024-08-07 10:45 ` Chang, Abner via groups.io
2024-08-07 10:56 ` Leif Lindholm
2024-08-07 10:59 ` Chang, Abner via groups.io
2024-08-08 3:06 ` Nhi Pham via groups.io
[not found] ` <17E9A1ED2D454E7A.19172@groups.io>
2024-08-13 4:16 ` Nhi Pham via groups.io
2024-08-29 5:55 ` Chuong Tran
2024-08-29 7:11 ` Nhi Pham via groups.io
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240807064731.4049764-4-nhi@os.amperecomputing.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox