xref: /openbmc/phosphor-host-ipmid/ipmisensor.cpp (revision d5b2ac0e5d5decac55e7ed4be989e3d57a45c35e)
198a23840SMatthew Barth #include <stdio.h>
298a23840SMatthew Barth #include <string.h>
398a23840SMatthew Barth #include <stdint.h>
498a23840SMatthew Barth #include <malloc.h>
598a23840SMatthew Barth #include "sensorhandler.h"
698a23840SMatthew Barth 
798a23840SMatthew Barth extern uint8_t find_sensor(uint8_t);
898a23840SMatthew Barth 
998a23840SMatthew Barth 
1098a23840SMatthew Barth struct sensorRES_t {
1198a23840SMatthew Barth 	uint8_t sensor_number;
1298a23840SMatthew Barth 	uint8_t operation;
1398a23840SMatthew Barth 	uint8_t sensor_reading;
1498a23840SMatthew Barth 	uint8_t assert_state7_0;
1598a23840SMatthew Barth 	uint8_t assert_state14_8;
1698a23840SMatthew Barth 	uint8_t deassert_state7_0;
1798a23840SMatthew Barth 	uint8_t deassert_state14_8;
1898a23840SMatthew Barth 	uint8_t event_data1;
1998a23840SMatthew Barth 	uint8_t event_data2;
2098a23840SMatthew Barth 	uint8_t event_data3;
2198a23840SMatthew Barth } __attribute__ ((packed));
2298a23840SMatthew Barth 
2398a23840SMatthew Barth #define ISBITSET(x,y) (((x)>>(y))&0x01)
2498a23840SMatthew Barth #define ASSERTINDEX 0
2598a23840SMatthew Barth #define DEASSERTINDEX 1
2698a23840SMatthew Barth 
2798a23840SMatthew Barth // Sensor Type,  Offset, function handler, Dbus Method, Assert value, Deassert value
2898a23840SMatthew Barth struct lookup_t {
2998a23840SMatthew Barth 	uint8_t sensor_type;
3098a23840SMatthew Barth 	uint8_t offset;
3198a23840SMatthew Barth 	int (*func)(const sensorRES_t *, const lookup_t *, const char *);
3298a23840SMatthew Barth 	char    member[16];
3398a23840SMatthew Barth 	char    assertion[64];
3498a23840SMatthew Barth 	char    deassertion[64];
3598a23840SMatthew Barth };
3698a23840SMatthew Barth 
3798a23840SMatthew Barth extern int updateDbusInterface(uint8_t , const char *, const char *);
3898a23840SMatthew Barth 
3998a23840SMatthew Barth int set_sensor_dbus_state_simple(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
4098a23840SMatthew Barth 
4198a23840SMatthew Barth 	return set_sensor_dbus_state_s(pRec->sensor_number,
4298a23840SMatthew Barth                                    pTable->member,
4398a23840SMatthew Barth                                    value);
4498a23840SMatthew Barth }
4598a23840SMatthew Barth 
4698a23840SMatthew Barth struct event_data_t {
4798a23840SMatthew Barth 	uint8_t data;
4898a23840SMatthew Barth 	char    text[64];
4998a23840SMatthew Barth };
5098a23840SMatthew Barth 
5198a23840SMatthew Barth event_data_t g_fwprogress02h[] = {
5298a23840SMatthew Barth 	{0x00, "Unspecified"},
5398a23840SMatthew Barth 	{0x01, "Memory Init"},
5498a23840SMatthew Barth 	{0x02, "HD Init"},
5598a23840SMatthew Barth 	{0x03, "Secondary Proc Init"},
5698a23840SMatthew Barth 	{0x04, "User Authentication"},
5798a23840SMatthew Barth 	{0x05, "User init system setup"},
5898a23840SMatthew Barth 	{0x06, "USB configuration"},
5998a23840SMatthew Barth 	{0x07, "PCI configuration"},
6098a23840SMatthew Barth 	{0x08, "Option ROM Init"},
6198a23840SMatthew Barth 	{0x09, "Video Init"},
6298a23840SMatthew Barth 	{0x0A, "Cache Init"},
6398a23840SMatthew Barth 	{0x0B, "SM Bus init"},
6498a23840SMatthew Barth 	{0x0C, "Keyboard Init"},
6598a23840SMatthew Barth 	{0x0D, "Embedded ctrl init"},
6698a23840SMatthew Barth 	{0x0E, "Docking station attachment"},
6798a23840SMatthew Barth 	{0x0F, "Enable docking station"},
6898a23840SMatthew Barth 	{0x10, "Docking station ejection"},
6998a23840SMatthew Barth 	{0x11, "Disabling docking station"},
7098a23840SMatthew Barth 	{0x12, "Calling OS Wakeup"},
7198a23840SMatthew Barth 	{0x13, "Starting OS"},
7298a23840SMatthew Barth 	{0x14, "Baseboard Init"},
7398a23840SMatthew Barth 	{0x15, ""},
7498a23840SMatthew Barth 	{0x16, "Floppy Init"},
7598a23840SMatthew Barth 	{0x17, "Keyboard Test"},
7698a23840SMatthew Barth 	{0x18, "Pointing Device Test"},
7798a23840SMatthew Barth 	{0x19, "Primary Proc Init"},
7898a23840SMatthew Barth 	{0xFF, "Unknown"}
7998a23840SMatthew Barth };
8098a23840SMatthew Barth 
8198a23840SMatthew Barth event_data_t g_fwprogress00h[] = {
8298a23840SMatthew Barth 	{0x00, "Unspecified."},
8398a23840SMatthew Barth 	{0x01, "No system memory detected"},
8498a23840SMatthew Barth 	{0x02, "No usable system memory"},
8598a23840SMatthew Barth 	{0x03, "Unrecoverable hard-disk/ATAPI/IDE"},
8698a23840SMatthew Barth 	{0x04, "Unrecoverable system-board"},
8798a23840SMatthew Barth 	{0x05, "Unrecoverable diskette"},
8898a23840SMatthew Barth 	{0x06, "Unrecoverable hard-disk controller"},
8998a23840SMatthew Barth 	{0x07, "Unrecoverable PS/2 or USB keyboard"},
9098a23840SMatthew Barth 	{0x08, "Removable boot media not found"},
9198a23840SMatthew Barth 	{0x09, "Unrecoverable video controller"},
9298a23840SMatthew Barth 	{0x0A, "No video device detected"},
9398a23840SMatthew Barth 	{0x0B, "Firmware ROM corruption detected"},
9498a23840SMatthew Barth 	{0x0C, "CPU voltage mismatch"},
9598a23840SMatthew Barth 	{0x0D, "CPU speed matching"},
9698a23840SMatthew Barth 	{0xFF, "unknown"},
9798a23840SMatthew Barth };
9898a23840SMatthew Barth 
9998a23840SMatthew Barth 
10098a23840SMatthew Barth char *event_data_lookup(event_data_t *p, uint8_t b) {
10198a23840SMatthew Barth 
10298a23840SMatthew Barth 	while(p->data != 0xFF) {
10398a23840SMatthew Barth 		if (p->data == b) {
10498a23840SMatthew Barth 			break;
10598a23840SMatthew Barth 		}
10698a23840SMatthew Barth 		p++;
10798a23840SMatthew Barth 	}
10898a23840SMatthew Barth 
10998a23840SMatthew Barth 	return p->text;
11098a23840SMatthew Barth }
11198a23840SMatthew Barth 
11298a23840SMatthew Barth 
11398a23840SMatthew Barth 
11498a23840SMatthew Barth //  The fw progress sensor contains some additional information that needs to be processed
11598a23840SMatthew Barth //  prior to calling the dbus code.
11698a23840SMatthew Barth int set_sensor_dbus_state_fwprogress(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
11798a23840SMatthew Barth 
11898a23840SMatthew Barth 	char valuestring[128];
11998a23840SMatthew Barth 	char* p = valuestring;
12098a23840SMatthew Barth 
12198a23840SMatthew Barth 	switch (pTable->offset) {
12298a23840SMatthew Barth 
12398a23840SMatthew Barth 		case 0x00 : snprintf(p, sizeof(valuestring), "POST Error, %s", event_data_lookup(g_fwprogress00h, pRec->event_data2));
12498a23840SMatthew Barth 					break;
12598a23840SMatthew Barth 		case 0x01 : /* Using g_fwprogress02h for 0x01 because thats what the ipmi spec says to do */
12698a23840SMatthew Barth 					snprintf(p, sizeof(valuestring), "FW Hang, %s", event_data_lookup(g_fwprogress02h, pRec->event_data2));
12798a23840SMatthew Barth 					break;
12898a23840SMatthew Barth 		case 0x02 : snprintf(p, sizeof(valuestring), "FW Progress, %s", event_data_lookup(g_fwprogress02h, pRec->event_data2));
12998a23840SMatthew Barth 					break;
13098a23840SMatthew Barth 		default : snprintf(p, sizeof(valuestring), "Internal warning, fw_progres offset unknown (0x%02x)", pTable->offset);
13198a23840SMatthew Barth 					break;
13298a23840SMatthew Barth 	}
13398a23840SMatthew Barth 
13498a23840SMatthew Barth 	return set_sensor_dbus_state_s(pRec->sensor_number,
13598a23840SMatthew Barth                                    pTable->member,
13698a23840SMatthew Barth                                    p);
13798a23840SMatthew Barth }
13898a23840SMatthew Barth 
13998a23840SMatthew Barth // Handling this special OEM sensor by coping what is in byte 4.  I also think that is odd
14098a23840SMatthew Barth // considering byte 3 is for sensor reading.  This seems like a misuse of the IPMI spec
14198a23840SMatthew Barth int set_sensor_dbus_state_osbootcount(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
14298a23840SMatthew Barth 	return set_sensor_dbus_state_y(pRec->sensor_number,
14398a23840SMatthew Barth                                    "setValue",
14498a23840SMatthew Barth                                    pRec->assert_state7_0);
14598a23840SMatthew Barth }
14698a23840SMatthew Barth 
14798a23840SMatthew Barth int set_sensor_dbus_state_system_event(const sensorRES_t *pRec, const lookup_t *pTable, const char *value) {
14898a23840SMatthew Barth 	char valuestring[128];
14998a23840SMatthew Barth 	char* p = valuestring;
15098a23840SMatthew Barth 
15198a23840SMatthew Barth 	switch (pTable->offset) {
15298a23840SMatthew Barth 
15398a23840SMatthew Barth 		case 0x00 : snprintf(p, sizeof(valuestring), "System Reconfigured");
15498a23840SMatthew Barth 					break;
15598a23840SMatthew Barth 		case 0x01 : snprintf(p, sizeof(valuestring), "OEM Boot Event");
15698a23840SMatthew Barth 					break;
15798a23840SMatthew Barth 		case 0x02 : snprintf(p, sizeof(valuestring), "Undetermine System Hardware Failure");
15898a23840SMatthew Barth 					break;
15998a23840SMatthew Barth 		case 0x03 : snprintf(p, sizeof(valuestring), "System Failure see error log for more details (0x%02x)", pRec->event_data2);
16098a23840SMatthew Barth 					break;
16198a23840SMatthew Barth 		case 0x04 : snprintf(p, sizeof(valuestring), "System Failure see PEF error log for more details (0x%02x)", pRec->event_data2);
16298a23840SMatthew Barth 					break;
16398a23840SMatthew Barth 		default : snprintf(p, sizeof(valuestring), "Internal warning, system_event offset unknown (0x%02x)", pTable->offset);
16498a23840SMatthew Barth 					break;
16598a23840SMatthew Barth 	}
16698a23840SMatthew Barth 
16798a23840SMatthew Barth 	return set_sensor_dbus_state_s(pRec->sensor_number,
16898a23840SMatthew Barth                                    pTable->member,
16998a23840SMatthew Barth                                    p);
17098a23840SMatthew Barth }
17198a23840SMatthew Barth 
17298a23840SMatthew Barth 
17398a23840SMatthew Barth //  This table lists only senors we care about telling dbus about.
17498a23840SMatthew Barth //  Offset definition cab be found in section 42.2 of the IPMI 2.0
17598a23840SMatthew Barth //  spec.  Add more if/when there are more items of interest.
17698a23840SMatthew Barth lookup_t g_ipmidbuslookup[] = {
17798a23840SMatthew Barth 
17898a23840SMatthew Barth 	{0xe9, 0x00, set_sensor_dbus_state_simple, "setValue", "Disabled", ""}, // OCC Inactive 0
17998a23840SMatthew Barth 	{0xe9, 0x01, set_sensor_dbus_state_simple, "setValue", "Enabled", ""},   // OCC Active 1
1800661beb1SJayanth Othayoth 	// Turbo Allowed
1810661beb1SJayanth Othayoth 	{0xda, 0x00, set_sensor_dbus_state_simple, "setValue", "False", ""},
182*d5b2ac0eSJayanth Othayoth 	// Power Supply Derating
183*d5b2ac0eSJayanth Othayoth 	{0xb4, 0x00, set_sensor_dbus_state_simple, "setValue", "", ""},
18498a23840SMatthew Barth 	{0x07, 0x07, set_sensor_dbus_state_simple, "setPresent", "True", "False"},
18598a23840SMatthew Barth 	{0x07, 0x08, set_sensor_dbus_state_simple, "setFault",   "True", "False"},
18698a23840SMatthew Barth 	{0x0C, 0x06, set_sensor_dbus_state_simple, "setPresent", "True", "False"},
18798a23840SMatthew Barth 	{0x0C, 0x04, set_sensor_dbus_state_simple, "setFault",   "True", "False"},
18898a23840SMatthew Barth 	{0x0F, 0x02, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
18998a23840SMatthew Barth 	{0x0F, 0x01, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
19098a23840SMatthew Barth 	{0x0F, 0x00, set_sensor_dbus_state_fwprogress, "setValue", "True", "False"},
19198a23840SMatthew Barth 	{0xC7, 0x01, set_sensor_dbus_state_simple, "setFault", "True", "False"},
19298a23840SMatthew Barth 	{0xc3, 0x00, set_sensor_dbus_state_osbootcount, "setValue", "" ,""},
19398a23840SMatthew Barth 	{0x1F, 0x00, set_sensor_dbus_state_simple, "setValue", "Boot completed (00)", ""},
19498a23840SMatthew Barth 	{0x1F, 0x01, set_sensor_dbus_state_simple, "setValue", "Boot completed (01)", ""},
19598a23840SMatthew Barth 	{0x1F, 0x02, set_sensor_dbus_state_simple, "setValue", "PXE boot completed", ""},
19698a23840SMatthew Barth 	{0x1F, 0x03, set_sensor_dbus_state_simple, "setValue", "Diagnostic boot completed", ""},
19798a23840SMatthew Barth 	{0x1F, 0x04, set_sensor_dbus_state_simple, "setValue", "CD-ROM boot completed", ""},
19898a23840SMatthew Barth 	{0x1F, 0x05, set_sensor_dbus_state_simple, "setValue", "ROM boot completed", ""},
19998a23840SMatthew Barth 	{0x1F, 0x06, set_sensor_dbus_state_simple, "setValue", "Boot completed (06)", ""},
20098a23840SMatthew Barth 	{0x12, 0x00, set_sensor_dbus_state_system_event, "setValue", "", ""},
20198a23840SMatthew Barth 	{0x12, 0x01, set_sensor_dbus_state_system_event, "setValue", "", ""},
20298a23840SMatthew Barth 	{0x12, 0x02, set_sensor_dbus_state_system_event, "setValue", "", ""},
20398a23840SMatthew Barth 	{0x12, 0x03, set_sensor_dbus_state_system_event, "setValue", "", ""},
20498a23840SMatthew Barth 	{0x12, 0x04, set_sensor_dbus_state_system_event, "setValue", "", ""},
20507248298SDhruvaraj S 	{0xD8, 0x00, set_sensor_dbus_state_simple,       "setValue", "Disabled", ""},
20698a23840SMatthew Barth 	{0xFF, 0xFF, NULL, "", "", ""}
20798a23840SMatthew Barth };
20898a23840SMatthew Barth 
20998a23840SMatthew Barth 
21098a23840SMatthew Barth void reportSensorEventAssert(sensorRES_t *pRec, int index) {
21198a23840SMatthew Barth 	lookup_t *pTable = &g_ipmidbuslookup[index];
21298a23840SMatthew Barth 	(*pTable->func)(pRec, pTable, pTable->assertion);
21398a23840SMatthew Barth }
21498a23840SMatthew Barth void reportSensorEventDeassert(sensorRES_t *pRec, int index) {
21598a23840SMatthew Barth 	lookup_t *pTable = &g_ipmidbuslookup[index];
21698a23840SMatthew Barth 	(*pTable->func)(pRec, pTable, pTable->deassertion);
21798a23840SMatthew Barth }
21898a23840SMatthew Barth 
21998a23840SMatthew Barth 
22098a23840SMatthew Barth int findindex(const uint8_t sensor_type, int offset, int *index) {
22198a23840SMatthew Barth 
22298a23840SMatthew Barth 	int i=0, rc=0;
22398a23840SMatthew Barth 	lookup_t *pTable = g_ipmidbuslookup;
22498a23840SMatthew Barth 
22598a23840SMatthew Barth 	do {
22698a23840SMatthew Barth 		if ( ((pTable+i)->sensor_type == sensor_type) &&
22798a23840SMatthew Barth 			 ((pTable+i)->offset  == offset) ) {
22898a23840SMatthew Barth 			rc = 1;
22998a23840SMatthew Barth 			*index = i;
23098a23840SMatthew Barth 			break;
23198a23840SMatthew Barth 		}
23298a23840SMatthew Barth 		i++;
23398a23840SMatthew Barth 	} while ((pTable+i)->sensor_type  != 0xFF);
23498a23840SMatthew Barth 
23598a23840SMatthew Barth 	return rc;
23698a23840SMatthew Barth }
23798a23840SMatthew Barth 
23898a23840SMatthew Barth void debug_print_ok_to_dont_care(uint8_t stype, int offset)
23998a23840SMatthew Barth {
24098a23840SMatthew Barth 	printf("LOOKATME: Sensor should not be reported:  Type 0x%02x, Offset 0x%02x\n",
24198a23840SMatthew Barth 		stype, offset);
24298a23840SMatthew Barth }
24398a23840SMatthew Barth 
24498a23840SMatthew Barth bool shouldReport(uint8_t sensorType, int offset, int *index) {
24598a23840SMatthew Barth 
24698a23840SMatthew Barth 	bool rc = false;
24798a23840SMatthew Barth 
24898a23840SMatthew Barth 	if (findindex(sensorType, offset, index)) { rc = true;	}
24998a23840SMatthew Barth 
25098a23840SMatthew Barth 	if (rc==false) { debug_print_ok_to_dont_care(sensorType, offset); }
25198a23840SMatthew Barth 
25298a23840SMatthew Barth 	return rc;
25398a23840SMatthew Barth }
25498a23840SMatthew Barth 
25598a23840SMatthew Barth 
25698a23840SMatthew Barth int updateSensorRecordFromSSRAESC(const void *record) {
25798a23840SMatthew Barth 
25898a23840SMatthew Barth 	sensorRES_t *pRec = (sensorRES_t *) record;
25998a23840SMatthew Barth 	uint8_t stype;
26098a23840SMatthew Barth 	int index, i=0;
26198a23840SMatthew Barth 
26298a23840SMatthew Barth 	stype = find_sensor(pRec->sensor_number);
26398a23840SMatthew Barth 
26498a23840SMatthew Barth 	// 0xC3 types use the assertion7_0 for the value to be set
26598a23840SMatthew Barth 	// so skip the reseach and call the correct event reporting
26698a23840SMatthew Barth 	// function
26798a23840SMatthew Barth 	if (stype == 0xC3) {
26898a23840SMatthew Barth 
26998a23840SMatthew Barth 		shouldReport(stype, 0x00, &index);
27098a23840SMatthew Barth 		reportSensorEventAssert(pRec, index);
27198a23840SMatthew Barth 
27298a23840SMatthew Barth 	} else {
27398a23840SMatthew Barth 		// Scroll through each bit position .  Determine
27498a23840SMatthew Barth 		// if any bit is either asserted or Deasserted.
27598a23840SMatthew Barth 		for(i=0;i<8;i++) {
27698a23840SMatthew Barth 
27798a23840SMatthew Barth 			if ((ISBITSET(pRec->assert_state7_0,i))  &&
27898a23840SMatthew Barth 				(shouldReport(stype, i, &index)))
27998a23840SMatthew Barth 			{
28098a23840SMatthew Barth 				reportSensorEventAssert(pRec, index);
28198a23840SMatthew Barth 			}
28298a23840SMatthew Barth 			if ((ISBITSET(pRec->assert_state14_8,i))  &&
28398a23840SMatthew Barth 				(shouldReport(stype, i+8, &index)))
28498a23840SMatthew Barth 			{
28598a23840SMatthew Barth 				reportSensorEventAssert(pRec, index);
28698a23840SMatthew Barth 			}
28798a23840SMatthew Barth 			if ((ISBITSET(pRec->deassert_state7_0,i))  &&
28898a23840SMatthew Barth 				(shouldReport(stype, i, &index)))
28998a23840SMatthew Barth 			{
29098a23840SMatthew Barth 				reportSensorEventDeassert(pRec, index);
29198a23840SMatthew Barth 			}
29298a23840SMatthew Barth 			if ((ISBITSET(pRec->deassert_state14_8,i))  &&
29398a23840SMatthew Barth 				(shouldReport(stype, i+8, &index)))
29498a23840SMatthew Barth 			{
29598a23840SMatthew Barth 				reportSensorEventDeassert(pRec, index);
29698a23840SMatthew Barth 			}
29798a23840SMatthew Barth 		}
29898a23840SMatthew Barth 
29998a23840SMatthew Barth 	}
30098a23840SMatthew Barth 
30198a23840SMatthew Barth 
30298a23840SMatthew Barth 	return 0;
30398a23840SMatthew Barth }
304