blob: 5e55080fd76444cb19fd1d44253e2cfd1c14c9b0 [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
Patrick Venture46470a32018-09-07 19:26:25 -07005#include <host-ipmid/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{
Tom Joseph5ca50952018-02-22 00:33:38 +053011 IPMI_CMD_GET_DEVICE_SDR_INFO = 0x20,
Patrick Venture0b02be92018-08-31 11:55:55 -070012 IPMI_CMD_GET_DEVICE_SDR = 0x21,
13 IPMI_CMD_RESERVE_DEVICE_SDR_REPO = 0x22,
Chris Austen10ccc0f2015-12-10 18:27:04 -060014 IPMI_CMD_GET_SENSOR_READING = 0x2D,
Patrick Venture0b02be92018-08-31 11:55:55 -070015 IPMI_CMD_GET_SENSOR_TYPE = 0x2F,
16 IPMI_CMD_SET_SENSOR = 0x30,
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -060017 IPMI_CMD_GET_SENSOR_THRESHOLDS = 0x27,
Chris Austenac4604a2015-10-13 12:43:27 -050018};
19
Ratan Guptae0cc8552018-01-22 14:23:04 +053020/**
21 * @enum device_type
22 * IPMI FRU device types
23 */
24enum device_type
25{
26 IPMI_PHYSICAL_FRU = 0x00,
27 IPMI_LOGICAL_FRU = 0x80,
28};
29
Emily Shaffer1fabf222017-04-05 08:53:21 -070030// Discrete sensor types.
31enum ipmi_sensor_types
32{
Patrick Venture0b02be92018-08-31 11:55:55 -070033 IPMI_SENSOR_TEMP = 0x01,
Emily Shaffer1fabf222017-04-05 08:53:21 -070034 IPMI_SENSOR_VOLTAGE = 0x02,
35 IPMI_SENSOR_CURRENT = 0x03,
Patrick Venture0b02be92018-08-31 11:55:55 -070036 IPMI_SENSOR_FAN = 0x04,
37 IPMI_SENSOR_TPM = 0xCC,
Emily Shaffer1fabf222017-04-05 08:53:21 -070038};
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
Patrick Venture0b02be92018-08-31 11:55:55 -070051int set_sensor_dbus_state_s(uint8_t, const char*, const char*);
52int set_sensor_dbus_state_y(uint8_t, const char*, const uint8_t);
53int find_openbmc_path(uint8_t, dbus_interface_t*);
Tom05732372016-09-06 17:21:23 +053054
Tom Joseph5ca50952018-02-22 00:33:38 +053055ipmi_ret_t ipmi_sen_get_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
56 ipmi_request_t request, ipmi_response_t response,
57 ipmi_data_len_t data_len, ipmi_context_t context);
58
59ipmi_ret_t ipmi_sen_reserve_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
60 ipmi_request_t request,
61 ipmi_response_t response,
62 ipmi_data_len_t data_len,
63 ipmi_context_t context);
64
Ratan Guptae0cc8552018-01-22 14:23:04 +053065static const uint16_t FRU_RECORD_ID_START = 256;
66static const uint8_t SDR_VERSION = 0x51;
67static const uint16_t END_OF_RECORD = 0xFFFF;
68static const uint8_t LENGTH_MASK = 0x1F;
69
Tom Josephbe703f72017-03-09 12:34:35 +053070/**
Emily Shafferd06e0e72017-04-05 09:08:57 -070071 * Get SDR Info
72 */
73
74namespace get_sdr_info
75{
76namespace request
77{
78// Note: for some reason the ipmi_request_t appears to be the
79// raw value for this call.
80inline bool get_count(void* req)
81{
Patrick Venture0b02be92018-08-31 11:55:55 -070082 return (bool)((uint64_t)(req)&1);
Emily Shafferd06e0e72017-04-05 09:08:57 -070083}
84} // namespace request
85
86namespace response
87{
88#define SDR_INFO_RESP_SIZE 2
89inline void set_lun_present(int lun, uint8_t* resp)
90{
91 *resp |= 1 << lun;
92}
93inline void set_lun_not_present(int lun, uint8_t* resp)
94{
95 *resp &= ~(1 << lun);
96}
97inline void set_dynamic_population(uint8_t* resp)
98{
99 *resp |= 1 << 7;
100}
101inline void set_static_population(uint8_t* resp)
102{
103 *resp &= ~(1 << 7);
104}
105} // namespace response
106
107struct GetSdrInfoResp
108{
109 uint8_t count;
110 uint8_t luns_and_dynamic_population;
111};
112
113} // namespace get_sdr_info
Emily Shafferbbef71c2017-05-08 16:36:17 -0700114
115/**
116 * Get SDR
117 */
118namespace get_sdr
119{
120
121struct GetSdrReq
122{
123 uint8_t reservation_id_lsb;
124 uint8_t reservation_id_msb;
125 uint8_t record_id_lsb;
126 uint8_t record_id_msb;
127 uint8_t offset;
128 uint8_t bytes_to_read;
129} __attribute__((packed));
130
131namespace request
132{
133
134inline uint8_t get_reservation_id(GetSdrReq* req)
135{
136 return (req->reservation_id_lsb + (req->reservation_id_msb << 8));
137};
138
Ratan Guptae0cc8552018-01-22 14:23:04 +0530139inline uint16_t get_record_id(GetSdrReq* req)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700140{
141 return (req->record_id_lsb + (req->record_id_msb << 8));
142};
143
144} // namespace request
145
146// Response
147struct GetSdrResp
148{
149 uint8_t next_record_id_lsb;
150 uint8_t next_record_id_msb;
151 uint8_t record_data[64];
152} __attribute__((packed));
153
154namespace response
155{
156
Ratan Guptae0cc8552018-01-22 14:23:04 +0530157inline void set_next_record_id(uint16_t next, GetSdrResp* resp)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700158{
159 resp->next_record_id_lsb = next & 0xff;
160 resp->next_record_id_msb = (next >> 8) & 0xff;
161};
162
163} // namespace response
164
165// Record header
166struct SensorDataRecordHeader
167{
168 uint8_t record_id_lsb;
169 uint8_t record_id_msb;
170 uint8_t sdr_version;
171 uint8_t record_type;
172 uint8_t record_length; // Length not counting the header
173} __attribute__((packed));
174
175namespace header
176{
177
178inline void set_record_id(int id, SensorDataRecordHeader* hdr)
179{
180 hdr->record_id_lsb = (id & 0xFF);
181 hdr->record_id_msb = (id >> 8) & 0xFF;
182};
183
184} // namespace header
185
186enum SensorDataRecordType
187{
Ratan Guptae0cc8552018-01-22 14:23:04 +0530188 SENSOR_DATA_FULL_RECORD = 0x1,
189 SENSOR_DATA_FRU_RECORD = 0x11,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700190};
191
192// Record key
193struct SensorDataRecordKey
194{
195 uint8_t owner_id;
196 uint8_t owner_lun;
197 uint8_t sensor_number;
198} __attribute__((packed));
199
Ratan Guptae0cc8552018-01-22 14:23:04 +0530200/** @struct SensorDataFruRecordKey
201 *
202 * FRU Device Locator Record(key) - SDR Type 11
203 */
204struct SensorDataFruRecordKey
205{
206 uint8_t deviceAddress;
207 uint8_t fruID;
208 uint8_t accessLun;
209 uint8_t channelNumber;
210} __attribute__((packed));
211
Emily Shafferbbef71c2017-05-08 16:36:17 -0700212namespace key
213{
214
215inline void set_owner_id_ipmb(SensorDataRecordKey* key)
216{
217 key->owner_id &= ~0x01;
218};
219
220inline void set_owner_id_system_sw(SensorDataRecordKey* key)
221{
222 key->owner_id |= 0x01;
223};
224
Tom Joseph96423912018-01-25 00:14:34 +0530225inline void set_owner_id_bmc(SensorDataRecordKey* key)
226{
227 key->owner_id |= 0x20;
228};
229
Emily Shafferbbef71c2017-05-08 16:36:17 -0700230inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key)
231{
232 key->owner_id &= 0x01;
Patrick Venture0b02be92018-08-31 11:55:55 -0700233 key->owner_id |= addr << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700234};
235
236inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key)
237{
238 key->owner_lun &= ~0x03;
Patrick Venture0b02be92018-08-31 11:55:55 -0700239 key->owner_lun |= (lun & 0x03);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700240};
241
242inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key)
243{
244 key->owner_lun &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700245 key->owner_lun |= ((channel & 0xf) << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700246};
247
248} // namespace key
249
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600250/** @struct GetSensorThresholdsResponse
251 *
252 * Response structure for Get Sensor Thresholds command
253 */
254struct GetSensorThresholdsResponse
255{
Patrick Venture0b02be92018-08-31 11:55:55 -0700256 uint8_t validMask; //!< valid mask
257 uint8_t lowerNonCritical; //!< lower non-critical threshold
258 uint8_t lowerCritical; //!< lower critical threshold
259 uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold
260 uint8_t upperNonCritical; //!< upper non-critical threshold
261 uint8_t upperCritical; //!< upper critical threshold
262 uint8_t upperNonRecoverable; //!< upper non-recoverable threshold
Dhruvaraj Subhashchandran5c0beec2018-01-23 04:47:06 -0600263} __attribute__((packed));
264
Emily Shafferbbef71c2017-05-08 16:36:17 -0700265// Body - full record
266#define FULL_RECORD_ID_STR_MAX_LENGTH 16
Ratan Guptae0cc8552018-01-22 14:23:04 +0530267
268static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16;
269
Emily Shafferbbef71c2017-05-08 16:36:17 -0700270struct SensorDataFullRecordBody
271{
272 uint8_t entity_id;
273 uint8_t entity_instance;
274 uint8_t sensor_initialization;
275 uint8_t sensor_capabilities; // no macro support
276 uint8_t sensor_type;
277 uint8_t event_reading_type;
Patrick Venture0b02be92018-08-31 11:55:55 -0700278 uint8_t supported_assertions[2]; // no macro support
279 uint8_t supported_deassertions[2]; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700280 uint8_t discrete_reading_setting_mask[2]; // no macro support
281 uint8_t sensor_units_1;
282 uint8_t sensor_units_2_base;
283 uint8_t sensor_units_3_modifier;
284 uint8_t linearization;
285 uint8_t m_lsb;
286 uint8_t m_msb_and_tolerance;
287 uint8_t b_lsb;
288 uint8_t b_msb_and_accuracy_lsb;
289 uint8_t accuracy_and_sensor_direction;
290 uint8_t r_b_exponents;
Patrick Venture0b02be92018-08-31 11:55:55 -0700291 uint8_t analog_characteristic_flags; // no macro support
Emily Shafferbbef71c2017-05-08 16:36:17 -0700292 uint8_t nominal_reading;
293 uint8_t normal_max;
294 uint8_t normal_min;
295 uint8_t sensor_max;
296 uint8_t sensor_min;
297 uint8_t upper_nonrecoverable_threshold;
298 uint8_t upper_critical_threshold;
299 uint8_t upper_noncritical_threshold;
300 uint8_t lower_nonrecoverable_threshold;
301 uint8_t lower_critical_threshold;
302 uint8_t lower_noncritical_threshold;
303 uint8_t positive_threshold_hysteresis;
304 uint8_t negative_threshold_hysteresis;
305 uint16_t reserved;
306 uint8_t oem_reserved;
307 uint8_t id_string_info;
Emily Shaffer10f49592017-05-10 12:01:10 -0700308 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
Emily Shafferbbef71c2017-05-08 16:36:17 -0700309} __attribute__((packed));
310
Ratan Guptae0cc8552018-01-22 14:23:04 +0530311/** @struct SensorDataFruRecordBody
312 *
313 * FRU Device Locator Record(body) - SDR Type 11
314 */
315struct SensorDataFruRecordBody
316{
317 uint8_t reserved;
318 uint8_t deviceType;
319 uint8_t deviceTypeModifier;
320 uint8_t entityID;
321 uint8_t entityInstance;
322 uint8_t oem;
323 uint8_t deviceIDLen;
324 char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH];
325} __attribute__((packed));
326
Emily Shafferbbef71c2017-05-08 16:36:17 -0700327namespace body
328{
329
330inline void set_entity_instance_number(uint8_t n,
331 SensorDataFullRecordBody* body)
332{
Patrick Venture0b02be92018-08-31 11:55:55 -0700333 body->entity_instance &= 1 << 7;
334 body->entity_instance |= (n & ~(1 << 7));
Emily Shafferbbef71c2017-05-08 16:36:17 -0700335};
336inline void set_entity_physical_entity(SensorDataFullRecordBody* body)
337{
Patrick Venture0b02be92018-08-31 11:55:55 -0700338 body->entity_instance &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700339};
340inline void set_entity_logical_container(SensorDataFullRecordBody* body)
341{
Patrick Venture0b02be92018-08-31 11:55:55 -0700342 body->entity_instance |= 1 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700343};
344
Patrick Venture0b02be92018-08-31 11:55:55 -0700345inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700346{
347 if (enabled)
348 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700349 body->sensor_initialization |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700350 }
351 else
352 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700353 body->sensor_initialization &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700354 };
355};
Patrick Venture0b02be92018-08-31 11:55:55 -0700356inline void event_generation_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700357{
358 if (enabled)
359 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700360 body->sensor_initialization |= 1 << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700361 }
362 else
363 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700364 body->sensor_initialization &= ~(1 << 1);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700365 }
366};
Patrick Venture0b02be92018-08-31 11:55:55 -0700367inline void init_types_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700368{
369 if (enabled)
370 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700371 body->sensor_initialization |= 1 << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700372 }
373 else
374 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700375 body->sensor_initialization &= ~(1 << 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700376 }
377};
Patrick Venture0b02be92018-08-31 11:55:55 -0700378inline void init_hyst_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700379{
380 if (enabled)
381 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700382 body->sensor_initialization |= 1 << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700383 }
384 else
385 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700386 body->sensor_initialization &= ~(1 << 3);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700387 }
388};
Patrick Venture0b02be92018-08-31 11:55:55 -0700389inline void init_thresh_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700390{
391 if (enabled)
392 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700393 body->sensor_initialization |= 1 << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700394 }
395 else
396 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700397 body->sensor_initialization &= ~(1 << 4);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700398 }
399};
Patrick Venture0b02be92018-08-31 11:55:55 -0700400inline void init_events_state(bool enabled, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700401{
402 if (enabled)
403 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700404 body->sensor_initialization |= 1 << 5;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700405 }
406 else
407 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700408 body->sensor_initialization &= ~(1 << 5);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700409 }
410};
Patrick Venture0b02be92018-08-31 11:55:55 -0700411inline void init_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 << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700416 }
417 else
418 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700419 body->sensor_initialization &= ~(1 << 6);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700420 }
421};
Patrick Venture0b02be92018-08-31 11:55:55 -0700422inline void init_settable_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 << 7;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700427 }
428 else
429 {
Patrick Venture0b02be92018-08-31 11:55:55 -0700430 body->sensor_initialization &= ~(1 << 7);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700431 }
432};
433
434inline void set_percentage(SensorDataFullRecordBody* body)
435{
Patrick Venture0b02be92018-08-31 11:55:55 -0700436 body->sensor_units_1 |= 1 << 0;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700437};
438inline void unset_percentage(SensorDataFullRecordBody* body)
439{
Patrick Venture0b02be92018-08-31 11:55:55 -0700440 body->sensor_units_1 &= ~(1 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700441};
442inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body)
443{
Patrick Venture0b02be92018-08-31 11:55:55 -0700444 body->sensor_units_1 &= ~(3 << 1);
445 body->sensor_units_1 |= (op & 0x3) << 1;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700446};
447inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body)
448{
Patrick Venture0b02be92018-08-31 11:55:55 -0700449 body->sensor_units_1 &= ~(7 << 3);
450 body->sensor_units_1 |= (unit & 0x7) << 3;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700451};
452inline void set_analog_data_format(uint8_t format,
453 SensorDataFullRecordBody* body)
454{
Patrick Venture0b02be92018-08-31 11:55:55 -0700455 body->sensor_units_1 &= ~(3 << 6);
456 body->sensor_units_1 |= (format & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700457};
458
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700459inline void set_m(uint16_t m, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700460{
461 body->m_lsb = m & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700462 body->m_msb_and_tolerance &= ~(3 << 6);
463 body->m_msb_and_tolerance |= ((m & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700464};
465inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body)
466{
467 body->m_msb_and_tolerance &= ~0x3f;
468 body->m_msb_and_tolerance |= tol & 0x3f;
469};
470
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700471inline void set_b(uint16_t b, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700472{
473 body->b_lsb = b & 0xff;
Patrick Venture0b02be92018-08-31 11:55:55 -0700474 body->b_msb_and_accuracy_lsb &= ~(3 << 6);
475 body->b_msb_and_accuracy_lsb |= ((b & (3 << 8)) >> 2);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700476};
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700477inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700478{
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700479 // bottom 6 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700480 body->b_msb_and_accuracy_lsb &= ~0x3f;
481 body->b_msb_and_accuracy_lsb |= acc & 0x3f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700482 // top 4 bits
Emily Shafferbbef71c2017-05-08 16:36:17 -0700483 body->accuracy_and_sensor_direction &= 0x0f;
Emily Shaffer7cad3fc2017-08-30 17:50:37 -0700484 body->accuracy_and_sensor_direction |= ((acc >> 6) & 0xf) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700485};
486inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body)
487{
Patrick Venture0b02be92018-08-31 11:55:55 -0700488 body->accuracy_and_sensor_direction &= ~(3 << 2);
489 body->accuracy_and_sensor_direction |= (exp & 3) << 2;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700490};
491inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body)
492{
Patrick Venture0b02be92018-08-31 11:55:55 -0700493 body->accuracy_and_sensor_direction &= ~(3 << 0);
Emily Shafferbbef71c2017-05-08 16:36:17 -0700494 body->accuracy_and_sensor_direction |= (dir & 3);
495};
496
497inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body)
498{
499 body->r_b_exponents &= 0xf0;
500 body->r_b_exponents |= exp & 0x0f;
501};
502inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body)
503{
504 body->r_b_exponents &= 0x0f;
Patrick Venture0b02be92018-08-31 11:55:55 -0700505 body->r_b_exponents |= (exp & 0x0f) << 4;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700506};
507
508inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body)
509{
510 body->id_string_info &= ~(0x1f);
511 body->id_string_info |= len & 0x1f;
512};
Patrick Venture0b02be92018-08-31 11:55:55 -0700513inline uint8_t get_id_strlen(SensorDataFullRecordBody* body)
Emily Shafferbbef71c2017-05-08 16:36:17 -0700514{
515 return body->id_string_info & 0x1f;
516};
517inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body)
518{
Patrick Venture0b02be92018-08-31 11:55:55 -0700519 body->id_string_info &= ~(3 << 6);
520 body->id_string_info |= (type & 0x3) << 6;
Emily Shafferbbef71c2017-05-08 16:36:17 -0700521};
522
Ratan Guptae0cc8552018-01-22 14:23:04 +0530523inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody* body)
524{
525 body->deviceIDLen &= ~(LENGTH_MASK);
526 body->deviceIDLen |= len & LENGTH_MASK;
527};
528
529inline uint8_t get_device_id_strlen(SensorDataFruRecordBody* body)
530{
531 return body->deviceIDLen & LENGTH_MASK;
532};
533
Tom Josephdc212b22018-02-16 09:59:57 +0530534inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody* body)
535{
536 body->discrete_reading_setting_mask[1] = mask & 0x3F;
537}
538
Emily Shafferbbef71c2017-05-08 16:36:17 -0700539} // namespace body
540
541// More types contained in section 43.17 Sensor Unit Type Codes,
542// IPMI spec v2 rev 1.1
543enum SensorUnitTypeCodes
544{
545 SENSOR_UNIT_UNSPECIFIED = 0,
546 SENSOR_UNIT_DEGREES_C = 1,
547 SENSOR_UNIT_VOLTS = 4,
548 SENSOR_UNIT_AMPERES = 5,
Tom Josephdc212b22018-02-16 09:59:57 +0530549 SENSOR_UNIT_WATTS = 6,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700550 SENSOR_UNIT_JOULES = 7,
Kirill Pakhomov812e44c2018-10-22 16:25:35 +0300551 SENSOR_UNIT_RPM = 18,
Emily Shafferbbef71c2017-05-08 16:36:17 -0700552 SENSOR_UNIT_METERS = 34,
553 SENSOR_UNIT_REVOLUTIONS = 41,
554};
555
556struct SensorDataFullRecord
557{
558 SensorDataRecordHeader header;
559 SensorDataRecordKey key;
560 SensorDataFullRecordBody body;
561} __attribute__((packed));
562
Ratan Guptae0cc8552018-01-22 14:23:04 +0530563/** @struct SensorDataFruRecord
564 *
565 * FRU Device Locator Record - SDR Type 11
566 */
567struct SensorDataFruRecord
568{
569 SensorDataRecordHeader header;
570 SensorDataFruRecordKey key;
571 SensorDataFruRecordBody body;
572} __attribute__((packed));
573
Patrick Venture0b02be92018-08-31 11:55:55 -0700574} // namespace get_sdr
Tom Joseph816e92b2017-09-06 19:23:00 +0530575
576namespace ipmi
577{
578
579namespace sensor
580{
581
582/**
583 * @brief Map offset to the corresponding bit in the assertion byte.
584 *
Gunnar Mills8991dd62017-10-25 17:11:29 -0500585 * The discrete sensors support up to 14 states. 0-7 offsets are stored in one
Tom Joseph816e92b2017-09-06 19:23:00 +0530586 * byte and offsets 8-14 in the second byte.
587 *
588 * @param[in] offset - offset number.
589 * @param[in/out] resp - get sensor reading response.
590 */
591inline void setOffset(uint8_t offset, ipmi::sensor::GetReadingResponse* resp)
592{
593 if (offset > 7)
594 {
595 resp->assertOffset8_14 |= 1 << (offset - 8);
596 }
597 else
598 {
599 resp->assertOffset0_7 |= 1 << offset;
600 }
601}
602
Tom Josephe4014fc2017-09-06 23:57:36 +0530603/**
604 * @brief Set the reading field in the response.
605 *
606 * @param[in] offset - offset number.
607 * @param[in/out] resp - get sensor reading response.
608 */
609inline void setReading(uint8_t value, ipmi::sensor::GetReadingResponse* resp)
610{
611 resp->reading = value;
612}
613
Tom Joseph295f17e2017-09-07 00:09:46 +0530614/**
615 * @brief Map the value to the assertion bytes. The assertion states are stored
616 * in 2 bytes.
617 *
618 * @param[in] value - value to mapped to the assertion byte.
619 * @param[in/out] resp - get sensor reading response.
620 */
621inline void setAssertionBytes(uint16_t value,
622 ipmi::sensor::GetReadingResponse* resp)
623{
624 resp->assertOffset0_7 = static_cast<uint8_t>(value & 0x00FF);
625 resp->assertOffset8_14 = static_cast<uint8_t>(value >> 8);
626}
627
Tom Josephe05b2922017-09-07 00:43:16 +0530628/**
629 * @brief Set the scanning enabled bit in the response.
630 *
631 * @param[in/out] resp - get sensor reading response.
632 */
633inline void enableScanning(ipmi::sensor::GetReadingResponse* resp)
634{
635 resp->operation = 1 << 6;
636}
637
Tom Joseph816e92b2017-09-06 19:23:00 +0530638} // namespace sensor
639
640} // namespace ipmi