blob: 6d3d3bd2efa54fc676b069da78be4faef83e8280 [file] [log] [blame]
Chris Austen8a45e7c2015-10-15 00:31:46 -05001#include <stdio.h>
2#include <string.h>
3#include <stdint.h>
Chris Austend7cf0e42015-11-07 14:27:12 -06004#include <malloc.h>
Chris Austen8a45e7c2015-10-15 00:31:46 -05005
6
Chris Austen0012e9b2015-10-22 01:37:46 -05007extern uint8_t find_sensor(uint8_t);
Chris Austen0130d6e2015-10-15 22:32:36 -05008extern int set_sensor_dbus_state_v(uint8_t , const char *, char *);
9
10
Chris Austen8a45e7c2015-10-15 00:31:46 -050011struct 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
Chris Austen0130d6e2015-10-15 22:32:36 -050024#define ISBITSET(x,y) (((x)>>(y))&0x01)
Chris Austen8a45e7c2015-10-15 00:31:46 -050025#define ASSERTINDEX 0
26#define DEASSERTINDEX 1
27
Chris Austen8a45e7c2015-10-15 00:31:46 -050028// Sensor Type, Offset, function handler, Dbus Method, Assert value, Deassert value
29struct lookup_t {
30 uint8_t sensor_type;
31 uint8_t offset;
Chris Austen0130d6e2015-10-15 22:32:36 -050032 int (*func)(const sensorRES_t *, const lookup_t *, const char *);
Chris Austen8a45e7c2015-10-15 00:31:46 -050033 char method[16];
Chris Austend7cf0e42015-11-07 14:27:12 -060034 char assertion[64];
35 char deassertion[64];
Chris Austen8a45e7c2015-10-15 00:31:46 -050036};
37
38
Chris Austen0130d6e2015-10-15 22:32:36 -050039extern int updateDbusInterface(uint8_t , const char *, const char *) ;
40extern int set_sensor_dbus_state(uint8_t ,const char *, const char *);
41
42
43int set_sensor_dbus_state_simple(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
44
45 return set_sensor_dbus_state(pRec->sensor_number, pTable->method, value);
46}
47
48struct event_data_t {
49 uint8_t data;
Chris Austend7cf0e42015-11-07 14:27:12 -060050 char text[64];
Chris Austen0130d6e2015-10-15 22:32:36 -050051};
52
53event_data_t g_fwprogress02h[] = {
54 {0x00, "Unspecified"},
55 {0x01, "Memory Init"},
56 {0x02, "HD Init"},
57 {0x03, "Secondary Proc Init"},
58 {0x04, "User Authentication"},
59 {0x05, "User init system setup"},
60 {0x06, "USB configuration"},
61 {0x07, "PCI configuration"},
62 {0x08, "Option ROM Init"},
63 {0x09, "Video Init"},
64 {0x0A, "Cache Init"},
65 {0x0B, "SM Bus init"},
66 {0x0C, "Keyboard Init"},
67 {0x0D, "Embedded ctrl init"},
68 {0x0E, "Docking station attachment"},
69 {0x0F, "Enable docking station"},
70 {0x10, "Docking station ejection"},
71 {0x11, "Disabling docking station"},
72 {0x12, "Calling OS Wakeup"},
73 {0x13, "Starting OS"},
74 {0x14, "Baseboard Init"},
75 {0x15, ""},
76 {0x16, "Floppy Init"},
77 {0x17, "Keyboard Test"},
78 {0x18, "Pointing Device Test"},
79 {0x19, "Primary Proc Init"},
80 {0xFF, "Unknown"}
81};
82
Chris Austend7cf0e42015-11-07 14:27:12 -060083event_data_t g_fwprogress00h[] = {
84 {0x00, "Unspecified."},
85 {0x01, "No system memory detected"},
86 {0x02, "No usable system memory"},
87 {0x03, "Unrecoverable hard-disk/ATAPI/IDE"},
88 {0x04, "Unrecoverable system-board"},
89 {0x05, "Unrecoverable diskette"},
90 {0x06, "Unrecoverable hard-disk controller"},
91 {0x07, "Unrecoverable PS/2 or USB keyboard"},
92 {0x08, "Removable boot media not found"},
93 {0x09, "Unrecoverable video controller"},
94 {0x0A, "No video device detected"},
95 {0x0B, "Firmware ROM corruption detected"},
96 {0x0C, "CPU voltage mismatch"},
97 {0x0D, "CPU speed matching"},
98 {0xFF, "unknown"},
99};
Chris Austen0130d6e2015-10-15 22:32:36 -0500100
Chris Austen0130d6e2015-10-15 22:32:36 -0500101
Chris Austend7cf0e42015-11-07 14:27:12 -0600102char *event_data_lookup(event_data_t *p, uint8_t b) {
Chris Austen0130d6e2015-10-15 22:32:36 -0500103
Chris Austen5a9f0b42015-10-21 20:32:19 -0500104 while(p->data != 0xFF) {
105 if (p->data == b) {
Chris Austen0130d6e2015-10-15 22:32:36 -0500106 break;
Chris Austen0012e9b2015-10-22 01:37:46 -0500107 }
Chris Austen5a9f0b42015-10-21 20:32:19 -0500108 p++;
109 }
Chris Austen0130d6e2015-10-15 22:32:36 -0500110
Chris Austen5a9f0b42015-10-21 20:32:19 -0500111 return p->text;
Chris Austen0130d6e2015-10-15 22:32:36 -0500112}
Chris Austend7cf0e42015-11-07 14:27:12 -0600113
114
115
Chris Austen0130d6e2015-10-15 22:32:36 -0500116// The fw progress sensor contains some additional information that needs to be processed
117// prior to calling the dbus code.
118int set_sensor_dbus_state_fwprogress(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
119
Chris Austend7cf0e42015-11-07 14:27:12 -0600120 char valuestring[128];
Chris Austen0012e9b2015-10-22 01:37:46 -0500121 char* p = valuestring;
Chris Austen0130d6e2015-10-15 22:32:36 -0500122
123 switch (pTable->offset) {
124
Chris Austend7cf0e42015-11-07 14:27:12 -0600125 case 0x00 : snprintf(p, sizeof(valuestring), "POST Error, %s", event_data_lookup(g_fwprogress00h, pRec->event_data2));
Chris Austen0130d6e2015-10-15 22:32:36 -0500126 break;
Chris Austend7cf0e42015-11-07 14:27:12 -0600127 case 0x01 : /* Using g_fwprogress02h for 0x01 because thats what the ipmi spec says to do */
128 snprintf(p, sizeof(valuestring), "FW Hang, %s", event_data_lookup(g_fwprogress02h, pRec->event_data2));
Chris Austen0130d6e2015-10-15 22:32:36 -0500129 break;
Chris Austend7cf0e42015-11-07 14:27:12 -0600130 case 0x02 : snprintf(p, sizeof(valuestring), "FW Progress, %s", event_data_lookup(g_fwprogress02h, pRec->event_data2));
Chris Austen0012e9b2015-10-22 01:37:46 -0500131 break;
Chris Austen0130d6e2015-10-15 22:32:36 -0500132 }
133
Chris Austen0012e9b2015-10-22 01:37:46 -0500134 return set_sensor_dbus_state_v(pRec->sensor_number, pTable->method, p);
Chris Austen0130d6e2015-10-15 22:32:36 -0500135}
136
Chris Austen0a4e2472015-10-18 12:19:40 -0500137// Handling this special OEM sensor by coping what is in byte 4. I also think that is odd
138// considering byte 3 is for sensor reading. This seems like a misuse of the IPMI spec
Chris Austend7cf0e42015-11-07 14:27:12 -0600139int set_sensor_dbus_state_osbootcount(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
Chris Austen0a4e2472015-10-18 12:19:40 -0500140 char valuestring[32];
141 char* pStr = valuestring;
142
143 sprintf(valuestring, "%d", pRec->assert_state7_0);
144
145 return set_sensor_dbus_state_v(pRec->sensor_number, pTable->method, pStr);
146}
147
Chris Austen0130d6e2015-10-15 22:32:36 -0500148
Chris Austend7cf0e42015-11-07 14:27:12 -0600149
Chris Austen8a45e7c2015-10-15 00:31:46 -0500150// This table lists only senors we care about telling dbus about.
Chris Austen0012e9b2015-10-22 01:37:46 -0500151// Offset definition cab be found in section 42.2 of the IPMI 2.0
Chris Austen8a45e7c2015-10-15 00:31:46 -0500152// spec. Add more if/when there are more items of interest.
Chris Austen0130d6e2015-10-15 22:32:36 -0500153lookup_t g_ipmidbuslookup[] = {
Chris Austen8a45e7c2015-10-15 00:31:46 -0500154
Chris Austend7cf0e42015-11-07 14:27:12 -0600155 {0xe9, 0x00, set_sensor_dbus_state_simple, "setValue", "Disabled", ""}, // OCC Inactive 0
156 {0xe9, 0x01, set_sensor_dbus_state_simple, "setValue", "Enabled", ""}, // OCC Active 1
Chris Austen0130d6e2015-10-15 22:32:36 -0500157 {0x07, 0x07, set_sensor_dbus_state_simple, "setPresent", "True", "False"},
Chris Austenf3644f12015-10-31 12:46:39 -0500158 {0x07, 0x08, set_sensor_dbus_state_simple, "setFault", "True", ""},
Chris Austen0130d6e2015-10-15 22:32:36 -0500159 {0x0C, 0x06, set_sensor_dbus_state_simple, "setPresent", "True", "False"},
Chris Austenf3644f12015-10-31 12:46:39 -0500160 {0x0C, 0x04, set_sensor_dbus_state_simple, "setFault", "True", ""},
Chris Austen0130d6e2015-10-15 22:32:36 -0500161 {0x0F, 0x02, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
162 {0x0F, 0x01, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
163 {0x0F, 0x00, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
Chris Austenf3644f12015-10-31 12:46:39 -0500164 {0xC7, 0x01, set_sensor_dbus_state_simple, "setFault", "True", ""},
Chris Austend7cf0e42015-11-07 14:27:12 -0600165 {0xc3, 0x00, set_sensor_dbus_state_osbootcount, "setValue", "" ,""},
166 {0x1F, 0x00, set_sensor_dbus_state_simple, "setValue", "Boot completed (00)", ""},
167 {0x1F, 0x01, set_sensor_dbus_state_simple, "setValue", "Boot completed (01)", ""},
168 {0x1F, 0x02, set_sensor_dbus_state_simple, "setValue", "PXE boot completed", ""},
169 {0x1F, 0x03, set_sensor_dbus_state_simple, "setValue", "Diagnostic boot completed", ""},
170 {0x1F, 0x04, set_sensor_dbus_state_simple, "setValue", "CD-ROM boot completed", ""},
171 {0x1F, 0x05, set_sensor_dbus_state_simple, "setValue", "ROM boot completed", ""},
172 {0x1F, 0x06, set_sensor_dbus_state_simple, "setValue", "Boot completed (06)", ""},
Chris Austen0130d6e2015-10-15 22:32:36 -0500173
174 {0xFF, 0xFF, NULL, "", "", ""}
Chris Austen8a45e7c2015-10-15 00:31:46 -0500175};
176
Chris Austen0130d6e2015-10-15 22:32:36 -0500177
Chris Austen0130d6e2015-10-15 22:32:36 -0500178void reportSensorEventAssert(sensorRES_t *pRec, int index) {
179 lookup_t *pTable = &g_ipmidbuslookup[index];
180 (*pTable->func)(pRec, pTable, pTable->assertion);
181}
182void reportSensorEventDeassert(sensorRES_t *pRec, int index) {
183 lookup_t *pTable = &g_ipmidbuslookup[index];
184 (*pTable->func)(pRec, pTable, pTable->deassertion);
185}
186
187
Chris Austen8a45e7c2015-10-15 00:31:46 -0500188int findindex(const uint8_t sensor_type, int offset, int *index) {
189
190 int i=0, rc=0;
Chris Austen0130d6e2015-10-15 22:32:36 -0500191 lookup_t *pTable = g_ipmidbuslookup;
Chris Austen8a45e7c2015-10-15 00:31:46 -0500192
193 do {
Chris Austen8a45e7c2015-10-15 00:31:46 -0500194 if ( ((pTable+i)->sensor_type == sensor_type) &&
Chris Austen0130d6e2015-10-15 22:32:36 -0500195 ((pTable+i)->offset == offset) ) {
Chris Austen8a45e7c2015-10-15 00:31:46 -0500196 rc = 1;
197 *index = i;
198 break;
199 }
200 i++;
201 } while ((pTable+i)->sensor_type != 0xFF);
202
203 return rc;
204}
205
Chris Austen0a4e2472015-10-18 12:19:40 -0500206void debug_print_ok_to_dont_care(uint8_t stype, int offset)
207{
Chris Austen0012e9b2015-10-22 01:37:46 -0500208 printf("LOOKATME: Sensor should not be reported: Type 0x%02x, Offset 0x%02x\n",
Chris Austen0a4e2472015-10-18 12:19:40 -0500209 stype, offset);
210}
211
Chris Austen0130d6e2015-10-15 22:32:36 -0500212bool shouldReport(uint8_t sensorType, int offset, int *index) {
Chris Austen8a45e7c2015-10-15 00:31:46 -0500213
Chris Austen0130d6e2015-10-15 22:32:36 -0500214 bool rc = false;
Chris Austen0a4e2472015-10-18 12:19:40 -0500215
Chris Austen0130d6e2015-10-15 22:32:36 -0500216 if (findindex(sensorType, offset, index)) { rc = true; }
Chris Austen8a45e7c2015-10-15 00:31:46 -0500217
Chris Austen0a4e2472015-10-18 12:19:40 -0500218 if (rc==false) { debug_print_ok_to_dont_care(sensorType, offset); }
219
Chris Austen0130d6e2015-10-15 22:32:36 -0500220 return rc;
Chris Austen8a45e7c2015-10-15 00:31:46 -0500221}
222
223
224int updateSensorRecordFromSSRAESC(const void *record) {
225
226 sensorRES_t *pRec = (sensorRES_t *) record;
Chris Austen0012e9b2015-10-22 01:37:46 -0500227 uint8_t stype;
Chris Austen8a45e7c2015-10-15 00:31:46 -0500228 int index, i=0;
Chris Austen8a45e7c2015-10-15 00:31:46 -0500229
Chris Austend7cf0e42015-11-07 14:27:12 -0600230 stype = find_sensor(pRec->sensor_number);
Chris Austen0012e9b2015-10-22 01:37:46 -0500231
232 // 0xC3 types use the assertion7_0 for the value to be set
233 // so skip the reseach and call the correct event reporting
234 // function
235 if (stype == 0xC3) {
236
237 shouldReport(stype, 0x00, &index);
238 reportSensorEventAssert(pRec, index);
239
240 } else {
241 // Scroll through each bit position . Determine
242 // if any bit is either asserted or Deasserted.
243 for(i=0;i<8;i++) {
Chris Austend7cf0e42015-11-07 14:27:12 -0600244
Chris Austen0012e9b2015-10-22 01:37:46 -0500245 if ((ISBITSET(pRec->assert_state7_0,i)) &&
246 (shouldReport(stype, i, &index)))
247 {
248 reportSensorEventAssert(pRec, index);
249 }
250 if ((ISBITSET(pRec->assert_state14_8,i)) &&
251 (shouldReport(stype, i+8, &index)))
252 {
253 reportSensorEventAssert(pRec, index);
254 }
255 if ((ISBITSET(pRec->deassert_state7_0,i)) &&
256 (shouldReport(stype, i, &index)))
257 {
258 reportSensorEventDeassert(pRec, index);
259 }
260 if ((ISBITSET(pRec->deassert_state14_8,i)) &&
261 (shouldReport(stype, i+8, &index)))
262 {
263 reportSensorEventDeassert(pRec, index);
264 }
Chris Austen8a45e7c2015-10-15 00:31:46 -0500265 }
Chris Austen0012e9b2015-10-22 01:37:46 -0500266
Chris Austen8a45e7c2015-10-15 00:31:46 -0500267 }
268
Chris Austen0012e9b2015-10-22 01:37:46 -0500269
Chris Austen8a45e7c2015-10-15 00:31:46 -0500270 return 0;
271}