Add NM discovery SDR support
NM discovery is an Intel OEM SDR,
it is used by external SW to check the NM functionality
Tested:
ipmitool sdr dump sdr.bin
The new added sdr is included at the end of the .bin file:
51 c0 0b 57 01 00 0d 01 2c 60 19 18 1a 1b
Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
Change-Id: I2b7e8059908791dcc6853be5ba2b9e22210eb736
diff --git a/include/storagecommands.hpp b/include/storagecommands.hpp
index 8516a9d..2055bd0 100644
--- a/include/storagecommands.hpp
+++ b/include/storagecommands.hpp
@@ -111,11 +111,30 @@
};
#pragma pack(pop)
+#pragma pack(push, 1)
+struct NMDiscoveryRecord
+{
+ get_sdr::SensorDataRecordHeader header;
+ uint8_t oemID0;
+ uint8_t oemID1;
+ uint8_t oemID2;
+ uint8_t subType;
+ uint8_t version;
+ uint8_t slaveAddress;
+ uint8_t channelNumber;
+ uint8_t healthEventSensor;
+ uint8_t exceptionEventSensor;
+ uint8_t operationalCapSensor;
+ uint8_t thresholdExceededSensor;
+};
+#pragma pack(pop)
+
namespace ipmi
{
namespace storage
{
+constexpr const size_t nmDiscoverySDRCount = 1;
constexpr const size_t type12Count = 2;
ipmi_ret_t getFruSdrs(ipmi::Context::ptr ctx, size_t index,
get_sdr::SensorDataFruRecord& resp);
@@ -123,5 +142,6 @@
ipmi_ret_t getFruSdrCount(ipmi::Context::ptr ctx, size_t& count);
std::vector<uint8_t> getType12SDRs(uint16_t index, uint16_t recordId);
+std::vector<uint8_t> getNMDiscoverySDR(uint16_t index, uint16_t recordId);
} // namespace storage
} // namespace ipmi
diff --git a/src/sensorcommands.cpp b/src/sensorcommands.cpp
index d500a00..f58f0e2 100644
--- a/src/sensorcommands.cpp
+++ b/src/sensorcommands.cpp
@@ -1170,8 +1170,9 @@
return ipmi::response(ret);
}
- size_t lastRecord =
- sensorTree.size() + fruCount + ipmi::storage::type12Count - 1;
+ size_t lastRecord = sensorTree.size() + fruCount +
+ ipmi::storage::type12Count +
+ ipmi::storage::nmDiscoverySDRCount - 1;
if (recordID == lastRecordIndex)
{
recordID = lastRecord;
@@ -1187,7 +1188,28 @@
{
std::vector<uint8_t> recordData;
size_t fruIndex = recordID - sensorTree.size();
- if (fruIndex >= fruCount)
+ size_t type12End = fruCount + ipmi::storage::type12Count;
+
+ if (fruIndex >= type12End)
+ {
+ // NM discovery SDR
+ size_t nmDiscoveryIndex = fruIndex - type12End;
+ if (nmDiscoveryIndex >= ipmi::storage::nmDiscoverySDRCount ||
+ offset > sizeof(NMDiscoveryRecord))
+ {
+ return ipmi::responseInvalidFieldRequest();
+ }
+
+ std::vector<uint8_t> record =
+ ipmi::storage::getNMDiscoverySDR(nmDiscoveryIndex, recordID);
+ if (record.size() < (offset + bytesToRead))
+ {
+ bytesToRead = record.size() - offset;
+ }
+ recordData.insert(recordData.end(), record.begin() + offset,
+ record.begin() + offset + bytesToRead);
+ }
+ else if (fruIndex >= fruCount)
{
// handle type 12 hardcoded records
size_t type12Index = fruIndex - fruCount;
diff --git a/src/storagecommands.cpp b/src/storagecommands.cpp
index f398980..631d063 100644
--- a/src/storagecommands.cpp
+++ b/src/storagecommands.cpp
@@ -1175,6 +1175,41 @@
return resp;
}
+std::vector<uint8_t> getNMDiscoverySDR(uint16_t index, uint16_t recordId)
+{
+ std::vector<uint8_t> resp;
+ if (index == 0)
+ {
+ NMDiscoveryRecord nm = {};
+ nm.header.record_id_lsb = recordId;
+ nm.header.record_id_msb = recordId >> 8;
+ nm.header.sdr_version = ipmiSdrVersion;
+ nm.header.record_type = 0xC0;
+ nm.header.record_length = 0xB;
+ nm.oemID0 = 0x57;
+ nm.oemID1 = 0x1;
+ nm.oemID2 = 0x0;
+ nm.subType = 0x0D;
+ nm.version = 0x1;
+ nm.slaveAddress = 0x2C;
+ nm.channelNumber = 0x60;
+ nm.healthEventSensor = 0x19;
+ nm.exceptionEventSensor = 0x18;
+ nm.operationalCapSensor = 0x1A;
+ nm.thresholdExceededSensor = 0x1B;
+
+ uint8_t* nmPtr = reinterpret_cast<uint8_t*>(&nm);
+ resp.insert(resp.end(), nmPtr, nmPtr + sizeof(NMDiscoveryRecord));
+ }
+ else
+ {
+ throw std::runtime_error("getNMDiscoverySDR:: Illegal index " +
+ std::to_string(index));
+ }
+
+ return resp;
+}
+
void registerStorageFunctions()
{
createTimers();