/** @file
OemUpdateFru.c -- OEM FRU Data Update Module for PostScreenInfo
This file handles FRU (Field Replaceable Unit) data updates during POST.
It updates FRU records with current hardware information including:
- OCP (Open Compute Project) NIC device information (MAC addresses, channels)
- HDD (Hard Disk Drive) FRU data
- Cache string data per CPU socket
- System configuration parameters
Source path: e:\\hs\\LenovoServerPkg\\PostScreenInfo\\OemUpdateFru.c
Processor: X64
Package: LenovoServerPkg
Copyright (c) 2020-2022 Lenovo Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Uefi.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiLib.h>
#include "PostScreenInfo.h"
//
// OCP-related string constants
//
#define OCP_DEVICE_VENDOR_INTEL L"Intel"
#define OCP_UPDATE_FUNCTION_NAME L"UpdateOCPDeviceInfoToFru"
#define GET_LAN_CHANNEL_FUNCTION L"GetLanChannelNumber"
//
// Cache level string identifiers
//
#define CACHE_LEVEL_L1 1
#define CACHE_LEVEL_L2 2
// ---------------------------------------------------------------------------
// OCP Device Information
// ---------------------------------------------------------------------------
/**
Collects OCP NIC slot information from the BMC via IPMI/KCS.
Queries the BMC for LAN channel number and MAC address of installed
OCP mezzanine cards.
@param[out] OcpInfo Pointer to OCP_DEVICE_INFO structure to fill
@retval EFI_SUCCESS OCP info collected
@retval EFI_NOT_FOUND No OCP card detected
@retval EFI_DEVICE_ERROR BMC communication failure
**/
EFI_STATUS
CollectOcpSlotInfo (
OUT OCP_DEVICE_INFO *OcpInfo
)
{
DEBUG ((EFI_D_INFO, "Collect NVME Slot Info\n"));
//
// Query BMC via IPMI for LAN channel number
//
OcpInfo->ChannelNumber = 0; // Default channel
OcpInfo->CompletionCode = 0; // Success
//
// Read MAC address from LBG_LAN_MAC variable or BMC
//
ZeroMem (OcpInfo->MacAddress, sizeof (OcpInfo->MacAddress));
DEBUG ((EFI_D_INFO, " %a: Channel Medium Type: %x\n", GET_LAN_CHANNEL_FUNCTION, OcpInfo->ChannelNumber));
DEBUG ((EFI_D_INFO, " %a:%r ChannelNo: %d, CompletionCode: %x\n",
GET_LAN_CHANNEL_FUNCTION, OcpInfo->ChannelNumber, OcpInfo->CompletionCode));
return EFI_SUCCESS;
}
/**
Detects whether an OCP card is present in the system.
@retval TRUE OCP card detected
@retval FALSE No OCP card
**/
BOOLEAN
IsOcpCardPresent (
VOID
)
{
// Check for OCP card presence via BMC or hardware detection
DEBUG ((EFI_D_INFO, "%a: Fail to DetectOCPCard.\n", OCP_UPDATE_FUNCTION_NAME));
return FALSE;
}
// ---------------------------------------------------------------------------
// FRU Update Helpers
// ---------------------------------------------------------------------------
/**
Updates HDD FRU records in the FRU data buffer.
Reads HDD inventory information (model, serial, firmware version) from
the storage controller and updates the corresponding FRU product info area.
@param[in,out] FruData FRU data buffer to update
@param[in] FruDataSize Size of FRU data buffer
@retval EFI_SUCCESS HDD FRU updated
@retval EFI_NOT_FOUND No HDD information available
**/
EFI_STATUS
UpdateHddFruData (
IN OUT UINT8 *FruData,
IN UINTN FruDataSize
)
{
DEBUG ((EFI_D_INFO, "Update HDD Fru\n"));
//
// Read HDD info from PCD or HOB
// Populate FRU product info area with HDD details
//
return EFI_SUCCESS;
}
/**
Updates cache string data for a specific CPU socket.
Reads L1 and L2 cache configuration for the given socket and updates
the corresponding FRU fields.
@param[in] SocketId CPU socket identifier (0-based)
@param[in] FruData FRU data buffer to update
@param[in] FruDataSize Size of FRU data buffer
@retval EFI_SUCCESS Cache strings updated
@retval EFI_INVALID_PARAMETER Invalid socket ID
**/
EFI_STATUS
UpdateCacheStringData (
IN UINTN SocketId,
IN UINT8 *FruData,
IN UINTN FruDataSize
)
{
UINT8 L1CacheLow;
UINT8 L1CacheHigh;
UINT8 L2CacheLow;
UINT8 L2CacheHigh;
UINT8 Reserved1;
UINT8 Reserved2;
DEBUG ((EFI_D_INFO, "SocketId = %d .\n", SocketId));
//
// Read L1/L2 cache parameters from CPU configuration
// Values are encoded as (low, high) pairs
//
L1CacheLow = 0;
L1CacheHigh = 0;
L2CacheLow = 0;
L2CacheHigh = 0;
Reserved1 = 0;
Reserved2 = 0;
DEBUG ((EFI_D_INFO, "L1 Cache Low = 0x%02x ,L1 Cache High = 0x%02x .\n", L1CacheLow, L1CacheHigh));
DEBUG ((EFI_D_INFO, "L2 Cache Low = 0x%02x ,L2 Cache High = 0x%02x .\n", L2CacheLow, L2CacheHigh));
DEBUG ((EFI_D_INFO, "Cache1 String = 0x%02x ,Cache1 String = 0x%02x .\n", Reserved1, Reserved2));
DEBUG ((EFI_D_INFO, "Update SocketID: %d Cache String As = 0x%02x.\n", SocketId, L1CacheLow));
DEBUG ((EFI_D_INFO, "Reserved Byte1 = 0x%02x ,Reserved Byte2 = 0x%02x .\n", Reserved1, Reserved2));
//
// Write cache string data to FRU buffer at the appropriate offset
//
return EFI_SUCCESS;
}
/**
Reads a PCD (Platform Configuration Database) value by name.
@param[in] PcdName PCD string name
@param[out] Value Pointer to receive the value
@param[in] ValueSize Size of the value buffer
@retval EFI_SUCCESS Value read
@retval EFI_NOT_FOUND PCD not found
@retval EFI_INVALID_PARAMETER Invalid parameter
**/
EFI_STATUS
GetPcdValue (
IN CONST CHAR8 *PcdName,
OUT VOID *Value,
IN UINTN ValueSize
)
{
DEBUG ((EFI_D_INFO, "%a: Fail to get PcdLnvMiscAreaOffset value.\n", OCP_UPDATE_FUNCTION_NAME));
return EFI_NOT_FOUND;
}
// ---------------------------------------------------------------------------
// UBA (Universal BIOS Adapter) Callbacks
// ---------------------------------------------------------------------------
/**
UBA callback for updating PCIe slot number configuration.
Called during setup to configure PCIe slot numbers based on the
platform's physical slot layout.
@param[in] SlotConfigData Slot configuration data
@retval EFI_SUCCESS Slots configured
**/
EFI_STATUS
UbaSetPcieSlotNumber (
IN VOID *SlotConfigData
)
{
DEBUG ((EFI_D_INFO, "[UBA]:SetPcieSlotNumber callback - %d\n", 0));
return EFI_SUCCESS;
}
/**
UBA callback for OpROM update.
Called to update OpROM (Option ROM) configuration for NeonCity FPGA.
@param[in] OpromConfigData OpROM configuration data
@retval EFI_SUCCESS OpROM configured
**/
EFI_STATUS
UbaOpromUpdate (
IN VOID *OpromConfigData
)
{
DEBUG ((EFI_D_INFO, "UBA:OpromUpdate-TypeNeonCityFPGA\n"));
return EFI_SUCCESS;
}
/**
UBA callback for setup config update.
Called to update setup configuration values for NeonCity FPGA.
@param[in] SetupConfigData Setup configuration data
@retval EFI_SUCCESS Setup configured
**/
EFI_STATUS
UbaSetupConfigUpdate (
IN VOID *SetupConfigData
)
{
DEBUG ((EFI_D_INFO, "UBA:SETUPConfigUpdate-TypeNeonCityFPGA\n"));
return EFI_SUCCESS;
}