blob: bb5dd96585e4492e5e5ed8f539ed39066c9e9c48 [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 Austen10ccc0f2015-12-10 18:27:04 -06005#include "sensorhandler.h"
Chris Austen8a45e7c2015-10-15 00:31:46 -05006
Emily Shaffer391f3302017-04-03 10:27:08 -07007extern uint8_t find_type_for_sensor_number(uint8_t);
Chris Austen0130d6e2015-10-15 22:32:36 -05008
9
Chris Austen8a45e7c2015-10-15 00:31:46 -050010struct sensorRES_t {
11 uint8_t sensor_number;
12 uint8_t operation;
13 uint8_t sensor_reading;
14 uint8_t assert_state7_0;
Gunnar Millsd8249ee2018-04-12 16:33:53 -050015 uint8_t assert_state14_8;
Chris Austen8a45e7c2015-10-15 00:31:46 -050016 uint8_t deassert_state7_0;
Gunnar Millsd8249ee2018-04-12 16:33:53 -050017 uint8_t deassert_state14_8;
Chris Austen8a45e7c2015-10-15 00:31:46 -050018 uint8_t event_data1;
19 uint8_t event_data2;
Gunnar Millsd8249ee2018-04-12 16:33:53 -050020 uint8_t event_data3;
Chris Austen8a45e7c2015-10-15 00:31:46 -050021} __attribute__ ((packed));
22
Chris Austen0130d6e2015-10-15 22:32:36 -050023#define ISBITSET(x,y) (((x)>>(y))&0x01)
Chris Austen8a45e7c2015-10-15 00:31:46 -050024#define ASSERTINDEX 0
25#define DEASSERTINDEX 1
26
Chris Austen8a45e7c2015-10-15 00:31:46 -050027// Sensor Type, Offset, function handler, Dbus Method, Assert value, Deassert value
28struct lookup_t {
29 uint8_t sensor_type;
30 uint8_t offset;
Chris Austen0130d6e2015-10-15 22:32:36 -050031 int (*func)(const sensorRES_t *, const lookup_t *, const char *);
Chris Austen10ccc0f2015-12-10 18:27:04 -060032 char member[16];
Chris Austend7cf0e42015-11-07 14:27:12 -060033 char assertion[64];
34 char deassertion[64];
Chris Austen8a45e7c2015-10-15 00:31:46 -050035};
36
Chris Austen10ccc0f2015-12-10 18:27:04 -060037extern int updateDbusInterface(uint8_t , const char *, const char *);
Chris Austen0130d6e2015-10-15 22:32:36 -050038
39int set_sensor_dbus_state_simple(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
40
Chris Austen10ccc0f2015-12-10 18:27:04 -060041 return set_sensor_dbus_state_s(pRec->sensor_number,
42 pTable->member,
43 value);
Chris Austen0130d6e2015-10-15 22:32:36 -050044}
45
46struct event_data_t {
47 uint8_t data;
Chris Austend7cf0e42015-11-07 14:27:12 -060048 char text[64];
Chris Austen0130d6e2015-10-15 22:32:36 -050049};
50
51event_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
Chris Austend7cf0e42015-11-07 14:27:12 -060081event_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};
Chris Austen0130d6e2015-10-15 22:32:36 -050098
Chris Austen0130d6e2015-10-15 22:32:36 -050099
Chris Austend7cf0e42015-11-07 14:27:12 -0600100char *event_data_lookup(event_data_t *p, uint8_t b) {
Chris Austen0130d6e2015-10-15 22:32:36 -0500101
Chris Austen5a9f0b42015-10-21 20:32:19 -0500102 while(p->data != 0xFF) {
103 if (p->data == b) {
Chris Austen0130d6e2015-10-15 22:32:36 -0500104 break;
Chris Austen0012e9b2015-10-22 01:37:46 -0500105 }
Chris Austen5a9f0b42015-10-21 20:32:19 -0500106 p++;
107 }
Chris Austen0130d6e2015-10-15 22:32:36 -0500108
Chris Austen5a9f0b42015-10-21 20:32:19 -0500109 return p->text;
Chris Austen0130d6e2015-10-15 22:32:36 -0500110}
Chris Austend7cf0e42015-11-07 14:27:12 -0600111
112
113
Chris Austen0130d6e2015-10-15 22:32:36 -0500114// The fw progress sensor contains some additional information that needs to be processed
Gunnar Millsd8249ee2018-04-12 16:33:53 -0500115// prior to calling the dbus code.
Chris Austen0130d6e2015-10-15 22:32:36 -0500116int set_sensor_dbus_state_fwprogress(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
117
Chris Austend7cf0e42015-11-07 14:27:12 -0600118 char valuestring[128];
Chris Austen0012e9b2015-10-22 01:37:46 -0500119 char* p = valuestring;
Chris Austen0130d6e2015-10-15 22:32:36 -0500120
121 switch (pTable->offset) {
122
Chris Austend7cf0e42015-11-07 14:27:12 -0600123 case 0x00 : snprintf(p, sizeof(valuestring), "POST Error, %s", event_data_lookup(g_fwprogress00h, pRec->event_data2));
Chris Austen0130d6e2015-10-15 22:32:36 -0500124 break;
Gunnar Millsc9fa69e2018-04-08 16:35:25 -0500125 case 0x01 : /* Using g_fwprogress02h for 0x01 because that's what the ipmi spec says to do */
Chris Austend7cf0e42015-11-07 14:27:12 -0600126 snprintf(p, sizeof(valuestring), "FW Hang, %s", event_data_lookup(g_fwprogress02h, pRec->event_data2));
Chris Austen0130d6e2015-10-15 22:32:36 -0500127 break;
Chris Austend7cf0e42015-11-07 14:27:12 -0600128 case 0x02 : snprintf(p, sizeof(valuestring), "FW Progress, %s", event_data_lookup(g_fwprogress02h, pRec->event_data2));
Chris Austen0012e9b2015-10-22 01:37:46 -0500129 break;
Chris Austen800ba712015-12-03 15:31:00 -0600130 default : snprintf(p, sizeof(valuestring), "Internal warning, fw_progres offset unknown (0x%02x)", pTable->offset);
131 break;
Chris Austen0130d6e2015-10-15 22:32:36 -0500132 }
133
Chris Austen10ccc0f2015-12-10 18:27:04 -0600134 return set_sensor_dbus_state_s(pRec->sensor_number,
135 pTable->member,
136 p);
Chris Austen0130d6e2015-10-15 22:32:36 -0500137}
138
Chris Austen0a4e2472015-10-18 12:19:40 -0500139// 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
Chris Austend7cf0e42015-11-07 14:27:12 -0600141int set_sensor_dbus_state_osbootcount(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
Chris Austen10ccc0f2015-12-10 18:27:04 -0600142 return set_sensor_dbus_state_y(pRec->sensor_number,
143 "setValue",
144 pRec->assert_state7_0);
Chris Austen0a4e2472015-10-18 12:19:40 -0500145}
146
Chris Austen800ba712015-12-03 15:31:00 -0600147int 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;
Adriana Kobylakdd994312017-11-28 16:48:39 -0600157 case 0x02 : snprintf(p, sizeof(valuestring), "Undetermined System Hardware Failure");
Chris Austen800ba712015-12-03 15:31:00 -0600158 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
Chris Austen10ccc0f2015-12-10 18:27:04 -0600167 return set_sensor_dbus_state_s(pRec->sensor_number,
168 pTable->member,
169 p);
Chris Austen800ba712015-12-03 15:31:00 -0600170}
Chris Austen0130d6e2015-10-15 22:32:36 -0500171
Chris Austend7cf0e42015-11-07 14:27:12 -0600172
Chris Austen8a45e7c2015-10-15 00:31:46 -0500173// This table lists only senors we care about telling dbus about.
Chris Austen0012e9b2015-10-22 01:37:46 -0500174// Offset definition cab be found in section 42.2 of the IPMI 2.0
Chris Austen8a45e7c2015-10-15 00:31:46 -0500175// spec. Add more if/when there are more items of interest.
Chris Austen0130d6e2015-10-15 22:32:36 -0500176lookup_t g_ipmidbuslookup[] = {
Chris Austen8a45e7c2015-10-15 00:31:46 -0500177
Chris Austend7cf0e42015-11-07 14:27:12 -0600178 {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
Jayanth Othayoth0661beb2017-03-22 06:00:58 -0500180 // Turbo Allowed
Tom Joseph00f08152017-05-04 18:54:30 +0530181 {0xda, 0x00, set_sensor_dbus_state_simple, "setValue", "True", "False"},
Jayanth Othayothd5b2ac02017-03-27 08:19:18 -0500182 // Power Supply Derating
183 {0xb4, 0x00, set_sensor_dbus_state_simple, "setValue", "", ""},
Jayanth Othayoth5422e0e2017-04-18 21:22:13 -0500184 // Power Cap
185 {0xC2, 0x00, set_sensor_dbus_state_simple, "setValue", "", ""},
Chris Austen0130d6e2015-10-15 22:32:36 -0500186 {0x07, 0x07, set_sensor_dbus_state_simple, "setPresent", "True", "False"},
Chris Austen800ba712015-12-03 15:31:00 -0600187 {0x07, 0x08, set_sensor_dbus_state_simple, "setFault", "True", "False"},
Chris Austen0130d6e2015-10-15 22:32:36 -0500188 {0x0C, 0x06, set_sensor_dbus_state_simple, "setPresent", "True", "False"},
Chris Austen800ba712015-12-03 15:31:00 -0600189 {0x0C, 0x04, set_sensor_dbus_state_simple, "setFault", "True", "False"},
Chris Austen0130d6e2015-10-15 22:32:36 -0500190 {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"},
Chris Austen800ba712015-12-03 15:31:00 -0600193 {0xC7, 0x01, set_sensor_dbus_state_simple, "setFault", "True", "False"},
Chris Austend7cf0e42015-11-07 14:27:12 -0600194 {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)", ""},
Chris Austen800ba712015-12-03 15:31:00 -0600202 {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", "", ""},
Dhruvaraj Subhashchandran6244f932017-11-23 01:08:46 -0600207 {0xCA, 0x00, set_sensor_dbus_state_simple, "setValue", "Disabled", ""},
208 {0xCA, 0x01, set_sensor_dbus_state_simple, "setValue", "Enabled", ""},
Chris Austen0130d6e2015-10-15 22:32:36 -0500209 {0xFF, 0xFF, NULL, "", "", ""}
Chris Austen8a45e7c2015-10-15 00:31:46 -0500210};
211
Chris Austen0130d6e2015-10-15 22:32:36 -0500212
Chris Austen0130d6e2015-10-15 22:32:36 -0500213void reportSensorEventAssert(sensorRES_t *pRec, int index) {
214 lookup_t *pTable = &g_ipmidbuslookup[index];
215 (*pTable->func)(pRec, pTable, pTable->assertion);
216}
217void reportSensorEventDeassert(sensorRES_t *pRec, int index) {
218 lookup_t *pTable = &g_ipmidbuslookup[index];
219 (*pTable->func)(pRec, pTable, pTable->deassertion);
220}
221
222
Chris Austen8a45e7c2015-10-15 00:31:46 -0500223int findindex(const uint8_t sensor_type, int offset, int *index) {
Gunnar Millsd8249ee2018-04-12 16:33:53 -0500224
Chris Austen8a45e7c2015-10-15 00:31:46 -0500225 int i=0, rc=0;
Chris Austen0130d6e2015-10-15 22:32:36 -0500226 lookup_t *pTable = g_ipmidbuslookup;
Chris Austen8a45e7c2015-10-15 00:31:46 -0500227
228 do {
Gunnar Millsd8249ee2018-04-12 16:33:53 -0500229 if ( ((pTable+i)->sensor_type == sensor_type) &&
Chris Austen0130d6e2015-10-15 22:32:36 -0500230 ((pTable+i)->offset == offset) ) {
Chris Austen8a45e7c2015-10-15 00:31:46 -0500231 rc = 1;
232 *index = i;
233 break;
234 }
235 i++;
236 } while ((pTable+i)->sensor_type != 0xFF);
237
238 return rc;
239}
240
Chris Austen0130d6e2015-10-15 22:32:36 -0500241bool shouldReport(uint8_t sensorType, int offset, int *index) {
Chris Austen8a45e7c2015-10-15 00:31:46 -0500242
Chris Austen0130d6e2015-10-15 22:32:36 -0500243 bool rc = false;
Chris Austen0a4e2472015-10-18 12:19:40 -0500244
Chris Austen0130d6e2015-10-15 22:32:36 -0500245 if (findindex(sensorType, offset, index)) { rc = true; }
Aditya Saripalli5fb14602017-11-09 14:46:27 +0530246 if (rc == false) {
247#ifdef __IPMI_DEBUG__
248 log<level::DEBUG>("LOOKATME: Sensor should not be reported",
249 entry("SENSORTYPE=0x%02x", sensorType),
250 entry("OFFSET=0x%02x", offset));
251#endif
252 }
Chris Austen0a4e2472015-10-18 12:19:40 -0500253
Chris Austen0130d6e2015-10-15 22:32:36 -0500254 return rc;
Chris Austen8a45e7c2015-10-15 00:31:46 -0500255}
256
257
258int updateSensorRecordFromSSRAESC(const void *record) {
259
260 sensorRES_t *pRec = (sensorRES_t *) record;
Chris Austen0012e9b2015-10-22 01:37:46 -0500261 uint8_t stype;
Chris Austen8a45e7c2015-10-15 00:31:46 -0500262 int index, i=0;
Chris Austen8a45e7c2015-10-15 00:31:46 -0500263
Emily Shaffer391f3302017-04-03 10:27:08 -0700264 stype = find_type_for_sensor_number(pRec->sensor_number);
Chris Austen0012e9b2015-10-22 01:37:46 -0500265
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++) {
Chris Austend7cf0e42015-11-07 14:27:12 -0600278
Chris Austen0012e9b2015-10-22 01:37:46 -0500279 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 }
Chris Austen8a45e7c2015-10-15 00:31:46 -0500299 }
Chris Austen0012e9b2015-10-22 01:37:46 -0500300
Chris Austen8a45e7c2015-10-15 00:31:46 -0500301 }
302
Chris Austen0012e9b2015-10-22 01:37:46 -0500303
Chris Austen8a45e7c2015-10-15 00:31:46 -0500304 return 0;
305}