Newer
Older
AMI-Aptio-BIOS-Reversed / PostScreenInfo / OemUpdateFru.c
@Ajax Dong Ajax Dong 2 days ago 7 KB Init
/** @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;
}