blob: 8fcf2b1ab9a296435a705e975e6d20922f197e57 [file] [log] [blame]
Patrick Venture46470a32018-09-07 19:26:25 -07001#pragma once
Chris Austenac4604a2015-10-13 12:43:27 -05002
Tom Joseph816e92b2017-09-06 19:23:00 +05303#include "types.hpp"
Patrick Venture0b02be92018-08-31 11:55:55 -07004
William A. Kennington III194375f2018-12-14 02:14:33 -08005#include <ipmid/api.h>
Patrick Venture0b02be92018-08-31 11:55:55 -07006#include <stdint.h>
7
Chris Austenac4604a2015-10-13 12:43:27 -05008// IPMI commands for net functions.
9enum ipmi_netfn_sen_cmds
10{
Jia, Chunhui3342a8e2018-12-29 13:32:26 +080011 IPMI_CMD_PLATFORM_EVENT = 0x2,
Tom Joseph5ca50952018-02-22 00:33:38 +053012 IPMI_CMD_GET_DEVICE_SDR_INFO = 0x20,
Patrick Venture0b02be92018-08-31 11:55:55 -070013 IPMI_CMD_GET_DEVICE_SDR = 0x21,
14 IPMI_CMD_RESERVE_DEVICE_SDR_REPO = 0x22,
Chris Austen10ccc0f2015-12-10 18:27:04 -060015 IPMI_CMD_GET_SENSOR_READING = 0x2D,
Patrick Venture0b02be92018-08-31 11:55:55 -070016 IPMI_CMD_GET_SENSOR_TYPE = 0x2F,
17 IPMI_CMD_SET_SENSOR = 0x30,
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -060018 IPMI_CMD_GET_SENSOR_THRESHOLDS = 0x27,
Chris Austenac4604a2015-10-13 12:43:27 -050019};
20
Ratan Guptae0cc8552018-01-22 14:23:04 +053021/**
22 * @enum device_type
23 * IPMI FRU device types
24 */
25enum device_type
26{
27 IPMI_PHYSICAL_FRU = 0x00,
28 IPMI_LOGICAL_FRU = 0x80,
29};
30
Emily Shaffer1fabf222017-04-05 08:53:21 -070031// Discrete sensor types.
32enum ipmi_sensor_types
33{
Patrick Venture0b02be92018-08-31 11:55:55 -070034 IPMI_SENSOR_TEMP = 0x01,
Emily Shaffer1fabf222017-04-05 08:53:21 -070035 IPMI_SENSOR_VOLTAGE = 0x02,
36 IPMI_SENSOR_CURRENT = 0x03,
Patrick Venture0b02be92018-08-31 11:55:55 -070037 IPMI_SENSOR_FAN = 0x04,
38 IPMI_SENSOR_TPM = 0xCC,
Emily Shaffer1fabf222017-04-05 08:53:21 -070039};
40
Chris Austen0012e9b2015-10-22 01:37:46 -050041#define MAX_DBUS_PATH 128
Patrick Venture0b02be92018-08-31 11:55:55 -070042struct dbus_interface_t
43{
44 uint8_t sensornumber;
45 uint8_t sensortype;
Chris Austen0012e9b2015-10-22 01:37:46 -050046
Patrick Venture0b02be92018-08-31 11:55:55 -070047 char bus[MAX_DBUS_PATH];
48 char path[MAX_DBUS_PATH];
49 char interface[MAX_DBUS_PATH];
Chris Austen0012e9b2015-10-22 01:37:46 -050050};
Tomd700e762016-09-20 18:24:13 +053051
Jia, Chunhui3342a8e2018-12-29 13:32:26 +080052struct PlatformEventRequest
53{
54 uint8_t eventMessageRevision;
55 uint8_t sensorType;
56 uint8_t sensorNumber;
57 uint8_t eventDirectionType;
58 uint8_t data[3];
59};
60
61static constexpr char const* ipmiSELPath = "/xyz/openbmc_project/Logging/IPMI";
62static constexpr char const* ipmiSELAddInterface =
63 "xyz.openbmc_project.Logging.IPMI";
64static const std::string ipmiSELAddMessage = "SEL Entry";
65
66static constexpr int selSystemEventSizeWith3Bytes = 8;
67static constexpr int selSystemEventSizeWith2Bytes = 7;
68static constexpr int selSystemEventSizeWith1Bytes = 6;
69static constexpr int selIPMBEventSize = 7;
70static constexpr uint8_t directionMask = 0x80;
71static constexpr uint8_t byte3EnableMask = 0x30;
72static constexpr uint8_t byte2EnableMask = 0xC0;
73
Patrick Venture0b02be92018-08-31 11:55:55 -070074int set_sensor_dbus_state_s(uint8_t, const char*, const char*);
75int set_sensor_dbus_state_y(uint8_t, const char*, const uint8_t);
76int find_openbmc_path(uint8_t, dbus_interface_t*);
Tom05732372016-09-06 17:21:23 +053077
Tom Joseph5ca50952018-02-22 00:33:38 +053078ipmi_ret_t ipmi_sen_get_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
79 ipmi_request_t request, ipmi_response_t response,
80 ipmi_data_len_t data_len, ipmi_context_t context);
81
82ipmi_ret_t ipmi_sen_reserve_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
83 ipmi_request_t request,
84 ipmi_response_t response,
85 ipmi_data_len_t data_len,
86 ipmi_context_t context);
87
Ratan Guptae0cc8552018-01-22 14:23:04 +053088static const uint16_t FRU_RECORD_ID_START = 256;
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -080089static const uint16_t ENTITY_RECORD_ID_START = 512;
Ratan Guptae0cc8552018-01-22 14:23:04 +053090static const uint8_t SDR_VERSION = 0x51;
91static const uint16_t END_OF_RECORD = 0xFFFF;
92static const uint8_t LENGTH_MASK = 0x1F;
93
Tom Josephbe703f72017-03-09 12:34:35 +053094/**
Emily Shafferd06e0e72017-04-05 09:08:57 -070095 * Get SDR Info
96 */
97
98namespace get_sdr_info
99{
100namespace request
101{
102// Note: for some reason the ipmi_request_t appears to be the
103// raw value for this call.
104inline bool get_count(void* req)
105{
Patrick Venture0b02be92018-08-31 11:55:55 -0700106 return (bool)((uint64_t)(req)&1);
Emily Shafferd06e0e72017-04-05 09:08:57 -0700107}
108} // namespace request
109
110namespace response
111{
112#define SDR_INFO_RESP_SIZE 2
113inline void set_lun_present(int lun, uint8_t* resp)
114{
115 *resp |= 1 << lun;
116}
117inline void set_lun_not_present(int lun, uint8_t* resp)
118{
119 *resp &= ~(1 << lun);
120}
121inline void set_dynamic_population(uint8_t* resp)
122{
123 *resp |= 1 << 7;
124}
125inline void set_static_population(uint8_t* resp)
126{
127 *resp &= ~(1 << 7);
128}
129} // namespace response
130
131struct GetSdrInfoResp
132{
133 uint8_t count;
134 uint8_t luns_and_dynamic_population;
135};
136
137} // namespace get_sdr_info
Emily Shafferbbef71c2017-05-08 16:36:17 -0700138
139/**
140 * Get SDR
141 */
142namespace get_sdr
143{
144
145struct GetSdrReq
146{
147 uint8_t reservation_id_lsb;
148 uint8_t reservation_id_msb;
149 uint8_t record_id_lsb;
150 uint8_t record_id_msb;
151 uint8_t offset;
152 uint8_t bytes_to_read;
153} __attribute__((packed));
154
155namespace request
156{
157
158inline uint8_t get_reservation_id(GetSdrReq* req)
159{
160 return (req->reservation_id_lsb + (req->reservation_id_msb << 8));
161};
162
Ratan Guptae0cc8552018-01-22 14:23:04 +0530163inline uint16_t get_record_id(GetSdrReq* req)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700164{
165 return (req->record_id_lsb + (req->record_id_msb << 8));
166};
167
168} // namespace request
169
170// Response
171struct GetSdrResp
172{
173 uint8_t next_record_id_lsb;
174 uint8_t next_record_id_msb;
175 uint8_t record_data[64];
176} __attribute__((packed));
177
178namespace response
179{
180
Ratan Guptae0cc8552018-01-22 14:23:04 +0530181inline void set_next_record_id(uint16_t next, GetSdrResp* resp)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700182{
183 resp->next_record_id_lsb = next & 0xff;
184 resp->next_record_id_msb = (next >> 8) & 0xff;
185};
186
187} // namespace response
188
189// Record header
190struct SensorDataRecordHeader
191{
192 uint8_t record_id_lsb;
193 uint8_t record_id_msb;
194 uint8_t sdr_version;
195 uint8_t record_type;
196 uint8_t record_length; // Length not counting the header
197} __attribute__((packed));
198
199namespace header
200{
201
202inline void set_record_id(int id, SensorDataRecordHeader* hdr)
203{
204 hdr->record_id_lsb = (id & 0xFF);
205 hdr->record_id_msb = (id >> 8) & 0xFF;
206};
207
208} // namespace header
209
210enum SensorDataRecordType
211{
Ratan Guptae0cc8552018-01-22 14:23:04 +0530212 SENSOR_DATA_FULL_RECORD = 0x1,
213 SENSOR_DATA_FRU_RECORD = 0x11,
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800214 SENSOR_DATA_ENTITY_RECORD = 0x8,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700215};
216
217// Record key
218struct SensorDataRecordKey
219{
220 uint8_t owner_id;
221 uint8_t owner_lun;
222 uint8_t sensor_number;
223} __attribute__((packed));
224
Ratan Guptae0cc8552018-01-22 14:23:04 +0530225/** @struct SensorDataFruRecordKey
226 *
227 * FRU Device Locator Record(key) - SDR Type 11
228 */
229struct SensorDataFruRecordKey
230{
231 uint8_t deviceAddress;
232 uint8_t fruID;
233 uint8_t accessLun;
234 uint8_t channelNumber;
235} __attribute__((packed));
236
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800237/** @struct SensorDataEntityRecordKey
238 *
239 * Entity Association Record(key) - SDR Type 8
240 */
241struct SensorDataEntityRecordKey
242{
243 uint8_t containerEntityId;
244 uint8_t containerEntityInstance;
245 uint8_t flags;
246 uint8_t entityId1;
247 uint8_t entityInstance1;
248} __attribute__((packed));
249
Emily Shafferbbef71c2017-05-08 16:36:17 -0700250namespace key
251{
252
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800253static constexpr uint8_t listOrRangeBit = 7;
254static constexpr uint8_t linkedBit = 6;
255
Emily Shafferbbef71c2017-05-08 16:36:17 -0700256inline void set_owner_id_ipmb(SensorDataRecordKey* key)
257{
258 key->owner_id &= ~0x01;
259};
260
261inline void set_owner_id_system_sw(SensorDataRecordKey* key)
262{
263 key->owner_id |= 0x01;
264};
265
Tom Joseph96423912018-01-25 00:14:34 +0530266inline void set_owner_id_bmc(SensorDataRecordKey* key)
267{
268 key->owner_id |= 0x20;
269};
270
Emily Shafferbbef71c2017-05-08 16:36:17 -0700271inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key)
272{
273 key->owner_id &= 0x01;
Patrick Venture0b02be92018-08-31 11:55:55 -0700274 key->owner_id |= addr << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700275};
276
277inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key)
278{
279 key->owner_lun &= ~0x03;
Patrick Venture0b02be92018-08-31 11:55:55 -0700280 key->owner_lun |= (lun & 0x03);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700281};
282
283inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key)
284{
285 key->owner_lun &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700286 key->owner_lun |= ((channel & 0xf) << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700287};
288
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800289inline void set_flags(bool isList, bool isLinked,
290 SensorDataEntityRecordKey* key)
291{
292 key->flags = 0x00;
293 if (!isList)
294 key->flags |= 1 << listOrRangeBit;
295
296 if (isLinked)
297 key->flags |= 1 << linkedBit;
298};
299
Emily Shafferbbef71c2017-05-08 16:36:17 -0700300} // namespace key
301
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600302/** @struct GetSensorThresholdsResponse
303 *
304 * Response structure for Get Sensor Thresholds command
305 */
306struct GetSensorThresholdsResponse
307{
Patrick Venture0b02be92018-08-31 11:55:55 -0700308 uint8_t validMask; //!< valid mask
309 uint8_t lowerNonCritical; //!< lower non-critical threshold
310 uint8_t lowerCritical; //!< lower critical threshold
311 uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
312 uint8_t upperNonCritical; //!< upper non-critical threshold
313 uint8_t upperCritical; //!< upper critical threshold
314 uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600315} __attribute__((packed));
316
Emily Shafferbbef71c2017-05-08 16:36:17 -0700317// Body - full record
318#define FULL_RECORD_ID_STR_MAX_LENGTH 16
Ratan Guptae0cc8552018-01-22 14:23:04 +0530319
320static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
321
Emily Shafferbbef71c2017-05-08 16:36:17 -0700322struct SensorDataFullRecordBody
323{
324 uint8_t entity_id;
325 uint8_t entity_instance;
326 uint8_t sensor_initialization;
327 uint8_t sensor_capabilities; // no macro support
328 uint8_t sensor_type;
329 uint8_t event_reading_type;
Patrick Venture0b02be92018-08-31 11:55:55 -0700330 uint8_t supported_assertions[2]; // no macro support
331 uint8_t supported_deassertions[2]; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700332 uint8_t discrete_reading_setting_mask[2]; // no macro support
333 uint8_t sensor_units_1;
334 uint8_t sensor_units_2_base;
335 uint8_t sensor_units_3_modifier;
336 uint8_t linearization;
337 uint8_t m_lsb;
338 uint8_t m_msb_and_tolerance;
339 uint8_t b_lsb;
340 uint8_t b_msb_and_accuracy_lsb;
341 uint8_t accuracy_and_sensor_direction;
342 uint8_t r_b_exponents;
Patrick Venture0b02be92018-08-31 11:55:55 -0700343 uint8_t analog_characteristic_flags; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700344 uint8_t nominal_reading;
345 uint8_t normal_max;
346 uint8_t normal_min;
347 uint8_t sensor_max;
348 uint8_t sensor_min;
349 uint8_t upper_nonrecoverable_threshold;
350 uint8_t upper_critical_threshold;
351 uint8_t upper_noncritical_threshold;
352 uint8_t lower_nonrecoverable_threshold;
353 uint8_t lower_critical_threshold;
354 uint8_t lower_noncritical_threshold;
355 uint8_t positive_threshold_hysteresis;
356 uint8_t negative_threshold_hysteresis;
357 uint16_t reserved;
358 uint8_t oem_reserved;
359 uint8_t id_string_info;
Emily Shaffer10f49592017-05-10 12:01:10 -0700360 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
Emily Shafferbbef71c2017-05-08 16:36:17 -0700361} __attribute__((packed));
362
Ratan Guptae0cc8552018-01-22 14:23:04 +0530363/** @struct SensorDataFruRecordBody
364 *
365 * FRU Device Locator Record(body) - SDR Type 11
366 */
367struct SensorDataFruRecordBody
368{
369 uint8_t reserved;
370 uint8_t deviceType;
371 uint8_t deviceTypeModifier;
372 uint8_t entityID;
373 uint8_t entityInstance;
374 uint8_t oem;
375 uint8_t deviceIDLen;
376 char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
377} __attribute__((packed));
378
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800379/** @struct SensorDataEntityRecordBody
380 *
381 * Entity Association Record(body) - SDR Type 8
382 */
383struct SensorDataEntityRecordBody
384{
385 uint8_t entityId2;
386 uint8_t entityInstance2;
387 uint8_t entityId3;
388 uint8_t entityInstance3;
389 uint8_t entityId4;
390 uint8_t entityInstance4;
391} __attribute__((packed));
392
Emily Shafferbbef71c2017-05-08 16:36:17 -0700393namespace body
394{
395
396inline void set_entity_instance_number(uint8_t n,
397 SensorDataFullRecordBody* body)
398{
Patrick Venture0b02be92018-08-31 11:55:55 -0700399 body->entity_instance &= 1 << 7;
400 body->entity_instance |= (n & ~(1 << 7));
Emily Shafferbbef71c2017-05-08 16:36:17 -0700401};
402inline void set_entity_physical_entity(SensorDataFullRecordBody* body)
403{
Patrick Venture0b02be92018-08-31 11:55:55 -0700404 body->entity_instance &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700405};
406inline void set_entity_logical_container(SensorDataFullRecordBody* body)
407{
Patrick Venture0b02be92018-08-31 11:55:55 -0700408 body->entity_instance |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700409};
410
Patrick Venture0b02be92018-08-31 11:55:55 -0700411inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700412{
413 if (enabled)
414 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700415 body->sensor_initialization |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700416 }
417 else
418 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700419 body->sensor_initialization &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700420 };
421};
Patrick Venture0b02be92018-08-31 11:55:55 -0700422inline void event_generation_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700423{
424 if (enabled)
425 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700426 body->sensor_initialization |= 1 << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700427 }
428 else
429 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700430 body->sensor_initialization &= ~(1 << 1);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700431 }
432};
Patrick Venture0b02be92018-08-31 11:55:55 -0700433inline void init_types_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700434{
435 if (enabled)
436 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700437 body->sensor_initialization |= 1 << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700438 }
439 else
440 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700441 body->sensor_initialization &= ~(1 << 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700442 }
443};
Patrick Venture0b02be92018-08-31 11:55:55 -0700444inline void init_hyst_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700445{
446 if (enabled)
447 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700448 body->sensor_initialization |= 1 << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700449 }
450 else
451 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700452 body->sensor_initialization &= ~(1 << 3);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700453 }
454};
Patrick Venture0b02be92018-08-31 11:55:55 -0700455inline void init_thresh_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700456{
457 if (enabled)
458 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700459 body->sensor_initialization |= 1 << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700460 }
461 else
462 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700463 body->sensor_initialization &= ~(1 << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700464 }
465};
Patrick Venture0b02be92018-08-31 11:55:55 -0700466inline void init_events_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700467{
468 if (enabled)
469 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700470 body->sensor_initialization |= 1 << 5;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700471 }
472 else
473 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700474 body->sensor_initialization &= ~(1 << 5);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700475 }
476};
Patrick Venture0b02be92018-08-31 11:55:55 -0700477inline void init_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700478{
479 if (enabled)
480 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700481 body->sensor_initialization |= 1 << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700482 }
483 else
484 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700485 body->sensor_initialization &= ~(1 << 6);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700486 }
487};
Patrick Venture0b02be92018-08-31 11:55:55 -0700488inline void init_settable_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700489{
490 if (enabled)
491 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700492 body->sensor_initialization |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700493 }
494 else
495 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700496 body->sensor_initialization &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700497 }
498};
499
500inline void set_percentage(SensorDataFullRecordBody* body)
501{
Patrick Venture0b02be92018-08-31 11:55:55 -0700502 body->sensor_units_1 |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700503};
504inline void unset_percentage(SensorDataFullRecordBody* body)
505{
Patrick Venture0b02be92018-08-31 11:55:55 -0700506 body->sensor_units_1 &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700507};
508inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body)
509{
Patrick Venture0b02be92018-08-31 11:55:55 -0700510 body->sensor_units_1 &= ~(3 << 1);
511 body->sensor_units_1 |= (op & 0x3) << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700512};
513inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body)
514{
Patrick Venture0b02be92018-08-31 11:55:55 -0700515 body->sensor_units_1 &= ~(7 << 3);
516 body->sensor_units_1 |= (unit & 0x7) << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700517};
518inline void set_analog_data_format(uint8_t format,
519 SensorDataFullRecordBody* body)
520{
Patrick Venture0b02be92018-08-31 11:55:55 -0700521 body->sensor_units_1 &= ~(3 << 6);
522 body->sensor_units_1 |= (format & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700523};
524
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700525inline void set_m(uint16_t m, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700526{
527 body->m_lsb = m & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700528 body->m_msb_and_tolerance &= ~(3 << 6);
529 body->m_msb_and_tolerance |= ((m & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700530};
531inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body)
532{
533 body->m_msb_and_tolerance &= ~0x3f;
534 body->m_msb_and_tolerance |= tol & 0x3f;
535};
536
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700537inline void set_b(uint16_t b, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700538{
539 body->b_lsb = b & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700540 body->b_msb_and_accuracy_lsb &= ~(3 << 6);
541 body->b_msb_and_accuracy_lsb |= ((b & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700542};
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700543inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700544{
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700545 // bottom 6 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700546 body->b_msb_and_accuracy_lsb &= ~0x3f;
547 body->b_msb_and_accuracy_lsb |= acc & 0x3f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700548 // top 4 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700549 body->accuracy_and_sensor_direction &= 0x0f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700550 body->accuracy_and_sensor_direction |= ((acc >> 6) & 0xf) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700551};
552inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body)
553{
Patrick Venture0b02be92018-08-31 11:55:55 -0700554 body->accuracy_and_sensor_direction &= ~(3 << 2);
555 body->accuracy_and_sensor_direction |= (exp & 3) << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700556};
557inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body)
558{
Patrick Venture0b02be92018-08-31 11:55:55 -0700559 body->accuracy_and_sensor_direction &= ~(3 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700560 body->accuracy_and_sensor_direction |= (dir & 3);
561};
562
563inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body)
564{
565 body->r_b_exponents &= 0xf0;
566 body->r_b_exponents |= exp & 0x0f;
567};
568inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body)
569{
570 body->r_b_exponents &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700571 body->r_b_exponents |= (exp & 0x0f) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700572};
573
574inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body)
575{
576 body->id_string_info &= ~(0x1f);
577 body->id_string_info |= len & 0x1f;
578};
Patrick Venture0b02be92018-08-31 11:55:55 -0700579inline uint8_t get_id_strlen(SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700580{
581 return body->id_string_info & 0x1f;
582};
583inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body)
584{
Patrick Venture0b02be92018-08-31 11:55:55 -0700585 body->id_string_info &= ~(3 << 6);
586 body->id_string_info |= (type & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700587};
588
Ratan Guptae0cc8552018-01-22 14:23:04 +0530589inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody* body)
590{
591 body->deviceIDLen &= ~(LENGTH_MASK);
592 body->deviceIDLen |= len & LENGTH_MASK;
593};
594
595inline uint8_t get_device_id_strlen(SensorDataFruRecordBody* body)
596{
597 return body->deviceIDLen & LENGTH_MASK;
598};
599
Tom Josephdc212b22018-02-16 09:59:57 +0530600inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody* body)
601{
602 body->discrete_reading_setting_mask[1] = mask & 0x3F;
603}
604
Emily Shafferbbef71c2017-05-08 16:36:17 -0700605} // namespace body
606
607// More types contained in section 43.17 Sensor Unit Type Codes,
608// IPMI spec v2 rev 1.1
609enum SensorUnitTypeCodes
610{
611 SENSOR_UNIT_UNSPECIFIED = 0,
612 SENSOR_UNIT_DEGREES_C = 1,
613 SENSOR_UNIT_VOLTS = 4,
614 SENSOR_UNIT_AMPERES = 5,
Tom Josephdc212b22018-02-16 09:59:57 +0530615 SENSOR_UNIT_WATTS = 6,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700616 SENSOR_UNIT_JOULES = 7,
Kirill Pakhomov812e44c2018-10-22 16:25:35 +0300617 SENSOR_UNIT_RPM = 18,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700618 SENSOR_UNIT_METERS = 34,
619 SENSOR_UNIT_REVOLUTIONS = 41,
620};
621
622struct SensorDataFullRecord
623{
624 SensorDataRecordHeader header;
625 SensorDataRecordKey key;
626 SensorDataFullRecordBody body;
627} __attribute__((packed));
628
Ratan Guptae0cc8552018-01-22 14:23:04 +0530629/** @struct SensorDataFruRecord
630 *
631 * FRU Device Locator Record - SDR Type 11
632 */
633struct SensorDataFruRecord
634{
635 SensorDataRecordHeader header;
636 SensorDataFruRecordKey key;
637 SensorDataFruRecordBody body;
638} __attribute__((packed));
639
Jaghathiswari Rankappagounder Natarajan9c118942019-02-12 13:22:55 -0800640/** @struct SensorDataEntityRecord
641 *
642 * Entity Association Record - SDR Type 8
643 */
644struct SensorDataEntityRecord
645{
646 SensorDataRecordHeader header;
647 SensorDataEntityRecordKey key;
648 SensorDataEntityRecordBody body;
649} __attribute__((packed));
650
Patrick Venture0b02be92018-08-31 11:55:55 -0700651} // namespace get_sdr
Tom Joseph816e92b2017-09-06 19:23:00 +0530652
653namespace ipmi
654{
655
656namespace sensor
657{
658
659/**
660 * @brief Map offset to the corresponding bit in the assertion byte.
661 *
Gunnar Mills8991dd62017-10-25 17:11:29 -0500662 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
Tom Joseph816e92b2017-09-06 19:23:00 +0530663 * byte and offsets 8-14 in the second byte.
664 *
665 * @param[in] offset - offset number.
666 * @param[in/out] resp - get sensor reading response.
667 */
668inline void setOffset(uint8_t offset, ipmi::sensor::GetReadingResponse* resp)
669{
670 if (offset > 7)
671 {
672 resp->assertOffset8_14 |= 1 << (offset - 8);
673 }
674 else
675 {
676 resp->assertOffset0_7 |= 1 << offset;
677 }
678}
679
Tom Josephe4014fc2017-09-06 23:57:36 +0530680/**
681 * @brief Set the reading field in the response.
682 *
683 * @param[in] offset - offset number.
684 * @param[in/out] resp - get sensor reading response.
685 */
686inline void setReading(uint8_t value, ipmi::sensor::GetReadingResponse* resp)
687{
688 resp->reading = value;
689}
690
Tom Joseph295f17e2017-09-07 00:09:46 +0530691/**
692 * @brief Map the value to the assertion bytes. The assertion states are stored
693 * in 2 bytes.
694 *
695 * @param[in] value - value to mapped to the assertion byte.
696 * @param[in/out] resp - get sensor reading response.
697 */
698inline void setAssertionBytes(uint16_t value,
699 ipmi::sensor::GetReadingResponse* resp)
700{
701 resp->assertOffset0_7 = static_cast<uint8_t>(value & 0x00FF);
702 resp->assertOffset8_14 = static_cast<uint8_t>(value >> 8);
703}
704
Tom Josephe05b2922017-09-07 00:43:16 +0530705/**
706 * @brief Set the scanning enabled bit in the response.
707 *
708 * @param[in/out] resp - get sensor reading response.
709 */
710inline void enableScanning(ipmi::sensor::GetReadingResponse* resp)
711{
712 resp->operation = 1 << 6;
713}
714
Tom Joseph816e92b2017-09-06 19:23:00 +0530715} // namespace sensor
716
717} // namespace ipmi