From: "Sean Rhodes" <sean@starlabs.systems>
To: devel@edk2.groups.io
Cc: guo.dong@intel.com,
Patrick Rudolph <patrick.rudolph@9elements.com>,
Ray Ni <ray.ni@intel.com>, Maurice Ma <maurice.ma@intel.com>,
Benjamin You <benjamin.you@intel.com>
Subject: [PATCH 2/2] UefipayloadPkg: Add SmbusConfigLoaderDxe
Date: Thu, 17 Feb 2022 17:51:27 +0000 [thread overview]
Message-ID: <1a141c15226d8ffbecfcdbe5b51d34a1f4b8887d.1645120287.git.sean@starlabs.systems> (raw)
In-Reply-To: <c8070771e19c158e3512319a33ae68bf32beab36.1645120287.git.sean@starlabs.systems>
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
next prev parent reply other threads:[~2022-02-17 17:51 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-17 17:51 [PATCH 1/2] UefiPayloadPkg: Add i801 SMBus controller DXE Sean Rhodes
2022-02-17 17:51 ` Sean Rhodes [this message]
2022-02-17 18:24 ` [edk2-devel] " Ma, Maurice
2022-02-24 10:46 ` Patrick Rudolph
2022-02-24 15:53 ` Guo Dong
2022-02-25 1:25 ` Guo Dong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1a141c15226d8ffbecfcdbe5b51d34a1f4b8887d.1645120287.git.sean@starlabs.systems \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox