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", "False", ""}, 182 // Power Supply Derating 183 {0xb4, 0x00, set_sensor_dbus_state_simple, "setValue", "", ""}, 184 {0x07, 0x07, set_sensor_dbus_state_simple, "setPresent", "True", "False"}, 185 {0x07, 0x08, set_sensor_dbus_state_simple, "setFault", "True", "False"}, 186 {0x0C, 0x06, set_sensor_dbus_state_simple, "setPresent", "True", "False"}, 187 {0x0C, 0x04, set_sensor_dbus_state_simple, "setFault", "True", "False"}, 188 {0x0F, 0x02, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"}, 189 {0x0F, 0x01, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"}, 190 {0x0F, 0x00, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"}, 191 {0xC7, 0x01, set_sensor_dbus_state_simple, "setFault", "True", "False"}, 192 {0xc3, 0x00, set_sensor_dbus_state_osbootcount, "setValue", "" ,""}, 193 {0x1F, 0x00, set_sensor_dbus_state_simple, "setValue", "Boot completed (00)", ""}, 194 {0x1F, 0x01, set_sensor_dbus_state_simple, "setValue", "Boot completed (01)", ""}, 195 {0x1F, 0x02, set_sensor_dbus_state_simple, "setValue", "PXE boot completed", ""}, 196 {0x1F, 0x03, set_sensor_dbus_state_simple, "setValue", "Diagnostic boot completed", ""}, 197 {0x1F, 0x04, set_sensor_dbus_state_simple, "setValue", "CD-ROM boot completed", ""}, 198 {0x1F, 0x05, set_sensor_dbus_state_simple, "setValue", "ROM boot completed", ""}, 199 {0x1F, 0x06, set_sensor_dbus_state_simple, "setValue", "Boot completed (06)", ""}, 200 {0x12, 0x00, set_sensor_dbus_state_system_event, "setValue", "", ""}, 201 {0x12, 0x01, set_sensor_dbus_state_system_event, "setValue", "", ""}, 202 {0x12, 0x02, set_sensor_dbus_state_system_event, "setValue", "", ""}, 203 {0x12, 0x03, set_sensor_dbus_state_system_event, "setValue", "", ""}, 204 {0x12, 0x04, set_sensor_dbus_state_system_event, "setValue", "", ""}, 205 {0xD8, 0x00, set_sensor_dbus_state_simple, "setValue", "Disabled", ""}, 206 {0xFF, 0xFF, NULL, "", "", ""} 207 }; 208 209 210 void reportSensorEventAssert(sensorRES_t *pRec, int index) { 211 lookup_t *pTable = &g_ipmidbuslookup[index]; 212 (*pTable->func)(pRec, pTable, pTable->assertion); 213 } 214 void reportSensorEventDeassert(sensorRES_t *pRec, int index) { 215 lookup_t *pTable = &g_ipmidbuslookup[index]; 216 (*pTable->func)(pRec, pTable, pTable->deassertion); 217 } 218 219 220 int findindex(const uint8_t sensor_type, int offset, int *index) { 221 222 int i=0, rc=0; 223 lookup_t *pTable = g_ipmidbuslookup; 224 225 do { 226 if ( ((pTable+i)->sensor_type == sensor_type) && 227 ((pTable+i)->offset == offset) ) { 228 rc = 1; 229 *index = i; 230 break; 231 } 232 i++; 233 } while ((pTable+i)->sensor_type != 0xFF); 234 235 return rc; 236 } 237 238 void debug_print_ok_to_dont_care(uint8_t stype, int offset) 239 { 240 printf("LOOKATME: Sensor should not be reported: Type 0x%02x, Offset 0x%02x\n", 241 stype, offset); 242 } 243 244 bool shouldReport(uint8_t sensorType, int offset, int *index) { 245 246 bool rc = false; 247 248 if (findindex(sensorType, offset, index)) { rc = true; } 249 250 if (rc==false) { debug_print_ok_to_dont_care(sensorType, offset); } 251 252 return rc; 253 } 254 255 256 int updateSensorRecordFromSSRAESC(const void *record) { 257 258 sensorRES_t *pRec = (sensorRES_t *) record; 259 uint8_t stype; 260 int index, i=0; 261 262 stype = find_sensor(pRec->sensor_number); 263 264 // 0xC3 types use the assertion7_0 for the value to be set 265 // so skip the reseach and call the correct event reporting 266 // function 267 if (stype == 0xC3) { 268 269 shouldReport(stype, 0x00, &index); 270 reportSensorEventAssert(pRec, index); 271 272 } else { 273 // Scroll through each bit position . Determine 274 // if any bit is either asserted or Deasserted. 275 for(i=0;i<8;i++) { 276 277 if ((ISBITSET(pRec->assert_state7_0,i)) && 278 (shouldReport(stype, i, &index))) 279 { 280 reportSensorEventAssert(pRec, index); 281 } 282 if ((ISBITSET(pRec->assert_state14_8,i)) && 283 (shouldReport(stype, i+8, &index))) 284 { 285 reportSensorEventAssert(pRec, index); 286 } 287 if ((ISBITSET(pRec->deassert_state7_0,i)) && 288 (shouldReport(stype, i, &index))) 289 { 290 reportSensorEventDeassert(pRec, index); 291 } 292 if ((ISBITSET(pRec->deassert_state14_8,i)) && 293 (shouldReport(stype, i+8, &index))) 294 { 295 reportSensorEventDeassert(pRec, index); 296 } 297 } 298 299 } 300 301 302 return 0; 303 } 304