blob: 4881741980f994c833f447b152b194dff5c3260b [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 Liu23c868c2025-07-04 09:31:35 +080077ipmi::Cc ipmi_sen_get_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
78 ipmi_request_t request, ipmi_response_t response,
79 ipmi_data_len_t data_len, ipmi_context_t context);
Tom Joseph5ca50952018-02-22 00:33:38 +053080
jayaprakash Mutyalad9578232019-05-13 20:22:50 +000081ipmi::RspType<uint16_t> ipmiSensorReserveSdr();
Tom Joseph5ca50952018-02-22 00:33:38 +053082
Ratan Guptae0cc8552018-01-22 14:23:04 +053083static const uint16_t FRU_RECORD_ID_START = 256;
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -080084static const uint16_t ENTITY_RECORD_ID_START = 512;
Ratan Guptae0cc8552018-01-22 14:23:04 +053085static const uint8_t SDR_VERSION = 0x51;
86static const uint16_t END_OF_RECORD = 0xFFFF;
87static const uint8_t LENGTH_MASK = 0x1F;
88
Tom Josephbe703f72017-03-09 12:34:35 +053089/**
Emily Shafferbbef71c2017-05-08 16:36:17 -070090 * Get SDR
91 */
92namespace get_sdr
93{
94
95struct GetSdrReq
96{
97 uint8_t reservation_id_lsb;
98 uint8_t reservation_id_msb;
99 uint8_t record_id_lsb;
100 uint8_t record_id_msb;
101 uint8_t offset;
102 uint8_t bytes_to_read;
103} __attribute__((packed));
104
105namespace request
106{
107
Emily Shaffere5c9d2f2019-06-25 14:26:45 -0700108inline uint16_t get_reservation_id(GetSdrReq* req)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700109{
110 return (req->reservation_id_lsb + (req->reservation_id_msb << 8));
111};
112
Ratan Guptae0cc8552018-01-22 14:23:04 +0530113inline uint16_t get_record_id(GetSdrReq* req)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700114{
115 return (req->record_id_lsb + (req->record_id_msb << 8));
116};
117
118} // namespace request
119
120// Response
121struct GetSdrResp
122{
123 uint8_t next_record_id_lsb;
124 uint8_t next_record_id_msb;
125 uint8_t record_data[64];
126} __attribute__((packed));
127
128namespace response
129{
130
Ratan Guptae0cc8552018-01-22 14:23:04 +0530131inline void set_next_record_id(uint16_t next, GetSdrResp* resp)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700132{
133 resp->next_record_id_lsb = next & 0xff;
134 resp->next_record_id_msb = (next >> 8) & 0xff;
135};
136
137} // namespace response
138
139// Record header
140struct SensorDataRecordHeader
141{
142 uint8_t record_id_lsb;
143 uint8_t record_id_msb;
144 uint8_t sdr_version;
145 uint8_t record_type;
146 uint8_t record_length; // Length not counting the header
147} __attribute__((packed));
148
149namespace header
150{
151
152inline void set_record_id(int id, SensorDataRecordHeader* hdr)
153{
154 hdr->record_id_lsb = (id & 0xFF);
155 hdr->record_id_msb = (id >> 8) & 0xFF;
156};
157
158} // namespace header
159
160enum SensorDataRecordType
161{
Ratan Guptae0cc8552018-01-22 14:23:04 +0530162 SENSOR_DATA_FULL_RECORD = 0x1,
selvaganapathi7b2e5502023-02-14 07:10:47 +0530163 SENSOR_DATA_COMPACT_RECORD = 0x2,
Hao Jiangda06d152021-01-19 15:27:43 -0800164 SENSOR_DATA_EVENT_RECORD = 0x3,
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800165 SENSOR_DATA_ENTITY_RECORD = 0x8,
Harvey Wua3476272023-03-22 10:09:38 +0800166 SENSOR_DATA_FRU_RECORD = 0x11,
167 SENSOR_DATA_MGMT_CTRL_LOCATOR = 0x12,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700168};
169
170// Record key
171struct SensorDataRecordKey
172{
173 uint8_t owner_id;
174 uint8_t owner_lun;
175 uint8_t sensor_number;
176} __attribute__((packed));
177
Ratan Guptae0cc8552018-01-22 14:23:04 +0530178/** @struct SensorDataFruRecordKey
179 *
180 * FRU Device Locator Record(key) - SDR Type 11
181 */
182struct SensorDataFruRecordKey
183{
184 uint8_t deviceAddress;
185 uint8_t fruID;
186 uint8_t accessLun;
187 uint8_t channelNumber;
188} __attribute__((packed));
189
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800190/** @struct SensorDataEntityRecordKey
191 *
192 * Entity Association Record(key) - SDR Type 8
193 */
194struct SensorDataEntityRecordKey
195{
196 uint8_t containerEntityId;
197 uint8_t containerEntityInstance;
198 uint8_t flags;
199 uint8_t entityId1;
200 uint8_t entityInstance1;
201} __attribute__((packed));
202
Emily Shafferbbef71c2017-05-08 16:36:17 -0700203namespace key
204{
205
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800206static constexpr uint8_t listOrRangeBit = 7;
207static constexpr uint8_t linkedBit = 6;
208
Emily Shafferbbef71c2017-05-08 16:36:17 -0700209inline void set_owner_id_ipmb(SensorDataRecordKey* key)
210{
211 key->owner_id &= ~0x01;
212};
213
214inline void set_owner_id_system_sw(SensorDataRecordKey* key)
215{
216 key->owner_id |= 0x01;
217};
218
Tom Joseph96423912018-01-25 00:14:34 +0530219inline void set_owner_id_bmc(SensorDataRecordKey* key)
220{
221 key->owner_id |= 0x20;
222};
223
Emily Shafferbbef71c2017-05-08 16:36:17 -0700224inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key)
225{
226 key->owner_id &= 0x01;
Patrick Venture0b02be92018-08-31 11:55:55 -0700227 key->owner_id |= addr << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700228};
229
230inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key)
231{
232 key->owner_lun &= ~0x03;
Patrick Venture0b02be92018-08-31 11:55:55 -0700233 key->owner_lun |= (lun & 0x03);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700234};
235
236inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key)
237{
238 key->owner_lun &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700239 key->owner_lun |= ((channel & 0xf) << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700240};
241
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800242inline void set_flags(bool isList, bool isLinked,
243 SensorDataEntityRecordKey* key)
244{
245 key->flags = 0x00;
246 if (!isList)
247 key->flags |= 1 << listOrRangeBit;
248
249 if (isLinked)
250 key->flags |= 1 << linkedBit;
251};
252
Emily Shafferbbef71c2017-05-08 16:36:17 -0700253} // namespace key
254
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600255/** @struct GetSensorThresholdsResponse
256 *
257 * Response structure for Get Sensor Thresholds command
258 */
259struct GetSensorThresholdsResponse
260{
Patrick Venture0b02be92018-08-31 11:55:55 -0700261 uint8_t validMask; //!< valid mask
262 uint8_t lowerNonCritical; //!< lower non-critical threshold
263 uint8_t lowerCritical; //!< lower critical threshold
264 uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
265 uint8_t upperNonCritical; //!< upper non-critical threshold
266 uint8_t upperCritical; //!< upper critical threshold
267 uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600268} __attribute__((packed));
269
Emily Shafferbbef71c2017-05-08 16:36:17 -0700270// Body - full record
271#define FULL_RECORD_ID_STR_MAX_LENGTH 16
Ratan Guptae0cc8552018-01-22 14:23:04 +0530272
273static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
274
Emily Shafferbbef71c2017-05-08 16:36:17 -0700275struct SensorDataFullRecordBody
276{
277 uint8_t entity_id;
278 uint8_t entity_instance;
279 uint8_t sensor_initialization;
280 uint8_t sensor_capabilities; // no macro support
281 uint8_t sensor_type;
282 uint8_t event_reading_type;
Patrick Venture0b02be92018-08-31 11:55:55 -0700283 uint8_t supported_assertions[2]; // no macro support
284 uint8_t supported_deassertions[2]; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700285 uint8_t discrete_reading_setting_mask[2]; // no macro support
286 uint8_t sensor_units_1;
287 uint8_t sensor_units_2_base;
288 uint8_t sensor_units_3_modifier;
289 uint8_t linearization;
290 uint8_t m_lsb;
291 uint8_t m_msb_and_tolerance;
292 uint8_t b_lsb;
293 uint8_t b_msb_and_accuracy_lsb;
294 uint8_t accuracy_and_sensor_direction;
295 uint8_t r_b_exponents;
Patrick Venture0b02be92018-08-31 11:55:55 -0700296 uint8_t analog_characteristic_flags; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700297 uint8_t nominal_reading;
298 uint8_t normal_max;
299 uint8_t normal_min;
300 uint8_t sensor_max;
301 uint8_t sensor_min;
302 uint8_t upper_nonrecoverable_threshold;
303 uint8_t upper_critical_threshold;
304 uint8_t upper_noncritical_threshold;
305 uint8_t lower_nonrecoverable_threshold;
306 uint8_t lower_critical_threshold;
307 uint8_t lower_noncritical_threshold;
308 uint8_t positive_threshold_hysteresis;
309 uint8_t negative_threshold_hysteresis;
310 uint16_t reserved;
311 uint8_t oem_reserved;
312 uint8_t id_string_info;
Emily Shaffer10f49592017-05-10 12:01:10 -0700313 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
Emily Shafferbbef71c2017-05-08 16:36:17 -0700314} __attribute__((packed));
315
selvaganapathi7b2e5502023-02-14 07:10:47 +0530316/** @struct SensorDataCompactRecord
317 *
318 * Compact Sensor Record(body) - SDR Type 2
319 */
320struct SensorDataCompactRecordBody
321{
322 uint8_t entity_id;
323 uint8_t entity_instance;
324 uint8_t sensor_initialization;
325 uint8_t sensor_capabilities; // no macro support
326 uint8_t sensor_type;
327 uint8_t event_reading_type;
328 uint8_t supported_assertions[2]; // no macro support
329 uint8_t supported_deassertions[2]; // no macro support
330 uint8_t discrete_reading_setting_mask[2]; // no macro support
331 uint8_t sensor_units_1;
332 uint8_t sensor_units_2_base;
333 uint8_t sensor_units_3_modifier;
334 uint8_t record_sharing[2];
335 uint8_t positive_threshold_hysteresis;
336 uint8_t negative_threshold_hysteresis;
337 uint8_t reserved[3];
338 uint8_t oem_reserved;
339 uint8_t id_string_info;
340 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
341} __attribute__((packed));
342
Hao Jiangda06d152021-01-19 15:27:43 -0800343/** @struct SensorDataEventRecord
344 *
345 * Event Only Sensor Record(body) - SDR Type 3
346 */
347struct SensorDataEventRecordBody
348{
349 uint8_t entity_id;
350 uint8_t entity_instance;
351 uint8_t sensor_type;
352 uint8_t event_reading_type;
353 uint8_t sensor_record_sharing_1;
354 uint8_t sensor_record_sharing_2;
355 uint8_t reserved;
356 uint8_t oem_reserved;
357 uint8_t id_string_info;
358 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
359} __attribute__((packed));
360
Ratan Guptae0cc8552018-01-22 14:23:04 +0530361/** @struct SensorDataFruRecordBody
362 *
363 * FRU Device Locator Record(body) - SDR Type 11
364 */
365struct SensorDataFruRecordBody
366{
367 uint8_t reserved;
368 uint8_t deviceType;
369 uint8_t deviceTypeModifier;
370 uint8_t entityID;
371 uint8_t entityInstance;
372 uint8_t oem;
373 uint8_t deviceIDLen;
374 char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
375} __attribute__((packed));
376
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800377/** @struct SensorDataEntityRecordBody
378 *
379 * Entity Association Record(body) - SDR Type 8
380 */
381struct SensorDataEntityRecordBody
382{
383 uint8_t entityId2;
384 uint8_t entityInstance2;
385 uint8_t entityId3;
386 uint8_t entityInstance3;
387 uint8_t entityId4;
388 uint8_t entityInstance4;
389} __attribute__((packed));
390
Emily Shafferbbef71c2017-05-08 16:36:17 -0700391namespace body
392{
393
394inline void set_entity_instance_number(uint8_t n,
395 SensorDataFullRecordBody* body)
396{
Patrick Venture0b02be92018-08-31 11:55:55 -0700397 body->entity_instance &= 1 << 7;
398 body->entity_instance |= (n & ~(1 << 7));
Emily Shafferbbef71c2017-05-08 16:36:17 -0700399};
400inline void set_entity_physical_entity(SensorDataFullRecordBody* body)
401{
Patrick Venture0b02be92018-08-31 11:55:55 -0700402 body->entity_instance &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700403};
404inline void set_entity_logical_container(SensorDataFullRecordBody* body)
405{
Patrick Venture0b02be92018-08-31 11:55:55 -0700406 body->entity_instance |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700407};
408
Patrick Venture0b02be92018-08-31 11:55:55 -0700409inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700410{
411 if (enabled)
412 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700413 body->sensor_initialization |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700414 }
415 else
416 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700417 body->sensor_initialization &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700418 };
419};
Patrick Venture0b02be92018-08-31 11:55:55 -0700420inline void event_generation_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700421{
422 if (enabled)
423 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700424 body->sensor_initialization |= 1 << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700425 }
426 else
427 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700428 body->sensor_initialization &= ~(1 << 1);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700429 }
430};
Patrick Venture0b02be92018-08-31 11:55:55 -0700431inline void init_types_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700432{
433 if (enabled)
434 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700435 body->sensor_initialization |= 1 << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700436 }
437 else
438 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700439 body->sensor_initialization &= ~(1 << 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700440 }
441};
Patrick Venture0b02be92018-08-31 11:55:55 -0700442inline void init_hyst_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700443{
444 if (enabled)
445 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700446 body->sensor_initialization |= 1 << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700447 }
448 else
449 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700450 body->sensor_initialization &= ~(1 << 3);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700451 }
452};
Patrick Venture0b02be92018-08-31 11:55:55 -0700453inline void init_thresh_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700454{
455 if (enabled)
456 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700457 body->sensor_initialization |= 1 << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700458 }
459 else
460 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700461 body->sensor_initialization &= ~(1 << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700462 }
463};
Patrick Venture0b02be92018-08-31 11:55:55 -0700464inline void init_events_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700465{
466 if (enabled)
467 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700468 body->sensor_initialization |= 1 << 5;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700469 }
470 else
471 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700472 body->sensor_initialization &= ~(1 << 5);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700473 }
474};
Patrick Venture0b02be92018-08-31 11:55:55 -0700475inline void init_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700476{
477 if (enabled)
478 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700479 body->sensor_initialization |= 1 << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700480 }
481 else
482 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700483 body->sensor_initialization &= ~(1 << 6);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700484 }
485};
Patrick Venture0b02be92018-08-31 11:55:55 -0700486inline void init_settable_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700487{
488 if (enabled)
489 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700490 body->sensor_initialization |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700491 }
492 else
493 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700494 body->sensor_initialization &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700495 }
496};
497
498inline void set_percentage(SensorDataFullRecordBody* body)
499{
Patrick Venture0b02be92018-08-31 11:55:55 -0700500 body->sensor_units_1 |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700501};
502inline void unset_percentage(SensorDataFullRecordBody* body)
503{
Patrick Venture0b02be92018-08-31 11:55:55 -0700504 body->sensor_units_1 &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700505};
506inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body)
507{
Patrick Venture0b02be92018-08-31 11:55:55 -0700508 body->sensor_units_1 &= ~(3 << 1);
509 body->sensor_units_1 |= (op & 0x3) << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700510};
511inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body)
512{
Patrick Venture0b02be92018-08-31 11:55:55 -0700513 body->sensor_units_1 &= ~(7 << 3);
514 body->sensor_units_1 |= (unit & 0x7) << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700515};
516inline void set_analog_data_format(uint8_t format,
517 SensorDataFullRecordBody* body)
518{
Patrick Venture0b02be92018-08-31 11:55:55 -0700519 body->sensor_units_1 &= ~(3 << 6);
520 body->sensor_units_1 |= (format & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700521};
522
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700523inline void set_m(uint16_t m, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700524{
525 body->m_lsb = m & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700526 body->m_msb_and_tolerance &= ~(3 << 6);
527 body->m_msb_and_tolerance |= ((m & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700528};
529inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body)
530{
531 body->m_msb_and_tolerance &= ~0x3f;
532 body->m_msb_and_tolerance |= tol & 0x3f;
533};
534
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700535inline void set_b(uint16_t b, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700536{
537 body->b_lsb = b & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700538 body->b_msb_and_accuracy_lsb &= ~(3 << 6);
539 body->b_msb_and_accuracy_lsb |= ((b & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700540};
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700541inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700542{
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700543 // bottom 6 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700544 body->b_msb_and_accuracy_lsb &= ~0x3f;
545 body->b_msb_and_accuracy_lsb |= acc & 0x3f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700546 // top 4 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700547 body->accuracy_and_sensor_direction &= 0x0f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700548 body->accuracy_and_sensor_direction |= ((acc >> 6) & 0xf) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700549};
550inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body)
551{
Patrick Venture0b02be92018-08-31 11:55:55 -0700552 body->accuracy_and_sensor_direction &= ~(3 << 2);
553 body->accuracy_and_sensor_direction |= (exp & 3) << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700554};
555inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body)
556{
Patrick Venture0b02be92018-08-31 11:55:55 -0700557 body->accuracy_and_sensor_direction &= ~(3 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700558 body->accuracy_and_sensor_direction |= (dir & 3);
559};
560
561inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body)
562{
563 body->r_b_exponents &= 0xf0;
564 body->r_b_exponents |= exp & 0x0f;
565};
566inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body)
567{
568 body->r_b_exponents &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700569 body->r_b_exponents |= (exp & 0x0f) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700570};
571
572inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body)
573{
574 body->id_string_info &= ~(0x1f);
575 body->id_string_info |= len & 0x1f;
576};
Willy Tueae88592022-12-13 14:28:02 -0800577inline void set_id_strlen(uint8_t len, SensorDataEventRecordBody* body)
578{
579 body->id_string_info &= ~(0x1f);
580 body->id_string_info |= len & 0x1f;
581};
Patrick Venture0b02be92018-08-31 11:55:55 -0700582inline uint8_t get_id_strlen(SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700583{
584 return body->id_string_info & 0x1f;
585};
586inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body)
587{
Patrick Venture0b02be92018-08-31 11:55:55 -0700588 body->id_string_info &= ~(3 << 6);
589 body->id_string_info |= (type & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700590};
Willy Tueae88592022-12-13 14:28:02 -0800591inline void set_id_type(uint8_t type, SensorDataEventRecordBody* body)
592{
593 body->id_string_info &= ~(3 << 6);
594 body->id_string_info |= (type & 0x3) << 6;
595};
Emily Shafferbbef71c2017-05-08 16:36:17 -0700596
Ratan Guptae0cc8552018-01-22 14:23:04 +0530597inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody* body)
598{
599 body->deviceIDLen &= ~(LENGTH_MASK);
600 body->deviceIDLen |= len & LENGTH_MASK;
601};
602
603inline uint8_t get_device_id_strlen(SensorDataFruRecordBody* body)
604{
605 return body->deviceIDLen & LENGTH_MASK;
606};
607
Tom Josephdc212b22018-02-16 09:59:57 +0530608inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody* body)
609{
610 body->discrete_reading_setting_mask[1] = mask & 0x3F;
611}
612
Emily Shafferbbef71c2017-05-08 16:36:17 -0700613} // namespace body
614
615// More types contained in section 43.17 Sensor Unit Type Codes,
616// IPMI spec v2 rev 1.1
617enum SensorUnitTypeCodes
618{
619 SENSOR_UNIT_UNSPECIFIED = 0,
620 SENSOR_UNIT_DEGREES_C = 1,
621 SENSOR_UNIT_VOLTS = 4,
622 SENSOR_UNIT_AMPERES = 5,
Tom Josephdc212b22018-02-16 09:59:57 +0530623 SENSOR_UNIT_WATTS = 6,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700624 SENSOR_UNIT_JOULES = 7,
Kirill Pakhomov812e44c2018-10-22 16:25:35 +0300625 SENSOR_UNIT_RPM = 18,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700626 SENSOR_UNIT_METERS = 34,
627 SENSOR_UNIT_REVOLUTIONS = 41,
628};
629
630struct SensorDataFullRecord
631{
632 SensorDataRecordHeader header;
633 SensorDataRecordKey key;
634 SensorDataFullRecordBody body;
635} __attribute__((packed));
636
selvaganapathi7b2e5502023-02-14 07:10:47 +0530637/** @struct SensorDataComapactRecord
638 *
639 * Compact Sensor Record - SDR Type 2
640 */
641struct SensorDataCompactRecord
642{
643 SensorDataRecordHeader header;
644 SensorDataRecordKey key;
645 SensorDataCompactRecordBody body;
646} __attribute__((packed));
647
Hao Jiangda06d152021-01-19 15:27:43 -0800648/** @struct SensorDataEventRecord
649 *
650 * Event Only Sensor Record - SDR Type 3
651 */
652struct SensorDataEventRecord
653{
654 SensorDataRecordHeader header;
655 SensorDataRecordKey key;
656 SensorDataEventRecordBody body;
657} __attribute__((packed));
658
Ratan Guptae0cc8552018-01-22 14:23:04 +0530659/** @struct SensorDataFruRecord
660 *
661 * FRU Device Locator Record - SDR Type 11
662 */
663struct SensorDataFruRecord
664{
665 SensorDataRecordHeader header;
666 SensorDataFruRecordKey key;
667 SensorDataFruRecordBody body;
668} __attribute__((packed));
669
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800670/** @struct SensorDataEntityRecord
671 *
672 * Entity Association Record - SDR Type 8
673 */
674struct SensorDataEntityRecord
675{
676 SensorDataRecordHeader header;
677 SensorDataEntityRecordKey key;
678 SensorDataEntityRecordBody body;
679} __attribute__((packed));
680
Patrick Venture0b02be92018-08-31 11:55:55 -0700681} // namespace get_sdr
Tom Joseph816e92b2017-09-06 19:23:00 +0530682
683namespace ipmi
684{
685
686namespace sensor
687{
688
689/**
690 * @brief Map offset to the corresponding bit in the assertion byte.
691 *
Gunnar Mills8991dd62017-10-25 17:11:29 -0500692 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
Tom Joseph816e92b2017-09-06 19:23:00 +0530693 * byte and offsets 8-14 in the second byte.
694 *
695 * @param[in] offset - offset number.
696 * @param[in/out] resp - get sensor reading response.
697 */
Sui Chen4cc42552019-09-11 10:28:35 -0700698inline void setOffset(uint8_t offset, ipmi::sensor::GetSensorResponse* resp)
Tom Joseph816e92b2017-09-06 19:23:00 +0530699{
700 if (offset > 7)
701 {
Sui Chen4cc42552019-09-11 10:28:35 -0700702 resp->discreteReadingSensorStates |= 1 << (offset - 8);
Tom Joseph816e92b2017-09-06 19:23:00 +0530703 }
704 else
705 {
Sui Chen4cc42552019-09-11 10:28:35 -0700706 resp->thresholdLevelsStates |= 1 << offset;
Tom Joseph816e92b2017-09-06 19:23:00 +0530707 }
708}
709
Tom Josephe4014fc2017-09-06 23:57:36 +0530710/**
711 * @brief Set the reading field in the response.
712 *
713 * @param[in] offset - offset number.
714 * @param[in/out] resp - get sensor reading response.
715 */
Sui Chen4cc42552019-09-11 10:28:35 -0700716inline void setReading(uint8_t value, ipmi::sensor::GetSensorResponse* resp)
Tom Josephe4014fc2017-09-06 23:57:36 +0530717{
718 resp->reading = value;
719}
720
Tom Joseph295f17e2017-09-07 00:09:46 +0530721/**
722 * @brief Map the value to the assertion bytes. The assertion states are stored
723 * in 2 bytes.
724 *
725 * @param[in] value - value to mapped to the assertion byte.
726 * @param[in/out] resp - get sensor reading response.
727 */
728inline void setAssertionBytes(uint16_t value,
Sui Chen4cc42552019-09-11 10:28:35 -0700729 ipmi::sensor::GetSensorResponse* resp)
Tom Joseph295f17e2017-09-07 00:09:46 +0530730{
Sui Chen4cc42552019-09-11 10:28:35 -0700731 resp->thresholdLevelsStates = static_cast<uint8_t>(value & 0x00FF);
732 resp->discreteReadingSensorStates = static_cast<uint8_t>(value >> 8);
Tom Joseph295f17e2017-09-07 00:09:46 +0530733}
734
Tom Josephe05b2922017-09-07 00:43:16 +0530735/**
736 * @brief Set the scanning enabled bit in the response.
737 *
738 * @param[in/out] resp - get sensor reading response.
739 */
Sui Chen4cc42552019-09-11 10:28:35 -0700740inline void enableScanning(ipmi::sensor::GetSensorResponse* resp)
Tom Josephe05b2922017-09-07 00:43:16 +0530741{
Sui Chen4cc42552019-09-11 10:28:35 -0700742 resp->readingOrStateUnavailable = false;
743 resp->scanningEnabled = true;
744 resp->allEventMessagesEnabled = false;
Tom Josephe05b2922017-09-07 00:43:16 +0530745}
746
Tom Joseph816e92b2017-09-06 19:23:00 +0530747} // namespace sensor
748
749} // namespace ipmi