public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [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