diff --git a/0001-LUXSHARE_2026041701.patch b/0001-LUXSHARE_2026041701.patch new file mode 100644 index 00000000..409a8940 --- /dev/null +++ b/0001-LUXSHARE_2026041701.patch @@ -0,0 +1,425 @@ +From 182a0516acfeffabf6f2ec863d078d3ef72b0265 Mon Sep 17 00:00:00 2001 +From: Your Name +Date: Thu, 23 Apr 2026 17:48:19 +0800 +Subject: [PATCH] LUXSHARE_2026041701 + +--- + .../dimm/dimm-spd-reader/dimmSpdReader.cpp | 281 ++++++++++++++---- + 1 file changed, 229 insertions(+), 52 deletions(-) + +diff --git a/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReader.cpp b/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReader.cpp +index cd730713..7438cbd3 100755 +--- a/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReader.cpp ++++ b/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReader.cpp +@@ -346,7 +346,7 @@ static int i3cWriteRead(std::string& i3cDev, uint8_t wBuf[], uint16_t wLen, + std::cout << "i3c data to write:" << std::endl; + for(int i=0; isecond.error)); + } else { + std::cout << "Invalid size for error array!" << std::endl; + } break; - default: std::cout << "Unknown field type!" << std::endl; break; @@ -456,10 +462,10 @@ int DIMMSpdReader::getPmicType(uint8_t cpuid, uint8_t rank) uint8_t index[] = {0xc8, 0xcc, 0xd0}; uint16_t wLen = 2; -//Jim debug uint8_t wrBuf[] = {0, 0}; - uint8_t wrBuf[] = {0, 0, 0}; //Jim debug + uint8_t wrBuf[] = {0, 0, 0}; uint8_t rdBuf[] = {0}; uint16_t rLen = 1; + uint8_t typeVal = 0; int spd = NUM_TO_SPD(rank); const uint8_t memReg = 0x80; @@ -484,12 +490,16 @@ int DIMMSpdReader::getPmicType(uint8_t cpuid, uint8_t rank) { return -1; } - - if((rdBuf[0] & 0xf) == 0x6) - { - pmicType[cpuid][rank] = PMIC5030; - break; - } + + //SPD 0xc8, 0xcc, 0xd0 is Device Types + //Check DeviceType[7] = 1 is Installed + if((rdBuf[0] & 0x80) != 0) + { + //read DeviceType Bits[3:0] + typeVal = rdBuf[0] & 0xf; + pmicType[cpuid][rank] = (typeVal <= PMIC5030) ? static_cast(typeVal) : Unknown; + break; + } } if(pmicType[cpuid][rank] == PMIC5030) @@ -499,8 +509,6 @@ int DIMMSpdReader::getPmicType(uint8_t cpuid, uint8_t rank) gotType[cpuid][rank] = true; -//Jim debug+S - //---------------------------------------------------------------------------- //A. 1B Write R30 = 0x84 // 1 byte format, set 2 byte mode //B. 2B Read R0030 //check 2 byte mode @@ -516,7 +524,7 @@ int DIMMSpdReader::getPmicType(uint8_t cpuid, uint8_t rank) int pmic = NUM_TO_PMIC(rank); std::string i3cPmicName = I3C_ADDR(cpuid) + to_hex(pmic); - + if constexpr (debug) { std::cout << "is PMIC5030"<< std::endl; @@ -561,8 +569,8 @@ int DIMMSpdReader::getPmicType(uint8_t cpuid, uint8_t rank) if constexpr (debug) { std::cout << "Is 2 Byte mode" << std::endl; - } - } + } + } // It was originally 2 bytes mode else { @@ -571,7 +579,7 @@ int DIMMSpdReader::getPmicType(uint8_t cpuid, uint8_t rank) wLen = 3; rLen = 0; ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen); - + std::this_thread::sleep_for(std::chrono::milliseconds(9)); //C2-2. 2B Read R30 = 0x84 wrBuf[0] = 0x30; wrBuf[1] = 0x00; @@ -592,8 +600,9 @@ int DIMMSpdReader::getPmicType(uint8_t cpuid, uint8_t rank) } } + + -//Jim debug+E if constexpr (debug) { std::cout << "pmicType[" << (int)cpuid << "][" << (int)rank << "] = "<< (int)pmicType[cpuid][rank] << std::endl; @@ -736,10 +745,10 @@ int DIMMSpdReader::getDIMMRegsVol(uint8_t cpuid, uint8_t rank, DimmData& dimmDat int index = (pmicType[cpuid][rank] == PMIC5030) ? 6 : 4; for(int i=0; i= MAX_CPU_ID || rank >= MAX_DIMM_RANK) return ret; + + if constexpr (debug) + { + std::cout << "Start to check ADC Accuracy Step Size."<< std::endl; + } + + uint16_t wLen; + uint16_t rLen; + uint8_t rdBuf[] = {0}; + uint8_t wrBuf[3] = {0, 0, 0}; + uint16_t ThresholdSel[6] = {0x1C, 0x1D, 0x1E, 0x1F, 0x11A, 0x11B}; //OUTPUT_HIGH_CURRENT_CONSUMPTION_WARNING_THRESHOLD + + int pmic = NUM_TO_PMIC(rank); + std::string i3cPmicName = I3C_ADDR(cpuid) + to_hex(pmic); + + // 1. Read R32 + rLen = 1; + wLen = 2; + wrBuf[0] = 0x32; //address_Low + wrBuf[1] = 0; //address_High + ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen); + if (ret < 0) + { + return -1; + } + if((rdBuf[0] & 0x3) != 1) + { + dimmData.error[0] |= 1; + } + + // 2. Read ThresholdSel {0x1C, 0x1D, 0x1E, 0x1F, 0x11A, 0x11B} + rLen = 1; + wLen = 2; + for(int i=0; i<6; i++) { + wrBuf[0] = static_cast(ThresholdSel[i] & 0xFF); //address_Low + wrBuf[1] = static_cast((ThresholdSel[i]>>8) & 0xFF); //address_High + ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen); + if (ret < 0) + { + return -1; + } + if(rdBuf[0] != TargetData[i]) + { + dimmData.error[0] |= 1<<(i+1); + } + } + return ret; +} + +int DIMMSpdReader::setADCAccuracyStepSize(uint8_t cpuid, uint8_t rank, DimmData& dimmData, uint8_t R32) +{ + int ret = -1; + if(cpuid >= MAX_CPU_ID || rank >= MAX_DIMM_RANK) return ret; + + + if constexpr (debug) + { + std::cout << "Start to set Pmic5030 ADC Accuracy Step Size."<< std::endl; + } + + uint16_t wLen; + uint16_t rLen; + uint8_t rdBuf[] = {0}; + uint8_t wrBuf[3] = {0, 0, 0}; + uint16_t ThresholdSel[6] = {0x1C, 0x1D, 0x1E, 0x1F, 0x11A, 0x11B}; //OUTPUT_HIGH_CURRENT_CONSUMPTION_WARNING_THRESHOLD + uint8_t ThresholdData[6] = {0, 0, 0, 0, 0, 0}; + uint8_t TargetData[6] = {0, 0, 0, 0, 0, 0}; + uint8_t adcAcc[] = {0x32, 0, 0}; + uint32_t calcData = 0; + constexpr int PMIC_CHANNEL_SWD_INDEX = 3; + constexpr uint8_t PMIC_MAX_CUR_7500MA_REG_VAL = 0xF0; // SWA, SWB, SWC, SWE, SWF + constexpr uint8_t PMIC_MAX_CUR_5000MA_REG_VAL = 0xA0; // SWD + + int pmic = NUM_TO_PMIC(rank); + std::string i3cPmicName = I3C_ADDR(cpuid) + to_hex(pmic); + + // 1. Read ThresholdSel {0x1C, 0x1D, 0x1E, 0x1F, 0x11A, 0x11B} + rLen = 1; + wLen = 2; + for(int i=0; i<6; i++) { + wrBuf[0] = static_cast(ThresholdSel[i] & 0xFF); //address_Low + wrBuf[1] = static_cast((ThresholdSel[i]>>8) & 0xFF); //address_High + ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, &ThresholdData[i], rLen); + if (ret < 0) + { + return -1; + } + } + + // 2. Write R32[1:0] = 01b + adcAcc[2] = (R32&0xFC)|0x1; + wLen = 3; + rLen = 0; + ret = i3cWriteRead(i3cPmicName, adcAcc, wLen, rdBuf, rLen); + if (ret < 0) + { + //std::cerr << " read word data failed. \n"; + return -1; + } + + // 3. Write ThresholdData + for(int i=0; i<6; i++) { + rLen = 0; + wLen = 3; + wrBuf[0] = static_cast(ThresholdSel[i] & 0xFF); //address_Low + wrBuf[1] = static_cast((ThresholdSel[i]>>8) & 0xFF); //address_High + + //data + calcData = (ThresholdData[i] * 4); // 125/31.25 = 4 + + if (i == PMIC_CHANNEL_SWD_INDEX) { + // SWD Maximum current is 5000mA + TargetData[i] = (calcData > PMIC_MAX_CUR_5000MA_REG_VAL) ? PMIC_MAX_CUR_5000MA_REG_VAL : static_cast(calcData); + } + else { + // SWA, SWB, SWC, SWE, SWF Maximum current is 7500mA + TargetData[i] = (calcData > PMIC_MAX_CUR_7500MA_REG_VAL) ? PMIC_MAX_CUR_7500MA_REG_VAL : static_cast(calcData); + } + wrBuf[2] = TargetData[i]; + + ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen); + if (ret < 0) + { + return -1; + } + } + + ret = checkADCAccuracyStepSize(cpuid, rank, dimmData, TargetData); + if (ret < 0) + { + //std::cerr << " set ADCAccuracy Step Size failed. \n"; + return -1; + } + + return ret; +} + int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& dimmData) { @@ -828,8 +976,7 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d uint8_t adcSelect[] = {0x1b, 0, 0}; uint16_t curOut[8]; uint8_t temp[8]; - uint8_t rdBuf[] = {0, 0, 0, 0, 0, 0, 0, 0}; //Jim debug, For Renesas requirements, I3C command: Continuously read R100~R107 -//Jim debug uint8_t rdBuf[] = {0}; + uint8_t rdBuf[] = {0, 0, 0, 0, 0, 0, 0, 0}; //For Renesas requirements, I3C command: Continuously read R100~R107 uint8_t wrBuf[] = {0, 0}; int pmic = NUM_TO_PMIC(rank); @@ -846,6 +993,20 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d return -1; } if((rdBuf[0] & 0x3) == 1) accStep31 = true; + else + { + if(twoByteMode[cpuid][rank]) + { + //if two Byte Mode + PMIC5030, R32[1:0] set 01b + ret = setADCAccuracyStepSize(cpuid, rank, dimmData, rdBuf[0]); + accStep31 = true; + if (ret < 0) + { + //std::cerr << " set ADCAccuracy Step Size failed. \n"; + return -1; + } + } + } if constexpr (debug) { std::cout << "accStep31: " << (int)accStep31 << std::endl; @@ -886,7 +1047,7 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d adcSelect[1] = rdBuf[0] & 0xbf; //Read current wLen = 2; } - rLen = 0; //Jim debug, For Renesas requirements, I3C write commands cannot be directly read; reading requires a separate I3C command. + rLen = 0; //For Renesas requirements, I3C write commands cannot be directly read; reading requires a separate I3C command. ret = i3cWriteRead(i3cPmicName, adcSelect, wLen, rdBuf, rLen); if (ret < 0) { @@ -916,13 +1077,6 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d { return -1; } - else - { - for(int i=0; i<6; i++) - { - dimmData.current[i] = calStep31CurPower(i, temp); - } - } } ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen); @@ -963,10 +1117,10 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d } dimmData.current[i] = rdBuf[0] * 125.0 / 1000.0; - + } } - + //start to read power if(twoByteMode[cpuid][rank]) @@ -979,7 +1133,7 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d adcSelect[1] |= 0x40; wLen = 2; } - rLen = 0; //Jim debug, For Renesas requirements, I3C write commands cannot be directly read; reading requires a separate I3C command. + rLen = 0; //For Renesas requirements, I3C write commands cannot be directly read; reading requires a separate I3C command. ret = i3cWriteRead(i3cPmicName, adcSelect, wLen, rdBuf, rLen); if (ret < 0) { @@ -1009,13 +1163,6 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d { return -1; } - else - { - for(int i=0; i<6; i++) - { - dimmData.current[i] = calStep31CurPower(i, temp); - } - } } ret = i3cWriteRead(i3cPmicName, wrBuf, wLen, rdBuf, rLen); @@ -1026,7 +1173,7 @@ int DIMMSpdReader::getDIMMRegsCurAndPow(uint8_t cpuid, uint8_t rank, DimmData& d for(int i=0; i::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}, @@ -1113,7 +1261,7 @@ void DIMMSpdReader::init() dimmDataTable.insert_or_assign(dimmName, std::move(dData)); - pmicType[cpuid][i] = PMIC5010; + pmicType[cpuid][i] = Unknown; gotType[cpuid][i] = false; twoByteMode[cpuid][i] = false; } @@ -1131,21 +1279,19 @@ void DIMMSpdReader::readDimmInfo() for(int cpuid=0; cpuid::quiet_NaN(), std::numeric_limits::quiet_NaN(), - std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), - std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}, - {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), - std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), - std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}, - {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), - std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), - std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}, - {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), - std::numeric_limits::quiet_NaN()}}; - std::string dimmName = "DIMM_CPU" + std::string(1, '0' + cpuid) + "_" + std::string(1, 'A' + i); + DimmData dData = dimmDataTable[dimmName]; + for (int j = 0; j < STATUS_TEMP_NUM; j++) { + dData.temp[j] = std::numeric_limits::quiet_NaN(); + } + for (int j = 0; j < STATUS_PMIC_RAIL_NUM; j++) { + dData.voltage[j] = std::numeric_limits::quiet_NaN(); + dData.current[j] = std::numeric_limits::quiet_NaN(); + dData.power[j] = std::numeric_limits::quiet_NaN(); + } + for (int j = 0; j < STATUS_REG_NUM; j++) { + dData.reg[j] = 0; + } int index = cpuid * 4 + i / 3; if(index != lastIndex) { @@ -1211,6 +1357,7 @@ void DIMMSpdReader::readDimmInfo() updateField(dimmName, CURRENT, dData.current, STATUS_PMIC_RAIL_NUM); updateField(dimmName, POWER, dData.power, STATUS_PMIC_RAIL_NUM); + updateField(dimmName, ERROR, dData.error, STATUS_ERROR_NUM); } #endif } @@ -1266,6 +1413,11 @@ void DIMMSpdReader::updateDbus() dimm_statusReg_inf[data.first]->set_property("0x0a", data.second.reg[6]); dimm_statusReg_inf[data.first]->set_property("0x0b", data.second.reg[7]); } + + if(dimm_errCode_inf.find(data.first) != dimm_errCode_inf.end()) { + dimm_errCode_inf[data.first]->set_property("0x32", data.second.error[0]); + } + } } @@ -1320,6 +1472,9 @@ void DIMMSpdReader::updateToDimmInfoFile() js[data.first]["Status_Reg"]["0x09"] = data.second.reg[5]; js[data.first]["Status_Reg"]["0x0a"] = data.second.reg[6]; js[data.first]["Status_Reg"]["0x0b"] = data.second.reg[7]; + + //update error code + js[data.first]["Error_Code"]["0x32"] = data.second.error[0]; } jsonOutputFile << js.dump(4); @@ -1355,7 +1510,7 @@ void DIMMSpdReader::setupMatches(sdbusplus::bus_t& connection) if (ret != 0) { std::cout << "Failed to modprobe dw-i3c-master module" << std::endl; return; - } + } std::this_thread::sleep_for(std::chrono::milliseconds(500)); //switch dimm i3c to bmc std::cout << "start to Read" << std::endl; diff --git a/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReader.hpp b/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReader.hpp index b70ea48d..07c75753 100755 --- a/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReader.hpp +++ b/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReader.hpp @@ -16,28 +16,33 @@ #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> dimm_temp_inf; extern std::unordered_map> dimm_voltage_inf; extern std::unordered_map> dimm_current_inf; extern std::unordered_map> dimm_power_inf; extern std::unordered_map> dimm_statusReg_inf; +extern std::unordered_map> dimm_errCode_inf; enum FieldType { VOLTAGE, CURRENT, POWER, TEMP, - STATUS + 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 @@ -53,7 +58,8 @@ enum PMICType { PMIC5020, PMIC5120, PMIC5200, - PMIC5030 + PMIC5030, + Unknown = 0xFF }; struct DIMMSpdReader : std::enable_shared_from_this @@ -81,6 +87,8 @@ struct DIMMSpdReader : std::enable_shared_from_this void getdimmI3cSwitchState(const std::shared_ptr& 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 matches; diff --git a/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReaderMain.cpp b/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReaderMain.cpp index f4efaa44..d931216b 100755 --- a/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReaderMain.cpp +++ b/meta-luxshare/meta-bhs/recipes-phosphor/dimm/dimm-spd-reader/dimmSpdReaderMain.cpp @@ -59,6 +59,8 @@ std::unordered_map std::unordered_map> dimm_current_inf; std::unordered_map> dimm_power_inf; std::unordered_map> dimm_statusReg_inf; +std::unordered_map> dimm_errCode_inf; + int main() { @@ -177,6 +179,13 @@ int main() dimm_statusReg_inf[dimm]->register_property( "0x0b", uint8_t(0), sdbusplus::asio::PropertyPermission::readWrite); dimm_statusReg_inf[dimm]->initialize(); + + dimm_errCode_inf[dimm] = objectServer.add_interface(interfacePath, + "xyz.openbmc_project.Dimm.ErrCode"); + dimm_errCode_inf[dimm]->register_property( + "0x32", uint8_t(0), sdbusplus::asio::PropertyPermission::readWrite); + dimm_errCode_inf[dimm]->initialize(); + } double pollRate = 0.1; diff --git a/meta-luxshare/meta-common/recipes-luxshare/ipmi-lux-oem/ipmi-oem/ipmi-oem.cpp b/meta-luxshare/meta-common/recipes-luxshare/ipmi-lux-oem/ipmi-oem/ipmi-oem.cpp index e0408f6d..6989e3dd 100755 --- a/meta-luxshare/meta-common/recipes-luxshare/ipmi-lux-oem/ipmi-oem/ipmi-oem.cpp +++ b/meta-luxshare/meta-common/recipes-luxshare/ipmi-lux-oem/ipmi-oem/ipmi-oem.cpp @@ -1374,7 +1374,7 @@ ipmi::RspType ipmiBiosSetDimmPara(ipmi::Context::ptr ctx, std::vector(dimmInfo.dimmCur.SWD) / 1000.0; railData[4] = static_cast(dimmInfo.dimmCur.SWE) / 1000.0; railData[5] = static_cast(dimmInfo.dimmCur.SWF) / 1000.0; - for(int i=0; i<4; i++) { + for(int i=0; i<6; i++) { //Jim debug check i<6 or i<4 ret = setDimmParaToDbus(ctx, dimmName, "Current", railName[i], railData[i]); if(ret < 0) return ipmi::responseUnspecifiedError(); @@ -1387,7 +1387,7 @@ ipmi::RspType ipmiBiosSetDimmPara(ipmi::Context::ptr ctx, std::vector(dimmInfo.dimmPow.SWD) / 1000.0; railData[4] = static_cast(dimmInfo.dimmPow.SWE) / 1000.0; railData[5] = static_cast(dimmInfo.dimmPow.SWF) / 1000.0; - for(int i=0; i<4; i++) { + for(int i=0; i<6; i++) { //Jim debug check i<6 or i<4 ret = setDimmParaToDbus(ctx, dimmName, "Power", railName[i], railData[i]); if(ret < 0) return ipmi::responseUnspecifiedError(); @@ -1740,6 +1740,21 @@ static std::optional getDIMMData(const nlohmann::json& js, const std::string& auto value = dimmData["Status_Reg"][regStr]; return static_cast(value.get()); } + else if (dataType == DataType::ERROR) { + auto err = static_cast(indexId); + std::string errStr; + + char hexStr[5]; + snprintf(hexStr, sizeof(hexStr), "0x%02x", static_cast(err)); + errStr = hexStr; + + if (!dimmData["Error_Code"].contains(errStr)) { + return std::nullopt; + } + + auto value = dimmData["Error_Code"][errStr]; + return static_cast(value.get()); + } } catch (std::exception& e) { return std::nullopt; } @@ -1748,7 +1763,7 @@ static std::optional getDIMMData(const nlohmann::json& js, const std::string& } /**************************************************************************** - reqId: 0:TS0 1:TS1 2:SPD_TEMP 3: Max Temp 4:Voltage 5:Current 6: Status Reg + reqId: 0:TS0 1:TS1 2:SPD_TEMP 3: Max Temp 4:Voltage 5:Current 6: Status Reg 7: Error Code *****************************************************************************/ ipmi::RspType> ipmiGetDimmTemp(uint8_t reqId) { @@ -1757,7 +1772,7 @@ ipmi::RspType> ipmiGetDimmTemp(uint8_t reqId) const nlohmann::json empty{}; nlohmann::json js; - if(reqId > 6) { + if(reqId > 7) { std::cout << "invalid reqId :" << (int)reqId << std::endl; return ipmi::responseParmOutOfRange(); } @@ -1806,7 +1821,8 @@ ipmi::RspType> ipmiGetDimmTemp(uint8_t reqId) + "_" + std::string(1, 'A' + i); std::optional temp, swa, swb, swc, swd, swe, swf; std::optional r4, r5, r6, r7, r8, r9, ra, rb; - + std::optional err_r32; + switch(static_cast(reqId)) { case ReqId::TS0: @@ -1847,6 +1863,11 @@ ipmi::RspType> ipmiGetDimmTemp(uint8_t reqId) ra = getDIMMData(js, dimmName, DataType::STATUS, StatusReg::REG_0A); rb = getDIMMData(js, dimmName, DataType::STATUS, StatusReg::REG_0B); break; + + case ReqId::ERROR_CODE: + err_r32 = getDIMMData(js, dimmName, DataType::ERROR, ErrCode::errCode_REG_32); + break; + default: std::cout << "invalid reqId :" << (int)reqId << std::endl; return ipmi::responseParmOutOfRange(); @@ -1865,6 +1886,11 @@ ipmi::RspType> ipmiGetDimmTemp(uint8_t reqId) byte_vector.push_back(opt.value_or(0xFF)); } } + else if(reqId == 7) { + for (const auto& opt : {err_r32}) { + byte_vector.push_back(opt.value_or(0xFF)); + } + } else { for (const auto& rail : {swa, swb, swc, swd, swe, swf}) { auto bytes = convertDoubleToTwoBytes(rail); diff --git a/meta-luxshare/meta-common/recipes-luxshare/ipmi-lux-oem/ipmi-oem/ipmi-oem.hpp b/meta-luxshare/meta-common/recipes-luxshare/ipmi-lux-oem/ipmi-oem/ipmi-oem.hpp index 33888627..3a756cd9 100755 --- a/meta-luxshare/meta-common/recipes-luxshare/ipmi-lux-oem/ipmi-oem/ipmi-oem.hpp +++ b/meta-luxshare/meta-common/recipes-luxshare/ipmi-lux-oem/ipmi-oem/ipmi-oem.hpp @@ -20,7 +20,8 @@ enum class DataType { CURRENT, POWER, VOLTAGE, - STATUS + STATUS, + ERROR }; enum class TempSensor { @@ -37,7 +38,8 @@ enum class ReqId { MAX_TEMP = 3, VOLTAGE = 4, CURRENT = 5, - STATUS_REG = 6 + STATUS_REG = 6, + ERROR_CODE = 7 }; enum class RailChannel { @@ -60,6 +62,10 @@ enum class StatusReg { REG_0B = 0x0B }; +enum class ErrCode { + errCode_REG_32 = 0x32 +}; + typedef struct { int8_t int_part; uint8_t frac_part;