Files
OpenBMC/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReader.hpp
T
Your Name 0cc0c96893 dimm-spd-reader: fix PMIC type detection from SPD
Add support for identifying PMIC unknown state as 0xFF.

Update PMIC SPD detection flow to read SPD registers 0x200, 0x204, and 0x208. Check bit7 to determine whether the PMIC is installed, and use SPD bit[3:0] as the PMIC type.

Also update the IPMI error handling path to return completion code 0x07 for command 0x6c when PMIC detection fails or the PMIC type is unknown.
2026-04-27 10:01:06 +08:00

105 lines
3.4 KiB
C++
Executable File

#pragma once
#include <boost/asio/steady_timer.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/container/flat_map.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/bus/match.hpp>
#include <string>
#include <iostream>
#define MAX_CPU_ID 2
#define MAX_DIMM_RANK 12
#define STATUS_TEMP_NUM 3
#define STATUS_PMIC_RAIL_NUM 6
#define STATUS_REG_NUM 8
#define STATUS_ERROR_NUM 1
extern std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_temp_inf;
extern std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_voltage_inf;
extern std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_current_inf;
extern std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_power_inf;
extern std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_statusReg_inf;
extern std::unordered_map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>> dimm_errCode_inf;
enum FieldType {
VOLTAGE,
CURRENT,
POWER,
TEMP,
STATUS,
ERROR
};
struct DimmData
{
uint8_t reg[STATUS_REG_NUM];
uint8_t error[STATUS_ERROR_NUM];
double voltage[STATUS_PMIC_RAIL_NUM];
double current[STATUS_PMIC_RAIL_NUM];
double power[STATUS_PMIC_RAIL_NUM];
double temp[STATUS_TEMP_NUM];
};
struct DimmI3CAddr
{
std::string spdAddr;
std::string pmicAddr;
};
enum PMICType {
PMIC5000 = 0,
PMIC5010,
PMIC5100,
PMIC5020,
PMIC5120,
PMIC5200,
PMIC5030,
Unknown = 0xFF
};
struct DIMMSpdReader : std::enable_shared_from_this<DIMMSpdReader>
{
DIMMSpdReader(boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
const float pollRate) : sensorPollMs(static_cast<unsigned int>(pollRate * 1000)),
objectServer(objectServer), waitTimer(io) {};
~DIMMSpdReader()
{
waitTimer.cancel();
};
void init();
void startRead();
void readDimmInfo();
int getDIMMRegsTemp(uint8_t cpuid, uint8_t rank, DimmData& dimmData);
int getDIMMRegsVol(uint8_t cpuid, uint8_t rank, DimmData& dimmData);
int getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& dimmData);
void updateDbus();
void updateToDimmInfoFile();
void setupMatches(sdbusplus::bus_t&);
void dimmI3cSwitchMatcher( std::vector<sdbusplus::bus::match_t>& matches,
sdbusplus::bus_t& connection, std::function<void(bool)>&& onMatch);
void getdimmI3cSwitchState(const std::shared_ptr<sdbusplus::asio::connection>& conn, size_t retries = 2);
int getPmicType(uint8_t cpuid, uint8_t rank);
int getPmicStatusRegs(uint8_t cpuid, uint8_t rank, DimmData& dimmData);
int setADCAccuracyStepSize(uint8_t cpuid, uint8_t rank, DimmData& dimmData, uint8_t R32);
int checkADCAccuracyStepSize(uint8_t cpuid, uint8_t rank, DimmData& dimmData, const uint8_t* ThresholdData);
private:
std::vector<sdbusplus::bus::match_t> matches;
unsigned int sensorPollMs;
sdbusplus::asio::object_server& objectServer;
boost::asio::steady_timer waitTimer;
PMICType pmicType[MAX_CPU_ID][MAX_DIMM_RANK];
bool gotType[MAX_CPU_ID][MAX_DIMM_RANK];
bool twoByteMode[MAX_CPU_ID][MAX_DIMM_RANK];
int adcDelay[MAX_CPU_ID][MAX_DIMM_RANK];
uint16_t regCounter;
uint16_t pmicCounter;
};