1*46470a38SPatrick Venture #pragma once 2*46470a38SPatrick Venture 3*46470a38SPatrick Venture #include "types.hpp" 4*46470a38SPatrick Venture 5*46470a38SPatrick Venture #include <host-ipmid/ipmid-api.h> 6*46470a38SPatrick Venture #include <stdint.h> 7*46470a38SPatrick Venture 8*46470a38SPatrick Venture // IPMI commands for net functions. 9*46470a38SPatrick Venture enum ipmi_netfn_sen_cmds 10*46470a38SPatrick Venture { 11*46470a38SPatrick Venture IPMI_CMD_GET_DEVICE_SDR_INFO = 0x20, 12*46470a38SPatrick Venture IPMI_CMD_GET_DEVICE_SDR = 0x21, 13*46470a38SPatrick Venture IPMI_CMD_RESERVE_DEVICE_SDR_REPO = 0x22, 14*46470a38SPatrick Venture IPMI_CMD_GET_SENSOR_READING = 0x2D, 15*46470a38SPatrick Venture IPMI_CMD_GET_SENSOR_TYPE = 0x2F, 16*46470a38SPatrick Venture IPMI_CMD_SET_SENSOR = 0x30, 17*46470a38SPatrick Venture IPMI_CMD_GET_SENSOR_THRESHOLDS = 0x27, 18*46470a38SPatrick Venture }; 19*46470a38SPatrick Venture 20*46470a38SPatrick Venture /** 21*46470a38SPatrick Venture * @enum device_type 22*46470a38SPatrick Venture * IPMI FRU device types 23*46470a38SPatrick Venture */ 24*46470a38SPatrick Venture enum device_type 25*46470a38SPatrick Venture { 26*46470a38SPatrick Venture IPMI_PHYSICAL_FRU = 0x00, 27*46470a38SPatrick Venture IPMI_LOGICAL_FRU = 0x80, 28*46470a38SPatrick Venture }; 29*46470a38SPatrick Venture 30*46470a38SPatrick Venture // Discrete sensor types. 31*46470a38SPatrick Venture enum ipmi_sensor_types 32*46470a38SPatrick Venture { 33*46470a38SPatrick Venture IPMI_SENSOR_TEMP = 0x01, 34*46470a38SPatrick Venture IPMI_SENSOR_VOLTAGE = 0x02, 35*46470a38SPatrick Venture IPMI_SENSOR_CURRENT = 0x03, 36*46470a38SPatrick Venture IPMI_SENSOR_FAN = 0x04, 37*46470a38SPatrick Venture IPMI_SENSOR_TPM = 0xCC, 38*46470a38SPatrick Venture }; 39*46470a38SPatrick Venture 40*46470a38SPatrick Venture #define MAX_DBUS_PATH 128 41*46470a38SPatrick Venture struct dbus_interface_t 42*46470a38SPatrick Venture { 43*46470a38SPatrick Venture uint8_t sensornumber; 44*46470a38SPatrick Venture uint8_t sensortype; 45*46470a38SPatrick Venture 46*46470a38SPatrick Venture char bus[MAX_DBUS_PATH]; 47*46470a38SPatrick Venture char path[MAX_DBUS_PATH]; 48*46470a38SPatrick Venture char interface[MAX_DBUS_PATH]; 49*46470a38SPatrick Venture }; 50*46470a38SPatrick Venture 51*46470a38SPatrick Venture int set_sensor_dbus_state_s(uint8_t, const char*, const char*); 52*46470a38SPatrick Venture int set_sensor_dbus_state_y(uint8_t, const char*, const uint8_t); 53*46470a38SPatrick Venture int find_openbmc_path(uint8_t, dbus_interface_t*); 54*46470a38SPatrick Venture 55*46470a38SPatrick Venture ipmi_ret_t ipmi_sen_get_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 56*46470a38SPatrick Venture ipmi_request_t request, ipmi_response_t response, 57*46470a38SPatrick Venture ipmi_data_len_t data_len, ipmi_context_t context); 58*46470a38SPatrick Venture 59*46470a38SPatrick Venture ipmi_ret_t ipmi_sen_reserve_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 60*46470a38SPatrick Venture ipmi_request_t request, 61*46470a38SPatrick Venture ipmi_response_t response, 62*46470a38SPatrick Venture ipmi_data_len_t data_len, 63*46470a38SPatrick Venture ipmi_context_t context); 64*46470a38SPatrick Venture 65*46470a38SPatrick Venture static const uint16_t FRU_RECORD_ID_START = 256; 66*46470a38SPatrick Venture static const uint8_t SDR_VERSION = 0x51; 67*46470a38SPatrick Venture static const uint16_t END_OF_RECORD = 0xFFFF; 68*46470a38SPatrick Venture static const uint8_t LENGTH_MASK = 0x1F; 69*46470a38SPatrick Venture 70*46470a38SPatrick Venture /** 71*46470a38SPatrick Venture * Get SDR Info 72*46470a38SPatrick Venture */ 73*46470a38SPatrick Venture 74*46470a38SPatrick Venture namespace get_sdr_info 75*46470a38SPatrick Venture { 76*46470a38SPatrick Venture namespace request 77*46470a38SPatrick Venture { 78*46470a38SPatrick Venture // Note: for some reason the ipmi_request_t appears to be the 79*46470a38SPatrick Venture // raw value for this call. 80*46470a38SPatrick Venture inline bool get_count(void* req) 81*46470a38SPatrick Venture { 82*46470a38SPatrick Venture return (bool)((uint64_t)(req)&1); 83*46470a38SPatrick Venture } 84*46470a38SPatrick Venture } // namespace request 85*46470a38SPatrick Venture 86*46470a38SPatrick Venture namespace response 87*46470a38SPatrick Venture { 88*46470a38SPatrick Venture #define SDR_INFO_RESP_SIZE 2 89*46470a38SPatrick Venture inline void set_lun_present(int lun, uint8_t* resp) 90*46470a38SPatrick Venture { 91*46470a38SPatrick Venture *resp |= 1 << lun; 92*46470a38SPatrick Venture } 93*46470a38SPatrick Venture inline void set_lun_not_present(int lun, uint8_t* resp) 94*46470a38SPatrick Venture { 95*46470a38SPatrick Venture *resp &= ~(1 << lun); 96*46470a38SPatrick Venture } 97*46470a38SPatrick Venture inline void set_dynamic_population(uint8_t* resp) 98*46470a38SPatrick Venture { 99*46470a38SPatrick Venture *resp |= 1 << 7; 100*46470a38SPatrick Venture } 101*46470a38SPatrick Venture inline void set_static_population(uint8_t* resp) 102*46470a38SPatrick Venture { 103*46470a38SPatrick Venture *resp &= ~(1 << 7); 104*46470a38SPatrick Venture } 105*46470a38SPatrick Venture } // namespace response 106*46470a38SPatrick Venture 107*46470a38SPatrick Venture struct GetSdrInfoResp 108*46470a38SPatrick Venture { 109*46470a38SPatrick Venture uint8_t count; 110*46470a38SPatrick Venture uint8_t luns_and_dynamic_population; 111*46470a38SPatrick Venture }; 112*46470a38SPatrick Venture 113*46470a38SPatrick Venture } // namespace get_sdr_info 114*46470a38SPatrick Venture 115*46470a38SPatrick Venture /** 116*46470a38SPatrick Venture * Get SDR 117*46470a38SPatrick Venture */ 118*46470a38SPatrick Venture namespace get_sdr 119*46470a38SPatrick Venture { 120*46470a38SPatrick Venture 121*46470a38SPatrick Venture struct GetSdrReq 122*46470a38SPatrick Venture { 123*46470a38SPatrick Venture uint8_t reservation_id_lsb; 124*46470a38SPatrick Venture uint8_t reservation_id_msb; 125*46470a38SPatrick Venture uint8_t record_id_lsb; 126*46470a38SPatrick Venture uint8_t record_id_msb; 127*46470a38SPatrick Venture uint8_t offset; 128*46470a38SPatrick Venture uint8_t bytes_to_read; 129*46470a38SPatrick Venture } __attribute__((packed)); 130*46470a38SPatrick Venture 131*46470a38SPatrick Venture namespace request 132*46470a38SPatrick Venture { 133*46470a38SPatrick Venture 134*46470a38SPatrick Venture inline uint8_t get_reservation_id(GetSdrReq* req) 135*46470a38SPatrick Venture { 136*46470a38SPatrick Venture return (req->reservation_id_lsb + (req->reservation_id_msb << 8)); 137*46470a38SPatrick Venture }; 138*46470a38SPatrick Venture 139*46470a38SPatrick Venture inline uint16_t get_record_id(GetSdrReq* req) 140*46470a38SPatrick Venture { 141*46470a38SPatrick Venture return (req->record_id_lsb + (req->record_id_msb << 8)); 142*46470a38SPatrick Venture }; 143*46470a38SPatrick Venture 144*46470a38SPatrick Venture } // namespace request 145*46470a38SPatrick Venture 146*46470a38SPatrick Venture // Response 147*46470a38SPatrick Venture struct GetSdrResp 148*46470a38SPatrick Venture { 149*46470a38SPatrick Venture uint8_t next_record_id_lsb; 150*46470a38SPatrick Venture uint8_t next_record_id_msb; 151*46470a38SPatrick Venture uint8_t record_data[64]; 152*46470a38SPatrick Venture } __attribute__((packed)); 153*46470a38SPatrick Venture 154*46470a38SPatrick Venture namespace response 155*46470a38SPatrick Venture { 156*46470a38SPatrick Venture 157*46470a38SPatrick Venture inline void set_next_record_id(uint16_t next, GetSdrResp* resp) 158*46470a38SPatrick Venture { 159*46470a38SPatrick Venture resp->next_record_id_lsb = next & 0xff; 160*46470a38SPatrick Venture resp->next_record_id_msb = (next >> 8) & 0xff; 161*46470a38SPatrick Venture }; 162*46470a38SPatrick Venture 163*46470a38SPatrick Venture } // namespace response 164*46470a38SPatrick Venture 165*46470a38SPatrick Venture // Record header 166*46470a38SPatrick Venture struct SensorDataRecordHeader 167*46470a38SPatrick Venture { 168*46470a38SPatrick Venture uint8_t record_id_lsb; 169*46470a38SPatrick Venture uint8_t record_id_msb; 170*46470a38SPatrick Venture uint8_t sdr_version; 171*46470a38SPatrick Venture uint8_t record_type; 172*46470a38SPatrick Venture uint8_t record_length; // Length not counting the header 173*46470a38SPatrick Venture } __attribute__((packed)); 174*46470a38SPatrick Venture 175*46470a38SPatrick Venture namespace header 176*46470a38SPatrick Venture { 177*46470a38SPatrick Venture 178*46470a38SPatrick Venture inline void set_record_id(int id, SensorDataRecordHeader* hdr) 179*46470a38SPatrick Venture { 180*46470a38SPatrick Venture hdr->record_id_lsb = (id & 0xFF); 181*46470a38SPatrick Venture hdr->record_id_msb = (id >> 8) & 0xFF; 182*46470a38SPatrick Venture }; 183*46470a38SPatrick Venture 184*46470a38SPatrick Venture } // namespace header 185*46470a38SPatrick Venture 186*46470a38SPatrick Venture enum SensorDataRecordType 187*46470a38SPatrick Venture { 188*46470a38SPatrick Venture SENSOR_DATA_FULL_RECORD = 0x1, 189*46470a38SPatrick Venture SENSOR_DATA_FRU_RECORD = 0x11, 190*46470a38SPatrick Venture }; 191*46470a38SPatrick Venture 192*46470a38SPatrick Venture // Record key 193*46470a38SPatrick Venture struct SensorDataRecordKey 194*46470a38SPatrick Venture { 195*46470a38SPatrick Venture uint8_t owner_id; 196*46470a38SPatrick Venture uint8_t owner_lun; 197*46470a38SPatrick Venture uint8_t sensor_number; 198*46470a38SPatrick Venture } __attribute__((packed)); 199*46470a38SPatrick Venture 200*46470a38SPatrick Venture /** @struct SensorDataFruRecordKey 201*46470a38SPatrick Venture * 202*46470a38SPatrick Venture * FRU Device Locator Record(key) - SDR Type 11 203*46470a38SPatrick Venture */ 204*46470a38SPatrick Venture struct SensorDataFruRecordKey 205*46470a38SPatrick Venture { 206*46470a38SPatrick Venture uint8_t deviceAddress; 207*46470a38SPatrick Venture uint8_t fruID; 208*46470a38SPatrick Venture uint8_t accessLun; 209*46470a38SPatrick Venture uint8_t channelNumber; 210*46470a38SPatrick Venture } __attribute__((packed)); 211*46470a38SPatrick Venture 212*46470a38SPatrick Venture namespace key 213*46470a38SPatrick Venture { 214*46470a38SPatrick Venture 215*46470a38SPatrick Venture inline void set_owner_id_ipmb(SensorDataRecordKey* key) 216*46470a38SPatrick Venture { 217*46470a38SPatrick Venture key->owner_id &= ~0x01; 218*46470a38SPatrick Venture }; 219*46470a38SPatrick Venture 220*46470a38SPatrick Venture inline void set_owner_id_system_sw(SensorDataRecordKey* key) 221*46470a38SPatrick Venture { 222*46470a38SPatrick Venture key->owner_id |= 0x01; 223*46470a38SPatrick Venture }; 224*46470a38SPatrick Venture 225*46470a38SPatrick Venture inline void set_owner_id_bmc(SensorDataRecordKey* key) 226*46470a38SPatrick Venture { 227*46470a38SPatrick Venture key->owner_id |= 0x20; 228*46470a38SPatrick Venture }; 229*46470a38SPatrick Venture 230*46470a38SPatrick Venture inline void set_owner_id_address(uint8_t addr, SensorDataRecordKey* key) 231*46470a38SPatrick Venture { 232*46470a38SPatrick Venture key->owner_id &= 0x01; 233*46470a38SPatrick Venture key->owner_id |= addr << 1; 234*46470a38SPatrick Venture }; 235*46470a38SPatrick Venture 236*46470a38SPatrick Venture inline void set_owner_lun(uint8_t lun, SensorDataRecordKey* key) 237*46470a38SPatrick Venture { 238*46470a38SPatrick Venture key->owner_lun &= ~0x03; 239*46470a38SPatrick Venture key->owner_lun |= (lun & 0x03); 240*46470a38SPatrick Venture }; 241*46470a38SPatrick Venture 242*46470a38SPatrick Venture inline void set_owner_lun_channel(uint8_t channel, SensorDataRecordKey* key) 243*46470a38SPatrick Venture { 244*46470a38SPatrick Venture key->owner_lun &= 0x0f; 245*46470a38SPatrick Venture key->owner_lun |= ((channel & 0xf) << 4); 246*46470a38SPatrick Venture }; 247*46470a38SPatrick Venture 248*46470a38SPatrick Venture } // namespace key 249*46470a38SPatrick Venture 250*46470a38SPatrick Venture /** @struct GetSensorThresholdsResponse 251*46470a38SPatrick Venture * 252*46470a38SPatrick Venture * Response structure for Get Sensor Thresholds command 253*46470a38SPatrick Venture */ 254*46470a38SPatrick Venture struct GetSensorThresholdsResponse 255*46470a38SPatrick Venture { 256*46470a38SPatrick Venture uint8_t validMask; //!< valid mask 257*46470a38SPatrick Venture uint8_t lowerNonCritical; //!< lower non-critical threshold 258*46470a38SPatrick Venture uint8_t lowerCritical; //!< lower critical threshold 259*46470a38SPatrick Venture uint8_t lowerNonRecoverable; //!< lower non-recoverable threshold 260*46470a38SPatrick Venture uint8_t upperNonCritical; //!< upper non-critical threshold 261*46470a38SPatrick Venture uint8_t upperCritical; //!< upper critical threshold 262*46470a38SPatrick Venture uint8_t upperNonRecoverable; //!< upper non-recoverable threshold 263*46470a38SPatrick Venture } __attribute__((packed)); 264*46470a38SPatrick Venture 265*46470a38SPatrick Venture // Body - full record 266*46470a38SPatrick Venture #define FULL_RECORD_ID_STR_MAX_LENGTH 16 267*46470a38SPatrick Venture 268*46470a38SPatrick Venture static const int FRU_RECORD_DEVICE_ID_MAX_LENGTH = 16; 269*46470a38SPatrick Venture 270*46470a38SPatrick Venture struct SensorDataFullRecordBody 271*46470a38SPatrick Venture { 272*46470a38SPatrick Venture uint8_t entity_id; 273*46470a38SPatrick Venture uint8_t entity_instance; 274*46470a38SPatrick Venture uint8_t sensor_initialization; 275*46470a38SPatrick Venture uint8_t sensor_capabilities; // no macro support 276*46470a38SPatrick Venture uint8_t sensor_type; 277*46470a38SPatrick Venture uint8_t event_reading_type; 278*46470a38SPatrick Venture uint8_t supported_assertions[2]; // no macro support 279*46470a38SPatrick Venture uint8_t supported_deassertions[2]; // no macro support 280*46470a38SPatrick Venture uint8_t discrete_reading_setting_mask[2]; // no macro support 281*46470a38SPatrick Venture uint8_t sensor_units_1; 282*46470a38SPatrick Venture uint8_t sensor_units_2_base; 283*46470a38SPatrick Venture uint8_t sensor_units_3_modifier; 284*46470a38SPatrick Venture uint8_t linearization; 285*46470a38SPatrick Venture uint8_t m_lsb; 286*46470a38SPatrick Venture uint8_t m_msb_and_tolerance; 287*46470a38SPatrick Venture uint8_t b_lsb; 288*46470a38SPatrick Venture uint8_t b_msb_and_accuracy_lsb; 289*46470a38SPatrick Venture uint8_t accuracy_and_sensor_direction; 290*46470a38SPatrick Venture uint8_t r_b_exponents; 291*46470a38SPatrick Venture uint8_t analog_characteristic_flags; // no macro support 292*46470a38SPatrick Venture uint8_t nominal_reading; 293*46470a38SPatrick Venture uint8_t normal_max; 294*46470a38SPatrick Venture uint8_t normal_min; 295*46470a38SPatrick Venture uint8_t sensor_max; 296*46470a38SPatrick Venture uint8_t sensor_min; 297*46470a38SPatrick Venture uint8_t upper_nonrecoverable_threshold; 298*46470a38SPatrick Venture uint8_t upper_critical_threshold; 299*46470a38SPatrick Venture uint8_t upper_noncritical_threshold; 300*46470a38SPatrick Venture uint8_t lower_nonrecoverable_threshold; 301*46470a38SPatrick Venture uint8_t lower_critical_threshold; 302*46470a38SPatrick Venture uint8_t lower_noncritical_threshold; 303*46470a38SPatrick Venture uint8_t positive_threshold_hysteresis; 304*46470a38SPatrick Venture uint8_t negative_threshold_hysteresis; 305*46470a38SPatrick Venture uint16_t reserved; 306*46470a38SPatrick Venture uint8_t oem_reserved; 307*46470a38SPatrick Venture uint8_t id_string_info; 308*46470a38SPatrick Venture char id_string[FULL_RECORD_ID_STR_MAX_LENGTH]; 309*46470a38SPatrick Venture } __attribute__((packed)); 310*46470a38SPatrick Venture 311*46470a38SPatrick Venture /** @struct SensorDataFruRecordBody 312*46470a38SPatrick Venture * 313*46470a38SPatrick Venture * FRU Device Locator Record(body) - SDR Type 11 314*46470a38SPatrick Venture */ 315*46470a38SPatrick Venture struct SensorDataFruRecordBody 316*46470a38SPatrick Venture { 317*46470a38SPatrick Venture uint8_t reserved; 318*46470a38SPatrick Venture uint8_t deviceType; 319*46470a38SPatrick Venture uint8_t deviceTypeModifier; 320*46470a38SPatrick Venture uint8_t entityID; 321*46470a38SPatrick Venture uint8_t entityInstance; 322*46470a38SPatrick Venture uint8_t oem; 323*46470a38SPatrick Venture uint8_t deviceIDLen; 324*46470a38SPatrick Venture char deviceID[FRU_RECORD_DEVICE_ID_MAX_LENGTH]; 325*46470a38SPatrick Venture } __attribute__((packed)); 326*46470a38SPatrick Venture 327*46470a38SPatrick Venture namespace body 328*46470a38SPatrick Venture { 329*46470a38SPatrick Venture 330*46470a38SPatrick Venture inline void set_entity_instance_number(uint8_t n, 331*46470a38SPatrick Venture SensorDataFullRecordBody* body) 332*46470a38SPatrick Venture { 333*46470a38SPatrick Venture body->entity_instance &= 1 << 7; 334*46470a38SPatrick Venture body->entity_instance |= (n & ~(1 << 7)); 335*46470a38SPatrick Venture }; 336*46470a38SPatrick Venture inline void set_entity_physical_entity(SensorDataFullRecordBody* body) 337*46470a38SPatrick Venture { 338*46470a38SPatrick Venture body->entity_instance &= ~(1 << 7); 339*46470a38SPatrick Venture }; 340*46470a38SPatrick Venture inline void set_entity_logical_container(SensorDataFullRecordBody* body) 341*46470a38SPatrick Venture { 342*46470a38SPatrick Venture body->entity_instance |= 1 << 7; 343*46470a38SPatrick Venture }; 344*46470a38SPatrick Venture 345*46470a38SPatrick Venture inline void sensor_scanning_state(bool enabled, SensorDataFullRecordBody* body) 346*46470a38SPatrick Venture { 347*46470a38SPatrick Venture if (enabled) 348*46470a38SPatrick Venture { 349*46470a38SPatrick Venture body->sensor_initialization |= 1 << 0; 350*46470a38SPatrick Venture } 351*46470a38SPatrick Venture else 352*46470a38SPatrick Venture { 353*46470a38SPatrick Venture body->sensor_initialization &= ~(1 << 0); 354*46470a38SPatrick Venture }; 355*46470a38SPatrick Venture }; 356*46470a38SPatrick Venture inline void event_generation_state(bool enabled, SensorDataFullRecordBody* body) 357*46470a38SPatrick Venture { 358*46470a38SPatrick Venture if (enabled) 359*46470a38SPatrick Venture { 360*46470a38SPatrick Venture body->sensor_initialization |= 1 << 1; 361*46470a38SPatrick Venture } 362*46470a38SPatrick Venture else 363*46470a38SPatrick Venture { 364*46470a38SPatrick Venture body->sensor_initialization &= ~(1 << 1); 365*46470a38SPatrick Venture } 366*46470a38SPatrick Venture }; 367*46470a38SPatrick Venture inline void init_types_state(bool enabled, SensorDataFullRecordBody* body) 368*46470a38SPatrick Venture { 369*46470a38SPatrick Venture if (enabled) 370*46470a38SPatrick Venture { 371*46470a38SPatrick Venture body->sensor_initialization |= 1 << 2; 372*46470a38SPatrick Venture } 373*46470a38SPatrick Venture else 374*46470a38SPatrick Venture { 375*46470a38SPatrick Venture body->sensor_initialization &= ~(1 << 2); 376*46470a38SPatrick Venture } 377*46470a38SPatrick Venture }; 378*46470a38SPatrick Venture inline void init_hyst_state(bool enabled, SensorDataFullRecordBody* body) 379*46470a38SPatrick Venture { 380*46470a38SPatrick Venture if (enabled) 381*46470a38SPatrick Venture { 382*46470a38SPatrick Venture body->sensor_initialization |= 1 << 3; 383*46470a38SPatrick Venture } 384*46470a38SPatrick Venture else 385*46470a38SPatrick Venture { 386*46470a38SPatrick Venture body->sensor_initialization &= ~(1 << 3); 387*46470a38SPatrick Venture } 388*46470a38SPatrick Venture }; 389*46470a38SPatrick Venture inline void init_thresh_state(bool enabled, SensorDataFullRecordBody* body) 390*46470a38SPatrick Venture { 391*46470a38SPatrick Venture if (enabled) 392*46470a38SPatrick Venture { 393*46470a38SPatrick Venture body->sensor_initialization |= 1 << 4; 394*46470a38SPatrick Venture } 395*46470a38SPatrick Venture else 396*46470a38SPatrick Venture { 397*46470a38SPatrick Venture body->sensor_initialization &= ~(1 << 4); 398*46470a38SPatrick Venture } 399*46470a38SPatrick Venture }; 400*46470a38SPatrick Venture inline void init_events_state(bool enabled, SensorDataFullRecordBody* body) 401*46470a38SPatrick Venture { 402*46470a38SPatrick Venture if (enabled) 403*46470a38SPatrick Venture { 404*46470a38SPatrick Venture body->sensor_initialization |= 1 << 5; 405*46470a38SPatrick Venture } 406*46470a38SPatrick Venture else 407*46470a38SPatrick Venture { 408*46470a38SPatrick Venture body->sensor_initialization &= ~(1 << 5); 409*46470a38SPatrick Venture } 410*46470a38SPatrick Venture }; 411*46470a38SPatrick Venture inline void init_scanning_state(bool enabled, SensorDataFullRecordBody* body) 412*46470a38SPatrick Venture { 413*46470a38SPatrick Venture if (enabled) 414*46470a38SPatrick Venture { 415*46470a38SPatrick Venture body->sensor_initialization |= 1 << 6; 416*46470a38SPatrick Venture } 417*46470a38SPatrick Venture else 418*46470a38SPatrick Venture { 419*46470a38SPatrick Venture body->sensor_initialization &= ~(1 << 6); 420*46470a38SPatrick Venture } 421*46470a38SPatrick Venture }; 422*46470a38SPatrick Venture inline void init_settable_state(bool enabled, SensorDataFullRecordBody* body) 423*46470a38SPatrick Venture { 424*46470a38SPatrick Venture if (enabled) 425*46470a38SPatrick Venture { 426*46470a38SPatrick Venture body->sensor_initialization |= 1 << 7; 427*46470a38SPatrick Venture } 428*46470a38SPatrick Venture else 429*46470a38SPatrick Venture { 430*46470a38SPatrick Venture body->sensor_initialization &= ~(1 << 7); 431*46470a38SPatrick Venture } 432*46470a38SPatrick Venture }; 433*46470a38SPatrick Venture 434*46470a38SPatrick Venture inline void set_percentage(SensorDataFullRecordBody* body) 435*46470a38SPatrick Venture { 436*46470a38SPatrick Venture body->sensor_units_1 |= 1 << 0; 437*46470a38SPatrick Venture }; 438*46470a38SPatrick Venture inline void unset_percentage(SensorDataFullRecordBody* body) 439*46470a38SPatrick Venture { 440*46470a38SPatrick Venture body->sensor_units_1 &= ~(1 << 0); 441*46470a38SPatrick Venture }; 442*46470a38SPatrick Venture inline void set_modifier_operation(uint8_t op, SensorDataFullRecordBody* body) 443*46470a38SPatrick Venture { 444*46470a38SPatrick Venture body->sensor_units_1 &= ~(3 << 1); 445*46470a38SPatrick Venture body->sensor_units_1 |= (op & 0x3) << 1; 446*46470a38SPatrick Venture }; 447*46470a38SPatrick Venture inline void set_rate_unit(uint8_t unit, SensorDataFullRecordBody* body) 448*46470a38SPatrick Venture { 449*46470a38SPatrick Venture body->sensor_units_1 &= ~(7 << 3); 450*46470a38SPatrick Venture body->sensor_units_1 |= (unit & 0x7) << 3; 451*46470a38SPatrick Venture }; 452*46470a38SPatrick Venture inline void set_analog_data_format(uint8_t format, 453*46470a38SPatrick Venture SensorDataFullRecordBody* body) 454*46470a38SPatrick Venture { 455*46470a38SPatrick Venture body->sensor_units_1 &= ~(3 << 6); 456*46470a38SPatrick Venture body->sensor_units_1 |= (format & 0x3) << 6; 457*46470a38SPatrick Venture }; 458*46470a38SPatrick Venture 459*46470a38SPatrick Venture inline void set_m(uint16_t m, SensorDataFullRecordBody* body) 460*46470a38SPatrick Venture { 461*46470a38SPatrick Venture body->m_lsb = m & 0xff; 462*46470a38SPatrick Venture body->m_msb_and_tolerance &= ~(3 << 6); 463*46470a38SPatrick Venture body->m_msb_and_tolerance |= ((m & (3 << 8)) >> 2); 464*46470a38SPatrick Venture }; 465*46470a38SPatrick Venture inline void set_tolerance(uint8_t tol, SensorDataFullRecordBody* body) 466*46470a38SPatrick Venture { 467*46470a38SPatrick Venture body->m_msb_and_tolerance &= ~0x3f; 468*46470a38SPatrick Venture body->m_msb_and_tolerance |= tol & 0x3f; 469*46470a38SPatrick Venture }; 470*46470a38SPatrick Venture 471*46470a38SPatrick Venture inline void set_b(uint16_t b, SensorDataFullRecordBody* body) 472*46470a38SPatrick Venture { 473*46470a38SPatrick Venture body->b_lsb = b & 0xff; 474*46470a38SPatrick Venture body->b_msb_and_accuracy_lsb &= ~(3 << 6); 475*46470a38SPatrick Venture body->b_msb_and_accuracy_lsb |= ((b & (3 << 8)) >> 2); 476*46470a38SPatrick Venture }; 477*46470a38SPatrick Venture inline void set_accuracy(uint16_t acc, SensorDataFullRecordBody* body) 478*46470a38SPatrick Venture { 479*46470a38SPatrick Venture // bottom 6 bits 480*46470a38SPatrick Venture body->b_msb_and_accuracy_lsb &= ~0x3f; 481*46470a38SPatrick Venture body->b_msb_and_accuracy_lsb |= acc & 0x3f; 482*46470a38SPatrick Venture // top 4 bits 483*46470a38SPatrick Venture body->accuracy_and_sensor_direction &= 0x0f; 484*46470a38SPatrick Venture body->accuracy_and_sensor_direction |= ((acc >> 6) & 0xf) << 4; 485*46470a38SPatrick Venture }; 486*46470a38SPatrick Venture inline void set_accuracy_exp(uint8_t exp, SensorDataFullRecordBody* body) 487*46470a38SPatrick Venture { 488*46470a38SPatrick Venture body->accuracy_and_sensor_direction &= ~(3 << 2); 489*46470a38SPatrick Venture body->accuracy_and_sensor_direction |= (exp & 3) << 2; 490*46470a38SPatrick Venture }; 491*46470a38SPatrick Venture inline void set_sensor_dir(uint8_t dir, SensorDataFullRecordBody* body) 492*46470a38SPatrick Venture { 493*46470a38SPatrick Venture body->accuracy_and_sensor_direction &= ~(3 << 0); 494*46470a38SPatrick Venture body->accuracy_and_sensor_direction |= (dir & 3); 495*46470a38SPatrick Venture }; 496*46470a38SPatrick Venture 497*46470a38SPatrick Venture inline void set_b_exp(uint8_t exp, SensorDataFullRecordBody* body) 498*46470a38SPatrick Venture { 499*46470a38SPatrick Venture body->r_b_exponents &= 0xf0; 500*46470a38SPatrick Venture body->r_b_exponents |= exp & 0x0f; 501*46470a38SPatrick Venture }; 502*46470a38SPatrick Venture inline void set_r_exp(uint8_t exp, SensorDataFullRecordBody* body) 503*46470a38SPatrick Venture { 504*46470a38SPatrick Venture body->r_b_exponents &= 0x0f; 505*46470a38SPatrick Venture body->r_b_exponents |= (exp & 0x0f) << 4; 506*46470a38SPatrick Venture }; 507*46470a38SPatrick Venture 508*46470a38SPatrick Venture inline void set_id_strlen(uint8_t len, SensorDataFullRecordBody* body) 509*46470a38SPatrick Venture { 510*46470a38SPatrick Venture body->id_string_info &= ~(0x1f); 511*46470a38SPatrick Venture body->id_string_info |= len & 0x1f; 512*46470a38SPatrick Venture }; 513*46470a38SPatrick Venture inline uint8_t get_id_strlen(SensorDataFullRecordBody* body) 514*46470a38SPatrick Venture { 515*46470a38SPatrick Venture return body->id_string_info & 0x1f; 516*46470a38SPatrick Venture }; 517*46470a38SPatrick Venture inline void set_id_type(uint8_t type, SensorDataFullRecordBody* body) 518*46470a38SPatrick Venture { 519*46470a38SPatrick Venture body->id_string_info &= ~(3 << 6); 520*46470a38SPatrick Venture body->id_string_info |= (type & 0x3) << 6; 521*46470a38SPatrick Venture }; 522*46470a38SPatrick Venture 523*46470a38SPatrick Venture inline void set_device_id_strlen(uint8_t len, SensorDataFruRecordBody* body) 524*46470a38SPatrick Venture { 525*46470a38SPatrick Venture body->deviceIDLen &= ~(LENGTH_MASK); 526*46470a38SPatrick Venture body->deviceIDLen |= len & LENGTH_MASK; 527*46470a38SPatrick Venture }; 528*46470a38SPatrick Venture 529*46470a38SPatrick Venture inline uint8_t get_device_id_strlen(SensorDataFruRecordBody* body) 530*46470a38SPatrick Venture { 531*46470a38SPatrick Venture return body->deviceIDLen & LENGTH_MASK; 532*46470a38SPatrick Venture }; 533*46470a38SPatrick Venture 534*46470a38SPatrick Venture inline void set_readable_mask(uint8_t mask, SensorDataFullRecordBody* body) 535*46470a38SPatrick Venture { 536*46470a38SPatrick Venture body->discrete_reading_setting_mask[1] = mask & 0x3F; 537*46470a38SPatrick Venture } 538*46470a38SPatrick Venture 539*46470a38SPatrick Venture } // namespace body 540*46470a38SPatrick Venture 541*46470a38SPatrick Venture // More types contained in section 43.17 Sensor Unit Type Codes, 542*46470a38SPatrick Venture // IPMI spec v2 rev 1.1 543*46470a38SPatrick Venture enum SensorUnitTypeCodes 544*46470a38SPatrick Venture { 545*46470a38SPatrick Venture SENSOR_UNIT_UNSPECIFIED = 0, 546*46470a38SPatrick Venture SENSOR_UNIT_DEGREES_C = 1, 547*46470a38SPatrick Venture SENSOR_UNIT_VOLTS = 4, 548*46470a38SPatrick Venture SENSOR_UNIT_AMPERES = 5, 549*46470a38SPatrick Venture SENSOR_UNIT_WATTS = 6, 550*46470a38SPatrick Venture SENSOR_UNIT_JOULES = 7, 551*46470a38SPatrick Venture SENSOR_UNIT_METERS = 34, 552*46470a38SPatrick Venture SENSOR_UNIT_REVOLUTIONS = 41, 553*46470a38SPatrick Venture }; 554*46470a38SPatrick Venture 555*46470a38SPatrick Venture struct SensorDataFullRecord 556*46470a38SPatrick Venture { 557*46470a38SPatrick Venture SensorDataRecordHeader header; 558*46470a38SPatrick Venture SensorDataRecordKey key; 559*46470a38SPatrick Venture SensorDataFullRecordBody body; 560*46470a38SPatrick Venture } __attribute__((packed)); 561*46470a38SPatrick Venture 562*46470a38SPatrick Venture /** @struct SensorDataFruRecord 563*46470a38SPatrick Venture * 564*46470a38SPatrick Venture * FRU Device Locator Record - SDR Type 11 565*46470a38SPatrick Venture */ 566*46470a38SPatrick Venture struct SensorDataFruRecord 567*46470a38SPatrick Venture { 568*46470a38SPatrick Venture SensorDataRecordHeader header; 569*46470a38SPatrick Venture SensorDataFruRecordKey key; 570*46470a38SPatrick Venture SensorDataFruRecordBody body; 571*46470a38SPatrick Venture } __attribute__((packed)); 572*46470a38SPatrick Venture 573*46470a38SPatrick Venture } // namespace get_sdr 574*46470a38SPatrick Venture 575*46470a38SPatrick Venture namespace ipmi 576*46470a38SPatrick Venture { 577*46470a38SPatrick Venture 578*46470a38SPatrick Venture namespace sensor 579*46470a38SPatrick Venture { 580*46470a38SPatrick Venture 581*46470a38SPatrick Venture /** 582*46470a38SPatrick Venture * @brief Map offset to the corresponding bit in the assertion byte. 583*46470a38SPatrick Venture * 584*46470a38SPatrick Venture * The discrete sensors support up to 14 states. 0-7 offsets are stored in one 585*46470a38SPatrick Venture * byte and offsets 8-14 in the second byte. 586*46470a38SPatrick Venture * 587*46470a38SPatrick Venture * @param[in] offset - offset number. 588*46470a38SPatrick Venture * @param[in/out] resp - get sensor reading response. 589*46470a38SPatrick Venture */ 590*46470a38SPatrick Venture inline void setOffset(uint8_t offset, ipmi::sensor::GetReadingResponse* resp) 591*46470a38SPatrick Venture { 592*46470a38SPatrick Venture if (offset > 7) 593*46470a38SPatrick Venture { 594*46470a38SPatrick Venture resp->assertOffset8_14 |= 1 << (offset - 8); 595*46470a38SPatrick Venture } 596*46470a38SPatrick Venture else 597*46470a38SPatrick Venture { 598*46470a38SPatrick Venture resp->assertOffset0_7 |= 1 << offset; 599*46470a38SPatrick Venture } 600*46470a38SPatrick Venture } 601*46470a38SPatrick Venture 602*46470a38SPatrick Venture /** 603*46470a38SPatrick Venture * @brief Set the reading field in the response. 604*46470a38SPatrick Venture * 605*46470a38SPatrick Venture * @param[in] offset - offset number. 606*46470a38SPatrick Venture * @param[in/out] resp - get sensor reading response. 607*46470a38SPatrick Venture */ 608*46470a38SPatrick Venture inline void setReading(uint8_t value, ipmi::sensor::GetReadingResponse* resp) 609*46470a38SPatrick Venture { 610*46470a38SPatrick Venture resp->reading = value; 611*46470a38SPatrick Venture } 612*46470a38SPatrick Venture 613*46470a38SPatrick Venture /** 614*46470a38SPatrick Venture * @brief Map the value to the assertion bytes. The assertion states are stored 615*46470a38SPatrick Venture * in 2 bytes. 616*46470a38SPatrick Venture * 617*46470a38SPatrick Venture * @param[in] value - value to mapped to the assertion byte. 618*46470a38SPatrick Venture * @param[in/out] resp - get sensor reading response. 619*46470a38SPatrick Venture */ 620*46470a38SPatrick Venture inline void setAssertionBytes(uint16_t value, 621*46470a38SPatrick Venture ipmi::sensor::GetReadingResponse* resp) 622*46470a38SPatrick Venture { 623*46470a38SPatrick Venture resp->assertOffset0_7 = static_cast<uint8_t>(value & 0x00FF); 624*46470a38SPatrick Venture resp->assertOffset8_14 = static_cast<uint8_t>(value >> 8); 625*46470a38SPatrick Venture } 626*46470a38SPatrick Venture 627*46470a38SPatrick Venture /** 628*46470a38SPatrick Venture * @brief Set the scanning enabled bit in the response. 629*46470a38SPatrick Venture * 630*46470a38SPatrick Venture * @param[in/out] resp - get sensor reading response. 631*46470a38SPatrick Venture */ 632*46470a38SPatrick Venture inline void enableScanning(ipmi::sensor::GetReadingResponse* resp) 633*46470a38SPatrick Venture { 634*46470a38SPatrick Venture resp->operation = 1 << 6; 635*46470a38SPatrick Venture } 636*46470a38SPatrick Venture 637*46470a38SPatrick Venture } // namespace sensor 638*46470a38SPatrick Venture 639*46470a38SPatrick Venture } // namespace ipmi 640