blob: 74b1862e7533f1cd18b279eb688cd037603cf736 [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
Tom Joseph5ca50952018-02-22 00:33:38 +053077ipmi_ret_t 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);
80
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 Shafferd06e0e72017-04-05 09:08:57 -070090 * Get SDR Info
91 */
92
93namespace get_sdr_info
94{
95namespace request
96{
97// Note: for some reason the ipmi_request_t appears to be the
98// raw value for this call.
99inline bool get_count(void* req)
100{
Patrick Williams369824e2023-10-20 11:18:23 -0500101 return (bool)((uint64_t)(req) & 1);
Emily Shafferd06e0e72017-04-05 09:08:57 -0700102}
103} // namespace request
Emily Shafferd06e0e72017-04-05 09:08:57 -0700104} // namespace get_sdr_info
Emily Shafferbbef71c2017-05-08 16:36:17 -0700105
106/**
107 * Get SDR
108 */
109namespace get_sdr
110{
111
112struct GetSdrReq
113{
114 uint8_t reservation_id_lsb;
115 uint8_t reservation_id_msb;
116 uint8_t record_id_lsb;
117 uint8_t record_id_msb;
118 uint8_t offset;
119 uint8_t bytes_to_read;
120} __attribute__((packed));
121
122namespace request
123{
124
Emily Shaffere5c9d2f2019-06-25 14:26:45 -0700125inline uint16_t get_reservation_id(GetSdrReq* req)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700126{
127 return (req->reservation_id_lsb + (req->reservation_id_msb << 8));
128};
129
Ratan Guptae0cc8552018-01-22 14:23:04 +0530130inline uint16_t get_record_id(GetSdrReq* req)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700131{
132 return (req->record_id_lsb + (req->record_id_msb << 8));
133};
134
135} // namespace request
136
137// Response
138struct GetSdrResp
139{
140 uint8_t next_record_id_lsb;
141 uint8_t next_record_id_msb;
142 uint8_t record_data[64];
143} __attribute__((packed));
144
145namespace response
146{
147
Ratan Guptae0cc8552018-01-22 14:23:04 +0530148inline void set_next_record_id(uint16_t next, GetSdrResp* resp)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700149{
150 resp->next_record_id_lsb = next & 0xff;
151 resp->next_record_id_msb = (next >> 8) & 0xff;
152};
153
154} // namespace response
155
156// Record header
157struct SensorDataRecordHeader
158{
159 uint8_t record_id_lsb;
160 uint8_t record_id_msb;
161 uint8_t sdr_version;
162 uint8_t record_type;
163 uint8_t record_length; // Length not counting the header
164} __attribute__((packed));
165
166namespace header
167{
168
169inline void set_record_id(int id, SensorDataRecordHeader* hdr)
170{
171 hdr->record_id_lsb = (id & 0xFF);
172 hdr->record_id_msb = (id >> 8) & 0xFF;
173};
174
175} // namespace header
176
177enum SensorDataRecordType
178{
Ratan Guptae0cc8552018-01-22 14:23:04 +0530179 SENSOR_DATA_FULL_RECORD = 0x1,
selvaganapathi7b2e5502023-02-14 07:10:47 +0530180 SENSOR_DATA_COMPACT_RECORD = 0x2,
Hao Jiangda06d152021-01-19 15:27:43 -0800181 SENSOR_DATA_EVENT_RECORD = 0x3,
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800182 SENSOR_DATA_ENTITY_RECORD = 0x8,
Harvey Wua3476272023-03-22 10:09:38 +0800183 SENSOR_DATA_FRU_RECORD = 0x11,
184 SENSOR_DATA_MGMT_CTRL_LOCATOR = 0x12,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700185};
186
187// Record key
188struct SensorDataRecordKey
189{
190 uint8_t owner_id;
191 uint8_t owner_lun;
192 uint8_t sensor_number;
193} __attribute__((packed));
194
Ratan Guptae0cc8552018-01-22 14:23:04 +0530195/** @struct SensorDataFruRecordKey
196 *
197 * FRU Device Locator Record(key) - SDR Type 11
198 */
199struct SensorDataFruRecordKey
200{
201 uint8_t deviceAddress;
202 uint8_t fruID;
203 uint8_t accessLun;
204 uint8_t channelNumber;
205} __attribute__((packed));
206
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800207/** @struct SensorDataEntityRecordKey
208 *
209 * Entity Association Record(key) - SDR Type 8
210 */
211struct SensorDataEntityRecordKey
212{
213 uint8_t containerEntityId;
214 uint8_t containerEntityInstance;
215 uint8_t flags;
216 uint8_t entityId1;
217 uint8_t entityInstance1;
218} __attribute__((packed));
219
Emily Shafferbbef71c2017-05-08 16:36:17 -0700220namespace key
221{
222
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800223static constexpr uint8_t listOrRangeBit = 7;
224static constexpr uint8_t linkedBit = 6;
225
Emily Shafferbbef71c2017-05-08 16:36:17 -0700226inline void set_owner_id_ipmb(SensorDataRecordKey* key)
227{
228 key->owner_id &= ~0x01;
229};
230
231inline void set_owner_id_system_sw(SensorDataRecordKey* key)
232{
233 key->owner_id |= 0x01;
234};
235
Tom Joseph96423912018-01-25 00:14:34 +0530236inline void set_owner_id_bmc(SensorDataRecordKey* key)
237{
238 key->owner_id |= 0x20;
239};
240
Emily Shafferbbef71c2017-05-08 16:36:17 -0700241inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key)
242{
243 key->owner_id &= 0x01;
Patrick Venture0b02be92018-08-31 11:55:55 -0700244 key->owner_id |= addr << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700245};
246
247inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key)
248{
249 key->owner_lun &= ~0x03;
Patrick Venture0b02be92018-08-31 11:55:55 -0700250 key->owner_lun |= (lun & 0x03);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700251};
252
253inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key)
254{
255 key->owner_lun &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700256 key->owner_lun |= ((channel & 0xf) << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700257};
258
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800259inline void set_flags(bool isList, bool isLinked,
260 SensorDataEntityRecordKey* key)
261{
262 key->flags = 0x00;
263 if (!isList)
264 key->flags |= 1 << listOrRangeBit;
265
266 if (isLinked)
267 key->flags |= 1 << linkedBit;
268};
269
Emily Shafferbbef71c2017-05-08 16:36:17 -0700270} // namespace key
271
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600272/** @struct GetSensorThresholdsResponse
273 *
274 * Response structure for Get Sensor Thresholds command
275 */
276struct GetSensorThresholdsResponse
277{
Patrick Venture0b02be92018-08-31 11:55:55 -0700278 uint8_t validMask; //!< valid mask
279 uint8_t lowerNonCritical; //!< lower non-critical threshold
280 uint8_t lowerCritical; //!< lower critical threshold
281 uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
282 uint8_t upperNonCritical; //!< upper non-critical threshold
283 uint8_t upperCritical; //!< upper critical threshold
284 uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600285} __attribute__((packed));
286
Emily Shafferbbef71c2017-05-08 16:36:17 -0700287// Body - full record
288#define FULL_RECORD_ID_STR_MAX_LENGTH 16
Ratan Guptae0cc8552018-01-22 14:23:04 +0530289
290static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
291
Emily Shafferbbef71c2017-05-08 16:36:17 -0700292struct SensorDataFullRecordBody
293{
294 uint8_t entity_id;
295 uint8_t entity_instance;
296 uint8_t sensor_initialization;
297 uint8_t sensor_capabilities; // no macro support
298 uint8_t sensor_type;
299 uint8_t event_reading_type;
Patrick Venture0b02be92018-08-31 11:55:55 -0700300 uint8_t supported_assertions[2]; // no macro support
301 uint8_t supported_deassertions[2]; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700302 uint8_t discrete_reading_setting_mask[2]; // no macro support
303 uint8_t sensor_units_1;
304 uint8_t sensor_units_2_base;
305 uint8_t sensor_units_3_modifier;
306 uint8_t linearization;
307 uint8_t m_lsb;
308 uint8_t m_msb_and_tolerance;
309 uint8_t b_lsb;
310 uint8_t b_msb_and_accuracy_lsb;
311 uint8_t accuracy_and_sensor_direction;
312 uint8_t r_b_exponents;
Patrick Venture0b02be92018-08-31 11:55:55 -0700313 uint8_t analog_characteristic_flags; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700314 uint8_t nominal_reading;
315 uint8_t normal_max;
316 uint8_t normal_min;
317 uint8_t sensor_max;
318 uint8_t sensor_min;
319 uint8_t upper_nonrecoverable_threshold;
320 uint8_t upper_critical_threshold;
321 uint8_t upper_noncritical_threshold;
322 uint8_t lower_nonrecoverable_threshold;
323 uint8_t lower_critical_threshold;
324 uint8_t lower_noncritical_threshold;
325 uint8_t positive_threshold_hysteresis;
326 uint8_t negative_threshold_hysteresis;
327 uint16_t reserved;
328 uint8_t oem_reserved;
329 uint8_t id_string_info;
Emily Shaffer10f49592017-05-10 12:01:10 -0700330 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
Emily Shafferbbef71c2017-05-08 16:36:17 -0700331} __attribute__((packed));
332
selvaganapathi7b2e5502023-02-14 07:10:47 +0530333/** @struct SensorDataCompactRecord
334 *
335 * Compact Sensor Record(body) - SDR Type 2
336 */
337struct SensorDataCompactRecordBody
338{
339 uint8_t entity_id;
340 uint8_t entity_instance;
341 uint8_t sensor_initialization;
342 uint8_t sensor_capabilities; // no macro support
343 uint8_t sensor_type;
344 uint8_t event_reading_type;
345 uint8_t supported_assertions[2]; // no macro support
346 uint8_t supported_deassertions[2]; // no macro support
347 uint8_t discrete_reading_setting_mask[2]; // no macro support
348 uint8_t sensor_units_1;
349 uint8_t sensor_units_2_base;
350 uint8_t sensor_units_3_modifier;
351 uint8_t record_sharing[2];
352 uint8_t positive_threshold_hysteresis;
353 uint8_t negative_threshold_hysteresis;
354 uint8_t reserved[3];
355 uint8_t oem_reserved;
356 uint8_t id_string_info;
357 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
358} __attribute__((packed));
359
Hao Jiangda06d152021-01-19 15:27:43 -0800360/** @struct SensorDataEventRecord
361 *
362 * Event Only Sensor Record(body) - SDR Type 3
363 */
364struct SensorDataEventRecordBody
365{
366 uint8_t entity_id;
367 uint8_t entity_instance;
368 uint8_t sensor_type;
369 uint8_t event_reading_type;
370 uint8_t sensor_record_sharing_1;
371 uint8_t sensor_record_sharing_2;
372 uint8_t reserved;
373 uint8_t oem_reserved;
374 uint8_t id_string_info;
375 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
376} __attribute__((packed));
377
Ratan Guptae0cc8552018-01-22 14:23:04 +0530378/** @struct SensorDataFruRecordBody
379 *
380 * FRU Device Locator Record(body) - SDR Type 11
381 */
382struct SensorDataFruRecordBody
383{
384 uint8_t reserved;
385 uint8_t deviceType;
386 uint8_t deviceTypeModifier;
387 uint8_t entityID;
388 uint8_t entityInstance;
389 uint8_t oem;
390 uint8_t deviceIDLen;
391 char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
392} __attribute__((packed));
393
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800394/** @struct SensorDataEntityRecordBody
395 *
396 * Entity Association Record(body) - SDR Type 8
397 */
398struct SensorDataEntityRecordBody
399{
400 uint8_t entityId2;
401 uint8_t entityInstance2;
402 uint8_t entityId3;
403 uint8_t entityInstance3;
404 uint8_t entityId4;
405 uint8_t entityInstance4;
406} __attribute__((packed));
407
Emily Shafferbbef71c2017-05-08 16:36:17 -0700408namespace body
409{
410
411inline void set_entity_instance_number(uint8_t n,
412 SensorDataFullRecordBody* body)
413{
Patrick Venture0b02be92018-08-31 11:55:55 -0700414 body->entity_instance &= 1 << 7;
415 body->entity_instance |= (n & ~(1 << 7));
Emily Shafferbbef71c2017-05-08 16:36:17 -0700416};
417inline void set_entity_physical_entity(SensorDataFullRecordBody* body)
418{
Patrick Venture0b02be92018-08-31 11:55:55 -0700419 body->entity_instance &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700420};
421inline void set_entity_logical_container(SensorDataFullRecordBody* body)
422{
Patrick Venture0b02be92018-08-31 11:55:55 -0700423 body->entity_instance |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700424};
425
Patrick Venture0b02be92018-08-31 11:55:55 -0700426inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700427{
428 if (enabled)
429 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700430 body->sensor_initialization |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700431 }
432 else
433 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700434 body->sensor_initialization &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700435 };
436};
Patrick Venture0b02be92018-08-31 11:55:55 -0700437inline void event_generation_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700438{
439 if (enabled)
440 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700441 body->sensor_initialization |= 1 << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700442 }
443 else
444 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700445 body->sensor_initialization &= ~(1 << 1);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700446 }
447};
Patrick Venture0b02be92018-08-31 11:55:55 -0700448inline void init_types_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700449{
450 if (enabled)
451 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700452 body->sensor_initialization |= 1 << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700453 }
454 else
455 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700456 body->sensor_initialization &= ~(1 << 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700457 }
458};
Patrick Venture0b02be92018-08-31 11:55:55 -0700459inline void init_hyst_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700460{
461 if (enabled)
462 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700463 body->sensor_initialization |= 1 << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700464 }
465 else
466 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700467 body->sensor_initialization &= ~(1 << 3);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700468 }
469};
Patrick Venture0b02be92018-08-31 11:55:55 -0700470inline void init_thresh_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700471{
472 if (enabled)
473 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700474 body->sensor_initialization |= 1 << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700475 }
476 else
477 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700478 body->sensor_initialization &= ~(1 << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700479 }
480};
Patrick Venture0b02be92018-08-31 11:55:55 -0700481inline void init_events_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700482{
483 if (enabled)
484 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700485 body->sensor_initialization |= 1 << 5;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700486 }
487 else
488 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700489 body->sensor_initialization &= ~(1 << 5);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700490 }
491};
Patrick Venture0b02be92018-08-31 11:55:55 -0700492inline void init_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700493{
494 if (enabled)
495 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700496 body->sensor_initialization |= 1 << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700497 }
498 else
499 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700500 body->sensor_initialization &= ~(1 << 6);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700501 }
502};
Patrick Venture0b02be92018-08-31 11:55:55 -0700503inline void init_settable_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700504{
505 if (enabled)
506 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700507 body->sensor_initialization |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700508 }
509 else
510 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700511 body->sensor_initialization &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700512 }
513};
514
515inline void set_percentage(SensorDataFullRecordBody* body)
516{
Patrick Venture0b02be92018-08-31 11:55:55 -0700517 body->sensor_units_1 |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700518};
519inline void unset_percentage(SensorDataFullRecordBody* body)
520{
Patrick Venture0b02be92018-08-31 11:55:55 -0700521 body->sensor_units_1 &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700522};
523inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body)
524{
Patrick Venture0b02be92018-08-31 11:55:55 -0700525 body->sensor_units_1 &= ~(3 << 1);
526 body->sensor_units_1 |= (op & 0x3) << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700527};
528inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body)
529{
Patrick Venture0b02be92018-08-31 11:55:55 -0700530 body->sensor_units_1 &= ~(7 << 3);
531 body->sensor_units_1 |= (unit & 0x7) << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700532};
533inline void set_analog_data_format(uint8_t format,
534 SensorDataFullRecordBody* body)
535{
Patrick Venture0b02be92018-08-31 11:55:55 -0700536 body->sensor_units_1 &= ~(3 << 6);
537 body->sensor_units_1 |= (format & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700538};
539
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700540inline void set_m(uint16_t m, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700541{
542 body->m_lsb = m & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700543 body->m_msb_and_tolerance &= ~(3 << 6);
544 body->m_msb_and_tolerance |= ((m & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700545};
546inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body)
547{
548 body->m_msb_and_tolerance &= ~0x3f;
549 body->m_msb_and_tolerance |= tol & 0x3f;
550};
551
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700552inline void set_b(uint16_t b, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700553{
554 body->b_lsb = b & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700555 body->b_msb_and_accuracy_lsb &= ~(3 << 6);
556 body->b_msb_and_accuracy_lsb |= ((b & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700557};
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700558inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700559{
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700560 // bottom 6 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700561 body->b_msb_and_accuracy_lsb &= ~0x3f;
562 body->b_msb_and_accuracy_lsb |= acc & 0x3f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700563 // top 4 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700564 body->accuracy_and_sensor_direction &= 0x0f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700565 body->accuracy_and_sensor_direction |= ((acc >> 6) & 0xf) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700566};
567inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body)
568{
Patrick Venture0b02be92018-08-31 11:55:55 -0700569 body->accuracy_and_sensor_direction &= ~(3 << 2);
570 body->accuracy_and_sensor_direction |= (exp & 3) << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700571};
572inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body)
573{
Patrick Venture0b02be92018-08-31 11:55:55 -0700574 body->accuracy_and_sensor_direction &= ~(3 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700575 body->accuracy_and_sensor_direction |= (dir & 3);
576};
577
578inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body)
579{
580 body->r_b_exponents &= 0xf0;
581 body->r_b_exponents |= exp & 0x0f;
582};
583inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body)
584{
585 body->r_b_exponents &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700586 body->r_b_exponents |= (exp & 0x0f) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700587};
588
589inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body)
590{
591 body->id_string_info &= ~(0x1f);
592 body->id_string_info |= len & 0x1f;
593};
Willy Tueae88592022-12-13 14:28:02 -0800594inline void set_id_strlen(uint8_t len, SensorDataEventRecordBody* body)
595{
596 body->id_string_info &= ~(0x1f);
597 body->id_string_info |= len & 0x1f;
598};
Patrick Venture0b02be92018-08-31 11:55:55 -0700599inline uint8_t get_id_strlen(SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700600{
601 return body->id_string_info & 0x1f;
602};
603inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body)
604{
Patrick Venture0b02be92018-08-31 11:55:55 -0700605 body->id_string_info &= ~(3 << 6);
606 body->id_string_info |= (type & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700607};
Willy Tueae88592022-12-13 14:28:02 -0800608inline void set_id_type(uint8_t type, SensorDataEventRecordBody* body)
609{
610 body->id_string_info &= ~(3 << 6);
611 body->id_string_info |= (type & 0x3) << 6;
612};
Emily Shafferbbef71c2017-05-08 16:36:17 -0700613
Ratan Guptae0cc8552018-01-22 14:23:04 +0530614inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody* body)
615{
616 body->deviceIDLen &= ~(LENGTH_MASK);
617 body->deviceIDLen |= len & LENGTH_MASK;
618};
619
620inline uint8_t get_device_id_strlen(SensorDataFruRecordBody* body)
621{
622 return body->deviceIDLen & LENGTH_MASK;
623};
624
Tom Josephdc212b22018-02-16 09:59:57 +0530625inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody* body)
626{
627 body->discrete_reading_setting_mask[1] = mask & 0x3F;
628}
629
Emily Shafferbbef71c2017-05-08 16:36:17 -0700630} // namespace body
631
632// More types contained in section 43.17 Sensor Unit Type Codes,
633// IPMI spec v2 rev 1.1
634enum SensorUnitTypeCodes
635{
636 SENSOR_UNIT_UNSPECIFIED = 0,
637 SENSOR_UNIT_DEGREES_C = 1,
638 SENSOR_UNIT_VOLTS = 4,
639 SENSOR_UNIT_AMPERES = 5,
Tom Josephdc212b22018-02-16 09:59:57 +0530640 SENSOR_UNIT_WATTS = 6,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700641 SENSOR_UNIT_JOULES = 7,
Kirill Pakhomov812e44c2018-10-22 16:25:35 +0300642 SENSOR_UNIT_RPM = 18,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700643 SENSOR_UNIT_METERS = 34,
644 SENSOR_UNIT_REVOLUTIONS = 41,
645};
646
647struct SensorDataFullRecord
648{
649 SensorDataRecordHeader header;
650 SensorDataRecordKey key;
651 SensorDataFullRecordBody body;
652} __attribute__((packed));
653
selvaganapathi7b2e5502023-02-14 07:10:47 +0530654/** @struct SensorDataComapactRecord
655 *
656 * Compact Sensor Record - SDR Type 2
657 */
658struct SensorDataCompactRecord
659{
660 SensorDataRecordHeader header;
661 SensorDataRecordKey key;
662 SensorDataCompactRecordBody body;
663} __attribute__((packed));
664
Hao Jiangda06d152021-01-19 15:27:43 -0800665/** @struct SensorDataEventRecord
666 *
667 * Event Only Sensor Record - SDR Type 3
668 */
669struct SensorDataEventRecord
670{
671 SensorDataRecordHeader header;
672 SensorDataRecordKey key;
673 SensorDataEventRecordBody body;
674} __attribute__((packed));
675
Ratan Guptae0cc8552018-01-22 14:23:04 +0530676/** @struct SensorDataFruRecord
677 *
678 * FRU Device Locator Record - SDR Type 11
679 */
680struct SensorDataFruRecord
681{
682 SensorDataRecordHeader header;
683 SensorDataFruRecordKey key;
684 SensorDataFruRecordBody body;
685} __attribute__((packed));
686
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800687/** @struct SensorDataEntityRecord
688 *
689 * Entity Association Record - SDR Type 8
690 */
691struct SensorDataEntityRecord
692{
693 SensorDataRecordHeader header;
694 SensorDataEntityRecordKey key;
695 SensorDataEntityRecordBody body;
696} __attribute__((packed));
697
Patrick Venture0b02be92018-08-31 11:55:55 -0700698} // namespace get_sdr
Tom Joseph816e92b2017-09-06 19:23:00 +0530699
700namespace ipmi
701{
702
703namespace sensor
704{
705
706/**
707 * @brief Map offset to the corresponding bit in the assertion byte.
708 *
Gunnar Mills8991dd62017-10-25 17:11:29 -0500709 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
Tom Joseph816e92b2017-09-06 19:23:00 +0530710 * byte and offsets 8-14 in the second byte.
711 *
712 * @param[in] offset - offset number.
713 * @param[in/out] resp - get sensor reading response.
714 */
Sui Chen4cc42552019-09-11 10:28:35 -0700715inline void setOffset(uint8_t offset, ipmi::sensor::GetSensorResponse* resp)
Tom Joseph816e92b2017-09-06 19:23:00 +0530716{
717 if (offset > 7)
718 {
Sui Chen4cc42552019-09-11 10:28:35 -0700719 resp->discreteReadingSensorStates |= 1 << (offset - 8);
Tom Joseph816e92b2017-09-06 19:23:00 +0530720 }
721 else
722 {
Sui Chen4cc42552019-09-11 10:28:35 -0700723 resp->thresholdLevelsStates |= 1 << offset;
Tom Joseph816e92b2017-09-06 19:23:00 +0530724 }
725}
726
Tom Josephe4014fc2017-09-06 23:57:36 +0530727/**
728 * @brief Set the reading field in the response.
729 *
730 * @param[in] offset - offset number.
731 * @param[in/out] resp - get sensor reading response.
732 */
Sui Chen4cc42552019-09-11 10:28:35 -0700733inline void setReading(uint8_t value, ipmi::sensor::GetSensorResponse* resp)
Tom Josephe4014fc2017-09-06 23:57:36 +0530734{
735 resp->reading = value;
736}
737
Tom Joseph295f17e2017-09-07 00:09:46 +0530738/**
739 * @brief Map the value to the assertion bytes. The assertion states are stored
740 * in 2 bytes.
741 *
742 * @param[in] value - value to mapped to the assertion byte.
743 * @param[in/out] resp - get sensor reading response.
744 */
745inline void setAssertionBytes(uint16_t value,
Sui Chen4cc42552019-09-11 10:28:35 -0700746 ipmi::sensor::GetSensorResponse* resp)
Tom Joseph295f17e2017-09-07 00:09:46 +0530747{
Sui Chen4cc42552019-09-11 10:28:35 -0700748 resp->thresholdLevelsStates = static_cast<uint8_t>(value & 0x00FF);
749 resp->discreteReadingSensorStates = static_cast<uint8_t>(value >> 8);
Tom Joseph295f17e2017-09-07 00:09:46 +0530750}
751
Tom Josephe05b2922017-09-07 00:43:16 +0530752/**
753 * @brief Set the scanning enabled bit in the response.
754 *
755 * @param[in/out] resp - get sensor reading response.
756 */
Sui Chen4cc42552019-09-11 10:28:35 -0700757inline void enableScanning(ipmi::sensor::GetSensorResponse* resp)
Tom Josephe05b2922017-09-07 00:43:16 +0530758{
Sui Chen4cc42552019-09-11 10:28:35 -0700759 resp->readingOrStateUnavailable = false;
760 resp->scanningEnabled = true;
761 resp->allEventMessagesEnabled = false;
Tom Josephe05b2922017-09-07 00:43:16 +0530762}
763
Tom Joseph816e92b2017-09-06 19:23:00 +0530764} // namespace sensor
765
766} // namespace ipmi