blob: b67dfa6539254ea6eae27297b1cce88f00a67c92 [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;
Emily Shafferbbef71c2017-05-08 16:36:17 -070098 uint8_t sdr_version;
99 uint8_t record_type;
100 uint8_t record_length; // Length not counting the header
101} __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{
116 uint8_t owner_id;
117 uint8_t owner_lun;
118 uint8_t sensor_number;
119} __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
Emily Shafferbbef71c2017-05-08 16:36:17 -0700152inline void set_owner_id_ipmb(SensorDataRecordKey* key)
153{
154 key->owner_id &= ~0x01;
155};
156
157inline void set_owner_id_system_sw(SensorDataRecordKey* key)
158{
159 key->owner_id |= 0x01;
160};
161
Tom Joseph96423912018-01-25 00:14:34 +0530162inline void set_owner_id_bmc(SensorDataRecordKey* key)
163{
164 key->owner_id |= 0x20;
165};
166
Emily Shafferbbef71c2017-05-08 16:36:17 -0700167inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key)
168{
169 key->owner_id &= 0x01;
Patrick Venture0b02be92018-08-31 11:55:55 -0700170 key->owner_id |= addr << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700171};
172
173inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key)
174{
175 key->owner_lun &= ~0x03;
Patrick Venture0b02be92018-08-31 11:55:55 -0700176 key->owner_lun |= (lun & 0x03);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700177};
178
179inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key)
180{
181 key->owner_lun &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700182 key->owner_lun |= ((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,
186 SensorDataEntityRecordKey* key)
187{
188 key->flags = 0x00;
189 if (!isList)
190 key->flags |= 1 << listOrRangeBit;
191
192 if (isLinked)
193 key->flags |= 1 << linkedBit;
194};
195
Emily Shafferbbef71c2017-05-08 16:36:17 -0700196} // namespace key
197
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600198/** @struct GetSensorThresholdsResponse
199 *
200 * Response structure for Get Sensor Thresholds command
201 */
202struct GetSensorThresholdsResponse
203{
Patrick Venture0b02be92018-08-31 11:55:55 -0700204 uint8_t validMask; //!< valid mask
205 uint8_t lowerNonCritical; //!< lower non-critical threshold
206 uint8_t lowerCritical; //!< lower critical threshold
207 uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
208 uint8_t upperNonCritical; //!< upper non-critical threshold
209 uint8_t upperCritical; //!< upper critical threshold
210 uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600211} __attribute__((packed));
212
Emily Shafferbbef71c2017-05-08 16:36:17 -0700213// Body - full record
214#define FULL_RECORD_ID_STR_MAX_LENGTH 16
Ratan Guptae0cc8552018-01-22 14:23:04 +0530215
216static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
217
Emily Shafferbbef71c2017-05-08 16:36:17 -0700218struct SensorDataFullRecordBody
219{
220 uint8_t entity_id;
221 uint8_t entity_instance;
222 uint8_t sensor_initialization;
223 uint8_t sensor_capabilities; // no macro support
224 uint8_t sensor_type;
225 uint8_t event_reading_type;
Patrick Venture0b02be92018-08-31 11:55:55 -0700226 uint8_t supported_assertions[2]; // no macro support
227 uint8_t supported_deassertions[2]; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700228 uint8_t discrete_reading_setting_mask[2]; // no macro support
229 uint8_t sensor_units_1;
230 uint8_t sensor_units_2_base;
231 uint8_t sensor_units_3_modifier;
232 uint8_t linearization;
233 uint8_t m_lsb;
234 uint8_t m_msb_and_tolerance;
235 uint8_t b_lsb;
236 uint8_t b_msb_and_accuracy_lsb;
237 uint8_t accuracy_and_sensor_direction;
238 uint8_t r_b_exponents;
Patrick Venture0b02be92018-08-31 11:55:55 -0700239 uint8_t analog_characteristic_flags; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700240 uint8_t nominal_reading;
241 uint8_t normal_max;
242 uint8_t normal_min;
243 uint8_t sensor_max;
244 uint8_t sensor_min;
245 uint8_t upper_nonrecoverable_threshold;
246 uint8_t upper_critical_threshold;
247 uint8_t upper_noncritical_threshold;
248 uint8_t lower_nonrecoverable_threshold;
249 uint8_t lower_critical_threshold;
250 uint8_t lower_noncritical_threshold;
251 uint8_t positive_threshold_hysteresis;
252 uint8_t negative_threshold_hysteresis;
253 uint16_t reserved;
254 uint8_t oem_reserved;
255 uint8_t id_string_info;
Emily Shaffer10f49592017-05-10 12:01:10 -0700256 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
Emily Shafferbbef71c2017-05-08 16:36:17 -0700257} __attribute__((packed));
258
selvaganapathi7b2e5502023-02-14 07:10:47 +0530259/** @struct SensorDataCompactRecord
260 *
261 * Compact Sensor Record(body) - SDR Type 2
262 */
263struct SensorDataCompactRecordBody
264{
265 uint8_t entity_id;
266 uint8_t entity_instance;
267 uint8_t sensor_initialization;
268 uint8_t sensor_capabilities; // no macro support
269 uint8_t sensor_type;
270 uint8_t event_reading_type;
271 uint8_t supported_assertions[2]; // no macro support
272 uint8_t supported_deassertions[2]; // no macro support
273 uint8_t discrete_reading_setting_mask[2]; // no macro support
274 uint8_t sensor_units_1;
275 uint8_t sensor_units_2_base;
276 uint8_t sensor_units_3_modifier;
277 uint8_t record_sharing[2];
278 uint8_t positive_threshold_hysteresis;
279 uint8_t negative_threshold_hysteresis;
280 uint8_t reserved[3];
281 uint8_t oem_reserved;
282 uint8_t id_string_info;
283 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
284} __attribute__((packed));
285
Hao Jiangda06d152021-01-19 15:27:43 -0800286/** @struct SensorDataEventRecord
287 *
288 * Event Only Sensor Record(body) - SDR Type 3
289 */
290struct SensorDataEventRecordBody
291{
292 uint8_t entity_id;
293 uint8_t entity_instance;
294 uint8_t sensor_type;
295 uint8_t event_reading_type;
296 uint8_t sensor_record_sharing_1;
297 uint8_t sensor_record_sharing_2;
298 uint8_t reserved;
299 uint8_t oem_reserved;
300 uint8_t id_string_info;
301 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
302} __attribute__((packed));
303
Ratan Guptae0cc8552018-01-22 14:23:04 +0530304/** @struct SensorDataFruRecordBody
305 *
306 * FRU Device Locator Record(body) - SDR Type 11
307 */
308struct SensorDataFruRecordBody
309{
310 uint8_t reserved;
311 uint8_t deviceType;
312 uint8_t deviceTypeModifier;
313 uint8_t entityID;
314 uint8_t entityInstance;
315 uint8_t oem;
316 uint8_t deviceIDLen;
317 char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
318} __attribute__((packed));
319
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800320/** @struct SensorDataEntityRecordBody
321 *
322 * Entity Association Record(body) - SDR Type 8
323 */
324struct SensorDataEntityRecordBody
325{
326 uint8_t entityId2;
327 uint8_t entityInstance2;
328 uint8_t entityId3;
329 uint8_t entityInstance3;
330 uint8_t entityId4;
331 uint8_t entityInstance4;
332} __attribute__((packed));
333
Emily Shafferbbef71c2017-05-08 16:36:17 -0700334namespace body
335{
336
337inline void set_entity_instance_number(uint8_t n,
338 SensorDataFullRecordBody* body)
339{
Patrick Venture0b02be92018-08-31 11:55:55 -0700340 body->entity_instance &= 1 << 7;
341 body->entity_instance |= (n & ~(1 << 7));
Emily Shafferbbef71c2017-05-08 16:36:17 -0700342};
343inline void set_entity_physical_entity(SensorDataFullRecordBody* body)
344{
Patrick Venture0b02be92018-08-31 11:55:55 -0700345 body->entity_instance &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700346};
347inline void set_entity_logical_container(SensorDataFullRecordBody* body)
348{
Patrick Venture0b02be92018-08-31 11:55:55 -0700349 body->entity_instance |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700350};
351
Patrick Venture0b02be92018-08-31 11:55:55 -0700352inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700353{
354 if (enabled)
355 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700356 body->sensor_initialization |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700357 }
358 else
359 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700360 body->sensor_initialization &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700361 };
362};
Patrick Venture0b02be92018-08-31 11:55:55 -0700363inline void event_generation_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700364{
365 if (enabled)
366 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700367 body->sensor_initialization |= 1 << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700368 }
369 else
370 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700371 body->sensor_initialization &= ~(1 << 1);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700372 }
373};
Patrick Venture0b02be92018-08-31 11:55:55 -0700374inline void init_types_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700375{
376 if (enabled)
377 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700378 body->sensor_initialization |= 1 << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700379 }
380 else
381 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700382 body->sensor_initialization &= ~(1 << 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700383 }
384};
Patrick Venture0b02be92018-08-31 11:55:55 -0700385inline void init_hyst_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700386{
387 if (enabled)
388 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700389 body->sensor_initialization |= 1 << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700390 }
391 else
392 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700393 body->sensor_initialization &= ~(1 << 3);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700394 }
395};
Patrick Venture0b02be92018-08-31 11:55:55 -0700396inline void init_thresh_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700397{
398 if (enabled)
399 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700400 body->sensor_initialization |= 1 << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700401 }
402 else
403 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700404 body->sensor_initialization &= ~(1 << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700405 }
406};
Patrick Venture0b02be92018-08-31 11:55:55 -0700407inline void init_events_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700408{
409 if (enabled)
410 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700411 body->sensor_initialization |= 1 << 5;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700412 }
413 else
414 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700415 body->sensor_initialization &= ~(1 << 5);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700416 }
417};
Patrick Venture0b02be92018-08-31 11:55:55 -0700418inline void init_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700419{
420 if (enabled)
421 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700422 body->sensor_initialization |= 1 << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700423 }
424 else
425 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700426 body->sensor_initialization &= ~(1 << 6);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700427 }
428};
Patrick Venture0b02be92018-08-31 11:55:55 -0700429inline void init_settable_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700430{
431 if (enabled)
432 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700433 body->sensor_initialization |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700434 }
435 else
436 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700437 body->sensor_initialization &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700438 }
439};
440
441inline void set_percentage(SensorDataFullRecordBody* body)
442{
Patrick Venture0b02be92018-08-31 11:55:55 -0700443 body->sensor_units_1 |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700444};
445inline void unset_percentage(SensorDataFullRecordBody* body)
446{
Patrick Venture0b02be92018-08-31 11:55:55 -0700447 body->sensor_units_1 &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700448};
449inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body)
450{
Patrick Venture0b02be92018-08-31 11:55:55 -0700451 body->sensor_units_1 &= ~(3 << 1);
452 body->sensor_units_1 |= (op & 0x3) << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700453};
454inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body)
455{
Patrick Venture0b02be92018-08-31 11:55:55 -0700456 body->sensor_units_1 &= ~(7 << 3);
457 body->sensor_units_1 |= (unit & 0x7) << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700458};
459inline void set_analog_data_format(uint8_t format,
460 SensorDataFullRecordBody* body)
461{
Patrick Venture0b02be92018-08-31 11:55:55 -0700462 body->sensor_units_1 &= ~(3 << 6);
463 body->sensor_units_1 |= (format & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700464};
465
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700466inline void set_m(uint16_t m, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700467{
468 body->m_lsb = m & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700469 body->m_msb_and_tolerance &= ~(3 << 6);
470 body->m_msb_and_tolerance |= ((m & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700471};
472inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body)
473{
474 body->m_msb_and_tolerance &= ~0x3f;
475 body->m_msb_and_tolerance |= tol & 0x3f;
476};
477
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700478inline void set_b(uint16_t b, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700479{
480 body->b_lsb = b & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700481 body->b_msb_and_accuracy_lsb &= ~(3 << 6);
482 body->b_msb_and_accuracy_lsb |= ((b & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700483};
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700484inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700485{
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700486 // bottom 6 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700487 body->b_msb_and_accuracy_lsb &= ~0x3f;
488 body->b_msb_and_accuracy_lsb |= acc & 0x3f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700489 // top 4 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700490 body->accuracy_and_sensor_direction &= 0x0f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700491 body->accuracy_and_sensor_direction |= ((acc >> 6) & 0xf) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700492};
493inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body)
494{
Patrick Venture0b02be92018-08-31 11:55:55 -0700495 body->accuracy_and_sensor_direction &= ~(3 << 2);
496 body->accuracy_and_sensor_direction |= (exp & 3) << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700497};
498inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body)
499{
Patrick Venture0b02be92018-08-31 11:55:55 -0700500 body->accuracy_and_sensor_direction &= ~(3 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700501 body->accuracy_and_sensor_direction |= (dir & 3);
502};
503
504inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body)
505{
506 body->r_b_exponents &= 0xf0;
507 body->r_b_exponents |= exp & 0x0f;
508};
509inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body)
510{
511 body->r_b_exponents &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700512 body->r_b_exponents |= (exp & 0x0f) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700513};
514
515inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body)
516{
517 body->id_string_info &= ~(0x1f);
518 body->id_string_info |= len & 0x1f;
519};
Willy Tueae88592022-12-13 14:28:02 -0800520inline void set_id_strlen(uint8_t len, SensorDataEventRecordBody* body)
521{
522 body->id_string_info &= ~(0x1f);
523 body->id_string_info |= len & 0x1f;
524};
Patrick Venture0b02be92018-08-31 11:55:55 -0700525inline uint8_t get_id_strlen(SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700526{
527 return body->id_string_info & 0x1f;
528};
529inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body)
530{
Patrick Venture0b02be92018-08-31 11:55:55 -0700531 body->id_string_info &= ~(3 << 6);
532 body->id_string_info |= (type & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700533};
Willy Tueae88592022-12-13 14:28:02 -0800534inline void set_id_type(uint8_t type, SensorDataEventRecordBody* body)
535{
536 body->id_string_info &= ~(3 << 6);
537 body->id_string_info |= (type & 0x3) << 6;
538};
Emily Shafferbbef71c2017-05-08 16:36:17 -0700539
Ratan Guptae0cc8552018-01-22 14:23:04 +0530540inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody* body)
541{
542 body->deviceIDLen &= ~(LENGTH_MASK);
543 body->deviceIDLen |= len & LENGTH_MASK;
544};
545
546inline uint8_t get_device_id_strlen(SensorDataFruRecordBody* body)
547{
548 return body->deviceIDLen & LENGTH_MASK;
549};
550
Tom Josephdc212b22018-02-16 09:59:57 +0530551inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody* body)
552{
553 body->discrete_reading_setting_mask[1] = mask & 0x3F;
554}
555
Emily Shafferbbef71c2017-05-08 16:36:17 -0700556} // namespace body
557
558// More types contained in section 43.17 Sensor Unit Type Codes,
559// IPMI spec v2 rev 1.1
560enum SensorUnitTypeCodes
561{
562 SENSOR_UNIT_UNSPECIFIED = 0,
563 SENSOR_UNIT_DEGREES_C = 1,
564 SENSOR_UNIT_VOLTS = 4,
565 SENSOR_UNIT_AMPERES = 5,
Tom Josephdc212b22018-02-16 09:59:57 +0530566 SENSOR_UNIT_WATTS = 6,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700567 SENSOR_UNIT_JOULES = 7,
Kirill Pakhomov812e44c2018-10-22 16:25:35 +0300568 SENSOR_UNIT_RPM = 18,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700569 SENSOR_UNIT_METERS = 34,
570 SENSOR_UNIT_REVOLUTIONS = 41,
571};
572
573struct SensorDataFullRecord
574{
575 SensorDataRecordHeader header;
576 SensorDataRecordKey key;
577 SensorDataFullRecordBody body;
578} __attribute__((packed));
579
selvaganapathi7b2e5502023-02-14 07:10:47 +0530580/** @struct SensorDataComapactRecord
581 *
582 * Compact Sensor Record - SDR Type 2
583 */
584struct SensorDataCompactRecord
585{
586 SensorDataRecordHeader header;
587 SensorDataRecordKey key;
588 SensorDataCompactRecordBody body;
589} __attribute__((packed));
590
Hao Jiangda06d152021-01-19 15:27:43 -0800591/** @struct SensorDataEventRecord
592 *
593 * Event Only Sensor Record - SDR Type 3
594 */
595struct SensorDataEventRecord
596{
597 SensorDataRecordHeader header;
598 SensorDataRecordKey key;
599 SensorDataEventRecordBody body;
600} __attribute__((packed));
601
Ratan Guptae0cc8552018-01-22 14:23:04 +0530602/** @struct SensorDataFruRecord
603 *
604 * FRU Device Locator Record - SDR Type 11
605 */
606struct SensorDataFruRecord
607{
608 SensorDataRecordHeader header;
609 SensorDataFruRecordKey key;
610 SensorDataFruRecordBody body;
611} __attribute__((packed));
612
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800613/** @struct SensorDataEntityRecord
614 *
615 * Entity Association Record - SDR Type 8
616 */
617struct SensorDataEntityRecord
618{
619 SensorDataRecordHeader header;
620 SensorDataEntityRecordKey key;
621 SensorDataEntityRecordBody body;
622} __attribute__((packed));
623
Patrick Venture0b02be92018-08-31 11:55:55 -0700624} // namespace get_sdr
Tom Joseph816e92b2017-09-06 19:23:00 +0530625
626namespace ipmi
627{
628
629namespace sensor
630{
631
632/**
633 * @brief Map offset to the corresponding bit in the assertion byte.
634 *
Gunnar Mills8991dd62017-10-25 17:11:29 -0500635 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
Tom Joseph816e92b2017-09-06 19:23:00 +0530636 * byte and offsets 8-14 in the second byte.
637 *
638 * @param[in] offset - offset number.
639 * @param[in/out] resp - get sensor reading response.
640 */
Sui Chen4cc42552019-09-11 10:28:35 -0700641inline void setOffset(uint8_t offset, ipmi::sensor::GetSensorResponse* resp)
Tom Joseph816e92b2017-09-06 19:23:00 +0530642{
643 if (offset > 7)
644 {
Sui Chen4cc42552019-09-11 10:28:35 -0700645 resp->discreteReadingSensorStates |= 1 << (offset - 8);
Tom Joseph816e92b2017-09-06 19:23:00 +0530646 }
647 else
648 {
Sui Chen4cc42552019-09-11 10:28:35 -0700649 resp->thresholdLevelsStates |= 1 << offset;
Tom Joseph816e92b2017-09-06 19:23:00 +0530650 }
651}
652
Tom Josephe4014fc2017-09-06 23:57:36 +0530653/**
654 * @brief Set the reading field in the response.
655 *
656 * @param[in] offset - offset number.
657 * @param[in/out] resp - get sensor reading response.
658 */
Sui Chen4cc42552019-09-11 10:28:35 -0700659inline void setReading(uint8_t value, ipmi::sensor::GetSensorResponse* resp)
Tom Josephe4014fc2017-09-06 23:57:36 +0530660{
661 resp->reading = value;
662}
663
Tom Joseph295f17e2017-09-07 00:09:46 +0530664/**
665 * @brief Map the value to the assertion bytes. The assertion states are stored
666 * in 2 bytes.
667 *
668 * @param[in] value - value to mapped to the assertion byte.
669 * @param[in/out] resp - get sensor reading response.
670 */
671inline void setAssertionBytes(uint16_t value,
Sui Chen4cc42552019-09-11 10:28:35 -0700672 ipmi::sensor::GetSensorResponse* resp)
Tom Joseph295f17e2017-09-07 00:09:46 +0530673{
Sui Chen4cc42552019-09-11 10:28:35 -0700674 resp->thresholdLevelsStates = static_cast<uint8_t>(value & 0x00FF);
675 resp->discreteReadingSensorStates = static_cast<uint8_t>(value >> 8);
Tom Joseph295f17e2017-09-07 00:09:46 +0530676}
677
Tom Josephe05b2922017-09-07 00:43:16 +0530678/**
679 * @brief Set the scanning enabled bit in the response.
680 *
681 * @param[in/out] resp - get sensor reading response.
682 */
Sui Chen4cc42552019-09-11 10:28:35 -0700683inline void enableScanning(ipmi::sensor::GetSensorResponse* resp)
Tom Josephe05b2922017-09-07 00:43:16 +0530684{
Sui Chen4cc42552019-09-11 10:28:35 -0700685 resp->readingOrStateUnavailable = false;
686 resp->scanningEnabled = true;
687 resp->allEventMessagesEnabled = false;
Tom Josephe05b2922017-09-07 00:43:16 +0530688}
689
Tom Joseph816e92b2017-09-06 19:23:00 +0530690} // namespace sensor
691
692} // namespace ipmi