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