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