blob: c8bab23c0ddc744554bb8d8c9baf7af485decbfe [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
George Liu6b47d5a2025-08-18 10:40:17 +080060static constexpr const char* ipmiSELObject = "xyz.openbmc_project.Logging.IPMI";
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050061static constexpr const char* ipmiSELPath = "/xyz/openbmc_project/Logging/IPMI";
62static constexpr const char* ipmiSELAddInterface =
Jia, Chunhui3342a8e2018-12-29 13:32:26 +080063 "xyz.openbmc_project.Logging.IPMI";
Konstantin Aladyshevb5160f52023-04-19 14:45:06 +030064static const std::string ipmiSELAddMessage = "IPMI generated SEL Entry";
Jia, Chunhui3342a8e2018-12-29 13:32:26 +080065
66static constexpr int selSystemEventSizeWith3Bytes = 8;
67static constexpr int selSystemEventSizeWith2Bytes = 7;
68static constexpr int selSystemEventSizeWith1Bytes = 6;
69static constexpr int selIPMBEventSize = 7;
70static constexpr uint8_t directionMask = 0x80;
71static constexpr uint8_t byte3EnableMask = 0x30;
72static constexpr uint8_t byte2EnableMask = 0xC0;
73
Patrick Venture0b02be92018-08-31 11:55:55 -070074int set_sensor_dbus_state_s(uint8_t, const char*, const char*);
75int set_sensor_dbus_state_y(uint8_t, const char*, const uint8_t);
76int find_openbmc_path(uint8_t, dbus_interface_t*);
Tom05732372016-09-06 17:21:23 +053077
George Liuc7a4da52025-08-19 16:20:31 +080078ipmi::RspType<uint16_t, std::vector<uint8_t>> ipmiSensorGetSdr(
79 uint16_t, uint16_t, uint8_t, uint8_t);
Tom Joseph5ca50952018-02-22 00:33:38 +053080
jayaprakash Mutyalad9578232019-05-13 20:22:50 +000081ipmi::RspType<uint16_t> ipmiSensorReserveSdr();
Tom Joseph5ca50952018-02-22 00:33:38 +053082
Ratan Guptae0cc8552018-01-22 14:23:04 +053083static const uint16_t FRU_RECORD_ID_START = 256;
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -080084static const uint16_t ENTITY_RECORD_ID_START = 512;
Ratan Guptae0cc8552018-01-22 14:23:04 +053085static const uint8_t SDR_VERSION = 0x51;
86static const uint16_t END_OF_RECORD = 0xFFFF;
87static const uint8_t LENGTH_MASK = 0x1F;
88
Tom Josephbe703f72017-03-09 12:34:35 +053089/**
Emily Shafferbbef71c2017-05-08 16:36:17 -070090 * Get SDR
91 */
92namespace get_sdr
93{
94
Emily Shafferbbef71c2017-05-08 16:36:17 -070095// Record header
96struct SensorDataRecordHeader
97{
George Liuc7a4da52025-08-19 16:20:31 +080098 uint16_t recordId;
George Liu42247d22025-08-19 10:24:47 +080099 uint8_t sdrVersion;
100 uint8_t recordType;
101 uint8_t recordLength; // Length not counting the header
Emily Shafferbbef71c2017-05-08 16:36:17 -0700102} __attribute__((packed));
103
Emily Shafferbbef71c2017-05-08 16:36:17 -0700104enum SensorDataRecordType
105{
Ratan Guptae0cc8552018-01-22 14:23:04 +0530106 SENSOR_DATA_FULL_RECORD = 0x1,
selvaganapathi7b2e5502023-02-14 07:10:47 +0530107 SENSOR_DATA_COMPACT_RECORD = 0x2,
Hao Jiangda06d152021-01-19 15:27:43 -0800108 SENSOR_DATA_EVENT_RECORD = 0x3,
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800109 SENSOR_DATA_ENTITY_RECORD = 0x8,
Harvey Wua3476272023-03-22 10:09:38 +0800110 SENSOR_DATA_FRU_RECORD = 0x11,
111 SENSOR_DATA_MGMT_CTRL_LOCATOR = 0x12,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700112};
113
114// Record key
115struct SensorDataRecordKey
116{
George Liu42247d22025-08-19 10:24:47 +0800117 uint8_t ownerId;
118 uint8_t ownerLun;
119 uint8_t sensorNumber;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700120} __attribute__((packed));
121
Ratan Guptae0cc8552018-01-22 14:23:04 +0530122/** @struct SensorDataFruRecordKey
123 *
124 * FRU Device Locator Record(key) - SDR Type 11
125 */
126struct SensorDataFruRecordKey
127{
128 uint8_t deviceAddress;
129 uint8_t fruID;
130 uint8_t accessLun;
131 uint8_t channelNumber;
132} __attribute__((packed));
133
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800134/** @struct SensorDataEntityRecordKey
135 *
136 * Entity Association Record(key) - SDR Type 8
137 */
138struct SensorDataEntityRecordKey
139{
140 uint8_t containerEntityId;
141 uint8_t containerEntityInstance;
142 uint8_t flags;
143 uint8_t entityId1;
144 uint8_t entityInstance1;
145} __attribute__((packed));
146
Emily Shafferbbef71c2017-05-08 16:36:17 -0700147namespace key
148{
149
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800150static constexpr uint8_t listOrRangeBit = 7;
151static constexpr uint8_t linkedBit = 6;
152
George Liuf60be692025-08-19 11:28:42 +0800153inline void setOwnerIdIpmb(SensorDataRecordKey& key)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700154{
George Liu42247d22025-08-19 10:24:47 +0800155 key.ownerId &= ~0x01;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700156};
157
George Liuf60be692025-08-19 11:28:42 +0800158inline void setOwnerIdSystemSw(SensorDataRecordKey& key)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700159{
George Liu42247d22025-08-19 10:24:47 +0800160 key.ownerId |= 0x01;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700161};
162
George Liuf60be692025-08-19 11:28:42 +0800163inline void setOwnerIdBmc(SensorDataRecordKey& key)
Tom Joseph96423912018-01-25 00:14:34 +0530164{
George Liu42247d22025-08-19 10:24:47 +0800165 key.ownerId |= 0x20;
Tom Joseph96423912018-01-25 00:14:34 +0530166};
167
George Liuf60be692025-08-19 11:28:42 +0800168inline void setOwnerIdAddress(uint8_t addr, SensorDataRecordKey& key)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700169{
George Liu42247d22025-08-19 10:24:47 +0800170 key.ownerId &= 0x01;
171 key.ownerId |= addr << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700172};
173
George Liuf60be692025-08-19 11:28:42 +0800174inline void setOwnerLun(uint8_t lun, SensorDataRecordKey& key)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700175{
George Liu42247d22025-08-19 10:24:47 +0800176 key.ownerLun &= ~0x03;
177 key.ownerLun |= (lun & 0x03);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700178};
179
George Liuf60be692025-08-19 11:28:42 +0800180inline void setOwnerLunChannel(uint8_t channel, SensorDataRecordKey& key)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700181{
George Liu42247d22025-08-19 10:24:47 +0800182 key.ownerLun &= 0x0f;
183 key.ownerLun |= ((channel & 0xf) << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700184};
185
George Liuf60be692025-08-19 11:28:42 +0800186inline void setFlags(bool isList, bool isLinked, SensorDataEntityRecordKey& key)
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800187{
George Liue6b2be52025-08-19 13:57:43 +0800188 key.flags = 0x00;
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800189 if (!isList)
George Liue6b2be52025-08-19 13:57:43 +0800190 {
191 key.flags |= 1 << listOrRangeBit;
192 }
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800193
194 if (isLinked)
George Liue6b2be52025-08-19 13:57:43 +0800195 {
196 key.flags |= 1 << linkedBit;
197 }
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800198};
199
Emily Shafferbbef71c2017-05-08 16:36:17 -0700200} // namespace key
201
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600202/** @struct GetSensorThresholdsResponse
203 *
204 * Response structure for Get Sensor Thresholds command
205 */
206struct GetSensorThresholdsResponse
207{
Patrick Venture0b02be92018-08-31 11:55:55 -0700208 uint8_t validMask; //!< valid mask
209 uint8_t lowerNonCritical; //!< lower non-critical threshold
210 uint8_t lowerCritical; //!< lower critical threshold
211 uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
212 uint8_t upperNonCritical; //!< upper non-critical threshold
213 uint8_t upperCritical; //!< upper critical threshold
214 uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600215} __attribute__((packed));
216
Emily Shafferbbef71c2017-05-08 16:36:17 -0700217// Body - full record
218#define FULL_RECORD_ID_STR_MAX_LENGTH 16
Ratan Guptae0cc8552018-01-22 14:23:04 +0530219
220static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
221
Emily Shafferbbef71c2017-05-08 16:36:17 -0700222struct SensorDataFullRecordBody
223{
George Liu42247d22025-08-19 10:24:47 +0800224 uint8_t entityId;
225 uint8_t entityInstance;
226 uint8_t sensorInitialization;
227 uint8_t sensorCapabilities; // no macro support
228 uint8_t sensorType;
229 uint8_t eventReadingType;
230 uint8_t supportedAssertions[2]; // no macro support
231 uint8_t supportedDeassertions[2]; // no macro support
232 uint8_t discreteReadingSettingMask[2]; // no macro support
233 uint8_t sensorUnits1;
234 uint8_t sensorUnits2Base;
235 uint8_t sensorUnits3Modifier;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700236 uint8_t linearization;
George Liu42247d22025-08-19 10:24:47 +0800237 uint8_t mLsb;
238 uint8_t mMsbAndTolerance;
239 uint8_t bLsb;
240 uint8_t bMsbAndAccuracyLsb;
241 uint8_t accuracyAndSensorDirection;
242 uint8_t rbExponents;
243 uint8_t analogCharacteristicFlags; // no macro support
244 uint8_t nominalReading;
245 uint8_t normalMax;
246 uint8_t normalMin;
247 uint8_t sensorMax;
248 uint8_t sensorMin;
249 uint8_t upperNonrecoverableThreshold;
250 uint8_t upperCriticalThreshold;
251 uint8_t upperNoncriticalThreshold;
252 uint8_t lowerNonrecoverableThreshold;
253 uint8_t lowerCriticalThreshold;
254 uint8_t lowerNoncriticalThreshold;
255 uint8_t positiveThresholdHysteresis;
256 uint8_t negativeThresholdHysteresis;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700257 uint16_t reserved;
George Liu42247d22025-08-19 10:24:47 +0800258 uint8_t oemReserved;
259 uint8_t idStringInfo;
260 char idString[FULL_RECORD_ID_STR_MAX_LENGTH];
Emily Shafferbbef71c2017-05-08 16:36:17 -0700261} __attribute__((packed));
262
selvaganapathi7b2e5502023-02-14 07:10:47 +0530263/** @struct SensorDataCompactRecord
264 *
265 * Compact Sensor Record(body) - SDR Type 2
266 */
267struct SensorDataCompactRecordBody
268{
George Liu42247d22025-08-19 10:24:47 +0800269 uint8_t entityId;
270 uint8_t entityInstance;
271 uint8_t sensorInitialization;
272 uint8_t sensorCapabilities; // no macro support
273 uint8_t sensorType;
274 uint8_t eventReadingType;
275 uint8_t supportedAssertions[2]; // no macro support
276 uint8_t supportedDeassertions[2]; // no macro support
277 uint8_t discreteReadingSettingMask[2]; // no macro support
278 uint8_t sensorUnits1;
279 uint8_t sensorUnits2Base;
280 uint8_t sensorUnits3Modifier;
selvaganapathi7b2e5502023-02-14 07:10:47 +0530281 uint8_t record_sharing[2];
George Liu42247d22025-08-19 10:24:47 +0800282 uint8_t positiveThresholdHysteresis;
283 uint8_t negativeThresholdHysteresis;
selvaganapathi7b2e5502023-02-14 07:10:47 +0530284 uint8_t reserved[3];
George Liu42247d22025-08-19 10:24:47 +0800285 uint8_t oemReserved;
286 uint8_t idStringInfo;
287 char idString[FULL_RECORD_ID_STR_MAX_LENGTH];
selvaganapathi7b2e5502023-02-14 07:10:47 +0530288} __attribute__((packed));
289
Hao Jiangda06d152021-01-19 15:27:43 -0800290/** @struct SensorDataEventRecord
291 *
292 * Event Only Sensor Record(body) - SDR Type 3
293 */
294struct SensorDataEventRecordBody
295{
George Liu42247d22025-08-19 10:24:47 +0800296 uint8_t entityId;
297 uint8_t entityInstance;
298 uint8_t sensorType;
299 uint8_t eventReadingType;
300 uint8_t sensorRecordSharing1;
301 uint8_t sensorRecordSharing2;
Hao Jiangda06d152021-01-19 15:27:43 -0800302 uint8_t reserved;
George Liu42247d22025-08-19 10:24:47 +0800303 uint8_t oemReserved;
304 uint8_t idStringInfo;
305 char idString[FULL_RECORD_ID_STR_MAX_LENGTH];
Hao Jiangda06d152021-01-19 15:27:43 -0800306} __attribute__((packed));
307
Ratan Guptae0cc8552018-01-22 14:23:04 +0530308/** @struct SensorDataFruRecordBody
309 *
310 * FRU Device Locator Record(body) - SDR Type 11
311 */
312struct SensorDataFruRecordBody
313{
314 uint8_t reserved;
315 uint8_t deviceType;
316 uint8_t deviceTypeModifier;
317 uint8_t entityID;
318 uint8_t entityInstance;
319 uint8_t oem;
320 uint8_t deviceIDLen;
321 char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
322} __attribute__((packed));
323
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800324/** @struct SensorDataEntityRecordBody
325 *
326 * Entity Association Record(body) - SDR Type 8
327 */
328struct SensorDataEntityRecordBody
329{
330 uint8_t entityId2;
331 uint8_t entityInstance2;
332 uint8_t entityId3;
333 uint8_t entityInstance3;
334 uint8_t entityId4;
335 uint8_t entityInstance4;
336} __attribute__((packed));
337
Emily Shafferbbef71c2017-05-08 16:36:17 -0700338namespace body
339{
340
George Liuf60be692025-08-19 11:28:42 +0800341inline void setEntityInstanceNumber(uint8_t n, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700342{
George Liu42247d22025-08-19 10:24:47 +0800343 body.entityInstance &= 1 << 7;
344 body.entityInstance |= (n & ~(1 << 7));
Emily Shafferbbef71c2017-05-08 16:36:17 -0700345};
346
George Liuf60be692025-08-19 11:28:42 +0800347inline void setEntityPhysicalEntity(SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800348{
George Liu42247d22025-08-19 10:24:47 +0800349 body.entityInstance &= ~(1 << 7);
George Liue6b2be52025-08-19 13:57:43 +0800350};
351
George Liuf60be692025-08-19 11:28:42 +0800352inline void setEntityLogicalContainer(SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800353{
George Liu42247d22025-08-19 10:24:47 +0800354 body.entityInstance |= 1 << 7;
George Liue6b2be52025-08-19 13:57:43 +0800355};
356
George Liuf60be692025-08-19 11:28:42 +0800357inline void sensorScanningState(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700358{
359 if (enabled)
360 {
George Liu42247d22025-08-19 10:24:47 +0800361 body.sensorInitialization |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700362 }
363 else
364 {
George Liu42247d22025-08-19 10:24:47 +0800365 body.sensorInitialization &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700366 };
367};
George Liue6b2be52025-08-19 13:57:43 +0800368
George Liuf60be692025-08-19 11:28:42 +0800369inline void eventGenerationState(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700370{
371 if (enabled)
372 {
George Liu42247d22025-08-19 10:24:47 +0800373 body.sensorInitialization |= 1 << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700374 }
375 else
376 {
George Liu42247d22025-08-19 10:24:47 +0800377 body.sensorInitialization &= ~(1 << 1);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700378 }
379};
380
George Liuf60be692025-08-19 11:28:42 +0800381inline void initTypesState(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700382{
George Liue6b2be52025-08-19 13:57:43 +0800383 if (enabled)
384 {
George Liu42247d22025-08-19 10:24:47 +0800385 body.sensorInitialization |= 1 << 2;
George Liue6b2be52025-08-19 13:57:43 +0800386 }
387 else
388 {
George Liu42247d22025-08-19 10:24:47 +0800389 body.sensorInitialization &= ~(1 << 2);
George Liue6b2be52025-08-19 13:57:43 +0800390 }
Emily Shafferbbef71c2017-05-08 16:36:17 -0700391};
George Liue6b2be52025-08-19 13:57:43 +0800392
George Liuf60be692025-08-19 11:28:42 +0800393inline void initHystState(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700394{
George Liue6b2be52025-08-19 13:57:43 +0800395 if (enabled)
396 {
George Liu42247d22025-08-19 10:24:47 +0800397 body.sensorInitialization |= 1 << 3;
George Liue6b2be52025-08-19 13:57:43 +0800398 }
399 else
400 {
George Liu42247d22025-08-19 10:24:47 +0800401 body.sensorInitialization &= ~(1 << 3);
George Liue6b2be52025-08-19 13:57:43 +0800402 }
Emily Shafferbbef71c2017-05-08 16:36:17 -0700403};
George Liue6b2be52025-08-19 13:57:43 +0800404
George Liuf60be692025-08-19 11:28:42 +0800405inline void initThreshState(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700406{
George Liue6b2be52025-08-19 13:57:43 +0800407 if (enabled)
408 {
George Liu42247d22025-08-19 10:24:47 +0800409 body.sensorInitialization |= 1 << 4;
George Liue6b2be52025-08-19 13:57:43 +0800410 }
411 else
412 {
George Liu42247d22025-08-19 10:24:47 +0800413 body.sensorInitialization &= ~(1 << 4);
George Liue6b2be52025-08-19 13:57:43 +0800414 }
Emily Shafferbbef71c2017-05-08 16:36:17 -0700415};
George Liue6b2be52025-08-19 13:57:43 +0800416
George Liuf60be692025-08-19 11:28:42 +0800417inline void initEventsState(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700418{
George Liue6b2be52025-08-19 13:57:43 +0800419 if (enabled)
420 {
George Liu42247d22025-08-19 10:24:47 +0800421 body.sensorInitialization |= 1 << 5;
George Liue6b2be52025-08-19 13:57:43 +0800422 }
423 else
424 {
George Liu42247d22025-08-19 10:24:47 +0800425 body.sensorInitialization &= ~(1 << 5);
George Liue6b2be52025-08-19 13:57:43 +0800426 }
Emily Shafferbbef71c2017-05-08 16:36:17 -0700427};
George Liue6b2be52025-08-19 13:57:43 +0800428
George Liuf60be692025-08-19 11:28:42 +0800429inline void initScanningState(bool enabled, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800430{
431 if (enabled)
432 {
George Liu42247d22025-08-19 10:24:47 +0800433 body.sensorInitialization |= 1 << 6;
George Liue6b2be52025-08-19 13:57:43 +0800434 }
435 else
436 {
George Liu42247d22025-08-19 10:24:47 +0800437 body.sensorInitialization &= ~(1 << 6);
George Liue6b2be52025-08-19 13:57:43 +0800438 }
439};
440
George Liuf60be692025-08-19 11:28:42 +0800441inline void initSettableState(bool enabled, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800442{
443 if (enabled)
444 {
George Liu42247d22025-08-19 10:24:47 +0800445 body.sensorInitialization |= 1 << 7;
George Liue6b2be52025-08-19 13:57:43 +0800446 }
447 else
448 {
George Liu42247d22025-08-19 10:24:47 +0800449 body.sensorInitialization &= ~(1 << 7);
George Liue6b2be52025-08-19 13:57:43 +0800450 }
451};
452
George Liuf60be692025-08-19 11:28:42 +0800453inline void setPercentage(SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800454{
George Liu42247d22025-08-19 10:24:47 +0800455 body.sensorUnits1 |= 1 << 0;
George Liue6b2be52025-08-19 13:57:43 +0800456};
457
George Liuf60be692025-08-19 11:28:42 +0800458inline void unsetPercentage(SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800459{
George Liu42247d22025-08-19 10:24:47 +0800460 body.sensorUnits1 &= ~(1 << 0);
George Liue6b2be52025-08-19 13:57:43 +0800461};
462
George Liuf60be692025-08-19 11:28:42 +0800463inline void setModifierOperation(uint8_t op, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800464{
George Liu42247d22025-08-19 10:24:47 +0800465 body.sensorUnits1 &= ~(3 << 1);
466 body.sensorUnits1 |= (op & 0x3) << 1;
George Liue6b2be52025-08-19 13:57:43 +0800467};
468
George Liuf60be692025-08-19 11:28:42 +0800469inline void setRateUnit(uint8_t unit, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800470{
George Liu42247d22025-08-19 10:24:47 +0800471 body.sensorUnits1 &= ~(7 << 3);
472 body.sensorUnits1 |= (unit & 0x7) << 3;
George Liue6b2be52025-08-19 13:57:43 +0800473};
474
George Liuf60be692025-08-19 11:28:42 +0800475inline void setAnalogDataFormat(uint8_t format, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700476{
George Liu42247d22025-08-19 10:24:47 +0800477 body.sensorUnits1 &= ~(3 << 6);
478 body.sensorUnits1 |= (format & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700479};
480
George Liuf60be692025-08-19 11:28:42 +0800481inline void setM(uint16_t m, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700482{
George Liu42247d22025-08-19 10:24:47 +0800483 body.mLsb = m & 0xff;
484 body.mMsbAndTolerance &= ~(3 << 6);
485 body.mMsbAndTolerance |= ((m & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700486};
487
George Liuf60be692025-08-19 11:28:42 +0800488inline void setTolerance(uint8_t tol, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700489{
George Liu42247d22025-08-19 10:24:47 +0800490 body.mMsbAndTolerance &= ~0x3f;
491 body.mMsbAndTolerance |= tol & 0x3f;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700492};
George Liue6b2be52025-08-19 13:57:43 +0800493
George Liuf60be692025-08-19 11:28:42 +0800494inline void setB(uint16_t b, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800495{
George Liu42247d22025-08-19 10:24:47 +0800496 body.bLsb = b & 0xff;
497 body.bMsbAndAccuracyLsb &= ~(3 << 6);
498 body.bMsbAndAccuracyLsb |= ((b & (3 << 8)) >> 2);
George Liue6b2be52025-08-19 13:57:43 +0800499};
500
George Liuf60be692025-08-19 11:28:42 +0800501inline void setAccuracy(uint16_t acc, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700502{
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700503 // bottom 6 bits
George Liu42247d22025-08-19 10:24:47 +0800504 body.bMsbAndAccuracyLsb &= ~0x3f;
505 body.bMsbAndAccuracyLsb |= acc & 0x3f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700506 // top 4 bits
George Liu42247d22025-08-19 10:24:47 +0800507 body.accuracyAndSensorDirection &= 0x0f;
508 body.accuracyAndSensorDirection |= ((acc >> 6) & 0xf) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700509};
510
George Liuf60be692025-08-19 11:28:42 +0800511inline void setAccuracyExp(uint8_t exp, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700512{
George Liu42247d22025-08-19 10:24:47 +0800513 body.accuracyAndSensorDirection &= ~(3 << 2);
514 body.accuracyAndSensorDirection |= (exp & 3) << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700515};
516
George Liuf60be692025-08-19 11:28:42 +0800517inline void setSensorDir(uint8_t dir, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700518{
George Liu42247d22025-08-19 10:24:47 +0800519 body.accuracyAndSensorDirection &= ~(3 << 0);
520 body.accuracyAndSensorDirection |= (dir & 3);
Willy Tueae88592022-12-13 14:28:02 -0800521};
Emily Shafferbbef71c2017-05-08 16:36:17 -0700522
George Liuf60be692025-08-19 11:28:42 +0800523inline void setBexp(uint8_t exp, SensorDataFullRecordBody& body)
Ratan Guptae0cc8552018-01-22 14:23:04 +0530524{
George Liu42247d22025-08-19 10:24:47 +0800525 body.rbExponents &= 0xf0;
526 body.rbExponents |= exp & 0x0f;
Ratan Guptae0cc8552018-01-22 14:23:04 +0530527};
528
George Liuf60be692025-08-19 11:28:42 +0800529inline void setRexp(uint8_t exp, SensorDataFullRecordBody& body)
Ratan Guptae0cc8552018-01-22 14:23:04 +0530530{
George Liu42247d22025-08-19 10:24:47 +0800531 body.rbExponents &= 0x0f;
532 body.rbExponents |= (exp & 0x0f) << 4;
Ratan Guptae0cc8552018-01-22 14:23:04 +0530533};
534
George Liuf60be692025-08-19 11:28:42 +0800535inline void setIdStrLen(uint8_t len, SensorDataFullRecordBody& body)
Tom Josephdc212b22018-02-16 09:59:57 +0530536{
George Liu42247d22025-08-19 10:24:47 +0800537 body.idStringInfo &= ~(0x1f);
538 body.idStringInfo |= len & 0x1f;
George Liue6b2be52025-08-19 13:57:43 +0800539};
540
George Liuf60be692025-08-19 11:28:42 +0800541inline void setIdStrLen(uint8_t len, SensorDataEventRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800542{
George Liu42247d22025-08-19 10:24:47 +0800543 body.idStringInfo &= ~(0x1f);
544 body.idStringInfo |= len & 0x1f;
George Liue6b2be52025-08-19 13:57:43 +0800545};
546
George Liuf60be692025-08-19 11:28:42 +0800547inline uint8_t getIdStrLen(const SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800548{
George Liu42247d22025-08-19 10:24:47 +0800549 return body.idStringInfo & 0x1f;
George Liue6b2be52025-08-19 13:57:43 +0800550};
551
George Liuf60be692025-08-19 11:28:42 +0800552inline void setIdType(uint8_t type, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800553{
George Liu42247d22025-08-19 10:24:47 +0800554 body.idStringInfo &= ~(3 << 6);
555 body.idStringInfo |= (type & 0x3) << 6;
George Liue6b2be52025-08-19 13:57:43 +0800556};
557
George Liuf60be692025-08-19 11:28:42 +0800558inline void setIdType(uint8_t type, SensorDataEventRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800559{
George Liu42247d22025-08-19 10:24:47 +0800560 body.idStringInfo &= ~(3 << 6);
561 body.idStringInfo |= (type & 0x3) << 6;
George Liue6b2be52025-08-19 13:57:43 +0800562};
563
George Liuf60be692025-08-19 11:28:42 +0800564inline void setDeviceIdStrLen(uint8_t len, SensorDataFruRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800565{
566 body.deviceIDLen &= ~(LENGTH_MASK);
567 body.deviceIDLen |= len & LENGTH_MASK;
568};
569
George Liuf60be692025-08-19 11:28:42 +0800570inline uint8_t getDeviceIdStrLen(const SensorDataFruRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800571{
572 return body.deviceIDLen & LENGTH_MASK;
573};
574
George Liuf60be692025-08-19 11:28:42 +0800575inline void setReadableMask(uint8_t mask, SensorDataFullRecordBody& body)
George Liue6b2be52025-08-19 13:57:43 +0800576{
George Liu42247d22025-08-19 10:24:47 +0800577 body.discreteReadingSettingMask[1] = mask & 0x3F;
Tom Josephdc212b22018-02-16 09:59:57 +0530578}
579
Emily Shafferbbef71c2017-05-08 16:36:17 -0700580} // namespace body
581
582// More types contained in section 43.17 Sensor Unit Type Codes,
583// IPMI spec v2 rev 1.1
584enum SensorUnitTypeCodes
585{
586 SENSOR_UNIT_UNSPECIFIED = 0,
587 SENSOR_UNIT_DEGREES_C = 1,
588 SENSOR_UNIT_VOLTS = 4,
589 SENSOR_UNIT_AMPERES = 5,
Tom Josephdc212b22018-02-16 09:59:57 +0530590 SENSOR_UNIT_WATTS = 6,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700591 SENSOR_UNIT_JOULES = 7,
Kirill Pakhomov812e44c2018-10-22 16:25:35 +0300592 SENSOR_UNIT_RPM = 18,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700593 SENSOR_UNIT_METERS = 34,
594 SENSOR_UNIT_REVOLUTIONS = 41,
595};
596
597struct SensorDataFullRecord
598{
599 SensorDataRecordHeader header;
600 SensorDataRecordKey key;
601 SensorDataFullRecordBody body;
602} __attribute__((packed));
603
selvaganapathi7b2e5502023-02-14 07:10:47 +0530604/** @struct SensorDataComapactRecord
605 *
606 * Compact Sensor Record - SDR Type 2
607 */
608struct SensorDataCompactRecord
609{
610 SensorDataRecordHeader header;
611 SensorDataRecordKey key;
612 SensorDataCompactRecordBody body;
613} __attribute__((packed));
614
Hao Jiangda06d152021-01-19 15:27:43 -0800615/** @struct SensorDataEventRecord
616 *
617 * Event Only Sensor Record - SDR Type 3
618 */
619struct SensorDataEventRecord
620{
621 SensorDataRecordHeader header;
622 SensorDataRecordKey key;
623 SensorDataEventRecordBody body;
624} __attribute__((packed));
625
Ratan Guptae0cc8552018-01-22 14:23:04 +0530626/** @struct SensorDataFruRecord
627 *
628 * FRU Device Locator Record - SDR Type 11
629 */
630struct SensorDataFruRecord
631{
632 SensorDataRecordHeader header;
633 SensorDataFruRecordKey key;
634 SensorDataFruRecordBody body;
635} __attribute__((packed));
636
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800637/** @struct SensorDataEntityRecord
638 *
639 * Entity Association Record - SDR Type 8
640 */
641struct SensorDataEntityRecord
642{
643 SensorDataRecordHeader header;
644 SensorDataEntityRecordKey key;
645 SensorDataEntityRecordBody body;
646} __attribute__((packed));
647
Patrick Venture0b02be92018-08-31 11:55:55 -0700648} // namespace get_sdr
Tom Joseph816e92b2017-09-06 19:23:00 +0530649
650namespace ipmi
651{
652
653namespace sensor
654{
655
656/**
657 * @brief Map offset to the corresponding bit in the assertion byte.
658 *
Gunnar Mills8991dd62017-10-25 17:11:29 -0500659 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
Tom Joseph816e92b2017-09-06 19:23:00 +0530660 * byte and offsets 8-14 in the second byte.
661 *
662 * @param[in] offset - offset number.
663 * @param[in/out] resp - get sensor reading response.
664 */
George Liue6b2be52025-08-19 13:57:43 +0800665inline void setOffset(uint8_t offset, ipmi::sensor::GetSensorResponse& resp)
Tom Joseph816e92b2017-09-06 19:23:00 +0530666{
667 if (offset > 7)
668 {
George Liue6b2be52025-08-19 13:57:43 +0800669 resp.discreteReadingSensorStates |= 1 << (offset - 8);
Tom Joseph816e92b2017-09-06 19:23:00 +0530670 }
671 else
672 {
George Liue6b2be52025-08-19 13:57:43 +0800673 resp.thresholdLevelsStates |= 1 << offset;
Tom Joseph816e92b2017-09-06 19:23:00 +0530674 }
675}
676
Tom Josephe4014fc2017-09-06 23:57:36 +0530677/**
678 * @brief Set the reading field in the response.
679 *
680 * @param[in] offset - offset number.
681 * @param[in/out] resp - get sensor reading response.
682 */
George Liue6b2be52025-08-19 13:57:43 +0800683inline void setReading(uint8_t value, ipmi::sensor::GetSensorResponse& resp)
Tom Josephe4014fc2017-09-06 23:57:36 +0530684{
George Liue6b2be52025-08-19 13:57:43 +0800685 resp.reading = value;
Tom Josephe4014fc2017-09-06 23:57:36 +0530686}
687
Tom Joseph295f17e2017-09-07 00:09:46 +0530688/**
689 * @brief Map the value to the assertion bytes. The assertion states are stored
690 * in 2 bytes.
691 *
692 * @param[in] value - value to mapped to the assertion byte.
693 * @param[in/out] resp - get sensor reading response.
694 */
695inline void setAssertionBytes(uint16_t value,
George Liue6b2be52025-08-19 13:57:43 +0800696 ipmi::sensor::GetSensorResponse& resp)
Tom Joseph295f17e2017-09-07 00:09:46 +0530697{
George Liue6b2be52025-08-19 13:57:43 +0800698 resp.thresholdLevelsStates = static_cast<uint8_t>(value & 0x00FF);
699 resp.discreteReadingSensorStates = static_cast<uint8_t>(value >> 8);
Tom Joseph295f17e2017-09-07 00:09:46 +0530700}
701
Tom Josephe05b2922017-09-07 00:43:16 +0530702/**
703 * @brief Set the scanning enabled bit in the response.
704 *
705 * @param[in/out] resp - get sensor reading response.
706 */
George Liue6b2be52025-08-19 13:57:43 +0800707inline void enableScanning(ipmi::sensor::GetSensorResponse& resp)
Tom Josephe05b2922017-09-07 00:43:16 +0530708{
George Liue6b2be52025-08-19 13:57:43 +0800709 resp.readingOrStateUnavailable = false;
710 resp.scanningEnabled = true;
711 resp.allEventMessagesEnabled = false;
Tom Josephe05b2922017-09-07 00:43:16 +0530712}
713
Tom Joseph816e92b2017-09-06 19:23:00 +0530714} // namespace sensor
715
716} // namespace ipmi