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