blob: 302229690b3163a6872b1754ba5b3fb99c0726e8 [file] [log] [blame]
Chris Austenac4604a2015-10-13 12:43:27 -05001#ifndef __HOST_IPMI_SEN_HANDLER_H__
2#define __HOST_IPMI_SEN_HANDLER_H__
3
Chris Austen0012e9b2015-10-22 01:37:46 -05004#include <stdint.h>
5
Chris Austenac4604a2015-10-13 12:43:27 -05006// IPMI commands for net functions.
7enum ipmi_netfn_sen_cmds
8{
Emily Shafferd06e0e72017-04-05 09:08:57 -07009 IPMI_CMD_GET_SDR_INFO = 0x20,
Emily Shafferbbef71c2017-05-08 16:36:17 -070010 IPMI_CMD_GET_SDR = 0x21,
Emily Shaffera344afc2017-04-13 15:09:39 -070011 IPMI_CMD_RESERVE_SDR_REPO = 0x22,
Chris Austen10ccc0f2015-12-10 18:27:04 -060012 IPMI_CMD_GET_SENSOR_READING = 0x2D,
Emily Shafferd06e0e72017-04-05 09:08:57 -070013 IPMI_CMD_GET_SENSOR_TYPE = 0x2F,
14 IPMI_CMD_SET_SENSOR = 0x30,
Chris Austenac4604a2015-10-13 12:43:27 -050015};
16
Emily Shaffer1fabf222017-04-05 08:53:21 -070017// Discrete sensor types.
18enum ipmi_sensor_types
19{
20 IPMI_SENSOR_TEMP = 0x01,
21 IPMI_SENSOR_VOLTAGE = 0x02,
22 IPMI_SENSOR_CURRENT = 0x03,
23 IPMI_SENSOR_FAN = 0x04,
24};
25
Chris Austen0012e9b2015-10-22 01:37:46 -050026#define MAX_DBUS_PATH 128
27struct dbus_interface_t {
28 uint8_t sensornumber;
29 uint8_t sensortype;
30
31 char bus[MAX_DBUS_PATH];
32 char path[MAX_DBUS_PATH];
33 char interface[MAX_DBUS_PATH];
34};
Tomd700e762016-09-20 18:24:13 +053035
36int set_sensor_dbus_state_s(uint8_t , const char *, const char *);
37int set_sensor_dbus_state_y(uint8_t , const char *, const uint8_t);
Emily Shaffer2ae09b92017-04-05 15:09:41 -070038int find_openbmc_path(uint8_t , dbus_interface_t *);
Tom05732372016-09-06 17:21:23 +053039
Tom Josephbe703f72017-03-09 12:34:35 +053040/**
41 * @struct SetSensorReadingReq
42 *
43 * IPMI Request data for Set Sensor Reading and Event Status Command
44 */
45struct SetSensorReadingReq
46{
47 uint8_t number;
48 uint8_t operation;
49 uint8_t reading;
50 uint8_t assertOffset0_7;
51 uint8_t assertOffset8_14;
52 uint8_t deassertOffset0_7;
53 uint8_t deassertOffset8_14;
54 uint8_t eventData1;
55 uint8_t eventData2;
56 uint8_t eventData3;
57} __attribute__((packed));
58
Emily Shafferd06e0e72017-04-05 09:08:57 -070059/**
60 * Get SDR Info
61 */
62
63namespace get_sdr_info
64{
65namespace request
66{
67// Note: for some reason the ipmi_request_t appears to be the
68// raw value for this call.
69inline bool get_count(void* req)
70{
71 return (bool)((uint64_t)(req) & 1);
72}
73} // namespace request
74
75namespace response
76{
77#define SDR_INFO_RESP_SIZE 2
78inline void set_lun_present(int lun, uint8_t* resp)
79{
80 *resp |= 1 << lun;
81}
82inline void set_lun_not_present(int lun, uint8_t* resp)
83{
84 *resp &= ~(1 << lun);
85}
86inline void set_dynamic_population(uint8_t* resp)
87{
88 *resp |= 1 << 7;
89}
90inline void set_static_population(uint8_t* resp)
91{
92 *resp &= ~(1 << 7);
93}
94} // namespace response
95
96struct GetSdrInfoResp
97{
98 uint8_t count;
99 uint8_t luns_and_dynamic_population;
100};
101
102} // namespace get_sdr_info
Emily Shafferbbef71c2017-05-08 16:36:17 -0700103
104/**
105 * Get SDR
106 */
107namespace get_sdr
108{
109
110struct GetSdrReq
111{
112 uint8_t reservation_id_lsb;
113 uint8_t reservation_id_msb;
114 uint8_t record_id_lsb;
115 uint8_t record_id_msb;
116 uint8_t offset;
117 uint8_t bytes_to_read;
118} __attribute__((packed));
119
120namespace request
121{
122
123inline uint8_t get_reservation_id(GetSdrReq* req)
124{
125 return (req->reservation_id_lsb + (req->reservation_id_msb << 8));
126};
127
128inline uint8_t get_record_id(GetSdrReq* req)
129{
130 return (req->record_id_lsb + (req->record_id_msb << 8));
131};
132
133} // namespace request
134
135// Response
136struct GetSdrResp
137{
138 uint8_t next_record_id_lsb;
139 uint8_t next_record_id_msb;
140 uint8_t record_data[64];
141} __attribute__((packed));
142
143namespace response
144{
145
146inline void set_next_record_id(int next, GetSdrResp* resp)
147{
148 resp->next_record_id_lsb = next & 0xff;
149 resp->next_record_id_msb = (next >> 8) & 0xff;
150};
151
152} // namespace response
153
154// Record header
155struct SensorDataRecordHeader
156{
157 uint8_t record_id_lsb;
158 uint8_t record_id_msb;
159 uint8_t sdr_version;
160 uint8_t record_type;
161 uint8_t record_length; // Length not counting the header
162} __attribute__((packed));
163
164namespace header
165{
166
167inline void set_record_id(int id, SensorDataRecordHeader* hdr)
168{
169 hdr->record_id_lsb = (id & 0xFF);
170 hdr->record_id_msb = (id >> 8) & 0xFF;
171};
172
173} // namespace header
174
175enum SensorDataRecordType
176{
177 SENSOR_DATA_FULL_RECORD = 1,
178};
179
180// Record key
181struct SensorDataRecordKey
182{
183 uint8_t owner_id;
184 uint8_t owner_lun;
185 uint8_t sensor_number;
186} __attribute__((packed));
187
188namespace key
189{
190
191inline void set_owner_id_ipmb(SensorDataRecordKey* key)
192{
193 key->owner_id &= ~0x01;
194};
195
196inline void set_owner_id_system_sw(SensorDataRecordKey* key)
197{
198 key->owner_id |= 0x01;
199};
200
201inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key)
202{
203 key->owner_id &= 0x01;
204 key->owner_id |= addr<<1;
205};
206
207inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key)
208{
209 key->owner_lun &= ~0x03;
210 key->owner_lun |= (lun&0x03);
211};
212
213inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key)
214{
215 key->owner_lun &= 0x0f;
216 key->owner_lun |= ((channel & 0xf)<<4);
217};
218
219} // namespace key
220
221// Body - full record
222#define FULL_RECORD_ID_STR_MAX_LENGTH 16
223struct SensorDataFullRecordBody
224{
225 uint8_t entity_id;
226 uint8_t entity_instance;
227 uint8_t sensor_initialization;
228 uint8_t sensor_capabilities; // no macro support
229 uint8_t sensor_type;
230 uint8_t event_reading_type;
231 uint8_t supported_assertions[2]; // no macro support
232 uint8_t supported_deassertions[2]; // no macro support
233 uint8_t discrete_reading_setting_mask[2]; // no macro support
234 uint8_t sensor_units_1;
235 uint8_t sensor_units_2_base;
236 uint8_t sensor_units_3_modifier;
237 uint8_t linearization;
238 uint8_t m_lsb;
239 uint8_t m_msb_and_tolerance;
240 uint8_t b_lsb;
241 uint8_t b_msb_and_accuracy_lsb;
242 uint8_t accuracy_and_sensor_direction;
243 uint8_t r_b_exponents;
244 uint8_t analog_characteristic_flags; //no macro support
245 uint8_t nominal_reading;
246 uint8_t normal_max;
247 uint8_t normal_min;
248 uint8_t sensor_max;
249 uint8_t sensor_min;
250 uint8_t upper_nonrecoverable_threshold;
251 uint8_t upper_critical_threshold;
252 uint8_t upper_noncritical_threshold;
253 uint8_t lower_nonrecoverable_threshold;
254 uint8_t lower_critical_threshold;
255 uint8_t lower_noncritical_threshold;
256 uint8_t positive_threshold_hysteresis;
257 uint8_t negative_threshold_hysteresis;
258 uint16_t reserved;
259 uint8_t oem_reserved;
260 uint8_t id_string_info;
Emily Shaffer10f49592017-05-10 12:01:10 -0700261 char id_string[FULL_RECORD_ID_STR_MAX_LENGTH];
Emily Shafferbbef71c2017-05-08 16:36:17 -0700262} __attribute__((packed));
263
264namespace body
265{
266
267inline void set_entity_instance_number(uint8_t n,
268 SensorDataFullRecordBody* body)
269{
270 body->entity_instance &= 1<<7;
271 body->entity_instance |= (n & ~(1<<7));
272};
273inline void set_entity_physical_entity(SensorDataFullRecordBody* body)
274{
275 body->entity_instance &= ~(1<<7);
276};
277inline void set_entity_logical_container(SensorDataFullRecordBody* body)
278{
279 body->entity_instance |= 1<<7;
280};
281
282inline void sensor_scanning_state(bool enabled,
283 SensorDataFullRecordBody* body)
284{
285 if (enabled)
286 {
287 body->sensor_initialization |= 1<<0;
288 }
289 else
290 {
291 body->sensor_initialization &= ~(1<<0);
292 };
293};
294inline void event_generation_state(bool enabled,
295 SensorDataFullRecordBody* body)
296{
297 if (enabled)
298 {
299 body->sensor_initialization |= 1<<1;
300 }
301 else
302 {
303 body->sensor_initialization &= ~(1<<1);
304 }
305};
306inline void init_types_state(bool enabled,
307 SensorDataFullRecordBody* body)
308{
309 if (enabled)
310 {
311 body->sensor_initialization |= 1<<2;
312 }
313 else
314 {
315 body->sensor_initialization &= ~(1<<2);
316 }
317};
318inline void init_hyst_state(bool enabled,
319 SensorDataFullRecordBody* body)
320{
321 if (enabled)
322 {
323 body->sensor_initialization |= 1<<3;
324 }
325 else
326 {
327 body->sensor_initialization &= ~(1<<3);
328 }
329};
330inline void init_thresh_state(bool enabled,
331 SensorDataFullRecordBody* body)
332{
333 if (enabled)
334 {
335 body->sensor_initialization |= 1<<4;
336 }
337 else
338 {
339 body->sensor_initialization &= ~(1<<4);
340 }
341};
342inline void init_events_state(bool enabled,
343 SensorDataFullRecordBody* body)
344{
345 if (enabled)
346 {
347 body->sensor_initialization |= 1<<5;
348 }
349 else
350 {
351 body->sensor_initialization &= ~(1<<5);
352 }
353};
354inline void init_scanning_state(bool enabled,
355 SensorDataFullRecordBody* body)
356{
357 if (enabled)
358 {
359 body->sensor_initialization |= 1<<6;
360 }
361 else
362 {
363 body->sensor_initialization &= ~(1<<6);
364 }
365};
366inline void init_settable_state(bool enabled,
367 SensorDataFullRecordBody* body)
368{
369 if (enabled)
370 {
371 body->sensor_initialization |= 1<<7;
372 }
373 else
374 {
375 body->sensor_initialization &= ~(1<<7);
376 }
377};
378
379inline void set_percentage(SensorDataFullRecordBody* body)
380{
381 body->sensor_units_1 |= 1<<0;
382};
383inline void unset_percentage(SensorDataFullRecordBody* body)
384{
385 body->sensor_units_1 &= ~(1<<0);
386};
387inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body)
388{
389 body->sensor_units_1 &= ~(3<<1);
390 body->sensor_units_1 |= (op & 0x3)<<1;
391};
392inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body)
393{
394 body->sensor_units_1 &= ~(7<<3);
395 body->sensor_units_1 |= (unit & 0x7)<<3;
396};
397inline void set_analog_data_format(uint8_t format,
398 SensorDataFullRecordBody* body)
399{
400 body->sensor_units_1 &= ~(3<<6);
401 body->sensor_units_1 |= (format & 0x3)<<6;
402};
403
404inline void set_m(uint8_t m, SensorDataFullRecordBody* body)
405{
406 body->m_lsb = m & 0xff;
407 body->m_msb_and_tolerance &= ~(3<<6);
408 body->m_msb_and_tolerance |= ((m & (3<<8)) >> 2);
409};
410inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body)
411{
412 body->m_msb_and_tolerance &= ~0x3f;
413 body->m_msb_and_tolerance |= tol & 0x3f;
414};
415
416inline void set_b(uint8_t b, SensorDataFullRecordBody* body)
417{
418 body->b_lsb = b & 0xff;
419 body->b_msb_and_accuracy_lsb &= ~(3<<6);
420 body->b_msb_and_accuracy_lsb |= ((b & (3<<8)) >> 2);
421};
422inline void set_accuracy(uint8_t acc, SensorDataFullRecordBody* body)
423{
424 body->b_msb_and_accuracy_lsb &= ~0x3f;
425 body->b_msb_and_accuracy_lsb |= acc & 0x3f;
426 body->accuracy_and_sensor_direction &= 0x0f;
427 body->accuracy_and_sensor_direction |= (acc & 0xf) << 4;
428};
429inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body)
430{
431 body->accuracy_and_sensor_direction &= ~(3<<2);
432 body->accuracy_and_sensor_direction |= (exp & 3)<<2;
433};
434inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body)
435{
436 body->accuracy_and_sensor_direction &= ~(3<<0);
437 body->accuracy_and_sensor_direction |= (dir & 3);
438};
439
440inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body)
441{
442 body->r_b_exponents &= 0xf0;
443 body->r_b_exponents |= exp & 0x0f;
444};
445inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body)
446{
447 body->r_b_exponents &= 0x0f;
448 body->r_b_exponents |= (exp & 0x0f)<<4;
449};
450
451inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body)
452{
453 body->id_string_info &= ~(0x1f);
454 body->id_string_info |= len & 0x1f;
455};
456inline uint8_t get_id_strlen( SensorDataFullRecordBody* body)
457{
458 return body->id_string_info & 0x1f;
459};
460inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body)
461{
462 body->id_string_info &= ~(3<<6);
463 body->id_string_info |= (type & 0x3)<<6;
464};
465
466} // namespace body
467
468// More types contained in section 43.17 Sensor Unit Type Codes,
469// IPMI spec v2 rev 1.1
470enum SensorUnitTypeCodes
471{
472 SENSOR_UNIT_UNSPECIFIED = 0,
473 SENSOR_UNIT_DEGREES_C = 1,
474 SENSOR_UNIT_VOLTS = 4,
475 SENSOR_UNIT_AMPERES = 5,
476 SENSOR_UNIT_JOULES = 7,
477 SENSOR_UNIT_METERS = 34,
478 SENSOR_UNIT_REVOLUTIONS = 41,
479};
480
481struct SensorDataFullRecord
482{
483 SensorDataRecordHeader header;
484 SensorDataRecordKey key;
485 SensorDataFullRecordBody body;
486} __attribute__((packed));
487
488} // get_sdr
Chris Austenac4604a2015-10-13 12:43:27 -0500489#endif