1 #include <stdio.h> 2 #include <string.h> 3 #include <stdint.h> 4 #include <malloc.h> 5 #include "sensorhandler.h" 6 7 extern uint8_t find_sensor(uint8_t); 8 9 10 struct sensorRES_t { 11 uint8_t sensor_number; 12 uint8_t operation; 13 uint8_t sensor_reading; 14 uint8_t assert_state7_0; 15 uint8_t assert_state14_8; 16 uint8_t deassert_state7_0; 17 uint8_t deassert_state14_8; 18 uint8_t event_data1; 19 uint8_t event_data2; 20 uint8_t event_data3; 21 } __attribute__ ((packed)); 22 23 #define ISBITSET(x,y) (((x)>>(y))&0x01) 24 #define ASSERTINDEX 0 25 #define DEASSERTINDEX 1 26 27 // Sensor Type, Offset, function handler, Dbus Method, Assert value, Deassert value 28 struct lookup_t { 29 uint8_t sensor_type; 30 uint8_t offset; 31 int (*func)(const sensorRES_t *, const lookup_t *, const char *); 32 char member[16]; 33 char assertion[64]; 34 char deassertion[64]; 35 }; 36 37 extern int updateDbusInterface(uint8_t , const char *, const char *); 38 39 int set_sensor_dbus_state_simple(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) { 40 41 return set_sensor_dbus_state_s(pRec->sensor_number, 42 pTable->member, 43 value); 44 } 45 46 struct event_data_t { 47 uint8_t data; 48 char text[64]; 49 }; 50 51 event_data_t g_fwprogress02h[] = { 52 {0x00, "Unspecified"}, 53 {0x01, "Memory Init"}, 54 {0x02, "HD Init"}, 55 {0x03, "Secondary Proc Init"}, 56 {0x04, "User Authentication"}, 57 {0x05, "User init system setup"}, 58 {0x06, "USB configuration"}, 59 {0x07, "PCI configuration"}, 60 {0x08, "Option ROM Init"}, 61 {0x09, "Video Init"}, 62 {0x0A, "Cache Init"}, 63 {0x0B, "SM Bus init"}, 64 {0x0C, "Keyboard Init"}, 65 {0x0D, "Embedded ctrl init"}, 66 {0x0E, "Docking station attachment"}, 67 {0x0F, "Enable docking station"}, 68 {0x10, "Docking station ejection"}, 69 {0x11, "Disabling docking station"}, 70 {0x12, "Calling OS Wakeup"}, 71 {0x13, "Starting OS"}, 72 {0x14, "Baseboard Init"}, 73 {0x15, ""}, 74 {0x16, "Floppy Init"}, 75 {0x17, "Keyboard Test"}, 76 {0x18, "Pointing Device Test"}, 77 {0x19, "Primary Proc Init"}, 78 {0xFF, "Unknown"} 79 }; 80 81 event_data_t g_fwprogress00h[] = { 82 {0x00, "Unspecified."}, 83 {0x01, "No system memory detected"}, 84 {0x02, "No usable system memory"}, 85 {0x03, "Unrecoverable hard-disk/ATAPI/IDE"}, 86 {0x04, "Unrecoverable system-board"}, 87 {0x05, "Unrecoverable diskette"}, 88 {0x06, "Unrecoverable hard-disk controller"}, 89 {0x07, "Unrecoverable PS/2 or USB keyboard"}, 90 {0x08, "Removable boot media not found"}, 91 {0x09, "Unrecoverable video controller"}, 92 {0x0A, "No video device detected"}, 93 {0x0B, "Firmware ROM corruption detected"}, 94 {0x0C, "CPU voltage mismatch"}, 95 {0x0D, "CPU speed matching"}, 96 {0xFF, "unknown"}, 97 }; 98 99 100 char *event_data_lookup(event_data_t *p, uint8_t b) { 101 102 while(p->data != 0xFF) { 103 if (p->data == b) { 104 break; 105 } 106 p++; 107 } 108 109 return p->text; 110 } 111 112 113 114 // The fw progress sensor contains some additional information that needs to be processed 115 // prior to calling the dbus code. 116 int set_sensor_dbus_state_fwprogress(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) { 117 118 char valuestring[128]; 119 char* p = valuestring; 120 121 switch (pTable->offset) { 122 123 case 0x00 : snprintf(p, sizeof(valuestring), "POST Error, %s", event_data_lookup(g_fwprogress00h, pRec->event_data2)); 124 break; 125 case 0x01 : /* Using g_fwprogress02h for 0x01 because thats what the ipmi spec says to do */ 126 snprintf(p, sizeof(valuestring), "FW Hang, %s", event_data_lookup(g_fwprogress02h, pRec->event_data2)); 127 break; 128 case 0x02 : snprintf(p, sizeof(valuestring), "FW Progress, %s", event_data_lookup(g_fwprogress02h, pRec->event_data2)); 129 break; 130 default : snprintf(p, sizeof(valuestring), "Internal warning, fw_progres offset unknown (0x%02x)", pTable->offset); 131 break; 132 } 133 134 return set_sensor_dbus_state_s(pRec->sensor_number, 135 pTable->member, 136 p); 137 } 138 139 // Handling this special OEM sensor by coping what is in byte 4. I also think that is odd 140 // considering byte 3 is for sensor reading. This seems like a misuse of the IPMI spec 141 int set_sensor_dbus_state_osbootcount(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) { 142 return set_sensor_dbus_state_y(pRec->sensor_number, 143 "setValue", 144 pRec->assert_state7_0); 145 } 146 147 int set_sensor_dbus_state_system_event(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) { 148 char valuestring[128]; 149 char* p = valuestring; 150 151 switch (pTable->offset) { 152 153 case 0x00 : snprintf(p, sizeof(valuestring), "System Reconfigured"); 154 break; 155 case 0x01 : snprintf(p, sizeof(valuestring), "OEM Boot Event"); 156 break; 157 case 0x02 : snprintf(p, sizeof(valuestring), "Undetermine System Hardware Failure"); 158 break; 159 case 0x03 : snprintf(p, sizeof(valuestring), "System Failure see error log for more details (0x%02x)", pRec->event_data2); 160 break; 161 case 0x04 : snprintf(p, sizeof(valuestring), "System Failure see PEF error log for more details (0x%02x)", pRec->event_data2); 162 break; 163 default : snprintf(p, sizeof(valuestring), "Internal warning, system_event offset unknown (0x%02x)", pTable->offset); 164 break; 165 } 166 167 return set_sensor_dbus_state_s(pRec->sensor_number, 168 pTable->member, 169 p); 170 } 171 172 173 // This table lists only senors we care about telling dbus about. 174 // Offset definition cab be found in section 42.2 of the IPMI 2.0 175 // spec. Add more if/when there are more items of interest. 176 lookup_t g_ipmidbuslookup[] = { 177 178 {0xe9, 0x00, set_sensor_dbus_state_simple, "setValue", "Disabled", ""}, // OCC Inactive 0 179 {0xe9, 0x01, set_sensor_dbus_state_simple, "setValue", "Enabled", ""}, // OCC Active 1 180 // Turbo Allowed 181 {0xda, 0x00, set_sensor_dbus_state_simple, "setValue", "True", "False"}, 182 // Power Supply Derating 183 {0xb4, 0x00, set_sensor_dbus_state_simple, "setValue", "", ""}, 184 // Power Cap 185 {0xC2, 0x00, set_sensor_dbus_state_simple, "setValue", "", ""}, 186 {0x07, 0x07, set_sensor_dbus_state_simple, "setPresent", "True", "False"}, 187 {0x07, 0x08, set_sensor_dbus_state_simple, "setFault", "True", "False"}, 188 {0x0C, 0x06, set_sensor_dbus_state_simple, "setPresent", "True", "False"}, 189 {0x0C, 0x04, set_sensor_dbus_state_simple, "setFault", "True", "False"}, 190 {0x0F, 0x02, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"}, 191 {0x0F, 0x01, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"}, 192 {0x0F, 0x00, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"}, 193 {0xC7, 0x01, set_sensor_dbus_state_simple, "setFault", "True", "False"}, 194 {0xc3, 0x00, set_sensor_dbus_state_osbootcount, "setValue", "" ,""}, 195 {0x1F, 0x00, set_sensor_dbus_state_simple, "setValue", "Boot completed (00)", ""}, 196 {0x1F, 0x01, set_sensor_dbus_state_simple, "setValue", "Boot completed (01)", ""}, 197 {0x1F, 0x02, set_sensor_dbus_state_simple, "setValue", "PXE boot completed", ""}, 198 {0x1F, 0x03, set_sensor_dbus_state_simple, "setValue", "Diagnostic boot completed", ""}, 199 {0x1F, 0x04, set_sensor_dbus_state_simple, "setValue", "CD-ROM boot completed", ""}, 200 {0x1F, 0x05, set_sensor_dbus_state_simple, "setValue", "ROM boot completed", ""}, 201 {0x1F, 0x06, set_sensor_dbus_state_simple, "setValue", "Boot completed (06)", ""}, 202 {0x12, 0x00, set_sensor_dbus_state_system_event, "setValue", "", ""}, 203 {0x12, 0x01, set_sensor_dbus_state_system_event, "setValue", "", ""}, 204 {0x12, 0x02, set_sensor_dbus_state_system_event, "setValue", "", ""}, 205 {0x12, 0x03, set_sensor_dbus_state_system_event, "setValue", "", ""}, 206 {0x12, 0x04, set_sensor_dbus_state_system_event, "setValue", "", ""}, 207 {0xD8, 0x00, set_sensor_dbus_state_simple, "setValue", "Disabled", ""}, 208 {0xFF, 0xFF, NULL, "", "", ""} 209 }; 210 211 212 void reportSensorEventAssert(sensorRES_t *pRec, int index) { 213 lookup_t *pTable = &g_ipmidbuslookup[index]; 214 (*pTable->func)(pRec, pTable, pTable->assertion); 215 } 216 void reportSensorEventDeassert(sensorRES_t *pRec, int index) { 217 lookup_t *pTable = &g_ipmidbuslookup[index]; 218 (*pTable->func)(pRec, pTable, pTable->deassertion); 219 } 220 221 222 int findindex(const uint8_t sensor_type, int offset, int *index) { 223 224 int i=0, rc=0; 225 lookup_t *pTable = g_ipmidbuslookup; 226 227 do { 228 if ( ((pTable+i)->sensor_type == sensor_type) && 229 ((pTable+i)->offset == offset) ) { 230 rc = 1; 231 *index = i; 232 break; 233 } 234 i++; 235 } while ((pTable+i)->sensor_type != 0xFF); 236 237 return rc; 238 } 239 240 void debug_print_ok_to_dont_care(uint8_t stype, int offset) 241 { 242 printf("LOOKATME: Sensor should not be reported: Type 0x%02x, Offset 0x%02x\n", 243 stype, offset); 244 } 245 246 bool shouldReport(uint8_t sensorType, int offset, int *index) { 247 248 bool rc = false; 249 250 if (findindex(sensorType, offset, index)) { rc = true; } 251 252 if (rc==false) { debug_print_ok_to_dont_care(sensorType, offset); } 253 254 return rc; 255 } 256 257 258 int updateSensorRecordFromSSRAESC(const void *record) { 259 260 sensorRES_t *pRec = (sensorRES_t *) record; 261 uint8_t stype; 262 int index, i=0; 263 264 stype = find_sensor(pRec->sensor_number); 265 266 // 0xC3 types use the assertion7_0 for the value to be set 267 // so skip the reseach and call the correct event reporting 268 // function 269 if (stype == 0xC3) { 270 271 shouldReport(stype, 0x00, &index); 272 reportSensorEventAssert(pRec, index); 273 274 } else { 275 // Scroll through each bit position . Determine 276 // if any bit is either asserted or Deasserted. 277 for(i=0;i<8;i++) { 278 279 if ((ISBITSET(pRec->assert_state7_0,i)) && 280 (shouldReport(stype, i, &index))) 281 { 282 reportSensorEventAssert(pRec, index); 283 } 284 if ((ISBITSET(pRec->assert_state14_8,i)) && 285 (shouldReport(stype, i+8, &index))) 286 { 287 reportSensorEventAssert(pRec, index); 288 } 289 if ((ISBITSET(pRec->deassert_state7_0,i)) && 290 (shouldReport(stype, i, &index))) 291 { 292 reportSensorEventDeassert(pRec, index); 293 } 294 if ((ISBITSET(pRec->deassert_state14_8,i)) && 295 (shouldReport(stype, i+8, &index))) 296 { 297 reportSensorEventDeassert(pRec, index); 298 } 299 } 300 301 } 302 303 304 return 0; 305 } 306