blob: 033859771f615ef5e8155aec0867f8f106b33786 [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;
89static const uint8_t SDR_VERSION = 0x51;
90static const uint16_t END_OF_RECORD = 0xFFFF;
91static const uint8_t LENGTH_MASK = 0x1F;
92
Tom Josephbe703f72017-03-09 12:34:35 +053093/**
Emily Shafferd06e0e72017-04-05 09:08:57 -070094 * Get SDR Info
95 */
96
97namespace get_sdr_info
98{
99namespace request
100{
101// Note: for some reason the ipmi_request_t appears to be the
102// raw value for this call.
103inline bool get_count(void* req)
104{
Patrick Venture0b02be92018-08-31 11:55:55 -0700105 return (bool)((uint64_t)(req)&1);
Emily Shafferd06e0e72017-04-05 09:08:57 -0700106}
107} // namespace request
108
109namespace response
110{
111#define SDR_INFO_RESP_SIZE 2
112inline void set_lun_present(int lun, uint8_t* resp)
113{
114 *resp |= 1 << lun;
115}
116inline void set_lun_not_present(int lun, uint8_t* resp)
117{
118 *resp &= ~(1 << lun);
119}
120inline void set_dynamic_population(uint8_t* resp)
121{
122 *resp |= 1 << 7;
123}
124inline void set_static_population(uint8_t* resp)
125{
126 *resp &= ~(1 << 7);
127}
128} // namespace response
129
130struct GetSdrInfoResp
131{
132 uint8_t count;
133 uint8_t luns_and_dynamic_population;
134};
135
136} // namespace get_sdr_info
Emily Shafferbbef71c2017-05-08 16:36:17 -0700137
138/**
139 * Get SDR
140 */
141namespace get_sdr
142{
143
144struct GetSdrReq
145{
146 uint8_t reservation_id_lsb;
147 uint8_t reservation_id_msb;
148 uint8_t record_id_lsb;
149 uint8_t record_id_msb;
150 uint8_t offset;
151 uint8_t bytes_to_read;
152} __attribute__((packed));
153
154namespace request
155{
156
157inline uint8_t get_reservation_id(GetSdrReq* req)
158{
159 return (req->reservation_id_lsb + (req->reservation_id_msb << 8));
160};
161
Ratan Guptae0cc8552018-01-22 14:23:04 +0530162inline uint16_t get_record_id(GetSdrReq* req)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700163{
164 return (req->record_id_lsb + (req->record_id_msb << 8));
165};
166
167} // namespace request
168
169// Response
170struct GetSdrResp
171{
172 uint8_t next_record_id_lsb;
173 uint8_t next_record_id_msb;
174 uint8_t record_data[64];
175} __attribute__((packed));
176
177namespace response
178{
179
Ratan Guptae0cc8552018-01-22 14:23:04 +0530180inline void set_next_record_id(uint16_t next, GetSdrResp* resp)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700181{
182 resp->next_record_id_lsb = next & 0xff;
183 resp->next_record_id_msb = (next >> 8) & 0xff;
184};
185
186} // namespace response
187
188// Record header
189struct SensorDataRecordHeader
190{
191 uint8_t record_id_lsb;
192 uint8_t record_id_msb;
193 uint8_t sdr_version;
194 uint8_t record_type;
195 uint8_t record_length; // Length not counting the header
196} __attribute__((packed));
197
198namespace header
199{
200
201inline void set_record_id(int id, SensorDataRecordHeader* hdr)
202{
203 hdr->record_id_lsb = (id & 0xFF);
204 hdr->record_id_msb = (id >> 8) & 0xFF;
205};
206
207} // namespace header
208
209enum SensorDataRecordType
210{
Ratan Guptae0cc8552018-01-22 14:23:04 +0530211 SENSOR_DATA_FULL_RECORD = 0x1,
212 SENSOR_DATA_FRU_RECORD = 0x11,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700213};
214
215// Record key
216struct SensorDataRecordKey
217{
218 uint8_t owner_id;
219 uint8_t owner_lun;
220 uint8_t sensor_number;
221} __attribute__((packed));
222
Ratan Guptae0cc8552018-01-22 14:23:04 +0530223/** @struct SensorDataFruRecordKey
224 *
225 * FRU Device Locator Record(key) - SDR Type 11
226 */
227struct SensorDataFruRecordKey
228{
229 uint8_t deviceAddress;
230 uint8_t fruID;
231 uint8_t accessLun;
232 uint8_t channelNumber;
233} __attribute__((packed));
234
Emily Shafferbbef71c2017-05-08 16:36:17 -0700235namespace key
236{
237
238inline 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
271} // namespace key
272
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600273/** @struct GetSensorThresholdsResponse
274 *
275 * Response structure for Get Sensor Thresholds command
276 */
277struct GetSensorThresholdsResponse
278{
Patrick Venture0b02be92018-08-31 11:55:55 -0700279 uint8_t validMask; //!< valid mask
280 uint8_t lowerNonCritical; //!< lower non-critical threshold
281 uint8_t lowerCritical; //!< lower critical threshold
282 uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
283 uint8_t upperNonCritical; //!< upper non-critical threshold
284 uint8_t upperCritical; //!< upper critical threshold
285 uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600286} __attribute__((packed));
287
Emily Shafferbbef71c2017-05-08 16:36:17 -0700288// Body - full record
289#define FULL_RECORD_ID_STR_MAX_LENGTH 16
Ratan Guptae0cc8552018-01-22 14:23:04 +0530290
291static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
292
Emily Shafferbbef71c2017-05-08 16:36:17 -0700293struct SensorDataFullRecordBody
294{
295 uint8_t entity_id;
296 uint8_t entity_instance;
297 uint8_t sensor_initialization;
298 uint8_t sensor_capabilities; // no macro support
299 uint8_t sensor_type;
300 uint8_t event_reading_type;
Patrick Venture0b02be92018-08-31 11:55:55 -0700301 uint8_t supported_assertions[2]; // no macro support
302 uint8_t supported_deassertions[2]; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700303 uint8_t discrete_reading_setting_mask[2]; // no macro support
304 uint8_t sensor_units_1;
305 uint8_t sensor_units_2_base;
306 uint8_t sensor_units_3_modifier;
307 uint8_t linearization;
308 uint8_t m_lsb;
309 uint8_t m_msb_and_tolerance;
310 uint8_t b_lsb;
311 uint8_t b_msb_and_accuracy_lsb;
312 uint8_t accuracy_and_sensor_direction;
313 uint8_t r_b_exponents;
Patrick Venture0b02be92018-08-31 11:55:55 -0700314 uint8_t analog_characteristic_flags; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700315 uint8_t nominal_reading;
316 uint8_t normal_max;
317 uint8_t normal_min;
318 uint8_t sensor_max;
319 uint8_t sensor_min;
320 uint8_t upper_nonrecoverable_threshold;
321 uint8_t upper_critical_threshold;
322 uint8_t upper_noncritical_threshold;
323 uint8_t lower_nonrecoverable_threshold;
324 uint8_t lower_critical_threshold;
325 uint8_t lower_noncritical_threshold;
326 uint8_t positive_threshold_hysteresis;
327 uint8_t negative_threshold_hysteresis;
328 uint16_t reserved;
329 uint8_t oem_reserved;
330 uint8_t id_string_info;
Emily Shaffer10f49592017-05-10 12:01:10 -0700331 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
Emily Shafferbbef71c2017-05-08 16:36:17 -0700332} __attribute__((packed));
333
Ratan Guptae0cc8552018-01-22 14:23:04 +0530334/** @struct SensorDataFruRecordBody
335 *
336 * FRU Device Locator Record(body) - SDR Type 11
337 */
338struct SensorDataFruRecordBody
339{
340 uint8_t reserved;
341 uint8_t deviceType;
342 uint8_t deviceTypeModifier;
343 uint8_t entityID;
344 uint8_t entityInstance;
345 uint8_t oem;
346 uint8_t deviceIDLen;
347 char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
348} __attribute__((packed));
349
Emily Shafferbbef71c2017-05-08 16:36:17 -0700350namespace body
351{
352
353inline void set_entity_instance_number(uint8_t n,
354 SensorDataFullRecordBody* body)
355{
Patrick Venture0b02be92018-08-31 11:55:55 -0700356 body->entity_instance &= 1 << 7;
357 body->entity_instance |= (n & ~(1 << 7));
Emily Shafferbbef71c2017-05-08 16:36:17 -0700358};
359inline void set_entity_physical_entity(SensorDataFullRecordBody* body)
360{
Patrick Venture0b02be92018-08-31 11:55:55 -0700361 body->entity_instance &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700362};
363inline void set_entity_logical_container(SensorDataFullRecordBody* body)
364{
Patrick Venture0b02be92018-08-31 11:55:55 -0700365 body->entity_instance |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700366};
367
Patrick Venture0b02be92018-08-31 11:55:55 -0700368inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700369{
370 if (enabled)
371 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700372 body->sensor_initialization |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700373 }
374 else
375 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700376 body->sensor_initialization &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700377 };
378};
Patrick Venture0b02be92018-08-31 11:55:55 -0700379inline void event_generation_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700380{
381 if (enabled)
382 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700383 body->sensor_initialization |= 1 << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700384 }
385 else
386 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700387 body->sensor_initialization &= ~(1 << 1);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700388 }
389};
Patrick Venture0b02be92018-08-31 11:55:55 -0700390inline void init_types_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700391{
392 if (enabled)
393 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700394 body->sensor_initialization |= 1 << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700395 }
396 else
397 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700398 body->sensor_initialization &= ~(1 << 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700399 }
400};
Patrick Venture0b02be92018-08-31 11:55:55 -0700401inline void init_hyst_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700402{
403 if (enabled)
404 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700405 body->sensor_initialization |= 1 << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700406 }
407 else
408 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700409 body->sensor_initialization &= ~(1 << 3);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700410 }
411};
Patrick Venture0b02be92018-08-31 11:55:55 -0700412inline void init_thresh_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700413{
414 if (enabled)
415 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700416 body->sensor_initialization |= 1 << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700417 }
418 else
419 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700420 body->sensor_initialization &= ~(1 << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700421 }
422};
Patrick Venture0b02be92018-08-31 11:55:55 -0700423inline void init_events_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700424{
425 if (enabled)
426 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700427 body->sensor_initialization |= 1 << 5;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700428 }
429 else
430 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700431 body->sensor_initialization &= ~(1 << 5);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700432 }
433};
Patrick Venture0b02be92018-08-31 11:55:55 -0700434inline void init_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700435{
436 if (enabled)
437 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700438 body->sensor_initialization |= 1 << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700439 }
440 else
441 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700442 body->sensor_initialization &= ~(1 << 6);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700443 }
444};
Patrick Venture0b02be92018-08-31 11:55:55 -0700445inline void init_settable_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700446{
447 if (enabled)
448 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700449 body->sensor_initialization |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700450 }
451 else
452 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700453 body->sensor_initialization &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700454 }
455};
456
457inline void set_percentage(SensorDataFullRecordBody* body)
458{
Patrick Venture0b02be92018-08-31 11:55:55 -0700459 body->sensor_units_1 |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700460};
461inline void unset_percentage(SensorDataFullRecordBody* body)
462{
Patrick Venture0b02be92018-08-31 11:55:55 -0700463 body->sensor_units_1 &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700464};
465inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body)
466{
Patrick Venture0b02be92018-08-31 11:55:55 -0700467 body->sensor_units_1 &= ~(3 << 1);
468 body->sensor_units_1 |= (op & 0x3) << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700469};
470inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body)
471{
Patrick Venture0b02be92018-08-31 11:55:55 -0700472 body->sensor_units_1 &= ~(7 << 3);
473 body->sensor_units_1 |= (unit & 0x7) << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700474};
475inline void set_analog_data_format(uint8_t format,
476 SensorDataFullRecordBody* body)
477{
Patrick Venture0b02be92018-08-31 11:55:55 -0700478 body->sensor_units_1 &= ~(3 << 6);
479 body->sensor_units_1 |= (format & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700480};
481
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700482inline void set_m(uint16_t m, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700483{
484 body->m_lsb = m & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700485 body->m_msb_and_tolerance &= ~(3 << 6);
486 body->m_msb_and_tolerance |= ((m & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700487};
488inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body)
489{
490 body->m_msb_and_tolerance &= ~0x3f;
491 body->m_msb_and_tolerance |= tol & 0x3f;
492};
493
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700494inline void set_b(uint16_t b, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700495{
496 body->b_lsb = b & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700497 body->b_msb_and_accuracy_lsb &= ~(3 << 6);
498 body->b_msb_and_accuracy_lsb |= ((b & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700499};
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700500inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700501{
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700502 // bottom 6 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700503 body->b_msb_and_accuracy_lsb &= ~0x3f;
504 body->b_msb_and_accuracy_lsb |= acc & 0x3f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700505 // top 4 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700506 body->accuracy_and_sensor_direction &= 0x0f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700507 body->accuracy_and_sensor_direction |= ((acc >> 6) & 0xf) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700508};
509inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body)
510{
Patrick Venture0b02be92018-08-31 11:55:55 -0700511 body->accuracy_and_sensor_direction &= ~(3 << 2);
512 body->accuracy_and_sensor_direction |= (exp & 3) << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700513};
514inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body)
515{
Patrick Venture0b02be92018-08-31 11:55:55 -0700516 body->accuracy_and_sensor_direction &= ~(3 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700517 body->accuracy_and_sensor_direction |= (dir & 3);
518};
519
520inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body)
521{
522 body->r_b_exponents &= 0xf0;
523 body->r_b_exponents |= exp & 0x0f;
524};
525inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body)
526{
527 body->r_b_exponents &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700528 body->r_b_exponents |= (exp & 0x0f) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700529};
530
531inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body)
532{
533 body->id_string_info &= ~(0x1f);
534 body->id_string_info |= len & 0x1f;
535};
Patrick Venture0b02be92018-08-31 11:55:55 -0700536inline uint8_t get_id_strlen(SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700537{
538 return body->id_string_info & 0x1f;
539};
540inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body)
541{
Patrick Venture0b02be92018-08-31 11:55:55 -0700542 body->id_string_info &= ~(3 << 6);
543 body->id_string_info |= (type & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700544};
545
Ratan Guptae0cc8552018-01-22 14:23:04 +0530546inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody* body)
547{
548 body->deviceIDLen &= ~(LENGTH_MASK);
549 body->deviceIDLen |= len & LENGTH_MASK;
550};
551
552inline uint8_t get_device_id_strlen(SensorDataFruRecordBody* body)
553{
554 return body->deviceIDLen & LENGTH_MASK;
555};
556
Tom Josephdc212b22018-02-16 09:59:57 +0530557inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody* body)
558{
559 body->discrete_reading_setting_mask[1] = mask & 0x3F;
560}
561
Emily Shafferbbef71c2017-05-08 16:36:17 -0700562} // namespace body
563
564// More types contained in section 43.17 Sensor Unit Type Codes,
565// IPMI spec v2 rev 1.1
566enum SensorUnitTypeCodes
567{
568 SENSOR_UNIT_UNSPECIFIED = 0,
569 SENSOR_UNIT_DEGREES_C = 1,
570 SENSOR_UNIT_VOLTS = 4,
571 SENSOR_UNIT_AMPERES = 5,
Tom Josephdc212b22018-02-16 09:59:57 +0530572 SENSOR_UNIT_WATTS = 6,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700573 SENSOR_UNIT_JOULES = 7,
Kirill Pakhomov812e44c2018-10-22 16:25:35 +0300574 SENSOR_UNIT_RPM = 18,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700575 SENSOR_UNIT_METERS = 34,
576 SENSOR_UNIT_REVOLUTIONS = 41,
577};
578
579struct SensorDataFullRecord
580{
581 SensorDataRecordHeader header;
582 SensorDataRecordKey key;
583 SensorDataFullRecordBody body;
584} __attribute__((packed));
585
Ratan Guptae0cc8552018-01-22 14:23:04 +0530586/** @struct SensorDataFruRecord
587 *
588 * FRU Device Locator Record - SDR Type 11
589 */
590struct SensorDataFruRecord
591{
592 SensorDataRecordHeader header;
593 SensorDataFruRecordKey key;
594 SensorDataFruRecordBody body;
595} __attribute__((packed));
596
Patrick Venture0b02be92018-08-31 11:55:55 -0700597} // namespace get_sdr
Tom Joseph816e92b2017-09-06 19:23:00 +0530598
599namespace ipmi
600{
601
602namespace sensor
603{
604
605/**
606 * @brief Map offset to the corresponding bit in the assertion byte.
607 *
Gunnar Mills8991dd62017-10-25 17:11:29 -0500608 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
Tom Joseph816e92b2017-09-06 19:23:00 +0530609 * byte and offsets 8-14 in the second byte.
610 *
611 * @param[in] offset - offset number.
612 * @param[in/out] resp - get sensor reading response.
613 */
614inline void setOffset(uint8_t offset, ipmi::sensor::GetReadingResponse* resp)
615{
616 if (offset > 7)
617 {
618 resp->assertOffset8_14 |= 1 << (offset - 8);
619 }
620 else
621 {
622 resp->assertOffset0_7 |= 1 << offset;
623 }
624}
625
Tom Josephe4014fc2017-09-06 23:57:36 +0530626/**
627 * @brief Set the reading field in the response.
628 *
629 * @param[in] offset - offset number.
630 * @param[in/out] resp - get sensor reading response.
631 */
632inline void setReading(uint8_t value, ipmi::sensor::GetReadingResponse* resp)
633{
634 resp->reading = value;
635}
636
Tom Joseph295f17e2017-09-07 00:09:46 +0530637/**
638 * @brief Map the value to the assertion bytes. The assertion states are stored
639 * in 2 bytes.
640 *
641 * @param[in] value - value to mapped to the assertion byte.
642 * @param[in/out] resp - get sensor reading response.
643 */
644inline void setAssertionBytes(uint16_t value,
645 ipmi::sensor::GetReadingResponse* resp)
646{
647 resp->assertOffset0_7 = static_cast<uint8_t>(value & 0x00FF);
648 resp->assertOffset8_14 = static_cast<uint8_t>(value >> 8);
649}
650
Tom Josephe05b2922017-09-07 00:43:16 +0530651/**
652 * @brief Set the scanning enabled bit in the response.
653 *
654 * @param[in/out] resp - get sensor reading response.
655 */
656inline void enableScanning(ipmi::sensor::GetReadingResponse* resp)
657{
658 resp->operation = 1 << 6;
659}
660
Tom Joseph816e92b2017-09-06 19:23:00 +0530661} // namespace sensor
662
663} // namespace ipmi