blob: 79ad4897ed2a0bb2f60eef19520a4f224a9e3bbe [file] [log] [blame]
Patrick Venture46470a32018-09-07 19:26:25 -07001#pragma once
Chris Austenac4604a2015-10-13 12:43:27 -05002
Patrick Venture0b02be92018-08-31 11:55:55 -07003#include <stdint.h>
4
Vernon Mauerye08fbff2019-04-03 09:19:34 -07005#include <ipmid/api.hpp>
Vernon Mauery33250242019-03-12 16:49:26 -07006#include <ipmid/types.hpp>
7
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -05008#include <exception>
9
Ratan Guptae0cc8552018-01-22 14:23:04 +053010/**
11 * @enum device_type
12 * IPMI FRU device types
13 */
14enum device_type
15{
16 IPMI_PHYSICAL_FRU = 0x00,
17 IPMI_LOGICAL_FRU = 0x80,
18};
19
Emily Shaffer1fabf222017-04-05 08:53:21 -070020// Discrete sensor types.
21enum ipmi_sensor_types
22{
Patrick Venture0b02be92018-08-31 11:55:55 -070023 IPMI_SENSOR_TEMP = 0x01,
Emily Shaffer1fabf222017-04-05 08:53:21 -070024 IPMI_SENSOR_VOLTAGE = 0x02,
25 IPMI_SENSOR_CURRENT = 0x03,
Patrick Venture0b02be92018-08-31 11:55:55 -070026 IPMI_SENSOR_FAN = 0x04,
27 IPMI_SENSOR_TPM = 0xCC,
Emily Shaffer1fabf222017-04-05 08:53:21 -070028};
29
Brandon Kim9cf85622019-06-19 12:05:08 -070030/** @brief Custom exception for reading sensors that are not funcitonal.
31 */
32struct SensorFunctionalError : public std::exception
33{
34 const char* what() const noexcept
35 {
36 return "Sensor not functional";
37 }
38};
39
Chris Austen0012e9b2015-10-22 01:37:46 -050040#define MAX_DBUS_PATH 128
Patrick Venture0b02be92018-08-31 11:55:55 -070041struct dbus_interface_t
42{
43 uint8_t sensornumber;
44 uint8_t sensortype;
Chris Austen0012e9b2015-10-22 01:37:46 -050045
Patrick Venture0b02be92018-08-31 11:55:55 -070046 char bus[MAX_DBUS_PATH];
47 char path[MAX_DBUS_PATH];
48 char interface[MAX_DBUS_PATH];
Chris Austen0012e9b2015-10-22 01:37:46 -050049};
Tomd700e762016-09-20 18:24:13 +053050
Jia, Chunhui3342a8e2018-12-29 13:32:26 +080051struct PlatformEventRequest
52{
53 uint8_t eventMessageRevision;
54 uint8_t sensorType;
55 uint8_t sensorNumber;
56 uint8_t eventDirectionType;
57 uint8_t data[3];
58};
59
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050060static constexpr const char* ipmiSELPath = "/xyz/openbmc_project/Logging/IPMI";
61static constexpr const char* ipmiSELAddInterface =
Jia, Chunhui3342a8e2018-12-29 13:32:26 +080062 "xyz.openbmc_project.Logging.IPMI";
Konstantin Aladyshevb5160f52023-04-19 14:45:06 +030063static const std::string ipmiSELAddMessage = "IPMI generated SEL Entry";
Jia, Chunhui3342a8e2018-12-29 13:32:26 +080064
65static constexpr int selSystemEventSizeWith3Bytes = 8;
66static constexpr int selSystemEventSizeWith2Bytes = 7;
67static constexpr int selSystemEventSizeWith1Bytes = 6;
68static constexpr int selIPMBEventSize = 7;
69static constexpr uint8_t directionMask = 0x80;
70static constexpr uint8_t byte3EnableMask = 0x30;
71static constexpr uint8_t byte2EnableMask = 0xC0;
72
Patrick Venture0b02be92018-08-31 11:55:55 -070073int set_sensor_dbus_state_s(uint8_t, const char*, const char*);
74int set_sensor_dbus_state_y(uint8_t, const char*, const uint8_t);
75int find_openbmc_path(uint8_t, dbus_interface_t*);
Tom05732372016-09-06 17:21:23 +053076
George Liuc7a4da52025-08-19 16:20:31 +080077ipmi::RspType<uint16_t, std::vector<uint8_t>> ipmiSensorGetSdr(
78 uint16_t, uint16_t, uint8_t, uint8_t);
Tom Joseph5ca50952018-02-22 00:33:38 +053079
jayaprakash Mutyalad9578232019-05-13 20:22:50 +000080ipmi::RspType<uint16_t> ipmiSensorReserveSdr();
Tom Joseph5ca50952018-02-22 00:33:38 +053081
Ratan Guptae0cc8552018-01-22 14:23:04 +053082static const uint16_t FRU_RECORD_ID_START = 256;
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -080083static const uint16_t ENTITY_RECORD_ID_START = 512;
Ratan Guptae0cc8552018-01-22 14:23:04 +053084static const uint8_t SDR_VERSION = 0x51;
85static const uint16_t END_OF_RECORD = 0xFFFF;
86static const uint8_t LENGTH_MASK = 0x1F;
87
Tom Josephbe703f72017-03-09 12:34:35 +053088/**
Emily Shafferbbef71c2017-05-08 16:36:17 -070089 * Get SDR
90 */
91namespace get_sdr
92{
93
Emily Shafferbbef71c2017-05-08 16:36:17 -070094// Record header
95struct SensorDataRecordHeader
96{
George Liuc7a4da52025-08-19 16:20:31 +080097 uint16_t recordId;
George Liu42247d22025-08-19 10:24:47 +080098 uint8_t sdrVersion;
99 uint8_t recordType;
100 uint8_t recordLength; // Length not counting the header
Emily Shafferbbef71c2017-05-08 16:36:17 -0700101} __attribute__((packed));
102
Emily Shafferbbef71c2017-05-08 16:36:17 -0700103enum SensorDataRecordType
104{
Ratan Guptae0cc8552018-01-22 14:23:04 +0530105 SENSOR_DATA_FULL_RECORD = 0x1,
selvaganapathi7b2e5502023-02-14 07:10:47 +0530106 SENSOR_DATA_COMPACT_RECORD = 0x2,
Hao Jiangda06d152021-01-19 15:27:43 -0800107 SENSOR_DATA_EVENT_RECORD = 0x3,
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800108 SENSOR_DATA_ENTITY_RECORD = 0x8,
Harvey Wua3476272023-03-22 10:09:38 +0800109 SENSOR_DATA_FRU_RECORD = 0x11,
110 SENSOR_DATA_MGMT_CTRL_LOCATOR = 0x12,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700111};
112
113// Record key
114struct SensorDataRecordKey
115{
George Liu42247d22025-08-19 10:24:47 +0800116 uint8_t ownerId;
117 uint8_t ownerLun;
118 uint8_t sensorNumber;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700119} __attribute__((packed));
120
Ratan Guptae0cc8552018-01-22 14:23:04 +0530121/** @struct SensorDataFruRecordKey
122 *
123 * FRU Device Locator Record(key) - SDR Type 11
124 */
125struct SensorDataFruRecordKey
126{
127 uint8_t deviceAddress;
128 uint8_t fruID;
129 uint8_t accessLun;
130 uint8_t channelNumber;
131} __attribute__((packed));
132
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800133/** @struct SensorDataEntityRecordKey
134 *
135 * Entity Association Record(key) - SDR Type 8
136 */
137struct SensorDataEntityRecordKey
138{
139 uint8_t containerEntityId;
140 uint8_t containerEntityInstance;
141 uint8_t flags;
142 uint8_t entityId1;
143 uint8_t entityInstance1;
144} __attribute__((packed));
145
Emily Shafferbbef71c2017-05-08 16:36:17 -0700146namespace key
147{
148
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800149static constexpr uint8_t listOrRangeBit = 7;
150static constexpr uint8_t linkedBit = 6;
151
George Liuf60be692025-08-19 11:28:42 +0800152inline void setOwnerIdIpmb(SensorDataRecordKey& key)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700153{
George Liu42247d22025-08-19 10:24:47 +0800154 key.ownerId &= ~0x01;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700155};
156
George Liuf60be692025-08-19 11:28:42 +0800157inline void setOwnerIdSystemSw(SensorDataRecordKey& key)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700158{
George Liu42247d22025-08-19 10:24:47 +0800159 key.ownerId |= 0x01;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700160};
161
George Liuf60be692025-08-19 11:28:42 +0800162inline void setOwnerIdBmc(SensorDataRecordKey& key)
Tom Joseph96423912018-01-25 00:14:34 +0530163{
George Liu42247d22025-08-19 10:24:47 +0800164 key.ownerId |= 0x20;
Tom Joseph96423912018-01-25 00:14:34 +0530165};
166
George Liuf60be692025-08-19 11:28:42 +0800167inline void setOwnerIdAddress(uint8_t addr, SensorDataRecordKey& key)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700168{
George Liu42247d22025-08-19 10:24:47 +0800169 key.ownerId &= 0x01;
170 key.ownerId |= addr << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700171};
172
George Liuf60be692025-08-19 11:28:42 +0800173inline void setOwnerLun(uint8_t lun, SensorDataRecordKey& key)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700174{
George Liu42247d22025-08-19 10:24:47 +0800175 key.ownerLun &= ~0x03;
176 key.ownerLun |= (lun & 0x03);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700177};
178
George Liuf60be692025-08-19 11:28:42 +0800179inline void setOwnerLunChannel(uint8_t channel, SensorDataRecordKey& key)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700180{
George Liu42247d22025-08-19 10:24:47 +0800181 key.ownerLun &= 0x0f;
182 key.ownerLun |= ((channel & 0xf) << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700183};
184
George Liuf60be692025-08-19 11:28:42 +0800185inline void setFlags(bool isList, bool isLinked, SensorDataEntityRecordKey& key)
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800186{
George Liue6b2be52025-08-19 13:57:43 +0800187 key.flags = 0x00;
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800188 if (!isList)
George Liue6b2be52025-08-19 13:57:43 +0800189 {
190 key.flags |= 1 << listOrRangeBit;
191 }
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800192
193 if (isLinked)
George Liue6b2be52025-08-19 13:57:43 +0800194 {
195 key.flags |= 1 << linkedBit;
196 }
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800197};
198
Emily Shafferbbef71c2017-05-08 16:36:17 -0700199} // namespace key
200
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600201/** @struct GetSensorThresholdsResponse
202 *
203 * Response structure for Get Sensor Thresholds command
204 */
205struct GetSensorThresholdsResponse
206{
Patrick Venture0b02be92018-08-31 11:55:55 -0700207 uint8_t validMask; //!< valid mask
208 uint8_t lowerNonCritical; //!< lower non-critical threshold
209 uint8_t lowerCritical; //!< lower critical threshold
210 uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
211 uint8_t upperNonCritical; //!< upper non-critical threshold
212 uint8_t upperCritical; //!< upper critical threshold
213 uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600214} __attribute__((packed));
215
Emily Shafferbbef71c2017-05-08 16:36:17 -0700216// Body - full record
217#define FULL_RECORD_ID_STR_MAX_LENGTH 16
Ratan Guptae0cc8552018-01-22 14:23:04 +0530218
219static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
220
Emily Shafferbbef71c2017-05-08 16:36:17 -0700221struct SensorDataFullRecordBody
222{
George Liu42247d22025-08-19 10:24:47 +0800223 uint8_t entityId;
224 uint8_t entityInstance;
225 uint8_t sensorInitialization;
226 uint8_t sensorCapabilities; // no macro support
227 uint8_t sensorType;
228 uint8_t eventReadingType;
229 uint8_t supportedAssertions[2]; // no macro support
230 uint8_t supportedDeassertions[2]; // no macro support
231 uint8_t discreteReadingSettingMask[2]; // no macro support
232 uint8_t sensorUnits1;
233 uint8_t sensorUnits2Base;
234 uint8_t sensorUnits3Modifier;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700235 uint8_t linearization;
George Liu42247d22025-08-19 10:24:47 +0800236 uint8_t mLsb;
237 uint8_t mMsbAndTolerance;
238 uint8_t bLsb;
239 uint8_t bMsbAndAccuracyLsb;
240 uint8_t accuracyAndSensorDirection;
241 uint8_t rbExponents;
242 uint8_t analogCharacteristicFlags; // no macro support
243 uint8_t nominalReading;
244 uint8_t normalMax;
245 uint8_t normalMin;
246 uint8_t sensorMax;
247 uint8_t sensorMin;
248 uint8_t upperNonrecoverableThreshold;
249 uint8_t upperCriticalThreshold;
250 uint8_t upperNoncriticalThreshold;
251 uint8_t lowerNonrecoverableThreshold;
252 uint8_t lowerCriticalThreshold;
253 uint8_t lowerNoncriticalThreshold;
254 uint8_t positiveThresholdHysteresis;
255 uint8_t negativeThresholdHysteresis;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700256 uint16_t reserved;
George Liu42247d22025-08-19 10:24:47 +0800257 uint8_t oemReserved;
258 uint8_t idStringInfo;
259 char idString[FULL_RECORD_ID_STR_MAX_LENGTH];
Emily Shafferbbef71c2017-05-08 16:36:17 -0700260} __attribute__((packed));
261
selvaganapathi7b2e5502023-02-14 07:10:47 +0530262/** @struct SensorDataCompactRecord
263 *
264 * Compact Sensor Record(body) - SDR Type 2
265 */
266struct SensorDataCompactRecordBody
267{
George Liu42247d22025-08-19 10:24:47 +0800268 uint8_t entityId;
269 uint8_t entityInstance;
270 uint8_t sensorInitialization;
271 uint8_t sensorCapabilities; // no macro support
272 uint8_t sensorType;
273 uint8_t eventReadingType;
274 uint8_t supportedAssertions[2]; // no macro support
275 uint8_t supportedDeassertions[2]; // no macro support
276 uint8_t discreteReadingSettingMask[2]; // no macro support
277 uint8_t sensorUnits1;
278 uint8_t sensorUnits2Base;
279 uint8_t sensorUnits3Modifier;
selvaganapathi7b2e5502023-02-14 07:10:47 +0530280 uint8_t record_sharing[2];
George Liu42247d22025-08-19 10:24:47 +0800281 uint8_t positiveThresholdHysteresis;
282 uint8_t negativeThresholdHysteresis;
selvaganapathi7b2e5502023-02-14 07:10:47 +0530283 uint8_t reserved[3];
George Liu42247d22025-08-19 10:24:47 +0800284 uint8_t oemReserved;
285 uint8_t idStringInfo;
286 char idString[FULL_RECORD_ID_STR_MAX_LENGTH];
selvaganapathi7b2e5502023-02-14 07:10:47 +0530287} __attribute__((packed));
288
Hao Jiangda06d152021-01-19 15:27:43 -0800289/** @struct SensorDataEventRecord
290 *
291 * Event Only Sensor Record(body) - SDR Type 3
292 */
293struct SensorDataEventRecordBody
294{
George Liu42247d22025-08-19 10:24:47 +0800295 uint8_t entityId;
296 uint8_t entityInstance;
297 uint8_t sensorType;
298 uint8_t eventReadingType;
299 uint8_t sensorRecordSharing1;
300 uint8_t sensorRecordSharing2;
Hao Jiangda06d152021-01-19 15:27:43 -0800301 uint8_t reserved;
George Liu42247d22025-08-19 10:24:47 +0800302 uint8_t oemReserved;
303 uint8_t idStringInfo;
304 char idString[FULL_RECORD_ID_STR_MAX_LENGTH];
Hao Jiangda06d152021-01-19 15:27:43 -0800305} __attribute__((packed));
306
Ratan Guptae0cc8552018-01-22 14:23:04 +0530307/** @struct SensorDataFruRecordBody
308 *
309 * FRU Device Locator Record(body) - SDR Type 11
310 */
311struct SensorDataFruRecordBody
312{
313 uint8_t reserved;
314 uint8_t deviceType;
315 uint8_t deviceTypeModifier;
316 uint8_t entityID;
317 uint8_t entityInstance;
318 uint8_t oem;
319 uint8_t deviceIDLen;
320 char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
321} __attribute__((packed));
322
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800323/** @struct SensorDataEntityRecordBody
324 *
325 * Entity Association Record(body) - SDR Type 8
326 */
327struct SensorDataEntityRecordBody
328{
329 uint8_t entityId2;
330 uint8_t entityInstance2;
331 uint8_t entityId3;
332 uint8_t entityInstance3;
333 uint8_t entityId4;
334 uint8_t entityInstance4;
335} __attribute__((packed));
336
Emily Shafferbbef71c2017-05-08 16:36:17 -0700337namespace body
338{
339
George Liuf60be692025-08-19 11:28:42 +0800340inline void setEntityInstanceNumber(uint8_t n, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700341{
George Liu42247d22025-08-19 10:24:47 +0800342 body.entityInstance &= 1 << 7;
343 body.entityInstance |= (n & ~(1 << 7));
Emily Shafferbbef71c2017-05-08 16:36:17 -0700344};
345
George Liuf60be692025-08-19 11:28:42 +0800346inline void setEntityPhysicalEntity(SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800347{
George Liu42247d22025-08-19 10:24:47 +0800348 body.entityInstance &= ~(1 << 7);
George Liue6b2be52025-08-19 13:57:43 +0800349};
350
George Liuf60be692025-08-19 11:28:42 +0800351inline void setEntityLogicalContainer(SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800352{
George Liu42247d22025-08-19 10:24:47 +0800353 body.entityInstance |= 1 << 7;
George Liue6b2be52025-08-19 13:57:43 +0800354};
355
George Liuf60be692025-08-19 11:28:42 +0800356inline void sensorScanningState(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700357{
358 if (enabled)
359 {
George Liu42247d22025-08-19 10:24:47 +0800360 body.sensorInitialization |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700361 }
362 else
363 {
George Liu42247d22025-08-19 10:24:47 +0800364 body.sensorInitialization &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700365 };
366};
George Liue6b2be52025-08-19 13:57:43 +0800367
George Liuf60be692025-08-19 11:28:42 +0800368inline void eventGenerationState(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700369{
370 if (enabled)
371 {
George Liu42247d22025-08-19 10:24:47 +0800372 body.sensorInitialization |= 1 << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700373 }
374 else
375 {
George Liu42247d22025-08-19 10:24:47 +0800376 body.sensorInitialization &= ~(1 << 1);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700377 }
378};
379
George Liuf60be692025-08-19 11:28:42 +0800380inline void initTypesState(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700381{
George Liue6b2be52025-08-19 13:57:43 +0800382 if (enabled)
383 {
George Liu42247d22025-08-19 10:24:47 +0800384 body.sensorInitialization |= 1 << 2;
George Liue6b2be52025-08-19 13:57:43 +0800385 }
386 else
387 {
George Liu42247d22025-08-19 10:24:47 +0800388 body.sensorInitialization &= ~(1 << 2);
George Liue6b2be52025-08-19 13:57:43 +0800389 }
Emily Shafferbbef71c2017-05-08 16:36:17 -0700390};
George Liue6b2be52025-08-19 13:57:43 +0800391
George Liuf60be692025-08-19 11:28:42 +0800392inline void initHystState(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700393{
George Liue6b2be52025-08-19 13:57:43 +0800394 if (enabled)
395 {
George Liu42247d22025-08-19 10:24:47 +0800396 body.sensorInitialization |= 1 << 3;
George Liue6b2be52025-08-19 13:57:43 +0800397 }
398 else
399 {
George Liu42247d22025-08-19 10:24:47 +0800400 body.sensorInitialization &= ~(1 << 3);
George Liue6b2be52025-08-19 13:57:43 +0800401 }
Emily Shafferbbef71c2017-05-08 16:36:17 -0700402};
George Liue6b2be52025-08-19 13:57:43 +0800403
George Liuf60be692025-08-19 11:28:42 +0800404inline void initThreshState(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700405{
George Liue6b2be52025-08-19 13:57:43 +0800406 if (enabled)
407 {
George Liu42247d22025-08-19 10:24:47 +0800408 body.sensorInitialization |= 1 << 4;
George Liue6b2be52025-08-19 13:57:43 +0800409 }
410 else
411 {
George Liu42247d22025-08-19 10:24:47 +0800412 body.sensorInitialization &= ~(1 << 4);
George Liue6b2be52025-08-19 13:57:43 +0800413 }
Emily Shafferbbef71c2017-05-08 16:36:17 -0700414};
George Liue6b2be52025-08-19 13:57:43 +0800415
George Liuf60be692025-08-19 11:28:42 +0800416inline void initEventsState(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700417{
George Liue6b2be52025-08-19 13:57:43 +0800418 if (enabled)
419 {
George Liu42247d22025-08-19 10:24:47 +0800420 body.sensorInitialization |= 1 << 5;
George Liue6b2be52025-08-19 13:57:43 +0800421 }
422 else
423 {
George Liu42247d22025-08-19 10:24:47 +0800424 body.sensorInitialization &= ~(1 << 5);
George Liue6b2be52025-08-19 13:57:43 +0800425 }
Emily Shafferbbef71c2017-05-08 16:36:17 -0700426};
George Liue6b2be52025-08-19 13:57:43 +0800427
George Liuf60be692025-08-19 11:28:42 +0800428inline void initScanningState(bool enabled, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800429{
430 if (enabled)
431 {
George Liu42247d22025-08-19 10:24:47 +0800432 body.sensorInitialization |= 1 << 6;
George Liue6b2be52025-08-19 13:57:43 +0800433 }
434 else
435 {
George Liu42247d22025-08-19 10:24:47 +0800436 body.sensorInitialization &= ~(1 << 6);
George Liue6b2be52025-08-19 13:57:43 +0800437 }
438};
439
George Liuf60be692025-08-19 11:28:42 +0800440inline void initSettableState(bool enabled, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800441{
442 if (enabled)
443 {
George Liu42247d22025-08-19 10:24:47 +0800444 body.sensorInitialization |= 1 << 7;
George Liue6b2be52025-08-19 13:57:43 +0800445 }
446 else
447 {
George Liu42247d22025-08-19 10:24:47 +0800448 body.sensorInitialization &= ~(1 << 7);
George Liue6b2be52025-08-19 13:57:43 +0800449 }
450};
451
George Liuf60be692025-08-19 11:28:42 +0800452inline void setPercentage(SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800453{
George Liu42247d22025-08-19 10:24:47 +0800454 body.sensorUnits1 |= 1 << 0;
George Liue6b2be52025-08-19 13:57:43 +0800455};
456
George Liuf60be692025-08-19 11:28:42 +0800457inline void unsetPercentage(SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800458{
George Liu42247d22025-08-19 10:24:47 +0800459 body.sensorUnits1 &= ~(1 << 0);
George Liue6b2be52025-08-19 13:57:43 +0800460};
461
George Liuf60be692025-08-19 11:28:42 +0800462inline void setModifierOperation(uint8_t op, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800463{
George Liu42247d22025-08-19 10:24:47 +0800464 body.sensorUnits1 &= ~(3 << 1);
465 body.sensorUnits1 |= (op & 0x3) << 1;
George Liue6b2be52025-08-19 13:57:43 +0800466};
467
George Liuf60be692025-08-19 11:28:42 +0800468inline void setRateUnit(uint8_t unit, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800469{
George Liu42247d22025-08-19 10:24:47 +0800470 body.sensorUnits1 &= ~(7 << 3);
471 body.sensorUnits1 |= (unit & 0x7) << 3;
George Liue6b2be52025-08-19 13:57:43 +0800472};
473
George Liuf60be692025-08-19 11:28:42 +0800474inline void setAnalogDataFormat(uint8_t format, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700475{
George Liu42247d22025-08-19 10:24:47 +0800476 body.sensorUnits1 &= ~(3 << 6);
477 body.sensorUnits1 |= (format & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700478};
479
George Liuf60be692025-08-19 11:28:42 +0800480inline void setM(uint16_t m, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700481{
George Liu42247d22025-08-19 10:24:47 +0800482 body.mLsb = m & 0xff;
483 body.mMsbAndTolerance &= ~(3 << 6);
484 body.mMsbAndTolerance |= ((m & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700485};
486
George Liuf60be692025-08-19 11:28:42 +0800487inline void setTolerance(uint8_t tol, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700488{
George Liu42247d22025-08-19 10:24:47 +0800489 body.mMsbAndTolerance &= ~0x3f;
490 body.mMsbAndTolerance |= tol & 0x3f;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700491};
George Liue6b2be52025-08-19 13:57:43 +0800492
George Liuf60be692025-08-19 11:28:42 +0800493inline void setB(uint16_t b, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800494{
George Liu42247d22025-08-19 10:24:47 +0800495 body.bLsb = b & 0xff;
496 body.bMsbAndAccuracyLsb &= ~(3 << 6);
497 body.bMsbAndAccuracyLsb |= ((b & (3 << 8)) >> 2);
George Liue6b2be52025-08-19 13:57:43 +0800498};
499
George Liuf60be692025-08-19 11:28:42 +0800500inline void setAccuracy(uint16_t acc, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700501{
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700502 // bottom 6 bits
George Liu42247d22025-08-19 10:24:47 +0800503 body.bMsbAndAccuracyLsb &= ~0x3f;
504 body.bMsbAndAccuracyLsb |= acc & 0x3f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700505 // top 4 bits
George Liu42247d22025-08-19 10:24:47 +0800506 body.accuracyAndSensorDirection &= 0x0f;
507 body.accuracyAndSensorDirection |= ((acc >> 6) & 0xf) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700508};
509
George Liuf60be692025-08-19 11:28:42 +0800510inline void setAccuracyExp(uint8_t exp, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700511{
George Liu42247d22025-08-19 10:24:47 +0800512 body.accuracyAndSensorDirection &= ~(3 << 2);
513 body.accuracyAndSensorDirection |= (exp & 3) << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700514};
515
George Liuf60be692025-08-19 11:28:42 +0800516inline void setSensorDir(uint8_t dir, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700517{
George Liu42247d22025-08-19 10:24:47 +0800518 body.accuracyAndSensorDirection &= ~(3 << 0);
519 body.accuracyAndSensorDirection |= (dir & 3);
Willy Tueae88592022-12-13 14:28:02 -0800520};
Emily Shafferbbef71c2017-05-08 16:36:17 -0700521
George Liuf60be692025-08-19 11:28:42 +0800522inline void setBexp(uint8_t exp, SensorDataFullRecordBody& body)
Ratan Guptae0cc8552018-01-22 14:23:04 +0530523{
George Liu42247d22025-08-19 10:24:47 +0800524 body.rbExponents &= 0xf0;
525 body.rbExponents |= exp & 0x0f;
Ratan Guptae0cc8552018-01-22 14:23:04 +0530526};
527
George Liuf60be692025-08-19 11:28:42 +0800528inline void setRexp(uint8_t exp, SensorDataFullRecordBody& body)
Ratan Guptae0cc8552018-01-22 14:23:04 +0530529{
George Liu42247d22025-08-19 10:24:47 +0800530 body.rbExponents &= 0x0f;
531 body.rbExponents |= (exp & 0x0f) << 4;
Ratan Guptae0cc8552018-01-22 14:23:04 +0530532};
533
George Liuf60be692025-08-19 11:28:42 +0800534inline void setIdStrLen(uint8_t len, SensorDataFullRecordBody& body)
Tom Josephdc212b22018-02-16 09:59:57 +0530535{
George Liu42247d22025-08-19 10:24:47 +0800536 body.idStringInfo &= ~(0x1f);
537 body.idStringInfo |= len & 0x1f;
George Liue6b2be52025-08-19 13:57:43 +0800538};
539
George Liuf60be692025-08-19 11:28:42 +0800540inline void setIdStrLen(uint8_t len, SensorDataEventRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800541{
George Liu42247d22025-08-19 10:24:47 +0800542 body.idStringInfo &= ~(0x1f);
543 body.idStringInfo |= len & 0x1f;
George Liue6b2be52025-08-19 13:57:43 +0800544};
545
George Liuf60be692025-08-19 11:28:42 +0800546inline uint8_t getIdStrLen(const SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800547{
George Liu42247d22025-08-19 10:24:47 +0800548 return body.idStringInfo & 0x1f;
George Liue6b2be52025-08-19 13:57:43 +0800549};
550
George Liuf60be692025-08-19 11:28:42 +0800551inline void setIdType(uint8_t type, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800552{
George Liu42247d22025-08-19 10:24:47 +0800553 body.idStringInfo &= ~(3 << 6);
554 body.idStringInfo |= (type & 0x3) << 6;
George Liue6b2be52025-08-19 13:57:43 +0800555};
556
George Liuf60be692025-08-19 11:28:42 +0800557inline void setIdType(uint8_t type, SensorDataEventRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800558{
George Liu42247d22025-08-19 10:24:47 +0800559 body.idStringInfo &= ~(3 << 6);
560 body.idStringInfo |= (type & 0x3) << 6;
George Liue6b2be52025-08-19 13:57:43 +0800561};
562
George Liuf60be692025-08-19 11:28:42 +0800563inline void setDeviceIdStrLen(uint8_t len, SensorDataFruRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800564{
565 body.deviceIDLen &= ~(LENGTH_MASK);
566 body.deviceIDLen |= len & LENGTH_MASK;
567};
568
George Liuf60be692025-08-19 11:28:42 +0800569inline uint8_t getDeviceIdStrLen(const SensorDataFruRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800570{
571 return body.deviceIDLen & LENGTH_MASK;
572};
573
George Liuf60be692025-08-19 11:28:42 +0800574inline void setReadableMask(uint8_t mask, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800575{
George Liu42247d22025-08-19 10:24:47 +0800576 body.discreteReadingSettingMask[1] = mask & 0x3F;
Tom Josephdc212b22018-02-16 09:59:57 +0530577}
578
Emily Shafferbbef71c2017-05-08 16:36:17 -0700579} // namespace body
580
581// More types contained in section 43.17 Sensor Unit Type Codes,
582// IPMI spec v2 rev 1.1
583enum SensorUnitTypeCodes
584{
585 SENSOR_UNIT_UNSPECIFIED = 0,
586 SENSOR_UNIT_DEGREES_C = 1,
587 SENSOR_UNIT_VOLTS = 4,
588 SENSOR_UNIT_AMPERES = 5,
Tom Josephdc212b22018-02-16 09:59:57 +0530589 SENSOR_UNIT_WATTS = 6,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700590 SENSOR_UNIT_JOULES = 7,
Kirill Pakhomov812e44c2018-10-22 16:25:35 +0300591 SENSOR_UNIT_RPM = 18,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700592 SENSOR_UNIT_METERS = 34,
593 SENSOR_UNIT_REVOLUTIONS = 41,
594};
595
596struct SensorDataFullRecord
597{
598 SensorDataRecordHeader header;
599 SensorDataRecordKey key;
600 SensorDataFullRecordBody body;
601} __attribute__((packed));
602
selvaganapathi7b2e5502023-02-14 07:10:47 +0530603/** @struct SensorDataComapactRecord
604 *
605 * Compact Sensor Record - SDR Type 2
606 */
607struct SensorDataCompactRecord
608{
609 SensorDataRecordHeader header;
610 SensorDataRecordKey key;
611 SensorDataCompactRecordBody body;
612} __attribute__((packed));
613
Hao Jiangda06d152021-01-19 15:27:43 -0800614/** @struct SensorDataEventRecord
615 *
616 * Event Only Sensor Record - SDR Type 3
617 */
618struct SensorDataEventRecord
619{
620 SensorDataRecordHeader header;
621 SensorDataRecordKey key;
622 SensorDataEventRecordBody body;
623} __attribute__((packed));
624
Ratan Guptae0cc8552018-01-22 14:23:04 +0530625/** @struct SensorDataFruRecord
626 *
627 * FRU Device Locator Record - SDR Type 11
628 */
629struct SensorDataFruRecord
630{
631 SensorDataRecordHeader header;
632 SensorDataFruRecordKey key;
633 SensorDataFruRecordBody body;
634} __attribute__((packed));
635
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800636/** @struct SensorDataEntityRecord
637 *
638 * Entity Association Record - SDR Type 8
639 */
640struct SensorDataEntityRecord
641{
642 SensorDataRecordHeader header;
643 SensorDataEntityRecordKey key;
644 SensorDataEntityRecordBody body;
645} __attribute__((packed));
646
Patrick Venture0b02be92018-08-31 11:55:55 -0700647} // namespace get_sdr
Tom Joseph816e92b2017-09-06 19:23:00 +0530648
649namespace ipmi
650{
651
652namespace sensor
653{
654
655/**
656 * @brief Map offset to the corresponding bit in the assertion byte.
657 *
Gunnar Mills8991dd62017-10-25 17:11:29 -0500658 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
Tom Joseph816e92b2017-09-06 19:23:00 +0530659 * byte and offsets 8-14 in the second byte.
660 *
661 * @param[in] offset - offset number.
662 * @param[in/out] resp - get sensor reading response.
663 */
George Liue6b2be52025-08-19 13:57:43 +0800664inline void setOffset(uint8_t offset, ipmi::sensor::GetSensorResponse& resp)
Tom Joseph816e92b2017-09-06 19:23:00 +0530665{
666 if (offset > 7)
667 {
George Liue6b2be52025-08-19 13:57:43 +0800668 resp.discreteReadingSensorStates |= 1 << (offset - 8);
Tom Joseph816e92b2017-09-06 19:23:00 +0530669 }
670 else
671 {
George Liue6b2be52025-08-19 13:57:43 +0800672 resp.thresholdLevelsStates |= 1 << offset;
Tom Joseph816e92b2017-09-06 19:23:00 +0530673 }
674}
675
Tom Josephe4014fc2017-09-06 23:57:36 +0530676/**
677 * @brief Set the reading field in the response.
678 *
679 * @param[in] offset - offset number.
680 * @param[in/out] resp - get sensor reading response.
681 */
George Liue6b2be52025-08-19 13:57:43 +0800682inline void setReading(uint8_t value, ipmi::sensor::GetSensorResponse& resp)
Tom Josephe4014fc2017-09-06 23:57:36 +0530683{
George Liue6b2be52025-08-19 13:57:43 +0800684 resp.reading = value;
Tom Josephe4014fc2017-09-06 23:57:36 +0530685}
686
Tom Joseph295f17e2017-09-07 00:09:46 +0530687/**
688 * @brief Map the value to the assertion bytes. The assertion states are stored
689 * in 2 bytes.
690 *
691 * @param[in] value - value to mapped to the assertion byte.
692 * @param[in/out] resp - get sensor reading response.
693 */
694inline void setAssertionBytes(uint16_t value,
George Liue6b2be52025-08-19 13:57:43 +0800695 ipmi::sensor::GetSensorResponse& resp)
Tom Joseph295f17e2017-09-07 00:09:46 +0530696{
George Liue6b2be52025-08-19 13:57:43 +0800697 resp.thresholdLevelsStates = static_cast<uint8_t>(value & 0x00FF);
698 resp.discreteReadingSensorStates = static_cast<uint8_t>(value >> 8);
Tom Joseph295f17e2017-09-07 00:09:46 +0530699}
700
Tom Josephe05b2922017-09-07 00:43:16 +0530701/**
702 * @brief Set the scanning enabled bit in the response.
703 *
704 * @param[in/out] resp - get sensor reading response.
705 */
George Liue6b2be52025-08-19 13:57:43 +0800706inline void enableScanning(ipmi::sensor::GetSensorResponse& resp)
Tom Josephe05b2922017-09-07 00:43:16 +0530707{
George Liue6b2be52025-08-19 13:57:43 +0800708 resp.readingOrStateUnavailable = false;
709 resp.scanningEnabled = true;
710 resp.allEventMessagesEnabled = false;
Tom Josephe05b2922017-09-07 00:43:16 +0530711}
712
Tom Joseph816e92b2017-09-06 19:23:00 +0530713} // namespace sensor
714
715} // namespace ipmi