blob: 5d58a6c9287211514ac9cceef2e60bb617da3ada [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 Liue6b2be52025-08-19 13:57:43 +0800152inline void set_owner_id_ipmb(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 Liue6b2be52025-08-19 13:57:43 +0800157inline void set_owner_id_system_sw(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 Liue6b2be52025-08-19 13:57:43 +0800162inline void set_owner_id_bmc(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 Liue6b2be52025-08-19 13:57:43 +0800167inline void set_owner_id_address(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 Liue6b2be52025-08-19 13:57:43 +0800173inline void set_owner_lun(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 Liue6b2be52025-08-19 13:57:43 +0800179inline void set_owner_lun_channel(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
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800185inline void set_flags(bool isList, bool isLinked,
George Liue6b2be52025-08-19 13:57:43 +0800186 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
341inline void set_entity_instance_number(uint8_t n,
George Liue6b2be52025-08-19 13:57:43 +0800342 SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700343{
George Liu42247d22025-08-19 10:24:47 +0800344 body.entityInstance &= 1 << 7;
345 body.entityInstance |= (n & ~(1 << 7));
Emily Shafferbbef71c2017-05-08 16:36:17 -0700346};
347
George Liue6b2be52025-08-19 13:57:43 +0800348inline void set_entity_physical_entity(SensorDataFullRecordBody& body)
349{
George Liu42247d22025-08-19 10:24:47 +0800350 body.entityInstance &= ~(1 << 7);
George Liue6b2be52025-08-19 13:57:43 +0800351};
352
353inline void set_entity_logical_container(SensorDataFullRecordBody& body)
354{
George Liu42247d22025-08-19 10:24:47 +0800355 body.entityInstance |= 1 << 7;
George Liue6b2be52025-08-19 13:57:43 +0800356};
357
358inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700359{
360 if (enabled)
361 {
George Liu42247d22025-08-19 10:24:47 +0800362 body.sensorInitialization |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700363 }
364 else
365 {
George Liu42247d22025-08-19 10:24:47 +0800366 body.sensorInitialization &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700367 };
368};
George Liue6b2be52025-08-19 13:57:43 +0800369
370inline void event_generation_state(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700371{
372 if (enabled)
373 {
George Liu42247d22025-08-19 10:24:47 +0800374 body.sensorInitialization |= 1 << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700375 }
376 else
377 {
George Liu42247d22025-08-19 10:24:47 +0800378 body.sensorInitialization &= ~(1 << 1);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700379 }
380};
381
George Liue6b2be52025-08-19 13:57:43 +0800382inline void init_types_state(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700383{
George Liue6b2be52025-08-19 13:57:43 +0800384 if (enabled)
385 {
George Liu42247d22025-08-19 10:24:47 +0800386 body.sensorInitialization |= 1 << 2;
George Liue6b2be52025-08-19 13:57:43 +0800387 }
388 else
389 {
George Liu42247d22025-08-19 10:24:47 +0800390 body.sensorInitialization &= ~(1 << 2);
George Liue6b2be52025-08-19 13:57:43 +0800391 }
Emily Shafferbbef71c2017-05-08 16:36:17 -0700392};
George Liue6b2be52025-08-19 13:57:43 +0800393
394inline void init_hyst_state(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700395{
George Liue6b2be52025-08-19 13:57:43 +0800396 if (enabled)
397 {
George Liu42247d22025-08-19 10:24:47 +0800398 body.sensorInitialization |= 1 << 3;
George Liue6b2be52025-08-19 13:57:43 +0800399 }
400 else
401 {
George Liu42247d22025-08-19 10:24:47 +0800402 body.sensorInitialization &= ~(1 << 3);
George Liue6b2be52025-08-19 13:57:43 +0800403 }
Emily Shafferbbef71c2017-05-08 16:36:17 -0700404};
George Liue6b2be52025-08-19 13:57:43 +0800405
406inline void init_thresh_state(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700407{
George Liue6b2be52025-08-19 13:57:43 +0800408 if (enabled)
409 {
George Liu42247d22025-08-19 10:24:47 +0800410 body.sensorInitialization |= 1 << 4;
George Liue6b2be52025-08-19 13:57:43 +0800411 }
412 else
413 {
George Liu42247d22025-08-19 10:24:47 +0800414 body.sensorInitialization &= ~(1 << 4);
George Liue6b2be52025-08-19 13:57:43 +0800415 }
Emily Shafferbbef71c2017-05-08 16:36:17 -0700416};
George Liue6b2be52025-08-19 13:57:43 +0800417
418inline void init_events_state(bool enabled, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700419{
George Liue6b2be52025-08-19 13:57:43 +0800420 if (enabled)
421 {
George Liu42247d22025-08-19 10:24:47 +0800422 body.sensorInitialization |= 1 << 5;
George Liue6b2be52025-08-19 13:57:43 +0800423 }
424 else
425 {
George Liu42247d22025-08-19 10:24:47 +0800426 body.sensorInitialization &= ~(1 << 5);
George Liue6b2be52025-08-19 13:57:43 +0800427 }
Emily Shafferbbef71c2017-05-08 16:36:17 -0700428};
George Liue6b2be52025-08-19 13:57:43 +0800429
430inline void init_scanning_state(bool enabled, SensorDataFullRecordBody& body)
431{
432 if (enabled)
433 {
George Liu42247d22025-08-19 10:24:47 +0800434 body.sensorInitialization |= 1 << 6;
George Liue6b2be52025-08-19 13:57:43 +0800435 }
436 else
437 {
George Liu42247d22025-08-19 10:24:47 +0800438 body.sensorInitialization &= ~(1 << 6);
George Liue6b2be52025-08-19 13:57:43 +0800439 }
440};
441
442inline void init_settable_state(bool enabled, SensorDataFullRecordBody& body)
443{
444 if (enabled)
445 {
George Liu42247d22025-08-19 10:24:47 +0800446 body.sensorInitialization |= 1 << 7;
George Liue6b2be52025-08-19 13:57:43 +0800447 }
448 else
449 {
George Liu42247d22025-08-19 10:24:47 +0800450 body.sensorInitialization &= ~(1 << 7);
George Liue6b2be52025-08-19 13:57:43 +0800451 }
452};
453
454inline void set_percentage(SensorDataFullRecordBody& body)
455{
George Liu42247d22025-08-19 10:24:47 +0800456 body.sensorUnits1 |= 1 << 0;
George Liue6b2be52025-08-19 13:57:43 +0800457};
458
459inline void unset_percentage(SensorDataFullRecordBody& body)
460{
George Liu42247d22025-08-19 10:24:47 +0800461 body.sensorUnits1 &= ~(1 << 0);
George Liue6b2be52025-08-19 13:57:43 +0800462};
463
464inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody& body)
465{
George Liu42247d22025-08-19 10:24:47 +0800466 body.sensorUnits1 &= ~(3 << 1);
467 body.sensorUnits1 |= (op & 0x3) << 1;
George Liue6b2be52025-08-19 13:57:43 +0800468};
469
470inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody& body)
471{
George Liu42247d22025-08-19 10:24:47 +0800472 body.sensorUnits1 &= ~(7 << 3);
473 body.sensorUnits1 |= (unit & 0x7) << 3;
George Liue6b2be52025-08-19 13:57:43 +0800474};
475
Emily Shafferbbef71c2017-05-08 16:36:17 -0700476inline void set_analog_data_format(uint8_t format,
George Liue6b2be52025-08-19 13:57:43 +0800477 SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700478{
George Liu42247d22025-08-19 10:24:47 +0800479 body.sensorUnits1 &= ~(3 << 6);
480 body.sensorUnits1 |= (format & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700481};
482
George Liue6b2be52025-08-19 13:57:43 +0800483inline void set_m(uint16_t m, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700484{
George Liu42247d22025-08-19 10:24:47 +0800485 body.mLsb = m & 0xff;
486 body.mMsbAndTolerance &= ~(3 << 6);
487 body.mMsbAndTolerance |= ((m & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700488};
489
George Liue6b2be52025-08-19 13:57:43 +0800490inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700491{
George Liu42247d22025-08-19 10:24:47 +0800492 body.mMsbAndTolerance &= ~0x3f;
493 body.mMsbAndTolerance |= tol & 0x3f;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700494};
George Liue6b2be52025-08-19 13:57:43 +0800495
496inline void set_b(uint16_t b, SensorDataFullRecordBody& body)
497{
George Liu42247d22025-08-19 10:24:47 +0800498 body.bLsb = b & 0xff;
499 body.bMsbAndAccuracyLsb &= ~(3 << 6);
500 body.bMsbAndAccuracyLsb |= ((b & (3 << 8)) >> 2);
George Liue6b2be52025-08-19 13:57:43 +0800501};
502
503inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700504{
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700505 // bottom 6 bits
George Liu42247d22025-08-19 10:24:47 +0800506 body.bMsbAndAccuracyLsb &= ~0x3f;
507 body.bMsbAndAccuracyLsb |= acc & 0x3f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700508 // top 4 bits
George Liu42247d22025-08-19 10:24:47 +0800509 body.accuracyAndSensorDirection &= 0x0f;
510 body.accuracyAndSensorDirection |= ((acc >> 6) & 0xf) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700511};
512
George Liue6b2be52025-08-19 13:57:43 +0800513inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700514{
George Liu42247d22025-08-19 10:24:47 +0800515 body.accuracyAndSensorDirection &= ~(3 << 2);
516 body.accuracyAndSensorDirection |= (exp & 3) << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700517};
518
George Liue6b2be52025-08-19 13:57:43 +0800519inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody& body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700520{
George Liu42247d22025-08-19 10:24:47 +0800521 body.accuracyAndSensorDirection &= ~(3 << 0);
522 body.accuracyAndSensorDirection |= (dir & 3);
Willy Tueae88592022-12-13 14:28:02 -0800523};
Emily Shafferbbef71c2017-05-08 16:36:17 -0700524
George Liue6b2be52025-08-19 13:57:43 +0800525inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody& body)
Ratan Guptae0cc8552018-01-22 14:23:04 +0530526{
George Liu42247d22025-08-19 10:24:47 +0800527 body.rbExponents &= 0xf0;
528 body.rbExponents |= exp & 0x0f;
Ratan Guptae0cc8552018-01-22 14:23:04 +0530529};
530
George Liue6b2be52025-08-19 13:57:43 +0800531inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody& body)
Ratan Guptae0cc8552018-01-22 14:23:04 +0530532{
George Liu42247d22025-08-19 10:24:47 +0800533 body.rbExponents &= 0x0f;
534 body.rbExponents |= (exp & 0x0f) << 4;
Ratan Guptae0cc8552018-01-22 14:23:04 +0530535};
536
George Liue6b2be52025-08-19 13:57:43 +0800537inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody& body)
Tom Josephdc212b22018-02-16 09:59:57 +0530538{
George Liu42247d22025-08-19 10:24:47 +0800539 body.idStringInfo &= ~(0x1f);
540 body.idStringInfo |= len & 0x1f;
George Liue6b2be52025-08-19 13:57:43 +0800541};
542
543inline void set_id_strlen(uint8_t len, SensorDataEventRecordBody& body)
544{
George Liu42247d22025-08-19 10:24:47 +0800545 body.idStringInfo &= ~(0x1f);
546 body.idStringInfo |= len & 0x1f;
George Liue6b2be52025-08-19 13:57:43 +0800547};
548
549inline uint8_t get_id_strlen(const SensorDataFullRecordBody& body)
550{
George Liu42247d22025-08-19 10:24:47 +0800551 return body.idStringInfo & 0x1f;
George Liue6b2be52025-08-19 13:57:43 +0800552};
553
554inline void set_id_type(uint8_t type, SensorDataFullRecordBody& body)
555{
George Liu42247d22025-08-19 10:24:47 +0800556 body.idStringInfo &= ~(3 << 6);
557 body.idStringInfo |= (type & 0x3) << 6;
George Liue6b2be52025-08-19 13:57:43 +0800558};
559
560inline void set_id_type(uint8_t type, SensorDataEventRecordBody& body)
561{
George Liu42247d22025-08-19 10:24:47 +0800562 body.idStringInfo &= ~(3 << 6);
563 body.idStringInfo |= (type & 0x3) << 6;
George Liue6b2be52025-08-19 13:57:43 +0800564};
565
566inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody& body)
567{
568 body.deviceIDLen &= ~(LENGTH_MASK);
569 body.deviceIDLen |= len & LENGTH_MASK;
570};
571
572inline uint8_t get_device_id_strlen(const SensorDataFruRecordBody& body)
573{
574 return body.deviceIDLen & LENGTH_MASK;
575};
576
577inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody& body)
578{
George Liu42247d22025-08-19 10:24:47 +0800579 body.discreteReadingSettingMask[1] = mask & 0x3F;
Tom Josephdc212b22018-02-16 09:59:57 +0530580}
581
Emily Shafferbbef71c2017-05-08 16:36:17 -0700582} // namespace body
583
584// More types contained in section 43.17 Sensor Unit Type Codes,
585// IPMI spec v2 rev 1.1
586enum SensorUnitTypeCodes
587{
588 SENSOR_UNIT_UNSPECIFIED = 0,
589 SENSOR_UNIT_DEGREES_C = 1,
590 SENSOR_UNIT_VOLTS = 4,
591 SENSOR_UNIT_AMPERES = 5,
Tom Josephdc212b22018-02-16 09:59:57 +0530592 SENSOR_UNIT_WATTS = 6,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700593 SENSOR_UNIT_JOULES = 7,
Kirill Pakhomov812e44c2018-10-22 16:25:35 +0300594 SENSOR_UNIT_RPM = 18,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700595 SENSOR_UNIT_METERS = 34,
596 SENSOR_UNIT_REVOLUTIONS = 41,
597};
598
599struct SensorDataFullRecord
600{
601 SensorDataRecordHeader header;
602 SensorDataRecordKey key;
603 SensorDataFullRecordBody body;
604} __attribute__((packed));
605
selvaganapathi7b2e5502023-02-14 07:10:47 +0530606/** @struct SensorDataComapactRecord
607 *
608 * Compact Sensor Record - SDR Type 2
609 */
610struct SensorDataCompactRecord
611{
612 SensorDataRecordHeader header;
613 SensorDataRecordKey key;
614 SensorDataCompactRecordBody body;
615} __attribute__((packed));
616
Hao Jiangda06d152021-01-19 15:27:43 -0800617/** @struct SensorDataEventRecord
618 *
619 * Event Only Sensor Record - SDR Type 3
620 */
621struct SensorDataEventRecord
622{
623 SensorDataRecordHeader header;
624 SensorDataRecordKey key;
625 SensorDataEventRecordBody body;
626} __attribute__((packed));
627
Ratan Guptae0cc8552018-01-22 14:23:04 +0530628/** @struct SensorDataFruRecord
629 *
630 * FRU Device Locator Record - SDR Type 11
631 */
632struct SensorDataFruRecord
633{
634 SensorDataRecordHeader header;
635 SensorDataFruRecordKey key;
636 SensorDataFruRecordBody body;
637} __attribute__((packed));
638
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800639/** @struct SensorDataEntityRecord
640 *
641 * Entity Association Record - SDR Type 8
642 */
643struct SensorDataEntityRecord
644{
645 SensorDataRecordHeader header;
646 SensorDataEntityRecordKey key;
647 SensorDataEntityRecordBody body;
648} __attribute__((packed));
649
Patrick Venture0b02be92018-08-31 11:55:55 -0700650} // namespace get_sdr
Tom Joseph816e92b2017-09-06 19:23:00 +0530651
652namespace ipmi
653{
654
655namespace sensor
656{
657
658/**
659 * @brief Map offset to the corresponding bit in the assertion byte.
660 *
Gunnar Mills8991dd62017-10-25 17:11:29 -0500661 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
Tom Joseph816e92b2017-09-06 19:23:00 +0530662 * byte and offsets 8-14 in the second byte.
663 *
664 * @param[in] offset - offset number.
665 * @param[in/out] resp - get sensor reading response.
666 */
George Liue6b2be52025-08-19 13:57:43 +0800667inline void setOffset(uint8_t offset, ipmi::sensor::GetSensorResponse& resp)
Tom Joseph816e92b2017-09-06 19:23:00 +0530668{
669 if (offset > 7)
670 {
George Liue6b2be52025-08-19 13:57:43 +0800671 resp.discreteReadingSensorStates |= 1 << (offset - 8);
Tom Joseph816e92b2017-09-06 19:23:00 +0530672 }
673 else
674 {
George Liue6b2be52025-08-19 13:57:43 +0800675 resp.thresholdLevelsStates |= 1 << offset;
Tom Joseph816e92b2017-09-06 19:23:00 +0530676 }
677}
678
Tom Josephe4014fc2017-09-06 23:57:36 +0530679/**
680 * @brief Set the reading field in the response.
681 *
682 * @param[in] offset - offset number.
683 * @param[in/out] resp - get sensor reading response.
684 */
George Liue6b2be52025-08-19 13:57:43 +0800685inline void setReading(uint8_t value, ipmi::sensor::GetSensorResponse& resp)
Tom Josephe4014fc2017-09-06 23:57:36 +0530686{
George Liue6b2be52025-08-19 13:57:43 +0800687 resp.reading = value;
Tom Josephe4014fc2017-09-06 23:57:36 +0530688}
689
Tom Joseph295f17e2017-09-07 00:09:46 +0530690/**
691 * @brief Map the value to the assertion bytes. The assertion states are stored
692 * in 2 bytes.
693 *
694 * @param[in] value - value to mapped to the assertion byte.
695 * @param[in/out] resp - get sensor reading response.
696 */
697inline void setAssertionBytes(uint16_t value,
George Liue6b2be52025-08-19 13:57:43 +0800698 ipmi::sensor::GetSensorResponse& resp)
Tom Joseph295f17e2017-09-07 00:09:46 +0530699{
George Liue6b2be52025-08-19 13:57:43 +0800700 resp.thresholdLevelsStates = static_cast<uint8_t>(value & 0x00FF);
701 resp.discreteReadingSensorStates = static_cast<uint8_t>(value >> 8);
Tom Joseph295f17e2017-09-07 00:09:46 +0530702}
703
Tom Josephe05b2922017-09-07 00:43:16 +0530704/**
705 * @brief Set the scanning enabled bit in the response.
706 *
707 * @param[in/out] resp - get sensor reading response.
708 */
George Liue6b2be52025-08-19 13:57:43 +0800709inline void enableScanning(ipmi::sensor::GetSensorResponse& resp)
Tom Josephe05b2922017-09-07 00:43:16 +0530710{
George Liue6b2be52025-08-19 13:57:43 +0800711 resp.readingOrStateUnavailable = false;
712 resp.scanningEnabled = true;
713 resp.allEventMessagesEnabled = false;
Tom Josephe05b2922017-09-07 00:43:16 +0530714}
715
Tom Joseph816e92b2017-09-06 19:23:00 +0530716} // namespace sensor
717
718} // namespace ipmi