blob: 357ade44ee95664e5bcc64e4a17f924ec29884ae [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
Brandon Kim9cf85622019-06-19 12:05:08 -07005#include <exception>
Vernon Mauerye08fbff2019-04-03 09:19:34 -07006#include <ipmid/api.hpp>
Vernon Mauery33250242019-03-12 16:49:26 -07007#include <ipmid/types.hpp>
8
Chris Austenac4604a2015-10-13 12:43:27 -05009// IPMI commands for net functions.
10enum ipmi_netfn_sen_cmds
11{
Jia, Chunhui3342a8e2018-12-29 13:32:26 +080012 IPMI_CMD_PLATFORM_EVENT = 0x2,
Tom Joseph5ca50952018-02-22 00:33:38 +053013 IPMI_CMD_GET_DEVICE_SDR_INFO = 0x20,
Patrick Venture0b02be92018-08-31 11:55:55 -070014 IPMI_CMD_GET_DEVICE_SDR = 0x21,
15 IPMI_CMD_RESERVE_DEVICE_SDR_REPO = 0x22,
Chris Austen10ccc0f2015-12-10 18:27:04 -060016 IPMI_CMD_GET_SENSOR_READING = 0x2D,
Patrick Venture0b02be92018-08-31 11:55:55 -070017 IPMI_CMD_GET_SENSOR_TYPE = 0x2F,
18 IPMI_CMD_SET_SENSOR = 0x30,
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -060019 IPMI_CMD_GET_SENSOR_THRESHOLDS = 0x27,
Chris Austenac4604a2015-10-13 12:43:27 -050020};
21
Ratan Guptae0cc8552018-01-22 14:23:04 +053022/**
23 * @enum device_type
24 * IPMI FRU device types
25 */
26enum device_type
27{
28 IPMI_PHYSICAL_FRU = 0x00,
29 IPMI_LOGICAL_FRU = 0x80,
30};
31
Emily Shaffer1fabf222017-04-05 08:53:21 -070032// Discrete sensor types.
33enum ipmi_sensor_types
34{
Patrick Venture0b02be92018-08-31 11:55:55 -070035 IPMI_SENSOR_TEMP = 0x01,
Emily Shaffer1fabf222017-04-05 08:53:21 -070036 IPMI_SENSOR_VOLTAGE = 0x02,
37 IPMI_SENSOR_CURRENT = 0x03,
Patrick Venture0b02be92018-08-31 11:55:55 -070038 IPMI_SENSOR_FAN = 0x04,
39 IPMI_SENSOR_TPM = 0xCC,
Emily Shaffer1fabf222017-04-05 08:53:21 -070040};
41
Brandon Kim9cf85622019-06-19 12:05:08 -070042/** @brief Custom exception for reading sensors that are not funcitonal.
43 */
44struct SensorFunctionalError : public std::exception
45{
46 const char* what() const noexcept
47 {
48 return "Sensor not functional";
49 }
50};
51
Chris Austen0012e9b2015-10-22 01:37:46 -050052#define MAX_DBUS_PATH 128
Patrick Venture0b02be92018-08-31 11:55:55 -070053struct dbus_interface_t
54{
55 uint8_t sensornumber;
56 uint8_t sensortype;
Chris Austen0012e9b2015-10-22 01:37:46 -050057
Patrick Venture0b02be92018-08-31 11:55:55 -070058 char bus[MAX_DBUS_PATH];
59 char path[MAX_DBUS_PATH];
60 char interface[MAX_DBUS_PATH];
Chris Austen0012e9b2015-10-22 01:37:46 -050061};
Tomd700e762016-09-20 18:24:13 +053062
Jia, Chunhui3342a8e2018-12-29 13:32:26 +080063struct PlatformEventRequest
64{
65 uint8_t eventMessageRevision;
66 uint8_t sensorType;
67 uint8_t sensorNumber;
68 uint8_t eventDirectionType;
69 uint8_t data[3];
70};
71
72static constexpr char const* ipmiSELPath = "/xyz/openbmc_project/Logging/IPMI";
73static constexpr char const* ipmiSELAddInterface =
74 "xyz.openbmc_project.Logging.IPMI";
75static const std::string ipmiSELAddMessage = "SEL Entry";
76
77static constexpr int selSystemEventSizeWith3Bytes = 8;
78static constexpr int selSystemEventSizeWith2Bytes = 7;
79static constexpr int selSystemEventSizeWith1Bytes = 6;
80static constexpr int selIPMBEventSize = 7;
81static constexpr uint8_t directionMask = 0x80;
82static constexpr uint8_t byte3EnableMask = 0x30;
83static constexpr uint8_t byte2EnableMask = 0xC0;
84
Patrick Venture0b02be92018-08-31 11:55:55 -070085int set_sensor_dbus_state_s(uint8_t, const char*, const char*);
86int set_sensor_dbus_state_y(uint8_t, const char*, const uint8_t);
87int find_openbmc_path(uint8_t, dbus_interface_t*);
Tom05732372016-09-06 17:21:23 +053088
Tom Joseph5ca50952018-02-22 00:33:38 +053089ipmi_ret_t ipmi_sen_get_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
90 ipmi_request_t request, ipmi_response_t response,
91 ipmi_data_len_t data_len, ipmi_context_t context);
92
jayaprakash Mutyalad9578232019-05-13 20:22:50 +000093ipmi::RspType<uint16_t> ipmiSensorReserveSdr();
Tom Joseph5ca50952018-02-22 00:33:38 +053094
Ratan Guptae0cc8552018-01-22 14:23:04 +053095static const uint16_t FRU_RECORD_ID_START = 256;
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -080096static const uint16_t ENTITY_RECORD_ID_START = 512;
Ratan Guptae0cc8552018-01-22 14:23:04 +053097static const uint8_t SDR_VERSION = 0x51;
98static const uint16_t END_OF_RECORD = 0xFFFF;
99static const uint8_t LENGTH_MASK = 0x1F;
100
Tom Josephbe703f72017-03-09 12:34:35 +0530101/**
Emily Shafferd06e0e72017-04-05 09:08:57 -0700102 * Get SDR Info
103 */
104
105namespace get_sdr_info
106{
107namespace request
108{
109// Note: for some reason the ipmi_request_t appears to be the
110// raw value for this call.
111inline bool get_count(void* req)
112{
Patrick Venture0b02be92018-08-31 11:55:55 -0700113 return (bool)((uint64_t)(req)&1);
Emily Shafferd06e0e72017-04-05 09:08:57 -0700114}
115} // namespace request
Emily Shafferd06e0e72017-04-05 09:08:57 -0700116} // namespace get_sdr_info
Emily Shafferbbef71c2017-05-08 16:36:17 -0700117
118/**
119 * Get SDR
120 */
121namespace get_sdr
122{
123
124struct GetSdrReq
125{
126 uint8_t reservation_id_lsb;
127 uint8_t reservation_id_msb;
128 uint8_t record_id_lsb;
129 uint8_t record_id_msb;
130 uint8_t offset;
131 uint8_t bytes_to_read;
132} __attribute__((packed));
133
134namespace request
135{
136
Emily Shaffere5c9d2f2019-06-25 14:26:45 -0700137inline uint16_t get_reservation_id(GetSdrReq* req)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700138{
139 return (req->reservation_id_lsb + (req->reservation_id_msb << 8));
140};
141
Ratan Guptae0cc8552018-01-22 14:23:04 +0530142inline uint16_t get_record_id(GetSdrReq* req)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700143{
144 return (req->record_id_lsb + (req->record_id_msb << 8));
145};
146
147} // namespace request
148
149// Response
150struct GetSdrResp
151{
152 uint8_t next_record_id_lsb;
153 uint8_t next_record_id_msb;
154 uint8_t record_data[64];
155} __attribute__((packed));
156
157namespace response
158{
159
Ratan Guptae0cc8552018-01-22 14:23:04 +0530160inline void set_next_record_id(uint16_t next, GetSdrResp* resp)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700161{
162 resp->next_record_id_lsb = next & 0xff;
163 resp->next_record_id_msb = (next >> 8) & 0xff;
164};
165
166} // namespace response
167
168// Record header
169struct SensorDataRecordHeader
170{
171 uint8_t record_id_lsb;
172 uint8_t record_id_msb;
173 uint8_t sdr_version;
174 uint8_t record_type;
175 uint8_t record_length; // Length not counting the header
176} __attribute__((packed));
177
178namespace header
179{
180
181inline void set_record_id(int id, SensorDataRecordHeader* hdr)
182{
183 hdr->record_id_lsb = (id & 0xFF);
184 hdr->record_id_msb = (id >> 8) & 0xFF;
185};
186
187} // namespace header
188
189enum SensorDataRecordType
190{
Ratan Guptae0cc8552018-01-22 14:23:04 +0530191 SENSOR_DATA_FULL_RECORD = 0x1,
selvaganapathi7b2e5502023-02-14 07:10:47 +0530192 SENSOR_DATA_COMPACT_RECORD = 0x2,
Hao Jiangda06d152021-01-19 15:27:43 -0800193 SENSOR_DATA_EVENT_RECORD = 0x3,
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800194 SENSOR_DATA_ENTITY_RECORD = 0x8,
Harvey Wua3476272023-03-22 10:09:38 +0800195 SENSOR_DATA_FRU_RECORD = 0x11,
196 SENSOR_DATA_MGMT_CTRL_LOCATOR = 0x12,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700197};
198
199// Record key
200struct SensorDataRecordKey
201{
202 uint8_t owner_id;
203 uint8_t owner_lun;
204 uint8_t sensor_number;
205} __attribute__((packed));
206
Ratan Guptae0cc8552018-01-22 14:23:04 +0530207/** @struct SensorDataFruRecordKey
208 *
209 * FRU Device Locator Record(key) - SDR Type 11
210 */
211struct SensorDataFruRecordKey
212{
213 uint8_t deviceAddress;
214 uint8_t fruID;
215 uint8_t accessLun;
216 uint8_t channelNumber;
217} __attribute__((packed));
218
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800219/** @struct SensorDataEntityRecordKey
220 *
221 * Entity Association Record(key) - SDR Type 8
222 */
223struct SensorDataEntityRecordKey
224{
225 uint8_t containerEntityId;
226 uint8_t containerEntityInstance;
227 uint8_t flags;
228 uint8_t entityId1;
229 uint8_t entityInstance1;
230} __attribute__((packed));
231
Emily Shafferbbef71c2017-05-08 16:36:17 -0700232namespace key
233{
234
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800235static constexpr uint8_t listOrRangeBit = 7;
236static constexpr uint8_t linkedBit = 6;
237
Emily Shafferbbef71c2017-05-08 16:36:17 -0700238inline void set_owner_id_ipmb(SensorDataRecordKey* key)
239{
240 key->owner_id &= ~0x01;
241};
242
243inline void set_owner_id_system_sw(SensorDataRecordKey* key)
244{
245 key->owner_id |= 0x01;
246};
247
Tom Joseph96423912018-01-25 00:14:34 +0530248inline void set_owner_id_bmc(SensorDataRecordKey* key)
249{
250 key->owner_id |= 0x20;
251};
252
Emily Shafferbbef71c2017-05-08 16:36:17 -0700253inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key)
254{
255 key->owner_id &= 0x01;
Patrick Venture0b02be92018-08-31 11:55:55 -0700256 key->owner_id |= addr << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700257};
258
259inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key)
260{
261 key->owner_lun &= ~0x03;
Patrick Venture0b02be92018-08-31 11:55:55 -0700262 key->owner_lun |= (lun & 0x03);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700263};
264
265inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key)
266{
267 key->owner_lun &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700268 key->owner_lun |= ((channel & 0xf) << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700269};
270
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800271inline void set_flags(bool isList, bool isLinked,
272 SensorDataEntityRecordKey* key)
273{
274 key->flags = 0x00;
275 if (!isList)
276 key->flags |= 1 << listOrRangeBit;
277
278 if (isLinked)
279 key->flags |= 1 << linkedBit;
280};
281
Emily Shafferbbef71c2017-05-08 16:36:17 -0700282} // namespace key
283
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600284/** @struct GetSensorThresholdsResponse
285 *
286 * Response structure for Get Sensor Thresholds command
287 */
288struct GetSensorThresholdsResponse
289{
Patrick Venture0b02be92018-08-31 11:55:55 -0700290 uint8_t validMask; //!< valid mask
291 uint8_t lowerNonCritical; //!< lower non-critical threshold
292 uint8_t lowerCritical; //!< lower critical threshold
293 uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
294 uint8_t upperNonCritical; //!< upper non-critical threshold
295 uint8_t upperCritical; //!< upper critical threshold
296 uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600297} __attribute__((packed));
298
Emily Shafferbbef71c2017-05-08 16:36:17 -0700299// Body - full record
300#define FULL_RECORD_ID_STR_MAX_LENGTH 16
Ratan Guptae0cc8552018-01-22 14:23:04 +0530301
302static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
303
Emily Shafferbbef71c2017-05-08 16:36:17 -0700304struct SensorDataFullRecordBody
305{
306 uint8_t entity_id;
307 uint8_t entity_instance;
308 uint8_t sensor_initialization;
309 uint8_t sensor_capabilities; // no macro support
310 uint8_t sensor_type;
311 uint8_t event_reading_type;
Patrick Venture0b02be92018-08-31 11:55:55 -0700312 uint8_t supported_assertions[2]; // no macro support
313 uint8_t supported_deassertions[2]; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700314 uint8_t discrete_reading_setting_mask[2]; // no macro support
315 uint8_t sensor_units_1;
316 uint8_t sensor_units_2_base;
317 uint8_t sensor_units_3_modifier;
318 uint8_t linearization;
319 uint8_t m_lsb;
320 uint8_t m_msb_and_tolerance;
321 uint8_t b_lsb;
322 uint8_t b_msb_and_accuracy_lsb;
323 uint8_t accuracy_and_sensor_direction;
324 uint8_t r_b_exponents;
Patrick Venture0b02be92018-08-31 11:55:55 -0700325 uint8_t analog_characteristic_flags; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700326 uint8_t nominal_reading;
327 uint8_t normal_max;
328 uint8_t normal_min;
329 uint8_t sensor_max;
330 uint8_t sensor_min;
331 uint8_t upper_nonrecoverable_threshold;
332 uint8_t upper_critical_threshold;
333 uint8_t upper_noncritical_threshold;
334 uint8_t lower_nonrecoverable_threshold;
335 uint8_t lower_critical_threshold;
336 uint8_t lower_noncritical_threshold;
337 uint8_t positive_threshold_hysteresis;
338 uint8_t negative_threshold_hysteresis;
339 uint16_t reserved;
340 uint8_t oem_reserved;
341 uint8_t id_string_info;
Emily Shaffer10f49592017-05-10 12:01:10 -0700342 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
Emily Shafferbbef71c2017-05-08 16:36:17 -0700343} __attribute__((packed));
344
selvaganapathi7b2e5502023-02-14 07:10:47 +0530345/** @struct SensorDataCompactRecord
346 *
347 * Compact Sensor Record(body) - SDR Type 2
348 */
349struct SensorDataCompactRecordBody
350{
351 uint8_t entity_id;
352 uint8_t entity_instance;
353 uint8_t sensor_initialization;
354 uint8_t sensor_capabilities; // no macro support
355 uint8_t sensor_type;
356 uint8_t event_reading_type;
357 uint8_t supported_assertions[2]; // no macro support
358 uint8_t supported_deassertions[2]; // no macro support
359 uint8_t discrete_reading_setting_mask[2]; // no macro support
360 uint8_t sensor_units_1;
361 uint8_t sensor_units_2_base;
362 uint8_t sensor_units_3_modifier;
363 uint8_t record_sharing[2];
364 uint8_t positive_threshold_hysteresis;
365 uint8_t negative_threshold_hysteresis;
366 uint8_t reserved[3];
367 uint8_t oem_reserved;
368 uint8_t id_string_info;
369 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
370} __attribute__((packed));
371
Hao Jiangda06d152021-01-19 15:27:43 -0800372/** @struct SensorDataEventRecord
373 *
374 * Event Only Sensor Record(body) - SDR Type 3
375 */
376struct SensorDataEventRecordBody
377{
378 uint8_t entity_id;
379 uint8_t entity_instance;
380 uint8_t sensor_type;
381 uint8_t event_reading_type;
382 uint8_t sensor_record_sharing_1;
383 uint8_t sensor_record_sharing_2;
384 uint8_t reserved;
385 uint8_t oem_reserved;
386 uint8_t id_string_info;
387 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
388} __attribute__((packed));
389
Ratan Guptae0cc8552018-01-22 14:23:04 +0530390/** @struct SensorDataFruRecordBody
391 *
392 * FRU Device Locator Record(body) - SDR Type 11
393 */
394struct SensorDataFruRecordBody
395{
396 uint8_t reserved;
397 uint8_t deviceType;
398 uint8_t deviceTypeModifier;
399 uint8_t entityID;
400 uint8_t entityInstance;
401 uint8_t oem;
402 uint8_t deviceIDLen;
403 char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
404} __attribute__((packed));
405
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800406/** @struct SensorDataEntityRecordBody
407 *
408 * Entity Association Record(body) - SDR Type 8
409 */
410struct SensorDataEntityRecordBody
411{
412 uint8_t entityId2;
413 uint8_t entityInstance2;
414 uint8_t entityId3;
415 uint8_t entityInstance3;
416 uint8_t entityId4;
417 uint8_t entityInstance4;
418} __attribute__((packed));
419
Emily Shafferbbef71c2017-05-08 16:36:17 -0700420namespace body
421{
422
423inline void set_entity_instance_number(uint8_t n,
424 SensorDataFullRecordBody* body)
425{
Patrick Venture0b02be92018-08-31 11:55:55 -0700426 body->entity_instance &= 1 << 7;
427 body->entity_instance |= (n & ~(1 << 7));
Emily Shafferbbef71c2017-05-08 16:36:17 -0700428};
429inline void set_entity_physical_entity(SensorDataFullRecordBody* body)
430{
Patrick Venture0b02be92018-08-31 11:55:55 -0700431 body->entity_instance &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700432};
433inline void set_entity_logical_container(SensorDataFullRecordBody* body)
434{
Patrick Venture0b02be92018-08-31 11:55:55 -0700435 body->entity_instance |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700436};
437
Patrick Venture0b02be92018-08-31 11:55:55 -0700438inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700439{
440 if (enabled)
441 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700442 body->sensor_initialization |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700443 }
444 else
445 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700446 body->sensor_initialization &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700447 };
448};
Patrick Venture0b02be92018-08-31 11:55:55 -0700449inline void event_generation_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700450{
451 if (enabled)
452 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700453 body->sensor_initialization |= 1 << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700454 }
455 else
456 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700457 body->sensor_initialization &= ~(1 << 1);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700458 }
459};
Patrick Venture0b02be92018-08-31 11:55:55 -0700460inline void init_types_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700461{
462 if (enabled)
463 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700464 body->sensor_initialization |= 1 << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700465 }
466 else
467 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700468 body->sensor_initialization &= ~(1 << 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700469 }
470};
Patrick Venture0b02be92018-08-31 11:55:55 -0700471inline void init_hyst_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700472{
473 if (enabled)
474 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700475 body->sensor_initialization |= 1 << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700476 }
477 else
478 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700479 body->sensor_initialization &= ~(1 << 3);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700480 }
481};
Patrick Venture0b02be92018-08-31 11:55:55 -0700482inline void init_thresh_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700483{
484 if (enabled)
485 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700486 body->sensor_initialization |= 1 << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700487 }
488 else
489 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700490 body->sensor_initialization &= ~(1 << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700491 }
492};
Patrick Venture0b02be92018-08-31 11:55:55 -0700493inline void init_events_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700494{
495 if (enabled)
496 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700497 body->sensor_initialization |= 1 << 5;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700498 }
499 else
500 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700501 body->sensor_initialization &= ~(1 << 5);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700502 }
503};
Patrick Venture0b02be92018-08-31 11:55:55 -0700504inline void init_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700505{
506 if (enabled)
507 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700508 body->sensor_initialization |= 1 << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700509 }
510 else
511 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700512 body->sensor_initialization &= ~(1 << 6);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700513 }
514};
Patrick Venture0b02be92018-08-31 11:55:55 -0700515inline void init_settable_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700516{
517 if (enabled)
518 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700519 body->sensor_initialization |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700520 }
521 else
522 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700523 body->sensor_initialization &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700524 }
525};
526
527inline void set_percentage(SensorDataFullRecordBody* body)
528{
Patrick Venture0b02be92018-08-31 11:55:55 -0700529 body->sensor_units_1 |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700530};
531inline void unset_percentage(SensorDataFullRecordBody* body)
532{
Patrick Venture0b02be92018-08-31 11:55:55 -0700533 body->sensor_units_1 &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700534};
535inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body)
536{
Patrick Venture0b02be92018-08-31 11:55:55 -0700537 body->sensor_units_1 &= ~(3 << 1);
538 body->sensor_units_1 |= (op & 0x3) << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700539};
540inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body)
541{
Patrick Venture0b02be92018-08-31 11:55:55 -0700542 body->sensor_units_1 &= ~(7 << 3);
543 body->sensor_units_1 |= (unit & 0x7) << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700544};
545inline void set_analog_data_format(uint8_t format,
546 SensorDataFullRecordBody* body)
547{
Patrick Venture0b02be92018-08-31 11:55:55 -0700548 body->sensor_units_1 &= ~(3 << 6);
549 body->sensor_units_1 |= (format & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700550};
551
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700552inline void set_m(uint16_t m, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700553{
554 body->m_lsb = m & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700555 body->m_msb_and_tolerance &= ~(3 << 6);
556 body->m_msb_and_tolerance |= ((m & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700557};
558inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body)
559{
560 body->m_msb_and_tolerance &= ~0x3f;
561 body->m_msb_and_tolerance |= tol & 0x3f;
562};
563
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700564inline void set_b(uint16_t b, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700565{
566 body->b_lsb = b & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700567 body->b_msb_and_accuracy_lsb &= ~(3 << 6);
568 body->b_msb_and_accuracy_lsb |= ((b & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700569};
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700570inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700571{
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700572 // bottom 6 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700573 body->b_msb_and_accuracy_lsb &= ~0x3f;
574 body->b_msb_and_accuracy_lsb |= acc & 0x3f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700575 // top 4 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700576 body->accuracy_and_sensor_direction &= 0x0f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700577 body->accuracy_and_sensor_direction |= ((acc >> 6) & 0xf) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700578};
579inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body)
580{
Patrick Venture0b02be92018-08-31 11:55:55 -0700581 body->accuracy_and_sensor_direction &= ~(3 << 2);
582 body->accuracy_and_sensor_direction |= (exp & 3) << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700583};
584inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body)
585{
Patrick Venture0b02be92018-08-31 11:55:55 -0700586 body->accuracy_and_sensor_direction &= ~(3 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700587 body->accuracy_and_sensor_direction |= (dir & 3);
588};
589
590inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body)
591{
592 body->r_b_exponents &= 0xf0;
593 body->r_b_exponents |= exp & 0x0f;
594};
595inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body)
596{
597 body->r_b_exponents &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700598 body->r_b_exponents |= (exp & 0x0f) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700599};
600
601inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body)
602{
603 body->id_string_info &= ~(0x1f);
604 body->id_string_info |= len & 0x1f;
605};
Willy Tueae88592022-12-13 14:28:02 -0800606inline void set_id_strlen(uint8_t len, SensorDataEventRecordBody* body)
607{
608 body->id_string_info &= ~(0x1f);
609 body->id_string_info |= len & 0x1f;
610};
Patrick Venture0b02be92018-08-31 11:55:55 -0700611inline uint8_t get_id_strlen(SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700612{
613 return body->id_string_info & 0x1f;
614};
615inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body)
616{
Patrick Venture0b02be92018-08-31 11:55:55 -0700617 body->id_string_info &= ~(3 << 6);
618 body->id_string_info |= (type & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700619};
Willy Tueae88592022-12-13 14:28:02 -0800620inline void set_id_type(uint8_t type, SensorDataEventRecordBody* body)
621{
622 body->id_string_info &= ~(3 << 6);
623 body->id_string_info |= (type & 0x3) << 6;
624};
Emily Shafferbbef71c2017-05-08 16:36:17 -0700625
Ratan Guptae0cc8552018-01-22 14:23:04 +0530626inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody* body)
627{
628 body->deviceIDLen &= ~(LENGTH_MASK);
629 body->deviceIDLen |= len & LENGTH_MASK;
630};
631
632inline uint8_t get_device_id_strlen(SensorDataFruRecordBody* body)
633{
634 return body->deviceIDLen & LENGTH_MASK;
635};
636
Tom Josephdc212b22018-02-16 09:59:57 +0530637inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody* body)
638{
639 body->discrete_reading_setting_mask[1] = mask & 0x3F;
640}
641
Emily Shafferbbef71c2017-05-08 16:36:17 -0700642} // namespace body
643
644// More types contained in section 43.17 Sensor Unit Type Codes,
645// IPMI spec v2 rev 1.1
646enum SensorUnitTypeCodes
647{
648 SENSOR_UNIT_UNSPECIFIED = 0,
649 SENSOR_UNIT_DEGREES_C = 1,
650 SENSOR_UNIT_VOLTS = 4,
651 SENSOR_UNIT_AMPERES = 5,
Tom Josephdc212b22018-02-16 09:59:57 +0530652 SENSOR_UNIT_WATTS = 6,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700653 SENSOR_UNIT_JOULES = 7,
Kirill Pakhomov812e44c2018-10-22 16:25:35 +0300654 SENSOR_UNIT_RPM = 18,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700655 SENSOR_UNIT_METERS = 34,
656 SENSOR_UNIT_REVOLUTIONS = 41,
657};
658
659struct SensorDataFullRecord
660{
661 SensorDataRecordHeader header;
662 SensorDataRecordKey key;
663 SensorDataFullRecordBody body;
664} __attribute__((packed));
665
selvaganapathi7b2e5502023-02-14 07:10:47 +0530666/** @struct SensorDataComapactRecord
667 *
668 * Compact Sensor Record - SDR Type 2
669 */
670struct SensorDataCompactRecord
671{
672 SensorDataRecordHeader header;
673 SensorDataRecordKey key;
674 SensorDataCompactRecordBody body;
675} __attribute__((packed));
676
Hao Jiangda06d152021-01-19 15:27:43 -0800677/** @struct SensorDataEventRecord
678 *
679 * Event Only Sensor Record - SDR Type 3
680 */
681struct SensorDataEventRecord
682{
683 SensorDataRecordHeader header;
684 SensorDataRecordKey key;
685 SensorDataEventRecordBody body;
686} __attribute__((packed));
687
Ratan Guptae0cc8552018-01-22 14:23:04 +0530688/** @struct SensorDataFruRecord
689 *
690 * FRU Device Locator Record - SDR Type 11
691 */
692struct SensorDataFruRecord
693{
694 SensorDataRecordHeader header;
695 SensorDataFruRecordKey key;
696 SensorDataFruRecordBody body;
697} __attribute__((packed));
698
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800699/** @struct SensorDataEntityRecord
700 *
701 * Entity Association Record - SDR Type 8
702 */
703struct SensorDataEntityRecord
704{
705 SensorDataRecordHeader header;
706 SensorDataEntityRecordKey key;
707 SensorDataEntityRecordBody body;
708} __attribute__((packed));
709
Patrick Venture0b02be92018-08-31 11:55:55 -0700710} // namespace get_sdr
Tom Joseph816e92b2017-09-06 19:23:00 +0530711
712namespace ipmi
713{
714
715namespace sensor
716{
717
718/**
719 * @brief Map offset to the corresponding bit in the assertion byte.
720 *
Gunnar Mills8991dd62017-10-25 17:11:29 -0500721 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
Tom Joseph816e92b2017-09-06 19:23:00 +0530722 * byte and offsets 8-14 in the second byte.
723 *
724 * @param[in] offset - offset number.
725 * @param[in/out] resp - get sensor reading response.
726 */
Sui Chen4cc42552019-09-11 10:28:35 -0700727inline void setOffset(uint8_t offset, ipmi::sensor::GetSensorResponse* resp)
Tom Joseph816e92b2017-09-06 19:23:00 +0530728{
729 if (offset > 7)
730 {
Sui Chen4cc42552019-09-11 10:28:35 -0700731 resp->discreteReadingSensorStates |= 1 << (offset - 8);
Tom Joseph816e92b2017-09-06 19:23:00 +0530732 }
733 else
734 {
Sui Chen4cc42552019-09-11 10:28:35 -0700735 resp->thresholdLevelsStates |= 1 << offset;
Tom Joseph816e92b2017-09-06 19:23:00 +0530736 }
737}
738
Tom Josephe4014fc2017-09-06 23:57:36 +0530739/**
740 * @brief Set the reading field in the response.
741 *
742 * @param[in] offset - offset number.
743 * @param[in/out] resp - get sensor reading response.
744 */
Sui Chen4cc42552019-09-11 10:28:35 -0700745inline void setReading(uint8_t value, ipmi::sensor::GetSensorResponse* resp)
Tom Josephe4014fc2017-09-06 23:57:36 +0530746{
747 resp->reading = value;
748}
749
Tom Joseph295f17e2017-09-07 00:09:46 +0530750/**
751 * @brief Map the value to the assertion bytes. The assertion states are stored
752 * in 2 bytes.
753 *
754 * @param[in] value - value to mapped to the assertion byte.
755 * @param[in/out] resp - get sensor reading response.
756 */
757inline void setAssertionBytes(uint16_t value,
Sui Chen4cc42552019-09-11 10:28:35 -0700758 ipmi::sensor::GetSensorResponse* resp)
Tom Joseph295f17e2017-09-07 00:09:46 +0530759{
Sui Chen4cc42552019-09-11 10:28:35 -0700760 resp->thresholdLevelsStates = static_cast<uint8_t>(value & 0x00FF);
761 resp->discreteReadingSensorStates = static_cast<uint8_t>(value >> 8);
Tom Joseph295f17e2017-09-07 00:09:46 +0530762}
763
Tom Josephe05b2922017-09-07 00:43:16 +0530764/**
765 * @brief Set the scanning enabled bit in the response.
766 *
767 * @param[in/out] resp - get sensor reading response.
768 */
Sui Chen4cc42552019-09-11 10:28:35 -0700769inline void enableScanning(ipmi::sensor::GetSensorResponse* resp)
Tom Josephe05b2922017-09-07 00:43:16 +0530770{
Sui Chen4cc42552019-09-11 10:28:35 -0700771 resp->readingOrStateUnavailable = false;
772 resp->scanningEnabled = true;
773 resp->allEventMessagesEnabled = false;
Tom Josephe05b2922017-09-07 00:43:16 +0530774}
775
Tom Joseph816e92b2017-09-06 19:23:00 +0530776} // namespace sensor
777
778} // namespace ipmi