blob: 6e196666483d91bdd544117b9a0e55f9a7a45b9a [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
Chris Austenac4604a2015-10-13 12:43:27 -050010// IPMI commands for net functions.
11enum ipmi_netfn_sen_cmds
12{
Jia, Chunhui3342a8e2018-12-29 13:32:26 +080013 IPMI_CMD_PLATFORM_EVENT = 0x2,
Tom Joseph5ca50952018-02-22 00:33:38 +053014 IPMI_CMD_GET_DEVICE_SDR_INFO = 0x20,
Patrick Venture0b02be92018-08-31 11:55:55 -070015 IPMI_CMD_GET_DEVICE_SDR = 0x21,
16 IPMI_CMD_RESERVE_DEVICE_SDR_REPO = 0x22,
Chris Austen10ccc0f2015-12-10 18:27:04 -060017 IPMI_CMD_GET_SENSOR_READING = 0x2D,
Patrick Venture0b02be92018-08-31 11:55:55 -070018 IPMI_CMD_GET_SENSOR_TYPE = 0x2F,
19 IPMI_CMD_SET_SENSOR = 0x30,
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -060020 IPMI_CMD_GET_SENSOR_THRESHOLDS = 0x27,
Chris Austenac4604a2015-10-13 12:43:27 -050021};
22
Ratan Guptae0cc8552018-01-22 14:23:04 +053023/**
24 * @enum device_type
25 * IPMI FRU device types
26 */
27enum device_type
28{
29 IPMI_PHYSICAL_FRU = 0x00,
30 IPMI_LOGICAL_FRU = 0x80,
31};
32
Emily Shaffer1fabf222017-04-05 08:53:21 -070033// Discrete sensor types.
34enum ipmi_sensor_types
35{
Patrick Venture0b02be92018-08-31 11:55:55 -070036 IPMI_SENSOR_TEMP = 0x01,
Emily Shaffer1fabf222017-04-05 08:53:21 -070037 IPMI_SENSOR_VOLTAGE = 0x02,
38 IPMI_SENSOR_CURRENT = 0x03,
Patrick Venture0b02be92018-08-31 11:55:55 -070039 IPMI_SENSOR_FAN = 0x04,
40 IPMI_SENSOR_TPM = 0xCC,
Emily Shaffer1fabf222017-04-05 08:53:21 -070041};
42
Brandon Kim9cf85622019-06-19 12:05:08 -070043/** @brief Custom exception for reading sensors that are not funcitonal.
44 */
45struct SensorFunctionalError : public std::exception
46{
47 const char* what() const noexcept
48 {
49 return "Sensor not functional";
50 }
51};
52
Chris Austen0012e9b2015-10-22 01:37:46 -050053#define MAX_DBUS_PATH 128
Patrick Venture0b02be92018-08-31 11:55:55 -070054struct dbus_interface_t
55{
56 uint8_t sensornumber;
57 uint8_t sensortype;
Chris Austen0012e9b2015-10-22 01:37:46 -050058
Patrick Venture0b02be92018-08-31 11:55:55 -070059 char bus[MAX_DBUS_PATH];
60 char path[MAX_DBUS_PATH];
61 char interface[MAX_DBUS_PATH];
Chris Austen0012e9b2015-10-22 01:37:46 -050062};
Tomd700e762016-09-20 18:24:13 +053063
Jia, Chunhui3342a8e2018-12-29 13:32:26 +080064struct PlatformEventRequest
65{
66 uint8_t eventMessageRevision;
67 uint8_t sensorType;
68 uint8_t sensorNumber;
69 uint8_t eventDirectionType;
70 uint8_t data[3];
71};
72
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050073static constexpr const char* ipmiSELPath = "/xyz/openbmc_project/Logging/IPMI";
74static constexpr const char* ipmiSELAddInterface =
Jia, Chunhui3342a8e2018-12-29 13:32:26 +080075 "xyz.openbmc_project.Logging.IPMI";
Konstantin Aladyshevb5160f52023-04-19 14:45:06 +030076static const std::string ipmiSELAddMessage = "IPMI generated SEL Entry";
Jia, Chunhui3342a8e2018-12-29 13:32:26 +080077
78static constexpr int selSystemEventSizeWith3Bytes = 8;
79static constexpr int selSystemEventSizeWith2Bytes = 7;
80static constexpr int selSystemEventSizeWith1Bytes = 6;
81static constexpr int selIPMBEventSize = 7;
82static constexpr uint8_t directionMask = 0x80;
83static constexpr uint8_t byte3EnableMask = 0x30;
84static constexpr uint8_t byte2EnableMask = 0xC0;
85
Patrick Venture0b02be92018-08-31 11:55:55 -070086int set_sensor_dbus_state_s(uint8_t, const char*, const char*);
87int set_sensor_dbus_state_y(uint8_t, const char*, const uint8_t);
88int find_openbmc_path(uint8_t, dbus_interface_t*);
Tom05732372016-09-06 17:21:23 +053089
Tom Joseph5ca50952018-02-22 00:33:38 +053090ipmi_ret_t ipmi_sen_get_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
91 ipmi_request_t request, ipmi_response_t response,
92 ipmi_data_len_t data_len, ipmi_context_t context);
93
jayaprakash Mutyalad9578232019-05-13 20:22:50 +000094ipmi::RspType<uint16_t> ipmiSensorReserveSdr();
Tom Joseph5ca50952018-02-22 00:33:38 +053095
Ratan Guptae0cc8552018-01-22 14:23:04 +053096static const uint16_t FRU_RECORD_ID_START = 256;
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -080097static const uint16_t ENTITY_RECORD_ID_START = 512;
Ratan Guptae0cc8552018-01-22 14:23:04 +053098static const uint8_t SDR_VERSION = 0x51;
99static const uint16_t END_OF_RECORD = 0xFFFF;
100static const uint8_t LENGTH_MASK = 0x1F;
101
Tom Josephbe703f72017-03-09 12:34:35 +0530102/**
Emily Shafferd06e0e72017-04-05 09:08:57 -0700103 * Get SDR Info
104 */
105
106namespace get_sdr_info
107{
108namespace request
109{
110// Note: for some reason the ipmi_request_t appears to be the
111// raw value for this call.
112inline bool get_count(void* req)
113{
Patrick Williams369824e2023-10-20 11:18:23 -0500114 return (bool)((uint64_t)(req) & 1);
Emily Shafferd06e0e72017-04-05 09:08:57 -0700115}
116} // namespace request
Emily Shafferd06e0e72017-04-05 09:08:57 -0700117} // namespace get_sdr_info
Emily Shafferbbef71c2017-05-08 16:36:17 -0700118
119/**
120 * Get SDR
121 */
122namespace get_sdr
123{
124
125struct GetSdrReq
126{
127 uint8_t reservation_id_lsb;
128 uint8_t reservation_id_msb;
129 uint8_t record_id_lsb;
130 uint8_t record_id_msb;
131 uint8_t offset;
132 uint8_t bytes_to_read;
133} __attribute__((packed));
134
135namespace request
136{
137
Emily Shaffere5c9d2f2019-06-25 14:26:45 -0700138inline uint16_t get_reservation_id(GetSdrReq* req)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700139{
140 return (req->reservation_id_lsb + (req->reservation_id_msb << 8));
141};
142
Ratan Guptae0cc8552018-01-22 14:23:04 +0530143inline uint16_t get_record_id(GetSdrReq* req)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700144{
145 return (req->record_id_lsb + (req->record_id_msb << 8));
146};
147
148} // namespace request
149
150// Response
151struct GetSdrResp
152{
153 uint8_t next_record_id_lsb;
154 uint8_t next_record_id_msb;
155 uint8_t record_data[64];
156} __attribute__((packed));
157
158namespace response
159{
160
Ratan Guptae0cc8552018-01-22 14:23:04 +0530161inline void set_next_record_id(uint16_t next, GetSdrResp* resp)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700162{
163 resp->next_record_id_lsb = next & 0xff;
164 resp->next_record_id_msb = (next >> 8) & 0xff;
165};
166
167} // namespace response
168
169// Record header
170struct SensorDataRecordHeader
171{
172 uint8_t record_id_lsb;
173 uint8_t record_id_msb;
174 uint8_t sdr_version;
175 uint8_t record_type;
176 uint8_t record_length; // Length not counting the header
177} __attribute__((packed));
178
179namespace header
180{
181
182inline void set_record_id(int id, SensorDataRecordHeader* hdr)
183{
184 hdr->record_id_lsb = (id & 0xFF);
185 hdr->record_id_msb = (id >> 8) & 0xFF;
186};
187
188} // namespace header
189
190enum SensorDataRecordType
191{
Ratan Guptae0cc8552018-01-22 14:23:04 +0530192 SENSOR_DATA_FULL_RECORD = 0x1,
selvaganapathi7b2e5502023-02-14 07:10:47 +0530193 SENSOR_DATA_COMPACT_RECORD = 0x2,
Hao Jiangda06d152021-01-19 15:27:43 -0800194 SENSOR_DATA_EVENT_RECORD = 0x3,
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800195 SENSOR_DATA_ENTITY_RECORD = 0x8,
Harvey Wua3476272023-03-22 10:09:38 +0800196 SENSOR_DATA_FRU_RECORD = 0x11,
197 SENSOR_DATA_MGMT_CTRL_LOCATOR = 0x12,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700198};
199
200// Record key
201struct SensorDataRecordKey
202{
203 uint8_t owner_id;
204 uint8_t owner_lun;
205 uint8_t sensor_number;
206} __attribute__((packed));
207
Ratan Guptae0cc8552018-01-22 14:23:04 +0530208/** @struct SensorDataFruRecordKey
209 *
210 * FRU Device Locator Record(key) - SDR Type 11
211 */
212struct SensorDataFruRecordKey
213{
214 uint8_t deviceAddress;
215 uint8_t fruID;
216 uint8_t accessLun;
217 uint8_t channelNumber;
218} __attribute__((packed));
219
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800220/** @struct SensorDataEntityRecordKey
221 *
222 * Entity Association Record(key) - SDR Type 8
223 */
224struct SensorDataEntityRecordKey
225{
226 uint8_t containerEntityId;
227 uint8_t containerEntityInstance;
228 uint8_t flags;
229 uint8_t entityId1;
230 uint8_t entityInstance1;
231} __attribute__((packed));
232
Emily Shafferbbef71c2017-05-08 16:36:17 -0700233namespace key
234{
235
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800236static constexpr uint8_t listOrRangeBit = 7;
237static constexpr uint8_t linkedBit = 6;
238
Emily Shafferbbef71c2017-05-08 16:36:17 -0700239inline void set_owner_id_ipmb(SensorDataRecordKey* key)
240{
241 key->owner_id &= ~0x01;
242};
243
244inline void set_owner_id_system_sw(SensorDataRecordKey* key)
245{
246 key->owner_id |= 0x01;
247};
248
Tom Joseph96423912018-01-25 00:14:34 +0530249inline void set_owner_id_bmc(SensorDataRecordKey* key)
250{
251 key->owner_id |= 0x20;
252};
253
Emily Shafferbbef71c2017-05-08 16:36:17 -0700254inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key)
255{
256 key->owner_id &= 0x01;
Patrick Venture0b02be92018-08-31 11:55:55 -0700257 key->owner_id |= addr << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700258};
259
260inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key)
261{
262 key->owner_lun &= ~0x03;
Patrick Venture0b02be92018-08-31 11:55:55 -0700263 key->owner_lun |= (lun & 0x03);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700264};
265
266inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key)
267{
268 key->owner_lun &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700269 key->owner_lun |= ((channel & 0xf) << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700270};
271
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800272inline void set_flags(bool isList, bool isLinked,
273 SensorDataEntityRecordKey* key)
274{
275 key->flags = 0x00;
276 if (!isList)
277 key->flags |= 1 << listOrRangeBit;
278
279 if (isLinked)
280 key->flags |= 1 << linkedBit;
281};
282
Emily Shafferbbef71c2017-05-08 16:36:17 -0700283} // namespace key
284
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600285/** @struct GetSensorThresholdsResponse
286 *
287 * Response structure for Get Sensor Thresholds command
288 */
289struct GetSensorThresholdsResponse
290{
Patrick Venture0b02be92018-08-31 11:55:55 -0700291 uint8_t validMask; //!< valid mask
292 uint8_t lowerNonCritical; //!< lower non-critical threshold
293 uint8_t lowerCritical; //!< lower critical threshold
294 uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
295 uint8_t upperNonCritical; //!< upper non-critical threshold
296 uint8_t upperCritical; //!< upper critical threshold
297 uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600298} __attribute__((packed));
299
Emily Shafferbbef71c2017-05-08 16:36:17 -0700300// Body - full record
301#define FULL_RECORD_ID_STR_MAX_LENGTH 16
Ratan Guptae0cc8552018-01-22 14:23:04 +0530302
303static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
304
Emily Shafferbbef71c2017-05-08 16:36:17 -0700305struct SensorDataFullRecordBody
306{
307 uint8_t entity_id;
308 uint8_t entity_instance;
309 uint8_t sensor_initialization;
310 uint8_t sensor_capabilities; // no macro support
311 uint8_t sensor_type;
312 uint8_t event_reading_type;
Patrick Venture0b02be92018-08-31 11:55:55 -0700313 uint8_t supported_assertions[2]; // no macro support
314 uint8_t supported_deassertions[2]; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700315 uint8_t discrete_reading_setting_mask[2]; // no macro support
316 uint8_t sensor_units_1;
317 uint8_t sensor_units_2_base;
318 uint8_t sensor_units_3_modifier;
319 uint8_t linearization;
320 uint8_t m_lsb;
321 uint8_t m_msb_and_tolerance;
322 uint8_t b_lsb;
323 uint8_t b_msb_and_accuracy_lsb;
324 uint8_t accuracy_and_sensor_direction;
325 uint8_t r_b_exponents;
Patrick Venture0b02be92018-08-31 11:55:55 -0700326 uint8_t analog_characteristic_flags; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700327 uint8_t nominal_reading;
328 uint8_t normal_max;
329 uint8_t normal_min;
330 uint8_t sensor_max;
331 uint8_t sensor_min;
332 uint8_t upper_nonrecoverable_threshold;
333 uint8_t upper_critical_threshold;
334 uint8_t upper_noncritical_threshold;
335 uint8_t lower_nonrecoverable_threshold;
336 uint8_t lower_critical_threshold;
337 uint8_t lower_noncritical_threshold;
338 uint8_t positive_threshold_hysteresis;
339 uint8_t negative_threshold_hysteresis;
340 uint16_t reserved;
341 uint8_t oem_reserved;
342 uint8_t id_string_info;
Emily Shaffer10f49592017-05-10 12:01:10 -0700343 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
Emily Shafferbbef71c2017-05-08 16:36:17 -0700344} __attribute__((packed));
345
selvaganapathi7b2e5502023-02-14 07:10:47 +0530346/** @struct SensorDataCompactRecord
347 *
348 * Compact Sensor Record(body) - SDR Type 2
349 */
350struct SensorDataCompactRecordBody
351{
352 uint8_t entity_id;
353 uint8_t entity_instance;
354 uint8_t sensor_initialization;
355 uint8_t sensor_capabilities; // no macro support
356 uint8_t sensor_type;
357 uint8_t event_reading_type;
358 uint8_t supported_assertions[2]; // no macro support
359 uint8_t supported_deassertions[2]; // no macro support
360 uint8_t discrete_reading_setting_mask[2]; // no macro support
361 uint8_t sensor_units_1;
362 uint8_t sensor_units_2_base;
363 uint8_t sensor_units_3_modifier;
364 uint8_t record_sharing[2];
365 uint8_t positive_threshold_hysteresis;
366 uint8_t negative_threshold_hysteresis;
367 uint8_t reserved[3];
368 uint8_t oem_reserved;
369 uint8_t id_string_info;
370 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
371} __attribute__((packed));
372
Hao Jiangda06d152021-01-19 15:27:43 -0800373/** @struct SensorDataEventRecord
374 *
375 * Event Only Sensor Record(body) - SDR Type 3
376 */
377struct SensorDataEventRecordBody
378{
379 uint8_t entity_id;
380 uint8_t entity_instance;
381 uint8_t sensor_type;
382 uint8_t event_reading_type;
383 uint8_t sensor_record_sharing_1;
384 uint8_t sensor_record_sharing_2;
385 uint8_t reserved;
386 uint8_t oem_reserved;
387 uint8_t id_string_info;
388 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
389} __attribute__((packed));
390
Ratan Guptae0cc8552018-01-22 14:23:04 +0530391/** @struct SensorDataFruRecordBody
392 *
393 * FRU Device Locator Record(body) - SDR Type 11
394 */
395struct SensorDataFruRecordBody
396{
397 uint8_t reserved;
398 uint8_t deviceType;
399 uint8_t deviceTypeModifier;
400 uint8_t entityID;
401 uint8_t entityInstance;
402 uint8_t oem;
403 uint8_t deviceIDLen;
404 char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
405} __attribute__((packed));
406
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800407/** @struct SensorDataEntityRecordBody
408 *
409 * Entity Association Record(body) - SDR Type 8
410 */
411struct SensorDataEntityRecordBody
412{
413 uint8_t entityId2;
414 uint8_t entityInstance2;
415 uint8_t entityId3;
416 uint8_t entityInstance3;
417 uint8_t entityId4;
418 uint8_t entityInstance4;
419} __attribute__((packed));
420
Emily Shafferbbef71c2017-05-08 16:36:17 -0700421namespace body
422{
423
424inline void set_entity_instance_number(uint8_t n,
425 SensorDataFullRecordBody* body)
426{
Patrick Venture0b02be92018-08-31 11:55:55 -0700427 body->entity_instance &= 1 << 7;
428 body->entity_instance |= (n & ~(1 << 7));
Emily Shafferbbef71c2017-05-08 16:36:17 -0700429};
430inline void set_entity_physical_entity(SensorDataFullRecordBody* body)
431{
Patrick Venture0b02be92018-08-31 11:55:55 -0700432 body->entity_instance &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700433};
434inline void set_entity_logical_container(SensorDataFullRecordBody* body)
435{
Patrick Venture0b02be92018-08-31 11:55:55 -0700436 body->entity_instance |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700437};
438
Patrick Venture0b02be92018-08-31 11:55:55 -0700439inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700440{
441 if (enabled)
442 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700443 body->sensor_initialization |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700444 }
445 else
446 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700447 body->sensor_initialization &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700448 };
449};
Patrick Venture0b02be92018-08-31 11:55:55 -0700450inline void event_generation_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700451{
452 if (enabled)
453 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700454 body->sensor_initialization |= 1 << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700455 }
456 else
457 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700458 body->sensor_initialization &= ~(1 << 1);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700459 }
460};
Patrick Venture0b02be92018-08-31 11:55:55 -0700461inline void init_types_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700462{
463 if (enabled)
464 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700465 body->sensor_initialization |= 1 << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700466 }
467 else
468 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700469 body->sensor_initialization &= ~(1 << 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700470 }
471};
Patrick Venture0b02be92018-08-31 11:55:55 -0700472inline void init_hyst_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700473{
474 if (enabled)
475 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700476 body->sensor_initialization |= 1 << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700477 }
478 else
479 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700480 body->sensor_initialization &= ~(1 << 3);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700481 }
482};
Patrick Venture0b02be92018-08-31 11:55:55 -0700483inline void init_thresh_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700484{
485 if (enabled)
486 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700487 body->sensor_initialization |= 1 << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700488 }
489 else
490 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700491 body->sensor_initialization &= ~(1 << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700492 }
493};
Patrick Venture0b02be92018-08-31 11:55:55 -0700494inline void init_events_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700495{
496 if (enabled)
497 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700498 body->sensor_initialization |= 1 << 5;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700499 }
500 else
501 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700502 body->sensor_initialization &= ~(1 << 5);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700503 }
504};
Patrick Venture0b02be92018-08-31 11:55:55 -0700505inline void init_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700506{
507 if (enabled)
508 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700509 body->sensor_initialization |= 1 << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700510 }
511 else
512 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700513 body->sensor_initialization &= ~(1 << 6);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700514 }
515};
Patrick Venture0b02be92018-08-31 11:55:55 -0700516inline void init_settable_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700517{
518 if (enabled)
519 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700520 body->sensor_initialization |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700521 }
522 else
523 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700524 body->sensor_initialization &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700525 }
526};
527
528inline void set_percentage(SensorDataFullRecordBody* body)
529{
Patrick Venture0b02be92018-08-31 11:55:55 -0700530 body->sensor_units_1 |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700531};
532inline void unset_percentage(SensorDataFullRecordBody* body)
533{
Patrick Venture0b02be92018-08-31 11:55:55 -0700534 body->sensor_units_1 &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700535};
536inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body)
537{
Patrick Venture0b02be92018-08-31 11:55:55 -0700538 body->sensor_units_1 &= ~(3 << 1);
539 body->sensor_units_1 |= (op & 0x3) << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700540};
541inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body)
542{
Patrick Venture0b02be92018-08-31 11:55:55 -0700543 body->sensor_units_1 &= ~(7 << 3);
544 body->sensor_units_1 |= (unit & 0x7) << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700545};
546inline void set_analog_data_format(uint8_t format,
547 SensorDataFullRecordBody* body)
548{
Patrick Venture0b02be92018-08-31 11:55:55 -0700549 body->sensor_units_1 &= ~(3 << 6);
550 body->sensor_units_1 |= (format & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700551};
552
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700553inline void set_m(uint16_t m, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700554{
555 body->m_lsb = m & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700556 body->m_msb_and_tolerance &= ~(3 << 6);
557 body->m_msb_and_tolerance |= ((m & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700558};
559inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body)
560{
561 body->m_msb_and_tolerance &= ~0x3f;
562 body->m_msb_and_tolerance |= tol & 0x3f;
563};
564
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700565inline void set_b(uint16_t b, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700566{
567 body->b_lsb = b & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700568 body->b_msb_and_accuracy_lsb &= ~(3 << 6);
569 body->b_msb_and_accuracy_lsb |= ((b & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700570};
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700571inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700572{
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700573 // bottom 6 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700574 body->b_msb_and_accuracy_lsb &= ~0x3f;
575 body->b_msb_and_accuracy_lsb |= acc & 0x3f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700576 // top 4 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700577 body->accuracy_and_sensor_direction &= 0x0f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700578 body->accuracy_and_sensor_direction |= ((acc >> 6) & 0xf) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700579};
580inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body)
581{
Patrick Venture0b02be92018-08-31 11:55:55 -0700582 body->accuracy_and_sensor_direction &= ~(3 << 2);
583 body->accuracy_and_sensor_direction |= (exp & 3) << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700584};
585inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body)
586{
Patrick Venture0b02be92018-08-31 11:55:55 -0700587 body->accuracy_and_sensor_direction &= ~(3 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700588 body->accuracy_and_sensor_direction |= (dir & 3);
589};
590
591inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body)
592{
593 body->r_b_exponents &= 0xf0;
594 body->r_b_exponents |= exp & 0x0f;
595};
596inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body)
597{
598 body->r_b_exponents &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700599 body->r_b_exponents |= (exp & 0x0f) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700600};
601
602inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body)
603{
604 body->id_string_info &= ~(0x1f);
605 body->id_string_info |= len & 0x1f;
606};
Willy Tueae88592022-12-13 14:28:02 -0800607inline void set_id_strlen(uint8_t len, SensorDataEventRecordBody* body)
608{
609 body->id_string_info &= ~(0x1f);
610 body->id_string_info |= len & 0x1f;
611};
Patrick Venture0b02be92018-08-31 11:55:55 -0700612inline uint8_t get_id_strlen(SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700613{
614 return body->id_string_info & 0x1f;
615};
616inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body)
617{
Patrick Venture0b02be92018-08-31 11:55:55 -0700618 body->id_string_info &= ~(3 << 6);
619 body->id_string_info |= (type & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700620};
Willy Tueae88592022-12-13 14:28:02 -0800621inline void set_id_type(uint8_t type, SensorDataEventRecordBody* body)
622{
623 body->id_string_info &= ~(3 << 6);
624 body->id_string_info |= (type & 0x3) << 6;
625};
Emily Shafferbbef71c2017-05-08 16:36:17 -0700626
Ratan Guptae0cc8552018-01-22 14:23:04 +0530627inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody* body)
628{
629 body->deviceIDLen &= ~(LENGTH_MASK);
630 body->deviceIDLen |= len & LENGTH_MASK;
631};
632
633inline uint8_t get_device_id_strlen(SensorDataFruRecordBody* body)
634{
635 return body->deviceIDLen & LENGTH_MASK;
636};
637
Tom Josephdc212b22018-02-16 09:59:57 +0530638inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody* body)
639{
640 body->discrete_reading_setting_mask[1] = mask & 0x3F;
641}
642
Emily Shafferbbef71c2017-05-08 16:36:17 -0700643} // namespace body
644
645// More types contained in section 43.17 Sensor Unit Type Codes,
646// IPMI spec v2 rev 1.1
647enum SensorUnitTypeCodes
648{
649 SENSOR_UNIT_UNSPECIFIED = 0,
650 SENSOR_UNIT_DEGREES_C = 1,
651 SENSOR_UNIT_VOLTS = 4,
652 SENSOR_UNIT_AMPERES = 5,
Tom Josephdc212b22018-02-16 09:59:57 +0530653 SENSOR_UNIT_WATTS = 6,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700654 SENSOR_UNIT_JOULES = 7,
Kirill Pakhomov812e44c2018-10-22 16:25:35 +0300655 SENSOR_UNIT_RPM = 18,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700656 SENSOR_UNIT_METERS = 34,
657 SENSOR_UNIT_REVOLUTIONS = 41,
658};
659
660struct SensorDataFullRecord
661{
662 SensorDataRecordHeader header;
663 SensorDataRecordKey key;
664 SensorDataFullRecordBody body;
665} __attribute__((packed));
666
selvaganapathi7b2e5502023-02-14 07:10:47 +0530667/** @struct SensorDataComapactRecord
668 *
669 * Compact Sensor Record - SDR Type 2
670 */
671struct SensorDataCompactRecord
672{
673 SensorDataRecordHeader header;
674 SensorDataRecordKey key;
675 SensorDataCompactRecordBody body;
676} __attribute__((packed));
677
Hao Jiangda06d152021-01-19 15:27:43 -0800678/** @struct SensorDataEventRecord
679 *
680 * Event Only Sensor Record - SDR Type 3
681 */
682struct SensorDataEventRecord
683{
684 SensorDataRecordHeader header;
685 SensorDataRecordKey key;
686 SensorDataEventRecordBody body;
687} __attribute__((packed));
688
Ratan Guptae0cc8552018-01-22 14:23:04 +0530689/** @struct SensorDataFruRecord
690 *
691 * FRU Device Locator Record - SDR Type 11
692 */
693struct SensorDataFruRecord
694{
695 SensorDataRecordHeader header;
696 SensorDataFruRecordKey key;
697 SensorDataFruRecordBody body;
698} __attribute__((packed));
699
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800700/** @struct SensorDataEntityRecord
701 *
702 * Entity Association Record - SDR Type 8
703 */
704struct SensorDataEntityRecord
705{
706 SensorDataRecordHeader header;
707 SensorDataEntityRecordKey key;
708 SensorDataEntityRecordBody body;
709} __attribute__((packed));
710
Patrick Venture0b02be92018-08-31 11:55:55 -0700711} // namespace get_sdr
Tom Joseph816e92b2017-09-06 19:23:00 +0530712
713namespace ipmi
714{
715
716namespace sensor
717{
718
719/**
720 * @brief Map offset to the corresponding bit in the assertion byte.
721 *
Gunnar Mills8991dd62017-10-25 17:11:29 -0500722 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
Tom Joseph816e92b2017-09-06 19:23:00 +0530723 * byte and offsets 8-14 in the second byte.
724 *
725 * @param[in] offset - offset number.
726 * @param[in/out] resp - get sensor reading response.
727 */
Sui Chen4cc42552019-09-11 10:28:35 -0700728inline void setOffset(uint8_t offset, ipmi::sensor::GetSensorResponse* resp)
Tom Joseph816e92b2017-09-06 19:23:00 +0530729{
730 if (offset > 7)
731 {
Sui Chen4cc42552019-09-11 10:28:35 -0700732 resp->discreteReadingSensorStates |= 1 << (offset - 8);
Tom Joseph816e92b2017-09-06 19:23:00 +0530733 }
734 else
735 {
Sui Chen4cc42552019-09-11 10:28:35 -0700736 resp->thresholdLevelsStates |= 1 << offset;
Tom Joseph816e92b2017-09-06 19:23:00 +0530737 }
738}
739
Tom Josephe4014fc2017-09-06 23:57:36 +0530740/**
741 * @brief Set the reading field in the response.
742 *
743 * @param[in] offset - offset number.
744 * @param[in/out] resp - get sensor reading response.
745 */
Sui Chen4cc42552019-09-11 10:28:35 -0700746inline void setReading(uint8_t value, ipmi::sensor::GetSensorResponse* resp)
Tom Josephe4014fc2017-09-06 23:57:36 +0530747{
748 resp->reading = value;
749}
750
Tom Joseph295f17e2017-09-07 00:09:46 +0530751/**
752 * @brief Map the value to the assertion bytes. The assertion states are stored
753 * in 2 bytes.
754 *
755 * @param[in] value - value to mapped to the assertion byte.
756 * @param[in/out] resp - get sensor reading response.
757 */
758inline void setAssertionBytes(uint16_t value,
Sui Chen4cc42552019-09-11 10:28:35 -0700759 ipmi::sensor::GetSensorResponse* resp)
Tom Joseph295f17e2017-09-07 00:09:46 +0530760{
Sui Chen4cc42552019-09-11 10:28:35 -0700761 resp->thresholdLevelsStates = static_cast<uint8_t>(value & 0x00FF);
762 resp->discreteReadingSensorStates = static_cast<uint8_t>(value >> 8);
Tom Joseph295f17e2017-09-07 00:09:46 +0530763}
764
Tom Josephe05b2922017-09-07 00:43:16 +0530765/**
766 * @brief Set the scanning enabled bit in the response.
767 *
768 * @param[in/out] resp - get sensor reading response.
769 */
Sui Chen4cc42552019-09-11 10:28:35 -0700770inline void enableScanning(ipmi::sensor::GetSensorResponse* resp)
Tom Josephe05b2922017-09-07 00:43:16 +0530771{
Sui Chen4cc42552019-09-11 10:28:35 -0700772 resp->readingOrStateUnavailable = false;
773 resp->scanningEnabled = true;
774 resp->allEventMessagesEnabled = false;
Tom Josephe05b2922017-09-07 00:43:16 +0530775}
776
Tom Joseph816e92b2017-09-06 19:23:00 +0530777} // namespace sensor
778
779} // namespace ipmi