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