* [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE @ 2022-02-17 17:51 Sean Rhodes 2022-02-17 17:51 ` [PATCH 2/2] UefipayloadPkg: Add SmbusConfigLoaderDxe Sean Rhodes 2022-02-17 18:24 ` [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE Ma, Maurice 0 siblings, 2 replies; 6+ messages in thread From: Sean Rhodes @ 2022-02-17 17:51 UTC (permalink / raw) To: devel; +Cc: guo.dong, Patrick Rudolph, Ray Ni, Maurice Ma, Benjamin You From: Patrick Rudolph <patrick.rudolph@9elements.com> Implement a subset of the gEfiSmbusHcProtocolGuid using a generic PCI i801 SMBus controller. Cc: Guo Dong <guo.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Maurice Ma <maurice.ma@intel.com> Cc: Benjamin You <benjamin.you@intel.com> Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> --- .../Library/BrotliCustomDecompressLib/brotli | 2 +- UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c | 556 ++++++++++++++++++ UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h | 17 + UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf | 45 ++ UefiPayloadPkg/UefiPayloadPkg.dsc | 7 + UefiPayloadPkg/UefiPayloadPkg.fdf | 5 + 6 files changed, 631 insertions(+), 1 deletion(-) create mode 100644 UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c create mode 100644 UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h create mode 100644 UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf diff --git a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli index f4153a09f8..666c3280cc 160000 --- a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli +++ b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli @@ -1 +1 @@ -Subproject commit f4153a09f87cbb9c826d8fc12c74642bb2d879ea +Subproject commit 666c3280cc11dc433c303d79a83d4ffbdd12cc8d diff --git a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c new file mode 100644 index 0000000000..7bf7b893ad --- /dev/null +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c @@ -0,0 +1,556 @@ +/** @file + Implementation for a generic i801 SMBus driver. + +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + +**/ + +#include "SMBusi801Dxe.h" +#include <Library/TimerLib.h> +#include <Library/PciLib.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiBootServicesTableLib.h> + +EFI_HANDLE mDriverHandle = NULL; +UINT32 PciDevice = 0; + +/* SMBus register offsets. */ +#define SMBHSTSTAT 0x0 +#define SMBHSTCTL 0x2 +#define SMBHSTCMD 0x3 +#define SMBXMITADD 0x4 +#define SMBHSTDAT0 0x5 +#define SMBHSTDAT1 0x6 +#define SMBBLKDAT 0x7 +#define SMBTRNSADD 0x9 +#define SMBSLVDATA 0xa +#define SMLINK_PIN_CTL 0xe +#define SMBUS_PIN_CTL 0xf +#define SMBSLVCMD 0x11 + +/* I801 command constants */ +#define I801_QUICK (0 << 2) +#define I801_BYTE (1 << 2) +#define I801_BYTE_DATA (2 << 2) +#define I801_WORD_DATA (3 << 2) +#define I801_PROCESS_CALL (4 << 2) +#define I801_BLOCK_DATA (5 << 2) +#define I801_I2C_BLOCK_DATA (6 << 2) /* ICH5 and later */ + +/* I801 Host Control register bits */ +#define SMBHSTCNT_INTREN (1 << 0) +#define SMBHSTCNT_KILL (1 << 1) +#define SMBHSTCNT_LAST_BYTE (1 << 5) +#define SMBHSTCNT_START (1 << 6) +#define SMBHSTCNT_PEC_EN (1 << 7) /* ICH3 and later */ + +/* I801 Hosts Status register bits */ +#define SMBHSTSTS_BYTE_DONE (1 << 7) +#define SMBHSTSTS_INUSE_STS (1 << 6) +#define SMBHSTSTS_SMBALERT_STS (1 << 5) +#define SMBHSTSTS_FAILED (1 << 4) +#define SMBHSTSTS_BUS_ERR (1 << 3) +#define SMBHSTSTS_DEV_ERR (1 << 2) +#define SMBHSTSTS_INTR (1 << 1) +#define SMBHSTSTS_HOST_BUSY (1 << 0) + +/* For SMBXMITADD register. */ +#define XMIT_WRITE(dev) (((dev) << 1) | 0) +#define XMIT_READ(dev) (((dev) << 1) | 1) + +STATIC +UINT16 +EFIAPI +SmbusGetSMBaseAddress ( + IN VOID + ) +{ + UINT16 Cmd; + UINT32 Reg32; + UINT16 IoBase; + + IoBase = 0; + // + // Test if I/O decoding is enabled + // + Cmd = PciRead16 (PciDevice + 0x4); + if (!(Cmd & 1)) { + goto CloseAndReturn; + } + + // + // Test if BAR0 is I/O bar and enabled + // + Reg32 = PciRead16 (PciDevice + 0x20); + if (!(Reg32 & 1) || !(Reg32 & 0xfffc) || ((Reg32 & 0xfffc) == 0xfffc)) { + goto CloseAndReturn; + } + + IoBase = Reg32 & 0xfffc; + +CloseAndReturn: + return IoBase; +} + +STATIC +EFI_STATUS +SmbusSetupCommand ( + IN UINT16 IoBase, + IN UINT8 Ctrl, + IN UINT8 Xmitadd + ) +{ + UINTN Loops = 10000; + UINT8 host_busy; + + do { + MicroSecondDelay (100); + host_busy = IoRead8 (IoBase + SMBHSTSTAT) & SMBHSTSTS_HOST_BUSY; + } while (--Loops && host_busy); + + if (Loops == 0) { + return EFI_TIMEOUT; + } + + /* Clear any lingering errors, so the transaction will run. */ + IoWrite8 (IoBase + SMBHSTSTAT, IoRead8 (IoBase + SMBHSTSTAT)); + + /* Set up transaction */ + /* Disable interrupts */ + IoWrite8 (IoBase + SMBHSTCTL, Ctrl); + + /* Set the device I'm talking to. */ + IoWrite8 (IoBase + SMBXMITADD, Xmitadd); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +SmbusExecuteCommand ( + IN UINT16 IoBase + ) +{ + UINTN Loops = 10000; + UINT8 Status; + + /* Start the command. */ + IoWrite8 (IoBase + SMBHSTCTL, IoRead8 (IoBase + SMBHSTCTL) | SMBHSTCNT_START); + Status = IoRead8 (IoBase + SMBHSTSTAT); + + /* Poll for it to start. */ + do { + MicroSecondDelay (100); + + /* If we poll too slow, we could miss HOST_BUSY flag + * set and detect INTR or x_ERR flags instead here. + */ + Status = IoRead8 (IoBase + SMBHSTSTAT); + + Status &= ~(SMBHSTSTS_SMBALERT_STS | SMBHSTSTS_INUSE_STS); + } while (--Loops && Status == 0); + + if (Loops == 0) { + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} + +STATIC +BOOLEAN +SmbusHostCompleted ( + IN UINT8 Status + ) +{ + if (Status & SMBHSTSTS_HOST_BUSY) { + return FALSE; + } + + /* These status bits do not imply completion of transaction. */ + Status &= ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS | SMBHSTSTS_SMBALERT_STS); + return Status != 0; +} + +STATIC +EFI_STATUS +SmbusCompleteCommand ( + IN UINT16 IoBase + ) +{ + UINTN Loops = 10000; + UINT8 Status; + + do { + MicroSecondDelay (100); + Status = IoRead8 (IoBase + SMBHSTSTAT); + } while (--Loops && !SmbusHostCompleted (Status)); + + if (Loops == 0) { + return EFI_TIMEOUT; + } + + /* These status bits do not imply errors. */ + Status &= ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS | SMBHSTSTS_SMBALERT_STS); + + if (Status == SMBHSTSTS_INTR) { + return EFI_SUCCESS; + } + + return EFI_NO_RESPONSE; +} + +STATIC +EFI_STATUS +EFIAPI +SmbusProcessCallOperation ( + IN CONST UINT16 IoBase, + IN CONST EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT16 ResultBuffer; + UINT16 AddrBuffer; + + if (!Buffer || !Length) { + return RETURN_INVALID_PARAMETER; + } + + if (*Length != 2) { + return RETURN_INVALID_PARAMETER; + } + + CopyMem (&AddrBuffer, Buffer, sizeof (AddrBuffer)); + + /* Set up for process call */ + Status = SmbusSetupCommand (IoBase, I801_PROCESS_CALL, XMIT_WRITE (SlaveAddress.SmbusDeviceAddress)); + if (EFI_ERROR (Status)) { + return Status; + } + + /* cmd will only be send if I2C_EN is zero */ + IoWrite8 (IoBase + SMBHSTCMD, Command); + + IoWrite8 (IoBase + SMBHSTDAT0, AddrBuffer & 0x00ff); + IoWrite8 (IoBase + SMBHSTDAT1, (AddrBuffer & 0xff00) >> 8); + + /* Start the command */ + Status = SmbusExecuteCommand (IoBase); + if (EFI_ERROR (Status)) { + return Status; + } + + /* Poll for transaction completion */ + Status = SmbusCompleteCommand (IoBase); + if (EFI_ERROR (Status)) { + return Status; + } + + /* Read results of transaction */ + ResultBuffer = IoRead8 (IoBase + SMBHSTDAT0); + ResultBuffer |= (IoRead8 (IoBase + SMBHSTDAT1) << 8); + + CopyMem (Buffer, &ResultBuffer, sizeof (ResultBuffer)); + *Length = sizeof (ResultBuffer); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +EFIAPI +SmbusReadOperation ( + IN CONST UINT16 IoBase, + IN CONST EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT8 ResultBuffer; + + if (!Buffer || !Length) { + return RETURN_INVALID_PARAMETER; + } + + /* Set up for a byte data read. */ + Status = SmbusSetupCommand (IoBase, I801_BYTE_DATA, XMIT_READ (SlaveAddress.SmbusDeviceAddress)); + if (EFI_ERROR (Status)) { + return Status; + } + + IoWrite8 (IoBase + SMBHSTCMD, Command); + + IoWrite8 (IoBase + SMBHSTDAT0, 0); + IoWrite8 (IoBase + SMBHSTDAT1, 0); + + /* Start the command */ + Status = SmbusExecuteCommand (IoBase); + if (EFI_ERROR (Status)) { + return Status; + } + + /* Poll for transaction completion */ + Status = SmbusCompleteCommand (IoBase); + if (EFI_ERROR (Status)) { + return Status; + } + + /* Read results of transaction */ + ResultBuffer = IoRead8 (IoBase + SMBHSTDAT0); + + CopyMem (Buffer, &ResultBuffer, sizeof (ResultBuffer)); + *Length = sizeof (ResultBuffer); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +EFIAPI +SmbusWriteOperation ( + IN CONST UINT16 IoBase, + IN CONST EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN EFI_SMBUS_DEVICE_COMMAND Command, + IN BOOLEAN PecCheck, + IN OUT UINTN *Length, + IN OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + UINT8 InputBuffer; + + if (!Buffer || !Length) { + return RETURN_INVALID_PARAMETER; + } + + if (*Length != 1) { + return RETURN_INVALID_PARAMETER; + } + + CopyMem (&InputBuffer, Buffer, sizeof (InputBuffer)); + + /* Set up for a byte data read. */ + Status = SmbusSetupCommand (IoBase, I801_BYTE_DATA, XMIT_WRITE (SlaveAddress.SmbusDeviceAddress)); + if (EFI_ERROR (Status)) { + return Status; + } + + IoWrite8 (IoBase + SMBHSTCMD, Command); + + IoWrite8 (IoBase + SMBHSTDAT0, InputBuffer); + + /* Start the command */ + Status = SmbusExecuteCommand (IoBase); + if (EFI_ERROR (Status)) { + return Status; + } + + /* Poll for transaction completion */ + Status = SmbusCompleteCommand (IoBase); + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +EFIAPI +SmbusExecuteOperation ( + 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 + ) +{ + UINT16 IoBase; + + IoBase = SmbusGetSMBaseAddress (); + if (!IoBase) { + return EFI_UNSUPPORTED; + } + + if (Operation == EfiSmbusProcessCall) { + return SmbusProcessCallOperation ( + IoBase, + This, + SlaveAddress, + Command, + PecCheck, + Length, + Buffer + ); + } else if (Operation == EfiSmbusReadByte) { + return SmbusReadOperation ( + IoBase, + This, + SlaveAddress, + Command, + PecCheck, + Length, + Buffer + ); + } else if (Operation == EfiSmbusWriteByte) { + return SmbusWriteOperation ( + IoBase, + This, + SlaveAddress, + Command, + PecCheck, + Length, + Buffer + ); + } + + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +SmbusHcProtocolArpDevice ( + IN CONST EFI_SMBUS_HC_PROTOCOL *This, + IN BOOLEAN ArpAll, + IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL + IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +SmbusHcProtocolGetArpMap ( + IN CONST EFI_SMBUS_HC_PROTOCOL *This, + IN OUT UINTN *Length, + IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +SmbusHcProtocolNotify ( + IN CONST EFI_SMBUS_HC_PROTOCOL *This, + IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, + IN UINTN Data, + IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_SMBUS_HC_PROTOCOL mSmbusProtocol = { + SmbusExecuteOperation, + SmbusHcProtocolArpDevice, + SmbusHcProtocolGetArpMap, + SmbusHcProtocolNotify +}; + +/** + The Entry Point for SMBUS driver. + + It installs DriverBinding. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +InstallSmbusProtocol ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINT16 IoBase; + UINT8 Device; + UINT8 Function; + BOOLEAN BreakLoop; + UINT8 BaseClass; + UINT8 SubClass; + + BreakLoop = FALSE; + Status = EFI_SUCCESS; + + // + // Search for SMBus Controller within PCI Devices on root bus + // + for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { + for (Function = 0; Function <= PCI_MAX_FUNC; Function++) { + if (PciRead16 (PCI_LIB_ADDRESS (0, Device, Function, 0x00)) != 0x8086) { + continue; + } + + BaseClass = PciRead8 (PCI_LIB_ADDRESS (0, Device, Function, 0x0B)); + + if (BaseClass == PCI_CLASS_SERIAL) { + SubClass = PciRead8 (PCI_LIB_ADDRESS (0, Device, Function, 0xA)); + + if (SubClass == PCI_CLASS_SERIAL_SMB) { + BreakLoop = TRUE; + PciDevice = PCI_LIB_ADDRESS (0, Device, Function, 0x00); + break; + } + } + } + + if (BreakLoop) { + break; + } + } + + if (!BreakLoop) { + DEBUG ((EFI_D_INFO, "No PCI SMBUS controller found.\n")); + return EFI_UNSUPPORTED; + } + + DEBUG ((EFI_D_INFO, "PCI Device found on 0-%x-%x\n", Device, Function)); + + IoBase = SmbusGetSMBaseAddress (); + if (!IoBase) { + return EFI_UNSUPPORTED; + } + + DEBUG (( + EFI_D_INFO, + "%a: Detected i801 SMBus controller with SMBASE 0x%x\n", + __FUNCTION__, + IoBase + )); + + Status = gBS->InstallProtocolInterface ( + &mDriverHandle, + &gEfiSmbusHcProtocolGuid, + EFI_NATIVE_INTERFACE, + &mSmbusProtocol + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} diff --git a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h new file mode 100644 index 0000000000..e88823da31 --- /dev/null +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h @@ -0,0 +1,17 @@ +/** @file + Header file for a generic i801 SMBUS driver. + +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + +**/ +#ifndef _PCI_PLATFORM_DXE_H_ +#define _PCI_PLATFORM_DXE_H_ +#include <PiDxe.h> + +#include <IndustryStandard/Pci.h> +#include <IndustryStandard/Pci22.h> +#include <Protocol/SmbusHc.h> + +#endif diff --git a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf new file mode 100644 index 0000000000..7d13c446ef --- /dev/null +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf @@ -0,0 +1,45 @@ +## @file +# This driver produces gEfiSmbusHcProtocolGuid protocol to load access SMBUS devices +# +# Copyright (c) 2020, 9elements Agency GmbH +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SMBusi801Dxe + FILE_GUID = 390208DA-8E6F-4957-90D6-421737FEA9BF + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = InstallSmbusProtocol + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.common] + SMBusi801Dxe.h + SMBusi801Dxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + DebugLib + IoLib + UefiLib + TimerLib + PciLib + +[Protocols] + gEfiSmbusHcProtocolGuid ## PRODUCES + +[Depex] + TRUE diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 1ce96a51c1..54543b7623 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -290,6 +290,7 @@ !if $(PERFORMANCE_MEASUREMENT_ENABLE) PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf !endif + SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf [LibraryClasses.common.DXE_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -304,6 +305,7 @@ !if $(PERFORMANCE_MEASUREMENT_ENABLE) PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf !endif + SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -657,6 +659,11 @@ !endif MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf + # + # SMBUS Support + # + UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf + # # Console Support # diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index c7b04978ad..8861d29162 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -178,6 +178,11 @@ INF MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf !endif INF MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf +# +# SMBUS Support +# +INF UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf + # # Console Support # -- 2.32.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] UefipayloadPkg: Add SmbusConfigLoaderDxe 2022-02-17 17:51 [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE Sean Rhodes @ 2022-02-17 17:51 ` Sean Rhodes 2022-02-17 18:24 ` [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE Ma, Maurice 1 sibling, 0 replies; 6+ messages in thread From: Sean Rhodes @ 2022-02-17 17:51 UTC (permalink / raw) To: devel; +Cc: guo.dong, Patrick Rudolph, Ray Ni, Maurice Ma, Benjamin You From: Patrick Rudolph <patrick.rudolph@9elements.com> Reads board specific configuration values from an EEPROM that is written to by the BMC. Cc: Guo Dong <guo.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Maurice Ma <maurice.ma@intel.com> Cc: Benjamin You <benjamin.you@intel.com> Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> --- .../Include/Guid/BoardSettingsGuid.h | 36 +++ .../SmbusConfigLoaderDxe/SMBusConfigLoader.c | 269 ++++++++++++++++++ .../SmbusConfigLoaderDxe/SMBusConfigLoader.h | 23 ++ .../SMBusConfigLoader.inf | 54 ++++ UefiPayloadPkg/UefiPayloadPkg.dec | 1 + UefiPayloadPkg/UefiPayloadPkg.dsc | 1 + UefiPayloadPkg/UefiPayloadPkg.fdf | 11 +- 7 files changed, 390 insertions(+), 5 deletions(-) create mode 100644 UefiPayloadPkg/Include/Guid/BoardSettingsGuid.h create mode 100644 UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.c create mode 100644 UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.h create mode 100644 UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.inf diff --git a/UefiPayloadPkg/Include/Guid/BoardSettingsGuid.h b/UefiPayloadPkg/Include/Guid/BoardSettingsGuid.h new file mode 100644 index 0000000000..415b49dcde --- /dev/null +++ b/UefiPayloadPkg/Include/Guid/BoardSettingsGuid.h @@ -0,0 +1,36 @@ +/** @file + This file defines the hob structure for board settings + + Copyright (c) 2020, 9elements GmbH. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __BOARD_SETTINGS_GUID_H__ +#define __BOARD_SETTINGS_GUID_H__ + +/// +/// Board information GUID +/// +extern EFI_GUID gEfiBoardSettingsVariableGuid; + +#pragma pack(1) + +typedef struct { + UINT32 Signature; + UINT8 SecureBoot; + UINT8 PrimaryVideo; + UINT8 DeepSx; + UINT8 WakeOnUSB; + UINT8 USBPowerinS5; + UINT8 PowerStateAfterG3; + UINT8 BlueRearPort; + UINT8 InternalAudioConnection; + UINT8 PxeBootCapability; +} BOARD_SETTINGS; + +#pragma pack() + +#define BOARD_SETTINGS_NAME L"BoardSettings" + +#endif // __BOARD_SETTINGS_GUID_H__ diff --git a/UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.c b/UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.c new file mode 100644 index 0000000000..c2edbaa74f --- /dev/null +++ b/UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.c @@ -0,0 +1,269 @@ +/** @file + Implementation for a generic i801 SMBus driver. + +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + +**/ + +#include "SMBusConfigLoader.h" +#include <Library/SmbusLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/PciLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Guid/GlobalVariable.h> +#include <Guid/AuthenticatedVariableFormat.h> + +/** + GetPciConfigSpaceAddress + + Return the PCI Config Space Address if found, zero otherwise. + + @retval 0 Can not find any SMBusController + @retval UINT32 PCI Config Space Address +**/ +STATIC UINT32 +EFIAPI +GetPciConfigSpaceAddress ( + ) +{ + UINT8 Device; + UINT8 Function; + UINT8 BaseClass; + UINT8 SubClass; + + // + // Search for SMBus Controller within PCI Devices on root bus + // + for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { + for (Function = 0; Function <= PCI_MAX_FUNC; Function++) { + if (PciRead16 (PCI_LIB_ADDRESS (0, Device, Function, 0x00)) != 0x8086) { + continue; + } + + BaseClass = PciRead8 (PCI_LIB_ADDRESS (0, Device, Function, 0x0B)); + + if (BaseClass == PCI_CLASS_SERIAL) { + SubClass = PciRead8 (PCI_LIB_ADDRESS (0, Device, Function, 0xA)); + + if (SubClass == PCI_CLASS_SERIAL_SMB) { + return PCI_LIB_ADDRESS (0, Device, Function, 0x00); + } + } + } + } + + return 0; +} + +/** + ReadBoardOptionFromEEPROM + + Reads the Board options like Primary Video from the EEPROM + + @param Buffer Pointer to the Buffer Array + +**/ +STATIC +EFI_STATUS +EFIAPI +ReadBoardOptionFromEEPROM ( + IN OUT UINT8 *Buffer, + IN UINT32 Size + ) +{ + EFI_STATUS Status; + UINT16 Index; + UINT16 Value; + + for (Index = BOARD_SETTINGS_OFFSET; Index < BOARD_SETTINGS_OFFSET + Size; Index += 2) { + Value = SmBusProcessCall (SMBUS_LIB_ADDRESS (0x57, 0, 0, 0), ((Index & 0xff) << 8) | ((Index & 0xff00) >> 8), &Status); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to read SMBUS byte at offset 0x%x\n", Index)); + return Status; + } + + DEBUG ((EFI_D_ERROR, "Read %x\n", Value)); + CopyMem (&Buffer[Index-BOARD_SETTINGS_OFFSET], &Value, sizeof (Value)); + } + + return EFI_SUCCESS; +} + +STATIC +UINT32 +EFIAPI +crc32_byte ( + UINT32 prev_crc, + UINT8 data + ) +{ + prev_crc ^= (UINT32)data << 24; + + for (int i = 0; i < 8; i++) { + if ((prev_crc & 0x80000000UL) != 0) { + prev_crc = ((prev_crc << 1) ^ 0x04C11DB7UL); + } else { + prev_crc <<= 1; + } + } + + return prev_crc; +} + +/** + Computes and returns a 32-bit CRC for a data buffer. + CRC32 value bases on ITU-T V.42. + + If Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param[in] Buffer A pointer to the buffer on which the 32-bit CRC is to be computed. + @param[in] Length The number of bytes in the buffer Data. + + @retval Crc32 The 32-bit CRC was computed for the data buffer. + +**/ +STATIC +UINT32 +EFIAPI +CalculateCrc32 ( + IN VOID *Buffer, + IN UINTN Length + ) +{ + int i; + UINT32 crc = 0x0; + + for ( i = 0; i < Length; i++ ) { + crc = crc32_byte (crc, ((UINT8 *)Buffer)[i]); + } + + return crc; +} + +/** + The Entry Point for SMBUS driver. + + It installs DriverBinding. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +InstallSMBusConfigLoader ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + BOARD_SETTINGS BoardSettings; + UINT32 BaseAddress; + UINT32 CRC32Array; + UINT32 HostCBackup; + UINT8 Array[sizeof (BOARD_SETTINGS)]; + + DEBUG ((DEBUG_INFO, "SMBusConfigLoader: InstallSMBusConfigLoader\n")); + + BaseAddress = GetPciConfigSpaceAddress (); + if (BaseAddress == 0) { + return EFI_NOT_FOUND; + } + + ZeroMem (&BoardSettings, sizeof (BOARD_SETTINGS)); + + // Set I2C_EN Bit + HostCBackup = PciRead32 (BaseAddress + HOSTC); + PciWrite32 (BaseAddress + HOSTC, HostCBackup | I2C_EN_HOSTC); + + Status = ReadBoardOptionFromEEPROM (Array, sizeof (Array)); + + CRC32Array = 0; + if (!EFI_ERROR (Status)) { + CopyMem (&BoardSettings, Array, sizeof (BOARD_SETTINGS)); + + DEBUG ((DEBUG_INFO, "SMBusConfigLoader: Board Settings:\n")); + DEBUG (( + DEBUG_INFO, + "SMBusConfigLoader: CRC: %08x - SecureBoot: %02x - PrimaryVideo: %02x\n", + BoardSettings.Signature, + BoardSettings.SecureBoot, + BoardSettings.PrimaryVideo + )); + + CRC32Array = CalculateCrc32 (&Array[sizeof (UINT32)], sizeof (BOARD_SETTINGS) - sizeof (UINT32)); + if (CRC32Array != BoardSettings.Signature) { + DEBUG ((DEBUG_ERROR, "SMBusConfigLoader: Checksum invalid. Should be %04X - is: %04x.\nReseting to defaults.\n", CRC32Array, BoardSettings.Signature)); + } + } + + if (EFI_ERROR (Status) || (CRC32Array != BoardSettings.Signature)) { + BoardSettings.PrimaryVideo = 0; + BoardSettings.SecureBoot = 1; + } + + // Set SecureBootEnable. Only affects SecureBootSetupDxe. + Status = gRT->SetVariable ( + EFI_SECURE_BOOT_ENABLE_NAME, + &gEfiSecureBootEnableDisableGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof BoardSettings.SecureBoot, + &BoardSettings.SecureBoot + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SMBusConfigLoader: Failed to set SecureBootEnable: %x\n", Status)); + } + + // Set SecureBoot. Only affects code outside of SecureBootSetupDxe. + Status = gRT->SetVariable ( + EFI_SECURE_BOOT_MODE_NAME, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof BoardSettings.SecureBoot, + &BoardSettings.SecureBoot + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SMBusConfigLoader: Failed to set SecureBoot: %x\n", Status)); + } + + if (BoardSettings.SecureBoot == 0) { + UINT8 SetupMode; + // Hide the UI if secureboot is disabled + SetupMode = 1; + Status = gRT->SetVariable ( + EFI_SETUP_MODE_NAME, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof SetupMode, + &SetupMode + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SMBusConfigLoader: Failed to set SetupMode: %x\n", Status)); + } + } + + // Restore I2C_EN Bit + PciWrite32 (BaseAddress + HOSTC, HostCBackup); + + // Save data into UEFI Variable for later use + Status = gRT->SetVariable ( + BOARD_SETTINGS_NAME, // Variable Name + &gEfiBoardSettingsVariableGuid, // Variable Guid + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), // Variable Attributes + sizeof (BOARD_SETTINGS), + &BoardSettings + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "SMBusConfigLoader: Failed to save BoardSettings %x\n", Status)); + return Status; + } + + return EFI_SUCCESS; +} diff --git a/UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.h b/UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.h new file mode 100644 index 0000000000..5e589cefff --- /dev/null +++ b/UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.h @@ -0,0 +1,23 @@ +/** @file + Header file for a generic i801 SMBUS driver. + +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + +**/ +#ifndef _PCI_PLATFORM_DXE_H_ +#define _PCI_PLATFORM_DXE_H_ +#include <PiDxe.h> + +#include <IndustryStandard/Pci.h> +#include <IndustryStandard/Pci22.h> +#include <Protocol/SmbusHc.h> +#include <Guid/BoardSettingsGuid.h> + +#define BOARD_SETTINGS_OFFSET 0x1f00 + +#define HOSTC 0x40 +#define I2C_EN_HOSTC (1 << 2) + +#endif diff --git a/UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.inf b/UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.inf new file mode 100644 index 0000000000..a2c2656a4d --- /dev/null +++ b/UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.inf @@ -0,0 +1,54 @@ +## @file +# This driver produces gEfiSmbusHcProtocolGuid protocol to load access SMBUS devices +# +# Copyright (c) 2020, 9elements Agency GmbH +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SMBusConfigLoader + FILE_GUID = FCBA64FC-BC6B-4B8B-A0E2-D1EC78B8C01A + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = InstallSMBusConfigLoader + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.common] + SMBusConfigLoader.h + SMBusConfigLoader.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec + SecurityPkg/SecurityPkg.dec + +[Guids] + gEfiBoardSettingsVariableGuid + gEfiSecureBootEnableDisableGuid + gEfiGlobalVariableGuid + +[LibraryClasses] + UefiDriverEntryPoint + DebugLib + DevicePathLib + SmbusLib + UefiRuntimeServicesTableLib + PciLib + +[Depex] + gEfiSmbusHcProtocolGuid AND + gEfiVariableArchProtocolGuid + +[Protocols] + gEfiSmbusHcProtocolGuid ## CONSUMES + gEfiVariableArchProtocolGuid ## CONSUMES diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayloadPkg.dec index 551f0a4915..e902180349 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dec +++ b/UefiPayloadPkg/UefiPayloadPkg.dec @@ -19,6 +19,7 @@ [Guids] + gEfiBoardSettingsVariableGuid = { 0xae2029d1, 0x11f2, 0x483d, { 0xbf, 0xbc, 0xad, 0x63, 0x5d, 0xe3, 0x32, 0x26 }} # ae2029d1-11f2-483d-bfbc-ad635de33226 # ## Defines the token space for the UEFI Payload Package PCDs. # diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 54543b7623..9321fa958c 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -663,6 +663,7 @@ # SMBUS Support # UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf + UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.inf # # Console Support diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 8861d29162..b241613507 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -158,6 +158,12 @@ INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf INF UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf +# +# SMBUS Support +# +INF UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf +INF UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.inf + # # PCI Support # @@ -178,11 +184,6 @@ INF MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf !endif INF MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf -# -# SMBUS Support -# -INF UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf - # # Console Support # -- 2.32.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE 2022-02-17 17:51 [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE Sean Rhodes 2022-02-17 17:51 ` [PATCH 2/2] UefipayloadPkg: Add SmbusConfigLoaderDxe Sean Rhodes @ 2022-02-17 18:24 ` Ma, Maurice 2022-02-24 10:46 ` Patrick Rudolph 1 sibling, 1 reply; 6+ messages in thread From: Ma, Maurice @ 2022-02-17 18:24 UTC (permalink / raw) To: devel@edk2.groups.io, Rhodes, Sean Cc: Dong, Guo, Patrick Rudolph, Ni, Ray, You, Benjamin This vendor specific device driver implementation does not seem to fit into UEFI payload package scope well. Do you think https://github.com/tianocore/edk2-platforms/tree/master/Silicon could be a better location ? Thanks Maurice > -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sean > Rhodes > Sent: Thursday, February 17, 2022 9:51 > To: devel@edk2.groups.io > Cc: Dong, Guo <guo.dong@intel.com>; Patrick Rudolph > <patrick.rudolph@9elements.com>; Ni, Ray <ray.ni@intel.com>; Ma, > Maurice <maurice.ma@intel.com>; You, Benjamin > <benjamin.you@intel.com> > Subject: [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus > controller DXE > > From: Patrick Rudolph <patrick.rudolph@9elements.com> > > Implement a subset of the gEfiSmbusHcProtocolGuid using a generic PCI i801 > SMBus controller. > > Cc: Guo Dong <guo.dong@intel.com> > Cc: Ray Ni <ray.ni@intel.com> > Cc: Maurice Ma <maurice.ma@intel.com> > Cc: Benjamin You <benjamin.you@intel.com> > Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> > --- > .../Library/BrotliCustomDecompressLib/brotli | 2 +- > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c | 556 > ++++++++++++++++++ > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h | 17 + > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf | 45 ++ > UefiPayloadPkg/UefiPayloadPkg.dsc | 7 + > UefiPayloadPkg/UefiPayloadPkg.fdf | 5 + > 6 files changed, 631 insertions(+), 1 deletion(-) create mode 100644 > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > create mode 100644 UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > create mode 100644 UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > > diff --git a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > index f4153a09f8..666c3280cc 160000 > --- a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > +++ b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > @@ -1 +1 @@ > -Subproject commit f4153a09f87cbb9c826d8fc12c74642bb2d879ea > +Subproject commit 666c3280cc11dc433c303d79a83d4ffbdd12cc8d > diff --git a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > new file mode 100644 > index 0000000000..7bf7b893ad > --- /dev/null > +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > @@ -0,0 +1,556 @@ > +/** @file+ Implementation for a generic i801 SMBus driver.++Copyright (c) > 2016, Intel Corporation. All rights reserved.<BR>+SPDX-License-Identifier: > BSD-2-Clause-Patent+++**/++#include "SMBusi801Dxe.h"+#include > <Library/TimerLib.h>+#include <Library/PciLib.h>+#include > <Library/IoLib.h>+#include <Library/DebugLib.h>+#include > <Library/BaseMemoryLib.h>+#include > <Library/UefiBootServicesTableLib.h>++EFI_HANDLE mDriverHandle = > NULL;+UINT32 PciDevice = 0;++/* SMBus register offsets. */+#define > SMBHSTSTAT 0x0+#define SMBHSTCTL 0x2+#define SMBHSTCMD > 0x3+#define SMBXMITADD 0x4+#define SMBHSTDAT0 0x5+#define > SMBHSTDAT1 0x6+#define SMBBLKDAT 0x7+#define SMBTRNSADD > 0x9+#define SMBSLVDATA 0xa+#define SMLINK_PIN_CTL 0xe+#define > SMBUS_PIN_CTL 0xf+#define SMBSLVCMD 0x11++/* I801 command > constants */+#define I801_QUICK (0 << 2)+#define I801_BYTE (1 > << 2)+#define I801_BYTE_DATA (2 << 2)+#define I801_WORD_DATA (3 > << 2)+#define I801_PROCESS_CALL (4 << 2)+#define I801_BLOCK_DATA > (5 << 2)+#define I801_I2C_BLOCK_DATA (6 << 2) /* ICH5 and later */++/* > I801 Host Control register bits */+#define SMBHSTCNT_INTREN (1 << > 0)+#define SMBHSTCNT_KILL (1 << 1)+#define SMBHSTCNT_LAST_BYTE > (1 << 5)+#define SMBHSTCNT_START (1 << 6)+#define > SMBHSTCNT_PEC_EN (1 << 7) /* ICH3 and later */++/* I801 Hosts Status > register bits */+#define SMBHSTSTS_BYTE_DONE (1 << 7)+#define > SMBHSTSTS_INUSE_STS (1 << 6)+#define SMBHSTSTS_SMBALERT_STS (1 > << 5)+#define SMBHSTSTS_FAILED (1 << 4)+#define > SMBHSTSTS_BUS_ERR (1 << 3)+#define SMBHSTSTS_DEV_ERR (1 << > 2)+#define SMBHSTSTS_INTR (1 << 1)+#define SMBHSTSTS_HOST_BUSY > (1 << 0)++/* For SMBXMITADD register. */+#define XMIT_WRITE(dev) > (((dev) << 1) | 0)+#define XMIT_READ(dev) (((dev) << 1) | > 1)++STATIC+UINT16+EFIAPI+SmbusGetSMBaseAddress (+ IN VOID+ )+{+ > UINT16 Cmd;+ UINT32 Reg32;+ UINT16 IoBase;++ IoBase = 0;+ //+ // Test > if I/O decoding is enabled+ //+ Cmd = PciRead16 (PciDevice + 0x4);+ if > (!(Cmd & 1)) {+ goto CloseAndReturn;+ }++ //+ // Test if BAR0 is I/O bar > and enabled+ //+ Reg32 = PciRead16 (PciDevice + 0x20);+ if (!(Reg32 & 1) > || !(Reg32 & 0xfffc) || ((Reg32 & 0xfffc) == 0xfffc)) {+ goto > CloseAndReturn;+ }++ IoBase = Reg32 & 0xfffc;++CloseAndReturn:+ return > IoBase;+}++STATIC+EFI_STATUS+SmbusSetupCommand (+ IN UINT16 > IoBase,+ IN UINT8 Ctrl,+ IN UINT8 Xmitadd+ )+{+ UINTN Loops = 10000;+ > UINT8 host_busy;++ do {+ MicroSecondDelay (100);+ host_busy = > IoRead8 (IoBase + SMBHSTSTAT) & SMBHSTSTS_HOST_BUSY;+ } while (-- > Loops && host_busy);++ if (Loops == 0) {+ return EFI_TIMEOUT;+ }++ /* > Clear any lingering errors, so the transaction will run. */+ IoWrite8 (IoBase + > SMBHSTSTAT, IoRead8 (IoBase + SMBHSTSTAT));++ /* Set up transaction */+ > /* Disable interrupts */+ IoWrite8 (IoBase + SMBHSTCTL, Ctrl);++ /* Set the > device I'm talking to. */+ IoWrite8 (IoBase + SMBXMITADD, Xmitadd);++ > return EFI_SUCCESS;+}++STATIC+EFI_STATUS+SmbusExecuteCommand (+ > IN UINT16 IoBase+ )+{+ UINTN Loops = 10000;+ UINT8 Status;++ /* Start > the command. */+ IoWrite8 (IoBase + SMBHSTCTL, IoRead8 (IoBase + > SMBHSTCTL) | SMBHSTCNT_START);+ Status = IoRead8 (IoBase + > SMBHSTSTAT);++ /* Poll for it to start. */+ do {+ MicroSecondDelay > (100);++ /* If we poll too slow, we could miss HOST_BUSY flag+ * set and > detect INTR or x_ERR flags instead here.+ */+ Status = IoRead8 (IoBase + > SMBHSTSTAT);++ Status &= ~(SMBHSTSTS_SMBALERT_STS | > SMBHSTSTS_INUSE_STS);+ } while (--Loops && Status == 0);++ if (Loops == 0) > {+ return EFI_TIMEOUT;+ }++ return > EFI_SUCCESS;+}++STATIC+BOOLEAN+SmbusHostCompleted (+ IN UINT8 > Status+ )+{+ if (Status & SMBHSTSTS_HOST_BUSY) {+ return FALSE;+ }++ > /* These status bits do not imply completion of transaction. */+ Status &= > ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS | > SMBHSTSTS_SMBALERT_STS);+ return Status != > 0;+}++STATIC+EFI_STATUS+SmbusCompleteCommand (+ IN UINT16 > IoBase+ )+{+ UINTN Loops = 10000;+ UINT8 Status;++ do {+ > MicroSecondDelay (100);+ Status = IoRead8 (IoBase + SMBHSTSTAT);+ } > while (--Loops && !SmbusHostCompleted (Status));++ if (Loops == 0) {+ > return EFI_TIMEOUT;+ }++ /* These status bits do not imply errors. */+ > Status &= ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS | > SMBHSTSTS_SMBALERT_STS);++ if (Status == SMBHSTSTS_INTR) {+ return > EFI_SUCCESS;+ }++ return > EFI_NO_RESPONSE;+}++STATIC+EFI_STATUS+EFIAPI+SmbusProcessCallOper > ation (+ IN CONST UINT16 IoBase,+ IN CONST > EFI_SMBUS_HC_PROTOCOL *This,+ IN EFI_SMBUS_DEVICE_ADDRESS > SlaveAddress,+ IN EFI_SMBUS_DEVICE_COMMAND Command,+ IN > BOOLEAN PecCheck,+ IN OUT UINTN *Length,+ IN OUT > VOID *Buffer+ )+{+ EFI_STATUS Status;+ UINT16 > ResultBuffer;+ UINT16 AddrBuffer;++ if (!Buffer || !Length) {+ return > RETURN_INVALID_PARAMETER;+ }++ if (*Length != 2) {+ return > RETURN_INVALID_PARAMETER;+ }++ CopyMem (&AddrBuffer, Buffer, > sizeof (AddrBuffer));++ /* Set up for process call */+ Status = > SmbusSetupCommand (IoBase, I801_PROCESS_CALL, XMIT_WRITE > (SlaveAddress.SmbusDeviceAddress));+ if (EFI_ERROR (Status)) {+ return > Status;+ }++ /* cmd will only be send if I2C_EN is zero */+ IoWrite8 (IoBase > + SMBHSTCMD, Command);++ IoWrite8 (IoBase + SMBHSTDAT0, AddrBuffer > & 0x00ff);+ IoWrite8 (IoBase + SMBHSTDAT1, (AddrBuffer & 0xff00) >> 8);++ > /* Start the command */+ Status = SmbusExecuteCommand (IoBase);+ if > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Poll for transaction > completion */+ Status = SmbusCompleteCommand (IoBase);+ if > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Read results of transaction > */+ ResultBuffer = IoRead8 (IoBase + SMBHSTDAT0);+ ResultBuffer |= > (IoRead8 (IoBase + SMBHSTDAT1) << 8);++ CopyMem (Buffer, > &ResultBuffer, sizeof (ResultBuffer));+ *Length = sizeof (ResultBuffer);++ > return EFI_SUCCESS;+}++STATIC+EFI_STATUS+EFIAPI+SmbusReadOperation > (+ IN CONST UINT16 IoBase,+ IN CONST > EFI_SMBUS_HC_PROTOCOL *This,+ IN EFI_SMBUS_DEVICE_ADDRESS > SlaveAddress,+ IN EFI_SMBUS_DEVICE_COMMAND Command,+ IN > BOOLEAN PecCheck,+ IN OUT UINTN *Length,+ IN OUT > VOID *Buffer+ )+{+ EFI_STATUS Status;+ UINT8 > ResultBuffer;++ if (!Buffer || !Length) {+ return > RETURN_INVALID_PARAMETER;+ }++ /* Set up for a byte data read. */+ > Status = SmbusSetupCommand (IoBase, I801_BYTE_DATA, XMIT_READ > (SlaveAddress.SmbusDeviceAddress));+ if (EFI_ERROR (Status)) {+ return > Status;+ }++ IoWrite8 (IoBase + SMBHSTCMD, Command);++ IoWrite8 > (IoBase + SMBHSTDAT0, 0);+ IoWrite8 (IoBase + SMBHSTDAT1, 0);++ /* Start > the command */+ Status = SmbusExecuteCommand (IoBase);+ if > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Poll for transaction > completion */+ Status = SmbusCompleteCommand (IoBase);+ if > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Read results of transaction > */+ ResultBuffer = IoRead8 (IoBase + SMBHSTDAT0);++ CopyMem (Buffer, > &ResultBuffer, sizeof (ResultBuffer));+ *Length = sizeof (ResultBuffer);++ > return EFI_SUCCESS;+}++STATIC+EFI_STATUS+EFIAPI+SmbusWriteOperation > (+ IN CONST UINT16 IoBase,+ IN CONST > EFI_SMBUS_HC_PROTOCOL *This,+ IN EFI_SMBUS_DEVICE_ADDRESS > SlaveAddress,+ IN EFI_SMBUS_DEVICE_COMMAND Command,+ IN > BOOLEAN PecCheck,+ IN OUT UINTN *Length,+ IN OUT > VOID *Buffer+ )+{+ EFI_STATUS Status;+ UINT8 > InputBuffer;++ if (!Buffer || !Length) {+ return > RETURN_INVALID_PARAMETER;+ }++ if (*Length != 1) {+ return > RETURN_INVALID_PARAMETER;+ }++ CopyMem (&InputBuffer, Buffer, > sizeof (InputBuffer));++ /* Set up for a byte data read. */+ Status = > SmbusSetupCommand (IoBase, I801_BYTE_DATA, XMIT_WRITE > (SlaveAddress.SmbusDeviceAddress));+ if (EFI_ERROR (Status)) {+ return > Status;+ }++ IoWrite8 (IoBase + SMBHSTCMD, Command);++ IoWrite8 > (IoBase + SMBHSTDAT0, InputBuffer);++ /* Start the command */+ Status = > SmbusExecuteCommand (IoBase);+ if (EFI_ERROR (Status)) {+ return > Status;+ }++ /* Poll for transaction completion */+ Status = > SmbusCompleteCommand (IoBase);+ if (EFI_ERROR (Status)) {+ return > Status;+ }++ return > EFI_SUCCESS;+}++STATIC+EFI_STATUS+EFIAPI+SmbusExecuteOperation (+ > 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+ )+{+ UINT16 IoBase;++ IoBase = SmbusGetSMBaseAddress ();+ if > (!IoBase) {+ return EFI_UNSUPPORTED;+ }++ if (Operation == > EfiSmbusProcessCall) {+ return SmbusProcessCallOperation (+ > IoBase,+ This,+ SlaveAddress,+ Command,+ > PecCheck,+ Length,+ Buffer+ );+ } else if (Operation == > EfiSmbusReadByte) {+ return SmbusReadOperation (+ IoBase,+ > This,+ SlaveAddress,+ Command,+ PecCheck,+ > Length,+ Buffer+ );+ } else if (Operation == EfiSmbusWriteByte) > {+ return SmbusWriteOperation (+ IoBase,+ This,+ > SlaveAddress,+ Command,+ PecCheck,+ Length,+ > Buffer+ );+ }++ return > EFI_UNSUPPORTED;+}++STATIC+EFI_STATUS+EFIAPI+SmbusHcProtocolArpD > evice (+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,+ IN BOOLEAN > ArpAll,+ IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL+ IN OUT > EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL+ )+{+ return > EFI_UNSUPPORTED;+}++STATIC+EFI_STATUS+EFIAPI+SmbusHcProtocolGetA > rpMap (+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,+ IN OUT UINTN > *Length,+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap+ )+{+ > return > EFI_UNSUPPORTED;+}++STATIC+EFI_STATUS+EFIAPI+SmbusHcProtocolNotif > y (+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,+ IN > EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,+ IN UINTN > Data,+ IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction+ )+{+ return > EFI_UNSUPPORTED;+}++EFI_SMBUS_HC_PROTOCOL mSmbusProtocol = {+ > SmbusExecuteOperation,+ SmbusHcProtocolArpDevice,+ > SmbusHcProtocolGetArpMap,+ SmbusHcProtocolNotify+};++/**+ The Entry > Point for SMBUS driver.++ It installs DriverBinding.++ @retval EFI_SUCCESS > The entry point is executed successfully.+ @retval other Some error > occurs when executing this entry > point.++**/+EFI_STATUS+EFIAPI+InstallSmbusProtocol (+ IN EFI_HANDLE > ImageHandle,+ IN EFI_SYSTEM_TABLE *SystemTable+ )+{+ EFI_STATUS > Status;+ UINT16 IoBase;+ UINT8 Device;+ UINT8 Function;+ > BOOLEAN BreakLoop;+ UINT8 BaseClass;+ UINT8 SubClass;++ > BreakLoop = FALSE;+ Status = EFI_SUCCESS;++ //+ // Search for SMBus > Controller within PCI Devices on root bus+ //+ for (Device = 0; Device <= > PCI_MAX_DEVICE; Device++) {+ for (Function = 0; Function <= > PCI_MAX_FUNC; Function++) {+ if (PciRead16 (PCI_LIB_ADDRESS (0, > Device, Function, 0x00)) != 0x8086) {+ continue;+ }++ BaseClass = > PciRead8 (PCI_LIB_ADDRESS (0, Device, Function, 0x0B));++ if (BaseClass > == PCI_CLASS_SERIAL) {+ SubClass = PciRead8 (PCI_LIB_ADDRESS (0, > Device, Function, 0xA));++ if (SubClass == PCI_CLASS_SERIAL_SMB) {+ > BreakLoop = TRUE;+ PciDevice = PCI_LIB_ADDRESS (0, Device, Function, > 0x00);+ break;+ }+ }+ }++ if (BreakLoop) {+ break;+ }+ }++ if > (!BreakLoop) {+ DEBUG ((EFI_D_INFO, "No PCI SMBUS controller > found.\n"));+ return EFI_UNSUPPORTED;+ }++ DEBUG ((EFI_D_INFO, "PCI > Device found on 0-%x-%x\n", Device, Function));++ IoBase = > SmbusGetSMBaseAddress ();+ if (!IoBase) {+ return > EFI_UNSUPPORTED;+ }++ DEBUG ((+ EFI_D_INFO,+ "%a: Detected i801 > SMBus controller with SMBASE 0x%x\n",+ __FUNCTION__,+ > IoBase+ ));++ Status = gBS->InstallProtocolInterface (+ > &mDriverHandle,+ &gEfiSmbusHcProtocolGuid,+ > EFI_NATIVE_INTERFACE,+ &mSmbusProtocol+ );++ if > (EFI_ERROR (Status)) {+ return Status;+ }++ return EFI_SUCCESS;+}diff --git > a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > new file mode 100644 > index 0000000000..e88823da31 > --- /dev/null > +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > @@ -0,0 +1,17 @@ > +/** @file+ Header file for a generic i801 SMBUS driver.++Copyright (c) > +2016, Intel Corporation. All rights > +reserved.<BR>+SPDX-License-Identifier: > +BSD-2-Clause-Patent+++**/+#ifndef _PCI_PLATFORM_DXE_H_+#define > +_PCI_PLATFORM_DXE_H_+#include <PiDxe.h>++#include > +<IndustryStandard/Pci.h>+#include <IndustryStandard/Pci22.h>+#include > +<Protocol/SmbusHc.h>++#endifdiff --git > +a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > +b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > new file mode 100644 > index 0000000000..7d13c446ef > --- /dev/null > +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > @@ -0,0 +1,45 @@ > +## @file+# This driver produces gEfiSmbusHcProtocolGuid protocol to load > access SMBUS devices+#+# Copyright (c) 2020, 9elements Agency > GmbH+#+# SPDX-License-Identifier: BSD-2-Clause- > Patent+#+#+##++[Defines]+ INF_VERSION = 0x00010005+ > BASE_NAME = SMBusi801Dxe+ FILE_GUID = 390208DA- > 8E6F-4957-90D6-421737FEA9BF+ MODULE_TYPE = DXE_DRIVER+ > VERSION_STRING = 1.0+ ENTRY_POINT = > InstallSmbusProtocol++#+# The following information is for reference only > and not required by the build tools.+#+# VALID_ARCHITECTURES = IA32 > X64+#++[Sources.common]+ SMBusi801Dxe.h+ > SMBusi801Dxe.c++[Packages]+ MdePkg/MdePkg.dec+ > MdeModulePkg/MdeModulePkg.dec++[LibraryClasses]+ > UefiDriverEntryPoint+ DebugLib+ IoLib+ UefiLib+ TimerLib+ > PciLib++[Protocols]+ gEfiSmbusHcProtocolGuid ## > PRODUCES++[Depex]+ TRUEdiff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc > b/UefiPayloadPkg/UefiPayloadPkg.dsc > index 1ce96a51c1..54543b7623 100644 > --- a/UefiPayloadPkg/UefiPayloadPkg.dsc > +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc > @@ -290,6 +290,7 @@ > !if $(PERFORMANCE_MEASUREMENT_ENABLE) > PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCore > PerformanceLib.inf !endif+ > SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf > [LibraryClasses.common.DXE_DRIVER] > PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf@@ -304,6 +305,7 @@ > !if $(PERFORMANCE_MEASUREMENT_ENABLE) > PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerforma > nceLib.inf !endif+ > SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf > [LibraryClasses.common.DXE_RUNTIME_DRIVER] > PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf@@ -657,6 +659,11 @@ > !endif MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf + #+ # > SMBUS Support+ #+ UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf+ # # > Console Support #diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf > b/UefiPayloadPkg/UefiPayloadPkg.fdf > index c7b04978ad..8861d29162 100644 > --- a/UefiPayloadPkg/UefiPayloadPkg.fdf > +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf > @@ -178,6 +178,11 @@ INF > MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf > !endif INF MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf +#+# > SMBUS Support+#+INF UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf+ # # > Console Support #-- > 2.32.0 > > > > -=-=-=-=-=-= > Groups.io Links: You receive all messages sent to this group. > View/Reply Online (#86730): https://edk2.groups.io/g/devel/message/86730 > Mute This Topic: https://groups.io/mt/89214991/1773972 > Group Owner: devel+owner@edk2.groups.io > Unsubscribe: https://edk2.groups.io/g/devel/unsub [maurice.ma@intel.com] > -=-=-=-=-=-= > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE 2022-02-17 18:24 ` [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE Ma, Maurice @ 2022-02-24 10:46 ` Patrick Rudolph 2022-02-24 15:53 ` Guo Dong 0 siblings, 1 reply; 6+ messages in thread From: Patrick Rudolph @ 2022-02-24 10:46 UTC (permalink / raw) To: devel, maurice.ma; +Cc: Rhodes, Sean, Dong, Guo, Ni, Ray, You, Benjamin Hi Maurice, I agree that edk2-platforms is the right place. How should it be used to build UefiPlayloadPkg? Should it be hooked up as git submodule? Just wondering why you added vendor (or platform) specific code in UefiPayloadPkg/Library/SpiFlashLib/SpiFlashLib.inf ? Please clarify. Regards, Patrick Rudolph On Thu, Feb 17, 2022 at 7:24 PM Ma, Maurice <maurice.ma@intel.com> wrote: > > This vendor specific device driver implementation does not seem to fit into UEFI payload package scope well. > > Do you think https://github.com/tianocore/edk2-platforms/tree/master/Silicon could be a better location ? > > Thanks > Maurice > > -----Original Message----- > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sean > > Rhodes > > Sent: Thursday, February 17, 2022 9:51 > > To: devel@edk2.groups.io > > Cc: Dong, Guo <guo.dong@intel.com>; Patrick Rudolph > > <patrick.rudolph@9elements.com>; Ni, Ray <ray.ni@intel.com>; Ma, > > Maurice <maurice.ma@intel.com>; You, Benjamin > > <benjamin.you@intel.com> > > Subject: [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus > > controller DXE > > > > From: Patrick Rudolph <patrick.rudolph@9elements.com> > > > > Implement a subset of the gEfiSmbusHcProtocolGuid using a generic PCI i801 > > SMBus controller. > > > > Cc: Guo Dong <guo.dong@intel.com> > > Cc: Ray Ni <ray.ni@intel.com> > > Cc: Maurice Ma <maurice.ma@intel.com> > > Cc: Benjamin You <benjamin.you@intel.com> > > Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> > > --- > > .../Library/BrotliCustomDecompressLib/brotli | 2 +- > > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c | 556 > > ++++++++++++++++++ > > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h | 17 + > > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf | 45 ++ > > UefiPayloadPkg/UefiPayloadPkg.dsc | 7 + > > UefiPayloadPkg/UefiPayloadPkg.fdf | 5 + > > 6 files changed, 631 insertions(+), 1 deletion(-) create mode 100644 > > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > > create mode 100644 UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > > create mode 100644 UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > > > > diff --git a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > > b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > > index f4153a09f8..666c3280cc 160000 > > --- a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > > +++ b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > > @@ -1 +1 @@ > > -Subproject commit f4153a09f87cbb9c826d8fc12c74642bb2d879ea > > +Subproject commit 666c3280cc11dc433c303d79a83d4ffbdd12cc8d > > diff --git a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > > b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > > new file mode 100644 > > index 0000000000..7bf7b893ad > > --- /dev/null > > +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > > @@ -0,0 +1,556 @@ > > +/** @file+ Implementation for a generic i801 SMBus driver.++Copyright (c) > > 2016, Intel Corporation. All rights reserved.<BR>+SPDX-License-Identifier: > > BSD-2-Clause-Patent+++**/++#include "SMBusi801Dxe.h"+#include > > <Library/TimerLib.h>+#include <Library/PciLib.h>+#include > > <Library/IoLib.h>+#include <Library/DebugLib.h>+#include > > <Library/BaseMemoryLib.h>+#include > > <Library/UefiBootServicesTableLib.h>++EFI_HANDLE mDriverHandle = > > NULL;+UINT32 PciDevice = 0;++/* SMBus register offsets. */+#define > > SMBHSTSTAT 0x0+#define SMBHSTCTL 0x2+#define SMBHSTCMD > > 0x3+#define SMBXMITADD 0x4+#define SMBHSTDAT0 0x5+#define > > SMBHSTDAT1 0x6+#define SMBBLKDAT 0x7+#define SMBTRNSADD > > 0x9+#define SMBSLVDATA 0xa+#define SMLINK_PIN_CTL 0xe+#define > > SMBUS_PIN_CTL 0xf+#define SMBSLVCMD 0x11++/* I801 command > > constants */+#define I801_QUICK (0 << 2)+#define I801_BYTE (1 > > << 2)+#define I801_BYTE_DATA (2 << 2)+#define I801_WORD_DATA (3 > > << 2)+#define I801_PROCESS_CALL (4 << 2)+#define I801_BLOCK_DATA > > (5 << 2)+#define I801_I2C_BLOCK_DATA (6 << 2) /* ICH5 and later */++/* > > I801 Host Control register bits */+#define SMBHSTCNT_INTREN (1 << > > 0)+#define SMBHSTCNT_KILL (1 << 1)+#define SMBHSTCNT_LAST_BYTE > > (1 << 5)+#define SMBHSTCNT_START (1 << 6)+#define > > SMBHSTCNT_PEC_EN (1 << 7) /* ICH3 and later */++/* I801 Hosts Status > > register bits */+#define SMBHSTSTS_BYTE_DONE (1 << 7)+#define > > SMBHSTSTS_INUSE_STS (1 << 6)+#define SMBHSTSTS_SMBALERT_STS (1 > > << 5)+#define SMBHSTSTS_FAILED (1 << 4)+#define > > SMBHSTSTS_BUS_ERR (1 << 3)+#define SMBHSTSTS_DEV_ERR (1 << > > 2)+#define SMBHSTSTS_INTR (1 << 1)+#define SMBHSTSTS_HOST_BUSY > > (1 << 0)++/* For SMBXMITADD register. */+#define XMIT_WRITE(dev) > > (((dev) << 1) | 0)+#define XMIT_READ(dev) (((dev) << 1) | > > 1)++STATIC+UINT16+EFIAPI+SmbusGetSMBaseAddress (+ IN VOID+ )+{+ > > UINT16 Cmd;+ UINT32 Reg32;+ UINT16 IoBase;++ IoBase = 0;+ //+ // Test > > if I/O decoding is enabled+ //+ Cmd = PciRead16 (PciDevice + 0x4);+ if > > (!(Cmd & 1)) {+ goto CloseAndReturn;+ }++ //+ // Test if BAR0 is I/O bar > > and enabled+ //+ Reg32 = PciRead16 (PciDevice + 0x20);+ if (!(Reg32 & 1) > > || !(Reg32 & 0xfffc) || ((Reg32 & 0xfffc) == 0xfffc)) {+ goto > > CloseAndReturn;+ }++ IoBase = Reg32 & 0xfffc;++CloseAndReturn:+ return > > IoBase;+}++STATIC+EFI_STATUS+SmbusSetupCommand (+ IN UINT16 > > IoBase,+ IN UINT8 Ctrl,+ IN UINT8 Xmitadd+ )+{+ UINTN Loops = 10000;+ > > UINT8 host_busy;++ do {+ MicroSecondDelay (100);+ host_busy = > > IoRead8 (IoBase + SMBHSTSTAT) & SMBHSTSTS_HOST_BUSY;+ } while (-- > > Loops && host_busy);++ if (Loops == 0) {+ return EFI_TIMEOUT;+ }++ /* > > Clear any lingering errors, so the transaction will run. */+ IoWrite8 (IoBase + > > SMBHSTSTAT, IoRead8 (IoBase + SMBHSTSTAT));++ /* Set up transaction */+ > > /* Disable interrupts */+ IoWrite8 (IoBase + SMBHSTCTL, Ctrl);++ /* Set the > > device I'm talking to. */+ IoWrite8 (IoBase + SMBXMITADD, Xmitadd);++ > > return EFI_SUCCESS;+}++STATIC+EFI_STATUS+SmbusExecuteCommand (+ > > IN UINT16 IoBase+ )+{+ UINTN Loops = 10000;+ UINT8 Status;++ /* Start > > the command. */+ IoWrite8 (IoBase + SMBHSTCTL, IoRead8 (IoBase + > > SMBHSTCTL) | SMBHSTCNT_START);+ Status = IoRead8 (IoBase + > > SMBHSTSTAT);++ /* Poll for it to start. */+ do {+ MicroSecondDelay > > (100);++ /* If we poll too slow, we could miss HOST_BUSY flag+ * set and > > detect INTR or x_ERR flags instead here.+ */+ Status = IoRead8 (IoBase + > > SMBHSTSTAT);++ Status &= ~(SMBHSTSTS_SMBALERT_STS | > > SMBHSTSTS_INUSE_STS);+ } while (--Loops && Status == 0);++ if (Loops == 0) > > {+ return EFI_TIMEOUT;+ }++ return > > EFI_SUCCESS;+}++STATIC+BOOLEAN+SmbusHostCompleted (+ IN UINT8 > > Status+ )+{+ if (Status & SMBHSTSTS_HOST_BUSY) {+ return FALSE;+ }++ > > /* These status bits do not imply completion of transaction. */+ Status &= > > ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS | > > SMBHSTSTS_SMBALERT_STS);+ return Status != > > 0;+}++STATIC+EFI_STATUS+SmbusCompleteCommand (+ IN UINT16 > > IoBase+ )+{+ UINTN Loops = 10000;+ UINT8 Status;++ do {+ > > MicroSecondDelay (100);+ Status = IoRead8 (IoBase + SMBHSTSTAT);+ } > > while (--Loops && !SmbusHostCompleted (Status));++ if (Loops == 0) {+ > > return EFI_TIMEOUT;+ }++ /* These status bits do not imply errors. */+ > > Status &= ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS | > > SMBHSTSTS_SMBALERT_STS);++ if (Status == SMBHSTSTS_INTR) {+ return > > EFI_SUCCESS;+ }++ return > > EFI_NO_RESPONSE;+}++STATIC+EFI_STATUS+EFIAPI+SmbusProcessCallOper > > ation (+ IN CONST UINT16 IoBase,+ IN CONST > > EFI_SMBUS_HC_PROTOCOL *This,+ IN EFI_SMBUS_DEVICE_ADDRESS > > SlaveAddress,+ IN EFI_SMBUS_DEVICE_COMMAND Command,+ IN > > BOOLEAN PecCheck,+ IN OUT UINTN *Length,+ IN OUT > > VOID *Buffer+ )+{+ EFI_STATUS Status;+ UINT16 > > ResultBuffer;+ UINT16 AddrBuffer;++ if (!Buffer || !Length) {+ return > > RETURN_INVALID_PARAMETER;+ }++ if (*Length != 2) {+ return > > RETURN_INVALID_PARAMETER;+ }++ CopyMem (&AddrBuffer, Buffer, > > sizeof (AddrBuffer));++ /* Set up for process call */+ Status = > > SmbusSetupCommand (IoBase, I801_PROCESS_CALL, XMIT_WRITE > > (SlaveAddress.SmbusDeviceAddress));+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ /* cmd will only be send if I2C_EN is zero */+ IoWrite8 (IoBase > > + SMBHSTCMD, Command);++ IoWrite8 (IoBase + SMBHSTDAT0, AddrBuffer > > & 0x00ff);+ IoWrite8 (IoBase + SMBHSTDAT1, (AddrBuffer & 0xff00) >> 8);++ > > /* Start the command */+ Status = SmbusExecuteCommand (IoBase);+ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Poll for transaction > > completion */+ Status = SmbusCompleteCommand (IoBase);+ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Read results of transaction > > */+ ResultBuffer = IoRead8 (IoBase + SMBHSTDAT0);+ ResultBuffer |= > > (IoRead8 (IoBase + SMBHSTDAT1) << 8);++ CopyMem (Buffer, > > &ResultBuffer, sizeof (ResultBuffer));+ *Length = sizeof (ResultBuffer);++ > > return EFI_SUCCESS;+}++STATIC+EFI_STATUS+EFIAPI+SmbusReadOperation > > (+ IN CONST UINT16 IoBase,+ IN CONST > > EFI_SMBUS_HC_PROTOCOL *This,+ IN EFI_SMBUS_DEVICE_ADDRESS > > SlaveAddress,+ IN EFI_SMBUS_DEVICE_COMMAND Command,+ IN > > BOOLEAN PecCheck,+ IN OUT UINTN *Length,+ IN OUT > > VOID *Buffer+ )+{+ EFI_STATUS Status;+ UINT8 > > ResultBuffer;++ if (!Buffer || !Length) {+ return > > RETURN_INVALID_PARAMETER;+ }++ /* Set up for a byte data read. */+ > > Status = SmbusSetupCommand (IoBase, I801_BYTE_DATA, XMIT_READ > > (SlaveAddress.SmbusDeviceAddress));+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ IoWrite8 (IoBase + SMBHSTCMD, Command);++ IoWrite8 > > (IoBase + SMBHSTDAT0, 0);+ IoWrite8 (IoBase + SMBHSTDAT1, 0);++ /* Start > > the command */+ Status = SmbusExecuteCommand (IoBase);+ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Poll for transaction > > completion */+ Status = SmbusCompleteCommand (IoBase);+ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Read results of transaction > > */+ ResultBuffer = IoRead8 (IoBase + SMBHSTDAT0);++ CopyMem (Buffer, > > &ResultBuffer, sizeof (ResultBuffer));+ *Length = sizeof (ResultBuffer);++ > > return EFI_SUCCESS;+}++STATIC+EFI_STATUS+EFIAPI+SmbusWriteOperation > > (+ IN CONST UINT16 IoBase,+ IN CONST > > EFI_SMBUS_HC_PROTOCOL *This,+ IN EFI_SMBUS_DEVICE_ADDRESS > > SlaveAddress,+ IN EFI_SMBUS_DEVICE_COMMAND Command,+ IN > > BOOLEAN PecCheck,+ IN OUT UINTN *Length,+ IN OUT > > VOID *Buffer+ )+{+ EFI_STATUS Status;+ UINT8 > > InputBuffer;++ if (!Buffer || !Length) {+ return > > RETURN_INVALID_PARAMETER;+ }++ if (*Length != 1) {+ return > > RETURN_INVALID_PARAMETER;+ }++ CopyMem (&InputBuffer, Buffer, > > sizeof (InputBuffer));++ /* Set up for a byte data read. */+ Status = > > SmbusSetupCommand (IoBase, I801_BYTE_DATA, XMIT_WRITE > > (SlaveAddress.SmbusDeviceAddress));+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ IoWrite8 (IoBase + SMBHSTCMD, Command);++ IoWrite8 > > (IoBase + SMBHSTDAT0, InputBuffer);++ /* Start the command */+ Status = > > SmbusExecuteCommand (IoBase);+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ /* Poll for transaction completion */+ Status = > > SmbusCompleteCommand (IoBase);+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ return > > EFI_SUCCESS;+}++STATIC+EFI_STATUS+EFIAPI+SmbusExecuteOperation (+ > > 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+ )+{+ UINT16 IoBase;++ IoBase = SmbusGetSMBaseAddress ();+ if > > (!IoBase) {+ return EFI_UNSUPPORTED;+ }++ if (Operation == > > EfiSmbusProcessCall) {+ return SmbusProcessCallOperation (+ > > IoBase,+ This,+ SlaveAddress,+ Command,+ > > PecCheck,+ Length,+ Buffer+ );+ } else if (Operation == > > EfiSmbusReadByte) {+ return SmbusReadOperation (+ IoBase,+ > > This,+ SlaveAddress,+ Command,+ PecCheck,+ > > Length,+ Buffer+ );+ } else if (Operation == EfiSmbusWriteByte) > > {+ return SmbusWriteOperation (+ IoBase,+ This,+ > > SlaveAddress,+ Command,+ PecCheck,+ Length,+ > > Buffer+ );+ }++ return > > EFI_UNSUPPORTED;+}++STATIC+EFI_STATUS+EFIAPI+SmbusHcProtocolArpD > > evice (+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,+ IN BOOLEAN > > ArpAll,+ IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL+ IN OUT > > EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL+ )+{+ return > > EFI_UNSUPPORTED;+}++STATIC+EFI_STATUS+EFIAPI+SmbusHcProtocolGetA > > rpMap (+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,+ IN OUT UINTN > > *Length,+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap+ )+{+ > > return > > EFI_UNSUPPORTED;+}++STATIC+EFI_STATUS+EFIAPI+SmbusHcProtocolNotif > > y (+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,+ IN > > EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,+ IN UINTN > > Data,+ IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction+ )+{+ return > > EFI_UNSUPPORTED;+}++EFI_SMBUS_HC_PROTOCOL mSmbusProtocol = {+ > > SmbusExecuteOperation,+ SmbusHcProtocolArpDevice,+ > > SmbusHcProtocolGetArpMap,+ SmbusHcProtocolNotify+};++/**+ The Entry > > Point for SMBUS driver.++ It installs DriverBinding.++ @retval EFI_SUCCESS > > The entry point is executed successfully.+ @retval other Some error > > occurs when executing this entry > > point.++**/+EFI_STATUS+EFIAPI+InstallSmbusProtocol (+ IN EFI_HANDLE > > ImageHandle,+ IN EFI_SYSTEM_TABLE *SystemTable+ )+{+ EFI_STATUS > > Status;+ UINT16 IoBase;+ UINT8 Device;+ UINT8 Function;+ > > BOOLEAN BreakLoop;+ UINT8 BaseClass;+ UINT8 SubClass;++ > > BreakLoop = FALSE;+ Status = EFI_SUCCESS;++ //+ // Search for SMBus > > Controller within PCI Devices on root bus+ //+ for (Device = 0; Device <= > > PCI_MAX_DEVICE; Device++) {+ for (Function = 0; Function <= > > PCI_MAX_FUNC; Function++) {+ if (PciRead16 (PCI_LIB_ADDRESS (0, > > Device, Function, 0x00)) != 0x8086) {+ continue;+ }++ BaseClass = > > PciRead8 (PCI_LIB_ADDRESS (0, Device, Function, 0x0B));++ if (BaseClass > > == PCI_CLASS_SERIAL) {+ SubClass = PciRead8 (PCI_LIB_ADDRESS (0, > > Device, Function, 0xA));++ if (SubClass == PCI_CLASS_SERIAL_SMB) {+ > > BreakLoop = TRUE;+ PciDevice = PCI_LIB_ADDRESS (0, Device, Function, > > 0x00);+ break;+ }+ }+ }++ if (BreakLoop) {+ break;+ }+ }++ if > > (!BreakLoop) {+ DEBUG ((EFI_D_INFO, "No PCI SMBUS controller > > found.\n"));+ return EFI_UNSUPPORTED;+ }++ DEBUG ((EFI_D_INFO, "PCI > > Device found on 0-%x-%x\n", Device, Function));++ IoBase = > > SmbusGetSMBaseAddress ();+ if (!IoBase) {+ return > > EFI_UNSUPPORTED;+ }++ DEBUG ((+ EFI_D_INFO,+ "%a: Detected i801 > > SMBus controller with SMBASE 0x%x\n",+ __FUNCTION__,+ > > IoBase+ ));++ Status = gBS->InstallProtocolInterface (+ > > &mDriverHandle,+ &gEfiSmbusHcProtocolGuid,+ > > EFI_NATIVE_INTERFACE,+ &mSmbusProtocol+ );++ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ return EFI_SUCCESS;+}diff --git > > a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > > b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > > new file mode 100644 > > index 0000000000..e88823da31 > > --- /dev/null > > +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > > @@ -0,0 +1,17 @@ > > +/** @file+ Header file for a generic i801 SMBUS driver.++Copyright (c) > > +2016, Intel Corporation. All rights > > +reserved.<BR>+SPDX-License-Identifier: > > +BSD-2-Clause-Patent+++**/+#ifndef _PCI_PLATFORM_DXE_H_+#define > > +_PCI_PLATFORM_DXE_H_+#include <PiDxe.h>++#include > > +<IndustryStandard/Pci.h>+#include <IndustryStandard/Pci22.h>+#include > > +<Protocol/SmbusHc.h>++#endifdiff --git > > +a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > > +b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > > new file mode 100644 > > index 0000000000..7d13c446ef > > --- /dev/null > > +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > > @@ -0,0 +1,45 @@ > > +## @file+# This driver produces gEfiSmbusHcProtocolGuid protocol to load > > access SMBUS devices+#+# Copyright (c) 2020, 9elements Agency > > GmbH+#+# SPDX-License-Identifier: BSD-2-Clause- > > Patent+#+#+##++[Defines]+ INF_VERSION = 0x00010005+ > > BASE_NAME = SMBusi801Dxe+ FILE_GUID = 390208DA- > > 8E6F-4957-90D6-421737FEA9BF+ MODULE_TYPE = DXE_DRIVER+ > > VERSION_STRING = 1.0+ ENTRY_POINT = > > InstallSmbusProtocol++#+# The following information is for reference only > > and not required by the build tools.+#+# VALID_ARCHITECTURES = IA32 > > X64+#++[Sources.common]+ SMBusi801Dxe.h+ > > SMBusi801Dxe.c++[Packages]+ MdePkg/MdePkg.dec+ > > MdeModulePkg/MdeModulePkg.dec++[LibraryClasses]+ > > UefiDriverEntryPoint+ DebugLib+ IoLib+ UefiLib+ TimerLib+ > > PciLib++[Protocols]+ gEfiSmbusHcProtocolGuid ## > > PRODUCES++[Depex]+ TRUEdiff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc > > b/UefiPayloadPkg/UefiPayloadPkg.dsc > > index 1ce96a51c1..54543b7623 100644 > > --- a/UefiPayloadPkg/UefiPayloadPkg.dsc > > +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc > > @@ -290,6 +290,7 @@ > > !if $(PERFORMANCE_MEASUREMENT_ENABLE) > > PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCore > > PerformanceLib.inf !endif+ > > SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf > > [LibraryClasses.common.DXE_DRIVER] > > PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf@@ -304,6 +305,7 @@ > > !if $(PERFORMANCE_MEASUREMENT_ENABLE) > > PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerforma > > nceLib.inf !endif+ > > SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf > > [LibraryClasses.common.DXE_RUNTIME_DRIVER] > > PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf@@ -657,6 +659,11 @@ > > !endif MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf + #+ # > > SMBUS Support+ #+ UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf+ # # > > Console Support #diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf > > b/UefiPayloadPkg/UefiPayloadPkg.fdf > > index c7b04978ad..8861d29162 100644 > > --- a/UefiPayloadPkg/UefiPayloadPkg.fdf > > +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf > > @@ -178,6 +178,11 @@ INF > > MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf > > !endif INF MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf +#+# > > SMBUS Support+#+INF UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf+ # # > > Console Support #-- > > 2.32.0 > > > > > > > > -=-=-=-=-=-= > > Groups.io Links: You receive all messages sent to this group. > > View/Reply Online (#86730): https://edk2.groups.io/g/devel/message/86730 > > Mute This Topic: https://groups.io/mt/89214991/1773972 > > Group Owner: devel+owner@edk2.groups.io > > Unsubscribe: https://edk2.groups.io/g/devel/unsub [maurice.ma@intel.com] > > -=-=-=-=-=-= > > > > > > > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE 2022-02-24 10:46 ` Patrick Rudolph @ 2022-02-24 15:53 ` Guo Dong 2022-02-25 1:25 ` Guo Dong 0 siblings, 1 reply; 6+ messages in thread From: Guo Dong @ 2022-02-24 15:53 UTC (permalink / raw) To: devel@edk2.groups.io, patrick.rudolph@9elements.com, Ma, Maurice Cc: Rhodes, Sean, Ni, Ray, You, Benjamin Hi Patrick, UefiPayloadPkg/Library/SpiFlashLib/SpiFlashLib.inf is a common module as the commit message mentioned as below: * UefiPayloadPkg: Add SpiFlashLib This is a common SPI Flash library used for the Intel platform that supports SPI hardware sequence. This library provides actual SPI flash operation via Intel PCH SPI controller. Thanks, Guo -----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Patrick Rudolph Sent: Thursday, February 24, 2022 3:46 AM To: devel@edk2.groups.io; Ma, Maurice <maurice.ma@intel.com> Cc: Rhodes, Sean <sean@starlabs.systems>; Dong, Guo <guo.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; You, Benjamin <benjamin.you@intel.com> Subject: Re: [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE Hi Maurice, I agree that edk2-platforms is the right place. How should it be used to build UefiPlayloadPkg? Should it be hooked up as git submodule? Just wondering why you added vendor (or platform) specific code in UefiPayloadPkg/Library/SpiFlashLib/SpiFlashLib.inf ? Please clarify. Regards, Patrick Rudolph On Thu, Feb 17, 2022 at 7:24 PM Ma, Maurice <maurice.ma@intel.com> wrote: > > This vendor specific device driver implementation does not seem to fit into UEFI payload package scope well. > > Do you think https://github.com/tianocore/edk2-platforms/tree/master/Silicon could be a better location ? > > Thanks > Maurice > > -----Original Message----- > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sean > > Rhodes > > Sent: Thursday, February 17, 2022 9:51 > > To: devel@edk2.groups.io > > Cc: Dong, Guo <guo.dong@intel.com>; Patrick Rudolph > > <patrick.rudolph@9elements.com>; Ni, Ray <ray.ni@intel.com>; Ma, > > Maurice <maurice.ma@intel.com>; You, Benjamin > > <benjamin.you@intel.com> > > Subject: [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus > > controller DXE > > > > From: Patrick Rudolph <patrick.rudolph@9elements.com> > > > > Implement a subset of the gEfiSmbusHcProtocolGuid using a generic > > PCI i801 SMBus controller. > > > > Cc: Guo Dong <guo.dong@intel.com> > > Cc: Ray Ni <ray.ni@intel.com> > > Cc: Maurice Ma <maurice.ma@intel.com> > > Cc: Benjamin You <benjamin.you@intel.com> > > Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> > > --- > > .../Library/BrotliCustomDecompressLib/brotli | 2 +- > > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c | 556 > > ++++++++++++++++++ > > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h | 17 + > > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf | 45 ++ > > UefiPayloadPkg/UefiPayloadPkg.dsc | 7 + > > UefiPayloadPkg/UefiPayloadPkg.fdf | 5 + > > 6 files changed, 631 insertions(+), 1 deletion(-) create mode > > 100644 UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > > create mode 100644 UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > > create mode 100644 UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > > > > diff --git a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > > b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > > index f4153a09f8..666c3280cc 160000 > > --- a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > > +++ b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > > @@ -1 +1 @@ > > -Subproject commit f4153a09f87cbb9c826d8fc12c74642bb2d879ea > > +Subproject commit 666c3280cc11dc433c303d79a83d4ffbdd12cc8d > > diff --git a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > > b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > > new file mode 100644 > > index 0000000000..7bf7b893ad > > --- /dev/null > > +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > > @@ -0,0 +1,556 @@ > > +/** @file+ Implementation for a generic i801 SMBus > > +driver.++Copyright (c) > > 2016, Intel Corporation. All rights reserved.<BR>+SPDX-License-Identifier: > > BSD-2-Clause-Patent+++**/++#include "SMBusi801Dxe.h"+#include > > <Library/TimerLib.h>+#include <Library/PciLib.h>+#include > > <Library/IoLib.h>+#include <Library/DebugLib.h>+#include > > <Library/BaseMemoryLib.h>+#include > > <Library/UefiBootServicesTableLib.h>++EFI_HANDLE mDriverHandle = > > NULL;+UINT32 PciDevice = 0;++/* SMBus register offsets. */+#define > > SMBHSTSTAT 0x0+#define SMBHSTCTL 0x2+#define SMBHSTCMD > > 0x3+#define SMBXMITADD 0x4+#define SMBHSTDAT0 0x5+#define > > SMBHSTDAT1 0x6+#define SMBBLKDAT 0x7+#define SMBTRNSADD > > 0x9+#define SMBSLVDATA 0xa+#define SMLINK_PIN_CTL 0xe+#define > > SMBUS_PIN_CTL 0xf+#define SMBSLVCMD 0x11++/* I801 command > > constants */+#define I801_QUICK (0 << 2)+#define I801_BYTE (1 > > << 2)+#define I801_BYTE_DATA (2 << 2)+#define I801_WORD_DATA (3 > > << 2)+#define I801_PROCESS_CALL (4 << 2)+#define I801_BLOCK_DATA > > (5 << 2)+#define I801_I2C_BLOCK_DATA (6 << 2) /* ICH5 and later */++/* > > I801 Host Control register bits */+#define SMBHSTCNT_INTREN (1 << > > 0)+#define SMBHSTCNT_KILL (1 << 1)+#define SMBHSTCNT_LAST_BYTE > > (1 << 5)+#define SMBHSTCNT_START (1 << 6)+#define > > SMBHSTCNT_PEC_EN (1 << 7) /* ICH3 and later */++/* I801 Hosts Status > > register bits */+#define SMBHSTSTS_BYTE_DONE (1 << 7)+#define > > SMBHSTSTS_INUSE_STS (1 << 6)+#define SMBHSTSTS_SMBALERT_STS (1 > > << 5)+#define SMBHSTSTS_FAILED (1 << 4)+#define > > SMBHSTSTS_BUS_ERR (1 << 3)+#define SMBHSTSTS_DEV_ERR (1 << > > 2)+#define SMBHSTSTS_INTR (1 << 1)+#define SMBHSTSTS_HOST_BUSY > > (1 << 0)++/* For SMBXMITADD register. */+#define XMIT_WRITE(dev) > > (((dev) << 1) | 0)+#define XMIT_READ(dev) (((dev) << 1) | > > 1)++STATIC+UINT16+EFIAPI+SmbusGetSMBaseAddress (+ IN VOID+ )+{+ > > UINT16 Cmd;+ UINT32 Reg32;+ UINT16 IoBase;++ IoBase = 0;+ //+ > > // Test if I/O decoding is enabled+ //+ Cmd = PciRead16 (PciDevice + 0x4);+ if > > (!(Cmd & 1)) {+ goto CloseAndReturn;+ }++ //+ // Test if BAR0 is I/O bar > > and enabled+ //+ Reg32 = PciRead16 (PciDevice + 0x20);+ if > > (!(Reg32 & 1) > > || !(Reg32 & 0xfffc) || ((Reg32 & 0xfffc) == 0xfffc)) {+ goto > > CloseAndReturn;+ }++ IoBase = Reg32 & 0xfffc;++CloseAndReturn:+ > > return IoBase;+}++STATIC+EFI_STATUS+SmbusSetupCommand (+ IN UINT16 > > IoBase,+ IN UINT8 Ctrl,+ IN UINT8 Xmitadd+ )+{+ UINTN Loops = 10000;+ > > UINT8 host_busy;++ do {+ MicroSecondDelay (100);+ host_busy = > > IoRead8 (IoBase + SMBHSTSTAT) & SMBHSTSTS_HOST_BUSY;+ } while (-- > > Loops && host_busy);++ if (Loops == 0) {+ return EFI_TIMEOUT;+ }++ /* > > Clear any lingering errors, so the transaction will run. */+ > > IoWrite8 (IoBase + SMBHSTSTAT, IoRead8 (IoBase + SMBHSTSTAT));++ /* > > Set up transaction */+ > > /* Disable interrupts */+ IoWrite8 (IoBase + SMBHSTCTL, Ctrl);++ > > /* Set the device I'm talking to. */+ IoWrite8 (IoBase + > > SMBXMITADD, Xmitadd);++ return > > EFI_SUCCESS;+}++STATIC+EFI_STATUS+SmbusExecuteCommand (+ IN UINT16 > > IoBase+ )+{+ UINTN Loops = 10000;+ UINT8 Status;++ /* Start > > the command. */+ IoWrite8 (IoBase + SMBHSTCTL, IoRead8 (IoBase + > > SMBHSTCTL) | SMBHSTCNT_START);+ Status = IoRead8 (IoBase + > > SMBHSTSTAT);++ /* Poll for it to start. */+ do {+ MicroSecondDelay > > (100);++ /* If we poll too slow, we could miss HOST_BUSY flag+ * set and > > detect INTR or x_ERR flags instead here.+ */+ Status = IoRead8 (IoBase + > > SMBHSTSTAT);++ Status &= ~(SMBHSTSTS_SMBALERT_STS | > > SMBHSTSTS_INUSE_STS);+ } while (--Loops && Status == 0);++ if (Loops == 0) > > {+ return EFI_TIMEOUT;+ }++ return > > EFI_SUCCESS;+}++STATIC+BOOLEAN+SmbusHostCompleted (+ IN UINT8 > > Status+ )+{+ if (Status & SMBHSTSTS_HOST_BUSY) {+ return FALSE;+ }++ > > /* These status bits do not imply completion of transaction. */+ > > Status &= ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS | > > SMBHSTSTS_SMBALERT_STS);+ return Status != > > 0;+}++STATIC+EFI_STATUS+SmbusCompleteCommand (+ IN UINT16 > > IoBase+ )+{+ UINTN Loops = 10000;+ UINT8 Status;++ do {+ > > MicroSecondDelay (100);+ Status = IoRead8 (IoBase + SMBHSTSTAT);+ } > > while (--Loops && !SmbusHostCompleted (Status));++ if (Loops == 0) > > {+ return EFI_TIMEOUT;+ }++ /* These status bits do not imply > > errors. */+ Status &= ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS | > > SMBHSTSTS_SMBALERT_STS);++ if (Status == SMBHSTSTS_INTR) {+ return > > EFI_SUCCESS;+ }++ return > > EFI_NO_RESPONSE;+}++STATIC+EFI_STATUS+EFIAPI+SmbusProcessCallOper > > ation (+ IN CONST UINT16 IoBase,+ IN CONST > > EFI_SMBUS_HC_PROTOCOL *This,+ IN EFI_SMBUS_DEVICE_ADDRESS > > SlaveAddress,+ IN EFI_SMBUS_DEVICE_COMMAND Command,+ IN > > BOOLEAN PecCheck,+ IN OUT UINTN *Length,+ IN OUT > > VOID *Buffer+ )+{+ EFI_STATUS Status;+ UINT16 > > ResultBuffer;+ UINT16 AddrBuffer;++ if (!Buffer || !Length) {+ return > > RETURN_INVALID_PARAMETER;+ }++ if (*Length != 2) {+ return > > RETURN_INVALID_PARAMETER;+ }++ CopyMem (&AddrBuffer, Buffer, > > sizeof (AddrBuffer));++ /* Set up for process call */+ Status = > > SmbusSetupCommand (IoBase, I801_PROCESS_CALL, XMIT_WRITE > > (SlaveAddress.SmbusDeviceAddress));+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ /* cmd will only be send if I2C_EN is zero */+ > > IoWrite8 (IoBase > > + SMBHSTCMD, Command);++ IoWrite8 (IoBase + SMBHSTDAT0, AddrBuffer > > & 0x00ff);+ IoWrite8 (IoBase + SMBHSTDAT1, (AddrBuffer & 0xff00) >> > > 8);++ > > /* Start the command */+ Status = SmbusExecuteCommand (IoBase);+ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Poll for transaction > > completion */+ Status = SmbusCompleteCommand (IoBase);+ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Read results of transaction > > */+ ResultBuffer = IoRead8 (IoBase + SMBHSTDAT0);+ ResultBuffer > > |= > > (IoRead8 (IoBase + SMBHSTDAT1) << 8);++ CopyMem (Buffer, > > &ResultBuffer, sizeof (ResultBuffer));+ *Length = sizeof > > (ResultBuffer);++ return EFI_SUCCESS;+}++STATIC+EFI_STATUS+EFIAPI+SmbusReadOperation > > (+ IN CONST UINT16 IoBase,+ IN CONST > > EFI_SMBUS_HC_PROTOCOL *This,+ IN EFI_SMBUS_DEVICE_ADDRESS > > SlaveAddress,+ IN EFI_SMBUS_DEVICE_COMMAND Command,+ IN > > BOOLEAN PecCheck,+ IN OUT UINTN *Length,+ IN OUT > > VOID *Buffer+ )+{+ EFI_STATUS Status;+ UINT8 > > ResultBuffer;++ if (!Buffer || !Length) {+ return > > RETURN_INVALID_PARAMETER;+ }++ /* Set up for a byte data read. */+ > > Status = SmbusSetupCommand (IoBase, I801_BYTE_DATA, XMIT_READ > > (SlaveAddress.SmbusDeviceAddress));+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ IoWrite8 (IoBase + SMBHSTCMD, Command);++ IoWrite8 > > (IoBase + SMBHSTDAT0, 0);+ IoWrite8 (IoBase + SMBHSTDAT1, 0);++ /* > > Start the command */+ Status = SmbusExecuteCommand (IoBase);+ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Poll for transaction > > completion */+ Status = SmbusCompleteCommand (IoBase);+ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Read results of transaction > > */+ ResultBuffer = IoRead8 (IoBase + SMBHSTDAT0);++ CopyMem > > (Buffer, &ResultBuffer, sizeof (ResultBuffer));+ *Length = sizeof > > (ResultBuffer);++ return EFI_SUCCESS;+}++STATIC+EFI_STATUS+EFIAPI+SmbusWriteOperation > > (+ IN CONST UINT16 IoBase,+ IN CONST > > EFI_SMBUS_HC_PROTOCOL *This,+ IN EFI_SMBUS_DEVICE_ADDRESS > > SlaveAddress,+ IN EFI_SMBUS_DEVICE_COMMAND Command,+ IN > > BOOLEAN PecCheck,+ IN OUT UINTN *Length,+ IN OUT > > VOID *Buffer+ )+{+ EFI_STATUS Status;+ UINT8 > > InputBuffer;++ if (!Buffer || !Length) {+ return > > RETURN_INVALID_PARAMETER;+ }++ if (*Length != 1) {+ return > > RETURN_INVALID_PARAMETER;+ }++ CopyMem (&InputBuffer, Buffer, > > sizeof (InputBuffer));++ /* Set up for a byte data read. */+ > > Status = SmbusSetupCommand (IoBase, I801_BYTE_DATA, XMIT_WRITE > > (SlaveAddress.SmbusDeviceAddress));+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ IoWrite8 (IoBase + SMBHSTCMD, Command);++ IoWrite8 > > (IoBase + SMBHSTDAT0, InputBuffer);++ /* Start the command */+ Status = > > SmbusExecuteCommand (IoBase);+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ /* Poll for transaction completion */+ Status = > > SmbusCompleteCommand (IoBase);+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ return > > EFI_SUCCESS;+}++STATIC+EFI_STATUS+EFIAPI+SmbusExecuteOperation (+ > > 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+ )+{+ UINT16 IoBase;++ IoBase = SmbusGetSMBaseAddress ();+ if > > (!IoBase) {+ return EFI_UNSUPPORTED;+ }++ if (Operation == > > EfiSmbusProcessCall) {+ return SmbusProcessCallOperation (+ > > IoBase,+ This,+ SlaveAddress,+ Command,+ > > PecCheck,+ Length,+ Buffer+ );+ } else if (Operation == > > EfiSmbusReadByte) {+ return SmbusReadOperation (+ IoBase,+ > > This,+ SlaveAddress,+ Command,+ PecCheck,+ > > Length,+ Buffer+ );+ } else if (Operation == EfiSmbusWriteByte) > > {+ return SmbusWriteOperation (+ IoBase,+ This,+ > > SlaveAddress,+ Command,+ PecCheck,+ Length,+ > > Buffer+ );+ }++ return > > EFI_UNSUPPORTED;+}++STATIC+EFI_STATUS+EFIAPI+SmbusHcProtocolArpD > > evice (+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,+ IN BOOLEAN > > ArpAll,+ IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL+ IN OUT > > EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL+ )+{+ return > > EFI_UNSUPPORTED;+}++STATIC+EFI_STATUS+EFIAPI+SmbusHcProtocolGetA > > rpMap (+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,+ IN OUT UINTN > > *Length,+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap+ )+{+ > > return > > EFI_UNSUPPORTED;+}++STATIC+EFI_STATUS+EFIAPI+SmbusHcProtocolNotif > > y (+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,+ IN > > EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,+ IN UINTN > > Data,+ IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction+ )+{+ return > > EFI_UNSUPPORTED;+}++EFI_SMBUS_HC_PROTOCOL mSmbusProtocol = {+ > > SmbusExecuteOperation,+ SmbusHcProtocolArpDevice,+ > > SmbusHcProtocolGetArpMap,+ SmbusHcProtocolNotify+};++/**+ The > > Entry Point for SMBUS driver.++ It installs DriverBinding.++ @retval EFI_SUCCESS > > The entry point is executed successfully.+ @retval other Some error > > occurs when executing this entry > > point.++**/+EFI_STATUS+EFIAPI+InstallSmbusProtocol (+ IN EFI_HANDLE > > ImageHandle,+ IN EFI_SYSTEM_TABLE *SystemTable+ )+{+ EFI_STATUS > > Status;+ UINT16 IoBase;+ UINT8 Device;+ UINT8 Function;+ > > BOOLEAN BreakLoop;+ UINT8 BaseClass;+ UINT8 SubClass;++ > > BreakLoop = FALSE;+ Status = EFI_SUCCESS;++ //+ // Search for SMBus > > Controller within PCI Devices on root bus+ //+ for (Device = 0; Device <= > > PCI_MAX_DEVICE; Device++) {+ for (Function = 0; Function <= > > PCI_MAX_FUNC; Function++) {+ if (PciRead16 (PCI_LIB_ADDRESS (0, > > Device, Function, 0x00)) != 0x8086) {+ continue;+ }++ BaseClass = > > PciRead8 (PCI_LIB_ADDRESS (0, Device, Function, 0x0B));++ if (BaseClass > > == PCI_CLASS_SERIAL) {+ SubClass = PciRead8 (PCI_LIB_ADDRESS (0, > > Device, Function, 0xA));++ if (SubClass == PCI_CLASS_SERIAL_SMB) {+ > > BreakLoop = TRUE;+ PciDevice = PCI_LIB_ADDRESS (0, Device, Function, > > 0x00);+ break;+ }+ }+ }++ if (BreakLoop) {+ break;+ }+ }++ if > > (!BreakLoop) {+ DEBUG ((EFI_D_INFO, "No PCI SMBUS controller > > found.\n"));+ return EFI_UNSUPPORTED;+ }++ DEBUG ((EFI_D_INFO, "PCI > > Device found on 0-%x-%x\n", Device, Function));++ IoBase = > > SmbusGetSMBaseAddress ();+ if (!IoBase) {+ return > > EFI_UNSUPPORTED;+ }++ DEBUG ((+ EFI_D_INFO,+ "%a: Detected i801 > > SMBus controller with SMBASE 0x%x\n",+ __FUNCTION__,+ > > IoBase+ ));++ Status = gBS->InstallProtocolInterface (+ > > &mDriverHandle,+ &gEfiSmbusHcProtocolGuid,+ > > EFI_NATIVE_INTERFACE,+ &mSmbusProtocol+ );++ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ return EFI_SUCCESS;+}diff --git > > a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > > b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > > new file mode 100644 > > index 0000000000..e88823da31 > > --- /dev/null > > +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > > @@ -0,0 +1,17 @@ > > +/** @file+ Header file for a generic i801 SMBUS driver.++Copyright > > +(c) 2016, Intel Corporation. All rights > > +reserved.<BR>+SPDX-License-Identifier: > > +BSD-2-Clause-Patent+++**/+#ifndef _PCI_PLATFORM_DXE_H_+#define > > +_PCI_PLATFORM_DXE_H_+#include <PiDxe.h>++#include > > +<IndustryStandard/Pci.h>+#include > > +<IndustryStandard/Pci22.h>+#include > > +<Protocol/SmbusHc.h>++#endifdiff --git > > +a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > > +b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > > new file mode 100644 > > index 0000000000..7d13c446ef > > --- /dev/null > > +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > > @@ -0,0 +1,45 @@ > > +## @file+# This driver produces gEfiSmbusHcProtocolGuid protocol to > > +load > > access SMBUS devices+#+# Copyright (c) 2020, 9elements Agency > > GmbH+#+# SPDX-License-Identifier: BSD-2-Clause- > > Patent+#+#+##++[Defines]+ INF_VERSION = 0x00010005+ > > BASE_NAME = SMBusi801Dxe+ FILE_GUID = 390208DA- > > 8E6F-4957-90D6-421737FEA9BF+ MODULE_TYPE = DXE_DRIVER+ > > VERSION_STRING = 1.0+ ENTRY_POINT = > > InstallSmbusProtocol++#+# The following information is for reference > > InstallSmbusProtocol++only > > and not required by the build tools.+#+# VALID_ARCHITECTURES = IA32 > > X64+#++[Sources.common]+ SMBusi801Dxe.h+ > > SMBusi801Dxe.c++[Packages]+ MdePkg/MdePkg.dec+ > > MdeModulePkg/MdeModulePkg.dec++[LibraryClasses]+ > > UefiDriverEntryPoint+ DebugLib+ IoLib+ UefiLib+ TimerLib+ > > PciLib++[Protocols]+ gEfiSmbusHcProtocolGuid ## > > PRODUCES++[Depex]+ TRUEdiff --git > > PRODUCES++a/UefiPayloadPkg/UefiPayloadPkg.dsc > > b/UefiPayloadPkg/UefiPayloadPkg.dsc > > index 1ce96a51c1..54543b7623 100644 > > --- a/UefiPayloadPkg/UefiPayloadPkg.dsc > > +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc > > @@ -290,6 +290,7 @@ > > !if $(PERFORMANCE_MEASUREMENT_ENABLE) > > PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCore > > PerformanceLib.inf !endif+ > > SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf > > [LibraryClasses.common.DXE_DRIVER] > > PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf@@ -304,6 +305,7 @@ > > !if $(PERFORMANCE_MEASUREMENT_ENABLE) > > PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerforma > > nceLib.inf !endif+ > > SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf > > [LibraryClasses.common.DXE_RUNTIME_DRIVER] > > PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf@@ -657,6 +659,11 @@ > > !endif MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf + #+ # > > SMBUS Support+ #+ UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf+ # # > > Console Support #diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf > > b/UefiPayloadPkg/UefiPayloadPkg.fdf > > index c7b04978ad..8861d29162 100644 > > --- a/UefiPayloadPkg/UefiPayloadPkg.fdf > > +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf > > @@ -178,6 +178,11 @@ INF > > MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf > > !endif INF MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf +#+# > > SMBUS Support+#+INF UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf+ # # > > Console Support #-- > > 2.32.0 > > > > > > > > -=-=-=-=-=-= > > Groups.io Links: You receive all messages sent to this group. > > View/Reply Online (#86730): > > https://edk2.groups.io/g/devel/message/86730 > > Mute This Topic: https://groups.io/mt/89214991/1773972 > > Group Owner: devel+owner@edk2.groups.io > > Unsubscribe: https://edk2.groups.io/g/devel/unsub > > [maurice.ma@intel.com] -=-=-=-=-=-= > > > > > > > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE 2022-02-24 15:53 ` Guo Dong @ 2022-02-25 1:25 ` Guo Dong 0 siblings, 0 replies; 6+ messages in thread From: Guo Dong @ 2022-02-25 1:25 UTC (permalink / raw) To: devel@edk2.groups.io, patrick.rudolph@9elements.com, Ma, Maurice Cc: Rhodes, Sean, Ni, Ray, You, Benjamin Hi Patrick, You could refer this page https://github.com/tianocore/edk2-platforms on how to build platform with EDK2 and edk2-platform repo. I had thought you added a SMbus driver that could only work on a particular device. I agree with Maurice to put this kind of modules to Edk2-platform repo. For SpiFlashLib it is library specific for Intel PCH SPI, we ever discussed to put to edk2-platform before. But we temporarily put to EDK2 with other SMM modules for convenience since there is only few this kind of modules. Let me explore a solution to move PCH specific modules to edk2-platform. Maybe create PayloadPlatformPkg under edk2-platforms\Platform\Intel to build universal UEFI payload from Edk2 repo, and build a separate FV to include PCH specific modules from edk2-platform repo. The build script could add the FV into the universal payload as a section of universal payload defined by the universal payload specification. This way the UEFI payload in EDK2 could be generic enough without platform specific modules. Thanks, Guo -----Original Message----- From: Dong, Guo Sent: Thursday, February 24, 2022 8:54 AM To: devel@edk2.groups.io; patrick.rudolph@9elements.com; Ma, Maurice <maurice.ma@intel.com> Cc: Rhodes, Sean <sean@starlabs.systems>; Ni, Ray <ray.ni@intel.com>; You, Benjamin <benjamin.you@intel.com> Subject: RE: [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE Hi Patrick, UefiPayloadPkg/Library/SpiFlashLib/SpiFlashLib.inf is a common module as the commit message mentioned as below: * UefiPayloadPkg: Add SpiFlashLib This is a common SPI Flash library used for the Intel platform that supports SPI hardware sequence. This library provides actual SPI flash operation via Intel PCH SPI controller. Thanks, Guo -----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Patrick Rudolph Sent: Thursday, February 24, 2022 3:46 AM To: devel@edk2.groups.io; Ma, Maurice <maurice.ma@intel.com> Cc: Rhodes, Sean <sean@starlabs.systems>; Dong, Guo <guo.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; You, Benjamin <benjamin.you@intel.com> Subject: Re: [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE Hi Maurice, I agree that edk2-platforms is the right place. How should it be used to build UefiPlayloadPkg? Should it be hooked up as git submodule? Just wondering why you added vendor (or platform) specific code in UefiPayloadPkg/Library/SpiFlashLib/SpiFlashLib.inf ? Please clarify. Regards, Patrick Rudolph On Thu, Feb 17, 2022 at 7:24 PM Ma, Maurice <maurice.ma@intel.com> wrote: > > This vendor specific device driver implementation does not seem to fit into UEFI payload package scope well. > > Do you think https://github.com/tianocore/edk2-platforms/tree/master/Silicon could be a better location ? > > Thanks > Maurice > > -----Original Message----- > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Sean > > Rhodes > > Sent: Thursday, February 17, 2022 9:51 > > To: devel@edk2.groups.io > > Cc: Dong, Guo <guo.dong@intel.com>; Patrick Rudolph > > <patrick.rudolph@9elements.com>; Ni, Ray <ray.ni@intel.com>; Ma, > > Maurice <maurice.ma@intel.com>; You, Benjamin > > <benjamin.you@intel.com> > > Subject: [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus > > controller DXE > > > > From: Patrick Rudolph <patrick.rudolph@9elements.com> > > > > Implement a subset of the gEfiSmbusHcProtocolGuid using a generic > > PCI i801 SMBus controller. > > > > Cc: Guo Dong <guo.dong@intel.com> > > Cc: Ray Ni <ray.ni@intel.com> > > Cc: Maurice Ma <maurice.ma@intel.com> > > Cc: Benjamin You <benjamin.you@intel.com> > > Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> > > --- > > .../Library/BrotliCustomDecompressLib/brotli | 2 +- > > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c | 556 > > ++++++++++++++++++ > > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h | 17 + > > UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf | 45 ++ > > UefiPayloadPkg/UefiPayloadPkg.dsc | 7 + > > UefiPayloadPkg/UefiPayloadPkg.fdf | 5 + > > 6 files changed, 631 insertions(+), 1 deletion(-) create mode > > 100644 UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > > create mode 100644 UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > > create mode 100644 UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > > > > diff --git a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > > b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > > index f4153a09f8..666c3280cc 160000 > > --- a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > > +++ b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli > > @@ -1 +1 @@ > > -Subproject commit f4153a09f87cbb9c826d8fc12c74642bb2d879ea > > +Subproject commit 666c3280cc11dc433c303d79a83d4ffbdd12cc8d > > diff --git a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > > b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > > new file mode 100644 > > index 0000000000..7bf7b893ad > > --- /dev/null > > +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.c > > @@ -0,0 +1,556 @@ > > +/** @file+ Implementation for a generic i801 SMBus > > +driver.++Copyright (c) > > 2016, Intel Corporation. All rights reserved.<BR>+SPDX-License-Identifier: > > BSD-2-Clause-Patent+++**/++#include "SMBusi801Dxe.h"+#include > > <Library/TimerLib.h>+#include <Library/PciLib.h>+#include > > <Library/IoLib.h>+#include <Library/DebugLib.h>+#include > > <Library/BaseMemoryLib.h>+#include > > <Library/UefiBootServicesTableLib.h>++EFI_HANDLE mDriverHandle = > > NULL;+UINT32 PciDevice = 0;++/* SMBus register offsets. */+#define > > SMBHSTSTAT 0x0+#define SMBHSTCTL 0x2+#define SMBHSTCMD > > 0x3+#define SMBXMITADD 0x4+#define SMBHSTDAT0 0x5+#define > > SMBHSTDAT1 0x6+#define SMBBLKDAT 0x7+#define SMBTRNSADD > > 0x9+#define SMBSLVDATA 0xa+#define SMLINK_PIN_CTL 0xe+#define > > SMBUS_PIN_CTL 0xf+#define SMBSLVCMD 0x11++/* I801 command > > constants */+#define I801_QUICK (0 << 2)+#define I801_BYTE (1 > > << 2)+#define I801_BYTE_DATA (2 << 2)+#define I801_WORD_DATA (3 > > << 2)+#define I801_PROCESS_CALL (4 << 2)+#define I801_BLOCK_DATA > > (5 << 2)+#define I801_I2C_BLOCK_DATA (6 << 2) /* ICH5 and later */++/* > > I801 Host Control register bits */+#define SMBHSTCNT_INTREN (1 << > > 0)+#define SMBHSTCNT_KILL (1 << 1)+#define SMBHSTCNT_LAST_BYTE > > (1 << 5)+#define SMBHSTCNT_START (1 << 6)+#define > > SMBHSTCNT_PEC_EN (1 << 7) /* ICH3 and later */++/* I801 Hosts Status > > register bits */+#define SMBHSTSTS_BYTE_DONE (1 << 7)+#define > > SMBHSTSTS_INUSE_STS (1 << 6)+#define SMBHSTSTS_SMBALERT_STS (1 > > << 5)+#define SMBHSTSTS_FAILED (1 << 4)+#define > > SMBHSTSTS_BUS_ERR (1 << 3)+#define SMBHSTSTS_DEV_ERR (1 << > > 2)+#define SMBHSTSTS_INTR (1 << 1)+#define SMBHSTSTS_HOST_BUSY > > (1 << 0)++/* For SMBXMITADD register. */+#define XMIT_WRITE(dev) > > (((dev) << 1) | 0)+#define XMIT_READ(dev) (((dev) << 1) | > > 1)++STATIC+UINT16+EFIAPI+SmbusGetSMBaseAddress (+ IN VOID+ )+{+ > > UINT16 Cmd;+ UINT32 Reg32;+ UINT16 IoBase;++ IoBase = 0;+ //+ > > // Test if I/O decoding is enabled+ //+ Cmd = PciRead16 (PciDevice + 0x4);+ if > > (!(Cmd & 1)) {+ goto CloseAndReturn;+ }++ //+ // Test if BAR0 is I/O bar > > and enabled+ //+ Reg32 = PciRead16 (PciDevice + 0x20);+ if > > (!(Reg32 & 1) > > || !(Reg32 & 0xfffc) || ((Reg32 & 0xfffc) == 0xfffc)) {+ goto > > CloseAndReturn;+ }++ IoBase = Reg32 & 0xfffc;++CloseAndReturn:+ > > return IoBase;+}++STATIC+EFI_STATUS+SmbusSetupCommand (+ IN UINT16 > > IoBase,+ IN UINT8 Ctrl,+ IN UINT8 Xmitadd+ )+{+ UINTN Loops = 10000;+ > > UINT8 host_busy;++ do {+ MicroSecondDelay (100);+ host_busy = > > IoRead8 (IoBase + SMBHSTSTAT) & SMBHSTSTS_HOST_BUSY;+ } while (-- > > Loops && host_busy);++ if (Loops == 0) {+ return EFI_TIMEOUT;+ }++ /* > > Clear any lingering errors, so the transaction will run. */+ > > IoWrite8 (IoBase + SMBHSTSTAT, IoRead8 (IoBase + SMBHSTSTAT));++ /* > > Set up transaction */+ > > /* Disable interrupts */+ IoWrite8 (IoBase + SMBHSTCTL, Ctrl);++ > > /* Set the device I'm talking to. */+ IoWrite8 (IoBase + > > SMBXMITADD, Xmitadd);++ return > > EFI_SUCCESS;+}++STATIC+EFI_STATUS+SmbusExecuteCommand (+ IN UINT16 > > IoBase+ )+{+ UINTN Loops = 10000;+ UINT8 Status;++ /* Start > > the command. */+ IoWrite8 (IoBase + SMBHSTCTL, IoRead8 (IoBase + > > SMBHSTCTL) | SMBHSTCNT_START);+ Status = IoRead8 (IoBase + > > SMBHSTSTAT);++ /* Poll for it to start. */+ do {+ MicroSecondDelay > > (100);++ /* If we poll too slow, we could miss HOST_BUSY flag+ * set and > > detect INTR or x_ERR flags instead here.+ */+ Status = IoRead8 (IoBase + > > SMBHSTSTAT);++ Status &= ~(SMBHSTSTS_SMBALERT_STS | > > SMBHSTSTS_INUSE_STS);+ } while (--Loops && Status == 0);++ if (Loops == 0) > > {+ return EFI_TIMEOUT;+ }++ return > > EFI_SUCCESS;+}++STATIC+BOOLEAN+SmbusHostCompleted (+ IN UINT8 > > Status+ )+{+ if (Status & SMBHSTSTS_HOST_BUSY) {+ return FALSE;+ }++ > > /* These status bits do not imply completion of transaction. */+ > > Status &= ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS | > > SMBHSTSTS_SMBALERT_STS);+ return Status != > > 0;+}++STATIC+EFI_STATUS+SmbusCompleteCommand (+ IN UINT16 > > IoBase+ )+{+ UINTN Loops = 10000;+ UINT8 Status;++ do {+ > > MicroSecondDelay (100);+ Status = IoRead8 (IoBase + SMBHSTSTAT);+ } > > while (--Loops && !SmbusHostCompleted (Status));++ if (Loops == 0) > > {+ return EFI_TIMEOUT;+ }++ /* These status bits do not imply > > errors. */+ Status &= ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS | > > SMBHSTSTS_SMBALERT_STS);++ if (Status == SMBHSTSTS_INTR) {+ return > > EFI_SUCCESS;+ }++ return > > EFI_NO_RESPONSE;+}++STATIC+EFI_STATUS+EFIAPI+SmbusProcessCallOper > > ation (+ IN CONST UINT16 IoBase,+ IN CONST > > EFI_SMBUS_HC_PROTOCOL *This,+ IN EFI_SMBUS_DEVICE_ADDRESS > > SlaveAddress,+ IN EFI_SMBUS_DEVICE_COMMAND Command,+ IN > > BOOLEAN PecCheck,+ IN OUT UINTN *Length,+ IN OUT > > VOID *Buffer+ )+{+ EFI_STATUS Status;+ UINT16 > > ResultBuffer;+ UINT16 AddrBuffer;++ if (!Buffer || !Length) {+ return > > RETURN_INVALID_PARAMETER;+ }++ if (*Length != 2) {+ return > > RETURN_INVALID_PARAMETER;+ }++ CopyMem (&AddrBuffer, Buffer, > > sizeof (AddrBuffer));++ /* Set up for process call */+ Status = > > SmbusSetupCommand (IoBase, I801_PROCESS_CALL, XMIT_WRITE > > (SlaveAddress.SmbusDeviceAddress));+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ /* cmd will only be send if I2C_EN is zero */+ > > IoWrite8 (IoBase > > + SMBHSTCMD, Command);++ IoWrite8 (IoBase + SMBHSTDAT0, AddrBuffer > > & 0x00ff);+ IoWrite8 (IoBase + SMBHSTDAT1, (AddrBuffer & 0xff00) >> > > 8);++ > > /* Start the command */+ Status = SmbusExecuteCommand (IoBase);+ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Poll for transaction > > completion */+ Status = SmbusCompleteCommand (IoBase);+ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Read results of transaction > > */+ ResultBuffer = IoRead8 (IoBase + SMBHSTDAT0);+ ResultBuffer > > |= > > (IoRead8 (IoBase + SMBHSTDAT1) << 8);++ CopyMem (Buffer, > > &ResultBuffer, sizeof (ResultBuffer));+ *Length = sizeof > > (ResultBuffer);++ return EFI_SUCCESS;+}++STATIC+EFI_STATUS+EFIAPI+SmbusReadOperation > > (+ IN CONST UINT16 IoBase,+ IN CONST > > EFI_SMBUS_HC_PROTOCOL *This,+ IN EFI_SMBUS_DEVICE_ADDRESS > > SlaveAddress,+ IN EFI_SMBUS_DEVICE_COMMAND Command,+ IN > > BOOLEAN PecCheck,+ IN OUT UINTN *Length,+ IN OUT > > VOID *Buffer+ )+{+ EFI_STATUS Status;+ UINT8 > > ResultBuffer;++ if (!Buffer || !Length) {+ return > > RETURN_INVALID_PARAMETER;+ }++ /* Set up for a byte data read. */+ > > Status = SmbusSetupCommand (IoBase, I801_BYTE_DATA, XMIT_READ > > (SlaveAddress.SmbusDeviceAddress));+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ IoWrite8 (IoBase + SMBHSTCMD, Command);++ IoWrite8 > > (IoBase + SMBHSTDAT0, 0);+ IoWrite8 (IoBase + SMBHSTDAT1, 0);++ /* > > Start the command */+ Status = SmbusExecuteCommand (IoBase);+ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Poll for transaction > > completion */+ Status = SmbusCompleteCommand (IoBase);+ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ /* Read results of transaction > > */+ ResultBuffer = IoRead8 (IoBase + SMBHSTDAT0);++ CopyMem > > (Buffer, &ResultBuffer, sizeof (ResultBuffer));+ *Length = sizeof > > (ResultBuffer);++ return EFI_SUCCESS;+}++STATIC+EFI_STATUS+EFIAPI+SmbusWriteOperation > > (+ IN CONST UINT16 IoBase,+ IN CONST > > EFI_SMBUS_HC_PROTOCOL *This,+ IN EFI_SMBUS_DEVICE_ADDRESS > > SlaveAddress,+ IN EFI_SMBUS_DEVICE_COMMAND Command,+ IN > > BOOLEAN PecCheck,+ IN OUT UINTN *Length,+ IN OUT > > VOID *Buffer+ )+{+ EFI_STATUS Status;+ UINT8 > > InputBuffer;++ if (!Buffer || !Length) {+ return > > RETURN_INVALID_PARAMETER;+ }++ if (*Length != 1) {+ return > > RETURN_INVALID_PARAMETER;+ }++ CopyMem (&InputBuffer, Buffer, > > sizeof (InputBuffer));++ /* Set up for a byte data read. */+ Status > > = SmbusSetupCommand (IoBase, I801_BYTE_DATA, XMIT_WRITE > > (SlaveAddress.SmbusDeviceAddress));+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ IoWrite8 (IoBase + SMBHSTCMD, Command);++ IoWrite8 > > (IoBase + SMBHSTDAT0, InputBuffer);++ /* Start the command */+ Status = > > SmbusExecuteCommand (IoBase);+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ /* Poll for transaction completion */+ Status = > > SmbusCompleteCommand (IoBase);+ if (EFI_ERROR (Status)) {+ return > > Status;+ }++ return > > EFI_SUCCESS;+}++STATIC+EFI_STATUS+EFIAPI+SmbusExecuteOperation (+ > > 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+ )+{+ UINT16 IoBase;++ IoBase = SmbusGetSMBaseAddress ();+ if > > (!IoBase) {+ return EFI_UNSUPPORTED;+ }++ if (Operation == > > EfiSmbusProcessCall) {+ return SmbusProcessCallOperation (+ > > IoBase,+ This,+ SlaveAddress,+ Command,+ > > PecCheck,+ Length,+ Buffer+ );+ } else if (Operation == > > EfiSmbusReadByte) {+ return SmbusReadOperation (+ IoBase,+ > > This,+ SlaveAddress,+ Command,+ PecCheck,+ > > Length,+ Buffer+ );+ } else if (Operation == EfiSmbusWriteByte) > > {+ return SmbusWriteOperation (+ IoBase,+ This,+ > > SlaveAddress,+ Command,+ PecCheck,+ Length,+ > > Buffer+ );+ }++ return > > EFI_UNSUPPORTED;+}++STATIC+EFI_STATUS+EFIAPI+SmbusHcProtocolArpD > > evice (+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,+ IN BOOLEAN > > ArpAll,+ IN EFI_SMBUS_UDID *SmbusUdid, OPTIONAL+ IN OUT > > EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL+ )+{+ return > > EFI_UNSUPPORTED;+}++STATIC+EFI_STATUS+EFIAPI+SmbusHcProtocolGetA > > rpMap (+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,+ IN OUT UINTN > > *Length,+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap+ )+{+ > > return > > EFI_UNSUPPORTED;+}++STATIC+EFI_STATUS+EFIAPI+SmbusHcProtocolNotif > > y (+ IN CONST EFI_SMBUS_HC_PROTOCOL *This,+ IN > > EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,+ IN UINTN > > Data,+ IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction+ )+{+ return > > EFI_UNSUPPORTED;+}++EFI_SMBUS_HC_PROTOCOL mSmbusProtocol = {+ > > SmbusExecuteOperation,+ SmbusHcProtocolArpDevice,+ > > SmbusHcProtocolGetArpMap,+ SmbusHcProtocolNotify+};++/**+ The > > Entry Point for SMBUS driver.++ It installs DriverBinding.++ @retval EFI_SUCCESS > > The entry point is executed successfully.+ @retval other Some error > > occurs when executing this entry > > point.++**/+EFI_STATUS+EFIAPI+InstallSmbusProtocol (+ IN EFI_HANDLE > > ImageHandle,+ IN EFI_SYSTEM_TABLE *SystemTable+ )+{+ EFI_STATUS > > Status;+ UINT16 IoBase;+ UINT8 Device;+ UINT8 Function;+ > > BOOLEAN BreakLoop;+ UINT8 BaseClass;+ UINT8 SubClass;++ > > BreakLoop = FALSE;+ Status = EFI_SUCCESS;++ //+ // Search for SMBus > > Controller within PCI Devices on root bus+ //+ for (Device = 0; Device <= > > PCI_MAX_DEVICE; Device++) {+ for (Function = 0; Function <= > > PCI_MAX_FUNC; Function++) {+ if (PciRead16 (PCI_LIB_ADDRESS (0, > > Device, Function, 0x00)) != 0x8086) {+ continue;+ }++ BaseClass = > > PciRead8 (PCI_LIB_ADDRESS (0, Device, Function, 0x0B));++ if (BaseClass > > == PCI_CLASS_SERIAL) {+ SubClass = PciRead8 (PCI_LIB_ADDRESS (0, > > Device, Function, 0xA));++ if (SubClass == PCI_CLASS_SERIAL_SMB) {+ > > BreakLoop = TRUE;+ PciDevice = PCI_LIB_ADDRESS (0, Device, Function, > > 0x00);+ break;+ }+ }+ }++ if (BreakLoop) {+ break;+ }+ }++ if > > (!BreakLoop) {+ DEBUG ((EFI_D_INFO, "No PCI SMBUS controller > > found.\n"));+ return EFI_UNSUPPORTED;+ }++ DEBUG ((EFI_D_INFO, "PCI > > Device found on 0-%x-%x\n", Device, Function));++ IoBase = > > SmbusGetSMBaseAddress ();+ if (!IoBase) {+ return > > EFI_UNSUPPORTED;+ }++ DEBUG ((+ EFI_D_INFO,+ "%a: Detected i801 > > SMBus controller with SMBASE 0x%x\n",+ __FUNCTION__,+ > > IoBase+ ));++ Status = gBS->InstallProtocolInterface (+ > > &mDriverHandle,+ &gEfiSmbusHcProtocolGuid,+ > > EFI_NATIVE_INTERFACE,+ &mSmbusProtocol+ );++ if > > (EFI_ERROR (Status)) {+ return Status;+ }++ return EFI_SUCCESS;+}diff --git > > a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > > b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > > new file mode 100644 > > index 0000000000..e88823da31 > > --- /dev/null > > +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.h > > @@ -0,0 +1,17 @@ > > +/** @file+ Header file for a generic i801 SMBUS driver.++Copyright > > +(c) 2016, Intel Corporation. All rights > > +reserved.<BR>+SPDX-License-Identifier: > > +BSD-2-Clause-Patent+++**/+#ifndef _PCI_PLATFORM_DXE_H_+#define > > +_PCI_PLATFORM_DXE_H_+#include <PiDxe.h>++#include > > +<IndustryStandard/Pci.h>+#include > > +<IndustryStandard/Pci22.h>+#include > > +<Protocol/SmbusHc.h>++#endifdiff --git > > +a/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > > +b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > > new file mode 100644 > > index 0000000000..7d13c446ef > > --- /dev/null > > +++ b/UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf > > @@ -0,0 +1,45 @@ > > +## @file+# This driver produces gEfiSmbusHcProtocolGuid protocol to > > +load > > access SMBUS devices+#+# Copyright (c) 2020, 9elements Agency > > GmbH+#+# SPDX-License-Identifier: BSD-2-Clause- > > Patent+#+#+##++[Defines]+ INF_VERSION = 0x00010005+ > > BASE_NAME = SMBusi801Dxe+ FILE_GUID = 390208DA- > > 8E6F-4957-90D6-421737FEA9BF+ MODULE_TYPE = DXE_DRIVER+ > > VERSION_STRING = 1.0+ ENTRY_POINT = > > InstallSmbusProtocol++#+# The following information is for reference > > InstallSmbusProtocol++only > > and not required by the build tools.+#+# VALID_ARCHITECTURES = IA32 > > X64+#++[Sources.common]+ SMBusi801Dxe.h+ > > SMBusi801Dxe.c++[Packages]+ MdePkg/MdePkg.dec+ > > MdeModulePkg/MdeModulePkg.dec++[LibraryClasses]+ > > UefiDriverEntryPoint+ DebugLib+ IoLib+ UefiLib+ TimerLib+ > > PciLib++[Protocols]+ gEfiSmbusHcProtocolGuid ## > > PRODUCES++[Depex]+ TRUEdiff --git > > PRODUCES++a/UefiPayloadPkg/UefiPayloadPkg.dsc > > b/UefiPayloadPkg/UefiPayloadPkg.dsc > > index 1ce96a51c1..54543b7623 100644 > > --- a/UefiPayloadPkg/UefiPayloadPkg.dsc > > +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc > > @@ -290,6 +290,7 @@ > > !if $(PERFORMANCE_MEASUREMENT_ENABLE) > > PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCore > > PerformanceLib.inf !endif+ > > SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf > > [LibraryClasses.common.DXE_DRIVER] > > PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf@@ -304,6 +305,7 @@ > > !if $(PERFORMANCE_MEASUREMENT_ENABLE) > > PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerforma > > nceLib.inf !endif+ > > SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf > > [LibraryClasses.common.DXE_RUNTIME_DRIVER] > > PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf@@ -657,6 +659,11 @@ > > !endif MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf + #+ # > > SMBUS Support+ #+ UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf+ # # > > Console Support #diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf > > b/UefiPayloadPkg/UefiPayloadPkg.fdf > > index c7b04978ad..8861d29162 100644 > > --- a/UefiPayloadPkg/UefiPayloadPkg.fdf > > +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf > > @@ -178,6 +178,11 @@ INF > > MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf > > !endif INF MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf +#+# > > SMBUS Support+#+INF UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf+ # # > > Console Support #-- > > 2.32.0 > > > > > > > > -=-=-=-=-=-= > > Groups.io Links: You receive all messages sent to this group. > > View/Reply Online (#86730): > > https://edk2.groups.io/g/devel/message/86730 > > Mute This Topic: https://groups.io/mt/89214991/1773972 > > Group Owner: devel+owner@edk2.groups.io > > Unsubscribe: https://edk2.groups.io/g/devel/unsub > > [maurice.ma@intel.com] -=-=-=-=-=-= > > > > > > > > ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-02-25 1:25 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-02-17 17:51 [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE Sean Rhodes 2022-02-17 17:51 ` [PATCH 2/2] UefipayloadPkg: Add SmbusConfigLoaderDxe Sean Rhodes 2022-02-17 18:24 ` [edk2-devel] [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE Ma, Maurice 2022-02-24 10:46 ` Patrick Rudolph 2022-02-24 15:53 ` Guo Dong 2022-02-25 1:25 ` Guo Dong
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox