From bbef71c2a9aab57a826b4c7ec8f183e92eb6e28c Mon Sep 17 00:00:00 2001 From: Emily Shaffer Date: Mon, 8 May 2017 16:36:17 -0700 Subject: sensorhandler: implement get SDR Change-Id: I79dc59585c1f3008fc42e95a5a4792afd7268255 Signed-off-by: Emily Shaffer Signed-off-by: Patrick Williams --- sensorhandler.h | 387 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) (limited to 'sensorhandler.h') diff --git a/sensorhandler.h b/sensorhandler.h index db58c63..2b1f527 100644 --- a/sensorhandler.h +++ b/sensorhandler.h @@ -7,6 +7,7 @@ enum ipmi_netfn_sen_cmds { IPMI_CMD_GET_SDR_INFO = 0x20, + IPMI_CMD_GET_SDR = 0x21, IPMI_CMD_RESERVE_SDR_REPO = 0x22, IPMI_CMD_GET_SENSOR_READING = 0x2D, IPMI_CMD_GET_SENSOR_TYPE = 0x2F, @@ -99,4 +100,390 @@ struct GetSdrInfoResp }; } // namespace get_sdr_info + +/** + * Get SDR + */ +namespace get_sdr +{ + +struct GetSdrReq +{ + uint8_t reservation_id_lsb; + uint8_t reservation_id_msb; + uint8_t record_id_lsb; + uint8_t record_id_msb; + uint8_t offset; + uint8_t bytes_to_read; +} __attribute__((packed)); + +namespace request +{ + +inline uint8_t get_reservation_id(GetSdrReq* req) +{ + return (req->reservation_id_lsb + (req->reservation_id_msb << 8)); +}; + +inline uint8_t get_record_id(GetSdrReq* req) +{ + return (req->record_id_lsb + (req->record_id_msb << 8)); +}; + +} // namespace request + +// Response +struct GetSdrResp +{ + uint8_t next_record_id_lsb; + uint8_t next_record_id_msb; + uint8_t record_data[64]; +} __attribute__((packed)); + +namespace response +{ + +inline void set_next_record_id(int next, GetSdrResp* resp) +{ + resp->next_record_id_lsb = next & 0xff; + resp->next_record_id_msb = (next >> 8) & 0xff; +}; + +} // namespace response + +// Record header +struct SensorDataRecordHeader +{ + uint8_t record_id_lsb; + uint8_t record_id_msb; + uint8_t sdr_version; + uint8_t record_type; + uint8_t record_length; // Length not counting the header +} __attribute__((packed)); + +namespace header +{ + +inline void set_record_id(int id, SensorDataRecordHeader* hdr) +{ + hdr->record_id_lsb = (id & 0xFF); + hdr->record_id_msb = (id >> 8) & 0xFF; +}; + +} // namespace header + +enum SensorDataRecordType +{ + SENSOR_DATA_FULL_RECORD = 1, +}; + +// Record key +struct SensorDataRecordKey +{ + uint8_t owner_id; + uint8_t owner_lun; + uint8_t sensor_number; +} __attribute__((packed)); + +namespace key +{ + +inline void set_owner_id_ipmb(SensorDataRecordKey* key) +{ + key->owner_id &= ~0x01; +}; + +inline void set_owner_id_system_sw(SensorDataRecordKey* key) +{ + key->owner_id |= 0x01; +}; + +inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key) +{ + key->owner_id &= 0x01; + key->owner_id |= addr<<1; +}; + +inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key) +{ + key->owner_lun &= ~0x03; + key->owner_lun |= (lun&0x03); +}; + +inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key) +{ + key->owner_lun &= 0x0f; + key->owner_lun |= ((channel & 0xf)<<4); +}; + +} // namespace key + +// Body - full record +#define FULL_RECORD_ID_STR_MAX_LENGTH 16 +struct SensorDataFullRecordBody +{ + uint8_t entity_id; + uint8_t entity_instance; + uint8_t sensor_initialization; + uint8_t sensor_capabilities; // no macro support + uint8_t sensor_type; + uint8_t event_reading_type; + uint8_t supported_assertions[2]; // no macro support + uint8_t supported_deassertions[2]; // no macro support + uint8_t discrete_reading_setting_mask[2]; // no macro support + uint8_t sensor_units_1; + uint8_t sensor_units_2_base; + uint8_t sensor_units_3_modifier; + uint8_t linearization; + uint8_t m_lsb; + uint8_t m_msb_and_tolerance; + uint8_t b_lsb; + uint8_t b_msb_and_accuracy_lsb; + uint8_t accuracy_and_sensor_direction; + uint8_t r_b_exponents; + uint8_t analog_characteristic_flags; //no macro support + uint8_t nominal_reading; + uint8_t normal_max; + uint8_t normal_min; + uint8_t sensor_max; + uint8_t sensor_min; + uint8_t upper_nonrecoverable_threshold; + uint8_t upper_critical_threshold; + uint8_t upper_noncritical_threshold; + uint8_t lower_nonrecoverable_threshold; + uint8_t lower_critical_threshold; + uint8_t lower_noncritical_threshold; + uint8_t positive_threshold_hysteresis; + uint8_t negative_threshold_hysteresis; + uint16_t reserved; + uint8_t oem_reserved; + uint8_t id_string_info; + char id_string[16]; +} __attribute__((packed)); + +namespace body +{ + +inline void set_entity_instance_number(uint8_t n, + SensorDataFullRecordBody* body) +{ + body->entity_instance &= 1<<7; + body->entity_instance |= (n & ~(1<<7)); +}; +inline void set_entity_physical_entity(SensorDataFullRecordBody* body) +{ + body->entity_instance &= ~(1<<7); +}; +inline void set_entity_logical_container(SensorDataFullRecordBody* body) +{ + body->entity_instance |= 1<<7; +}; + +inline void sensor_scanning_state(bool enabled, + SensorDataFullRecordBody* body) +{ + if (enabled) + { + body->sensor_initialization |= 1<<0; + } + else + { + body->sensor_initialization &= ~(1<<0); + }; +}; +inline void event_generation_state(bool enabled, + SensorDataFullRecordBody* body) +{ + if (enabled) + { + body->sensor_initialization |= 1<<1; + } + else + { + body->sensor_initialization &= ~(1<<1); + } +}; +inline void init_types_state(bool enabled, + SensorDataFullRecordBody* body) +{ + if (enabled) + { + body->sensor_initialization |= 1<<2; + } + else + { + body->sensor_initialization &= ~(1<<2); + } +}; +inline void init_hyst_state(bool enabled, + SensorDataFullRecordBody* body) +{ + if (enabled) + { + body->sensor_initialization |= 1<<3; + } + else + { + body->sensor_initialization &= ~(1<<3); + } +}; +inline void init_thresh_state(bool enabled, + SensorDataFullRecordBody* body) +{ + if (enabled) + { + body->sensor_initialization |= 1<<4; + } + else + { + body->sensor_initialization &= ~(1<<4); + } +}; +inline void init_events_state(bool enabled, + SensorDataFullRecordBody* body) +{ + if (enabled) + { + body->sensor_initialization |= 1<<5; + } + else + { + body->sensor_initialization &= ~(1<<5); + } +}; +inline void init_scanning_state(bool enabled, + SensorDataFullRecordBody* body) +{ + if (enabled) + { + body->sensor_initialization |= 1<<6; + } + else + { + body->sensor_initialization &= ~(1<<6); + } +}; +inline void init_settable_state(bool enabled, + SensorDataFullRecordBody* body) +{ + if (enabled) + { + body->sensor_initialization |= 1<<7; + } + else + { + body->sensor_initialization &= ~(1<<7); + } +}; + +inline void set_percentage(SensorDataFullRecordBody* body) +{ + body->sensor_units_1 |= 1<<0; +}; +inline void unset_percentage(SensorDataFullRecordBody* body) +{ + body->sensor_units_1 &= ~(1<<0); +}; +inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body) +{ + body->sensor_units_1 &= ~(3<<1); + body->sensor_units_1 |= (op & 0x3)<<1; +}; +inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body) +{ + body->sensor_units_1 &= ~(7<<3); + body->sensor_units_1 |= (unit & 0x7)<<3; +}; +inline void set_analog_data_format(uint8_t format, + SensorDataFullRecordBody* body) +{ + body->sensor_units_1 &= ~(3<<6); + body->sensor_units_1 |= (format & 0x3)<<6; +}; + +inline void set_m(uint8_t m, SensorDataFullRecordBody* body) +{ + body->m_lsb = m & 0xff; + body->m_msb_and_tolerance &= ~(3<<6); + body->m_msb_and_tolerance |= ((m & (3<<8)) >> 2); +}; +inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body) +{ + body->m_msb_and_tolerance &= ~0x3f; + body->m_msb_and_tolerance |= tol & 0x3f; +}; + +inline void set_b(uint8_t b, SensorDataFullRecordBody* body) +{ + body->b_lsb = b & 0xff; + body->b_msb_and_accuracy_lsb &= ~(3<<6); + body->b_msb_and_accuracy_lsb |= ((b & (3<<8)) >> 2); +}; +inline void set_accuracy(uint8_t acc, SensorDataFullRecordBody* body) +{ + body->b_msb_and_accuracy_lsb &= ~0x3f; + body->b_msb_and_accuracy_lsb |= acc & 0x3f; + body->accuracy_and_sensor_direction &= 0x0f; + body->accuracy_and_sensor_direction |= (acc & 0xf) << 4; +}; +inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body) +{ + body->accuracy_and_sensor_direction &= ~(3<<2); + body->accuracy_and_sensor_direction |= (exp & 3)<<2; +}; +inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body) +{ + body->accuracy_and_sensor_direction &= ~(3<<0); + body->accuracy_and_sensor_direction |= (dir & 3); +}; + +inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body) +{ + body->r_b_exponents &= 0xf0; + body->r_b_exponents |= exp & 0x0f; +}; +inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body) +{ + body->r_b_exponents &= 0x0f; + body->r_b_exponents |= (exp & 0x0f)<<4; +}; + +inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body) +{ + body->id_string_info &= ~(0x1f); + body->id_string_info |= len & 0x1f; +}; +inline uint8_t get_id_strlen( SensorDataFullRecordBody* body) +{ + return body->id_string_info & 0x1f; +}; +inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body) +{ + body->id_string_info &= ~(3<<6); + body->id_string_info |= (type & 0x3)<<6; +}; + +} // namespace body + +// More types contained in section 43.17 Sensor Unit Type Codes, +// IPMI spec v2 rev 1.1 +enum SensorUnitTypeCodes +{ + SENSOR_UNIT_UNSPECIFIED = 0, + SENSOR_UNIT_DEGREES_C = 1, + SENSOR_UNIT_VOLTS = 4, + SENSOR_UNIT_AMPERES = 5, + SENSOR_UNIT_JOULES = 7, + SENSOR_UNIT_METERS = 34, + SENSOR_UNIT_REVOLUTIONS = 41, +}; + +struct SensorDataFullRecord +{ + SensorDataRecordHeader header; + SensorDataRecordKey key; + SensorDataFullRecordBody body; +} __attribute__((packed)); + +} // get_sdr #endif -- cgit v1.2.1