diff options
author | Tian Fang <tfang@fb.com> | 2015-12-14 22:08:40 -0800 |
---|---|---|
committer | Tian Fang <tfang@fb.com> | 2015-12-15 09:49:21 -0800 |
commit | e65a7944211c70f6b5cfb6cedd73cc31105319de (patch) | |
tree | 067082251bc52bc6c09ca87feaa1352d0468a5ac /meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files | |
parent | 8a67fbdd0e251bb34d55992b0771edba1837d589 (diff) | |
download | ast2050-yocto-openbmc-e65a7944211c70f6b5cfb6cedd73cc31105319de.zip ast2050-yocto-openbmc-e65a7944211c70f6b5cfb6cedd73cc31105319de.tar.gz |
Sync to internal OpenBMC repo f926614
Diffstat (limited to 'meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files')
14 files changed, 1799 insertions, 351 deletions
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.c b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.c index 55cd56b..4139b44 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.c +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.c @@ -22,10 +22,15 @@ #include <stdio.h> #include <stdint.h> #include <fcntl.h> +#include <syslog.h> #include "bic.h" #define FRUID_READ_COUNT_MAX 0x30 +#define FRUID_WRITE_COUNT_MAX 0x30 +#define CPLD_WRITE_COUNT_MAX 0x50 #define SDR_READ_COUNT_MAX 0x1A +#define SIZE_SYS_GUID 16 +#define SIZE_IANA_ID 3 enum { IPMB_BUS_SLOT1 = 3, @@ -87,7 +92,9 @@ bic_ipmb_wrapper(uint8_t slot_id, uint8_t netfn, uint8_t cmd, ret = get_ipmb_bus_id(slot_id); if (ret < 0) { - printf("bic_ipmb_wrapper: Wrong Slot ID %d\n", slot_id); +#ifdef DEBUG + syslog(LOG_ERR, "bic_ipmb_wrapper: Wrong Slot ID %d\n", slot_id); +#endif return ret; } @@ -114,8 +121,11 @@ bic_ipmb_wrapper(uint8_t slot_id, uint8_t netfn, uint8_t cmd, // Invoke IPMB library handler lib_ipmb_handle(bus_id, tbuf, tlen, &rbuf, &rlen); + if (rlen == 0) { - printf("bic_ipmb_wrapper: Zero bytes received\n"); +#ifdef DEBUG + syslog(LOG_DEBUG, "bic_ipmb_wrapper: Zero bytes received\n"); +#endif return -1; } @@ -123,7 +133,9 @@ bic_ipmb_wrapper(uint8_t slot_id, uint8_t netfn, uint8_t cmd, res = (ipmb_res_t*) rbuf; if (res->cc) { - printf("bic_ipmb_wrapper: Completion Code: 0x%X\n", res->cc); +#ifdef DEBUG + syslog(LOG_ERR, "bic_ipmb_wrapper: Completion Code: 0x%X\n", res->cc); +#endif return -1; } @@ -148,17 +160,23 @@ bic_get_dev_id(uint8_t slot_id, ipmi_dev_id_t *dev_id) { // Get GPIO value and configuration int bic_get_gpio(uint8_t slot_id, bic_gpio_t *gpio) { + uint8_t tbuf[3] = {0x15, 0xA0, 0x00}; // IANA ID + uint8_t rbuf[7] = {0x00}; uint8_t rlen = 0; int ret; - ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_GPIO, NULL, 0, (uint8_t*) gpio, &rlen); + ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_GPIO, tbuf, 0x03, rbuf, &rlen); + + // Ignore first 3 bytes of IANA ID + memcpy((uint8_t*) gpio, &rbuf[3], 4); return ret; } int bic_get_gpio_config(uint8_t slot_id, uint8_t gpio, bic_gpio_config_t *gpio_config) { - uint8_t tbuf[4] = {0}; + uint8_t tbuf[7] = {0x15, 0xA0, 0x00}; // IANA ID + uint8_t rbuf[4] = {0x00}; uint8_t rlen = 0; uint8_t tlen = 0; uint32_t pin; @@ -166,75 +184,245 @@ bic_get_gpio_config(uint8_t slot_id, uint8_t gpio, bic_gpio_config_t *gpio_confi pin = 1 << gpio; - tbuf[0] = pin & 0xFF; - tbuf[1] = (pin >> 8) & 0xFF; - tbuf[2] = (pin >> 16) & 0xFF; - tbuf[3] = (pin >> 24) & 0xFF; + tbuf[3] = pin & 0xFF; + tbuf[4] = (pin >> 8) & 0xFF; + tbuf[5] = (pin >> 16) & 0xFF; + tbuf[6] = (pin >> 24) & 0xFF; - tlen = 4; + tlen = 7; - ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_GPIO_CONFIG, tbuf, tlen, (uint8_t *) gpio_config, &rlen); + ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_GPIO_CONFIG, tbuf, tlen, rbuf, &rlen); + + // Ignore IANA ID + *(uint8_t *) gpio_config = rbuf[3]; return ret; } int bic_set_gpio_config(uint8_t slot_id, uint8_t gpio, bic_gpio_config_t *gpio_config) { - uint8_t tbuf[5] = {0}; + uint8_t tbuf[8] = {0x15, 0xA0, 0x00}; // IANA ID + uint8_t rbuf[4] = {0x00}; uint8_t rlen = 0; uint8_t tlen = 0; uint32_t pin; - uint8_t res; int ret; pin = 1 << gpio; - tbuf[0] = pin & 0xFF; - tbuf[1] = (pin >> 8) & 0xFF; - tbuf[2] = (pin >> 16) & 0xFF; - tbuf[3] = (pin >> 24) & 0xFF; - tbuf[4] = (*(uint8_t *) gpio_config) & 0x1F; + tbuf[3] = pin & 0xFF; + tbuf[4] = (pin >> 8) & 0xFF; + tbuf[5] = (pin >> 16) & 0xFF; + tbuf[6] = (pin >> 24) & 0xFF; + tbuf[7] = (*(uint8_t *) gpio_config) & 0x1F; - tlen = 5; + tlen = 8; ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_SET_GPIO_CONFIG, - tbuf, tlen, &res, &rlen); + tbuf, tlen, rbuf, &rlen); return ret; } // Get BIC Configuration int bic_get_config(uint8_t slot_id, bic_config_t *cfg) { + uint8_t tbuf[3] = {0x15, 0xA0, 0x00}; // IANA ID + uint8_t rbuf[4] = {0x00}; uint8_t rlen = 0; int ret; ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_CONFIG, - NULL, 0x00, (uint8_t *) cfg, &rlen); + tbuf, 0x03, rbuf, &rlen); + // Ignore IANA ID + *(uint8_t *) cfg = rbuf[3]; + return ret; } // Set BIC Configuration int bic_set_config(uint8_t slot_id, bic_config_t *cfg) { + uint8_t tbuf[4] = {0x15, 0xA0, 0x00}; // IANA ID uint8_t rlen = 0; uint8_t rbuf[4] = {0}; int ret; + tbuf[3] = *(uint8_t *) cfg; + ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_SET_CONFIG, - (uint8_t *) cfg, 1, rbuf, &rlen); + tbuf, 0x04, rbuf, &rlen); return ret; } // Read POST Buffer int bic_get_post_buf(uint8_t slot_id, uint8_t *buf, uint8_t *len) { + uint8_t tbuf[3] = {0x15, 0xA0, 0x00}; // IANA ID + uint8_t rbuf[255] = {0x00}; + uint8_t rlen = 0; + int ret; + + ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_POST_BUF, tbuf, 0x03, rbuf, &rlen); + + //Ignore IANA ID + memcpy(buf, &rbuf[3], rlen-3); + + *len = rlen - 3; + + return ret; +} + +// Read Firwmare Versions of various components +int +bic_get_fw_ver(uint8_t slot_id, uint8_t comp, uint8_t *ver) { + uint8_t tbuf[4] = {0x15, 0xA0, 0x00}; // IANA ID + uint8_t rbuf[16] = {0x00}; + uint8_t rlen = 0; int ret; - ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_POST_BUF, NULL, 0, buf, len); + // Fill the component for which firmware is requested + tbuf[3] = comp; + + ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_FW_VER, tbuf, 0x04, rbuf, &rlen); + // fw version has to be between 2 and 5 bytes based on component + if (ret || (rlen < 2+SIZE_IANA_ID) || (rlen > 5+SIZE_IANA_ID)) { +#ifdef DEBUG + syslog(LOG_ERR, "bic_get_fw_ver: ret: %d, rlen: %d\n", ret, rlen); +#endif + return -1; + } + + //Ignore IANA ID + memcpy(ver, &rbuf[3], rlen-3); return ret; } +// Update firmware for various components +static int +_update_fw(uint8_t slot_id, uint8_t target, uint32_t offset, uint16_t len, uint8_t *buf) { + uint8_t tbuf[256] = {0x15, 0xA0, 0x00}; // IANA ID + uint8_t rbuf[16] = {0x00}; + uint8_t tlen = 0; + uint8_t rlen = 0; + int ret; + int retries = 3; + + // Fill the component for which firmware is requested + tbuf[3] = target; + + tbuf[4] = (offset) & 0xFF; + tbuf[5] = (offset >> 8) & 0xFF; + tbuf[6] = (offset >> 16) & 0xFF; + tbuf[7] = (offset >> 24) & 0xFF; + + tbuf[8] = len & 0xFF; + tbuf[9] = (len >> 8) & 0xFF; + + memcpy(&tbuf[10], buf, len); + + printf("_update_fw: target: %d, offset: %d, len: %d\n", target, offset, len); + + tlen = len + 10; + +bic_send: + ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_UPDATE_FW, tbuf, tlen, rbuf, &rlen); + if ((ret) && (retries--)) { + sleep(1); + printf("_update_fw: retrying..\n"); + goto bic_send; + } + + return ret; +} + +int +bic_update_fw(uint8_t slot_id, uint8_t comp, char *path) { + int ret; + uint32_t offset; + uint16_t count; + uint8_t buf[256] = {0}; + uint8_t len = 0; + uint8_t target; + int fd; + + // Open the file exclusively for read + fd = open(path, O_RDONLY, 0666); + if (fd < 0) { +#ifdef DEBUG + syslog(LOG_ERR, "bic_update_fw: open fails for path: %s\n", path); +#endif + goto error_exit; + } + + // Write chunks of CPLD binary data in a loop + offset = 0; + while (1) { + // Read from file + count = read(fd, buf, CPLD_WRITE_COUNT_MAX); + if (count <= 0) { + break; + } + + if (count == CPLD_WRITE_COUNT_MAX) { + target = comp; + } else { + target = comp | 0x80; + } + + // Write to the CPLD + ret = _update_fw(slot_id, target, offset, count, buf); + if (ret) { + break; + } + + // Update counter + offset += count; + } + +error_exit: + if (fd > 0 ) { + close(fd); + } + + return ret; +} + +int +bic_me_xmit(uint8_t slot_id, uint8_t *txbuf, uint8_t txlen, uint8_t *rxbuf, uint8_t *rxlen) { + uint8_t tbuf[256] = {0x15, 0xA0, 0x00}; // IANA ID + uint8_t rbuf[256] = {0x00}; + uint8_t rlen = 0; + uint8_t tlen = 0; + int ret; + + // Fill the interface number as ME + tbuf[3] = BIC_INTF_ME; + + // Fill the data to be sent + memcpy(&tbuf[4], txbuf, txlen); + + // Send data length includes IANA ID and interface number + tlen = txlen + 4; + + ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_MSG_OUT, tbuf, tlen, rbuf, &rlen); + if (ret ) { + return -1; + } + + // Make sure the received interface number is same + if (rbuf[3] != tbuf[3]) { + return -1; + } + + // Copy the received data to caller skipping header + memcpy(rxbuf, &rbuf[7], rlen-7); + + *rxlen = rlen-7; + + return 0; +} + // Read 1S server's FRUID int bic_get_fruid_info(uint8_t slot_id, uint8_t fru_id, ipmi_fruid_info_t *info) { @@ -279,19 +467,23 @@ bic_read_fruid(uint8_t slot_id, uint8_t fru_id, const char *path) { // Open the file exclusively for write fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0666); if (fd < 0) { - printf("bic_read_fruid: open fails for path: %s\n", path); +#ifdef DEBUG + syslog(LOG_ERR, "bic_read_fruid: open fails for path: %s\n", path); +#endif goto error_exit; } // Read the FRUID information ret = bic_get_fruid_info(slot_id, fru_id, &info); if (ret) { - printf("bic_read_fruid: bic_read_fruid_info returns %d\n", ret); +#ifdef DEBUG + syslog(LOG_ERR, "bic_read_fruid: bic_read_fruid_info returns %d\n", ret); +#endif goto error_exit; } // Indicates the size of the FRUID - nread = (info.size_msb << 8) + (info.size_lsb); + nread = (info.size_msb << 6) + (info.size_lsb); // Read chunks of FRUID binary data in a loop offset = 0; @@ -304,7 +496,9 @@ bic_read_fruid(uint8_t slot_id, uint8_t fru_id, const char *path) { ret = _read_fruid(slot_id, fru_id, offset, count, rbuf, &rlen); if (ret) { - printf("bic_read_fruid: ipmb_wrapper fails\n"); +#ifdef DEBUG + syslog(LOG_ERR, "bic_read_fruid: ipmb_wrapper fails\n"); +#endif goto error_exit; } @@ -324,6 +518,79 @@ error_exit: return ret; } +static int +_write_fruid(uint8_t slot_id, uint8_t fru_id, uint32_t offset, uint8_t count, uint8_t *buf) { + int ret; + uint8_t tbuf[64] = {0}; + uint8_t rbuf[4] = {0}; + uint8_t tlen = 0; + uint8_t rlen = 0; + + tbuf[0] = fru_id; + tbuf[1] = offset & 0xFF; + tbuf[2] = (offset >> 8) & 0xFF; + + memcpy(&tbuf[3], buf, count); + tlen = count + 3; + + ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_WRITE_FRUID_DATA, tbuf, tlen, rbuf, &rlen); + + if (ret) { + return ret; + } + + if (rbuf[0] != count) { + return -1; + } + + return ret; +} + +int +bic_write_fruid(uint8_t slot_id, uint8_t fru_id, const char *path) { + int ret; + uint32_t offset; + uint8_t count; + uint8_t buf[64] = {0}; + uint8_t len = 0; + int fd; + + // Open the file exclusively for read + fd = open(path, O_RDONLY, 0666); + if (fd < 0) { +#ifdef DEBUG + syslog(LOG_ERR, "bic_write_fruid: open fails for path: %s\n", path); +#endif + goto error_exit; + } + + // Write chunks of FRUID binary data in a loop + offset = 0; + while (1) { + // Read from file + count = read(fd, buf, FRUID_WRITE_COUNT_MAX); + if (count <= 0) { + break; + } + + // Write to the FRUID + ret = _write_fruid(slot_id, fru_id, offset, count, buf); + if (ret) { + break; + } + + // Update counter + offset += count; + } + +error_exit: + if (fd > 0 ) { + close(fd); + } + + return ret; +} + // Read System Event Log (SEL) int bic_get_sel_info(uint8_t slot_id, ipmi_sel_sdr_info_t *info) { @@ -398,7 +665,9 @@ bic_get_sdr(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *res, u // Get SDR reservation ID for the given record ret = _get_sdr_rsv(slot_id, &req->rsv_id); if (ret) { - printf("bic_read_sdr: _get_sdr_rsv returns %d\n", ret); +#ifdef DEBUG + syslog(LOG_ERR, "bic_read_sdr: _get_sdr_rsv returns %d\n", ret); +#endif return ret; } @@ -411,7 +680,9 @@ bic_get_sdr(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *res, u ret = _get_sdr(slot_id, req, tbuf, &tlen); if (ret) { - printf("bic_read_sdr: _get_sdr returns %d\n", ret); +#ifdef DEBUG + syslog(LOG_ERR, "bic_read_sdr: _get_sdr returns %d\n", ret); +#endif return ret; } @@ -439,7 +710,9 @@ bic_get_sdr(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *res, u ret = _get_sdr(slot_id, req, tbuf, &tlen); if (ret) { - printf("bic_read_sdr: _get_sdr returns %d\n", ret); +#ifdef DEBUG + syslog(LOG_ERR, "bic_read_sdr: _get_sdr returns %d\n", ret); +#endif return ret; } @@ -464,3 +737,19 @@ bic_read_sensor(uint8_t slot_id, uint8_t sensor_num, ipmi_sensor_reading_t *sens return ret; } + +int +bic_get_sys_guid(uint8_t slot_id, uint8_t *guid) { + int ret; + int rlen = 0; + + ret = bic_ipmb_wrapper(slot_id, NETFN_APP_REQ, CMD_APP_GET_SYSTEM_GUID, NULL, 0, guid, &rlen); + if (rlen != SIZE_SYS_GUID) { +#ifdef DEBUG + syslog(LOG_ERR, "bic_get_sys_guid: returned rlen of %d\n"); +#endif + return -1; + } + + return ret; +} diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.h b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.h index 47b0baa..7110574 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.h +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.h @@ -66,6 +66,23 @@ enum { RESERVED_31, }; +enum { + FW_CPLD = 1, + FW_BIC, + FW_ME, + FW_PVCCIN_VR, + FW_DDRAB_VR, + FW_P1V05_VR, + FW_PVCCGBE_VR, + FW_PVCCSCSUS_VR, +}; + +enum { + UPDATE_BIOS = 0, + UPDATE_CPLD, + UPDATE_BIC_BOOT +}; + // Bridge IC Spec typedef struct _bic_gpio_t { uint32_t pwrgood_cpu:1; @@ -138,6 +155,7 @@ int bic_get_post_buf(uint8_t slot_id, uint8_t *buf, uint8_t *len); int bic_get_fruid_info(uint8_t slot_id, uint8_t fru_id, ipmi_fruid_info_t *info); int bic_read_fruid(uint8_t slot_id, uint8_t fru_id, const char *path); +int bic_write_fruid(uint8_t slot_id, uint8_t fru_id, const char *path); int bic_get_sel_info(uint8_t slot_id, ipmi_sel_sdr_info_t *info); int bic_get_sel_rsv(uint8_t slot_id, uint16_t *rsv); @@ -149,6 +167,13 @@ int bic_get_sdr(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *re int bic_read_sensor(uint8_t slot_id, uint8_t sensor_num, ipmi_sensor_reading_t *sensor); +int bic_get_sys_guid(uint8_t slot_id, uint8_t *guid); + +int bic_get_fw_ver(uint8_t slot_id, uint8_t comp, uint8_t *ver); + +int bic_update_fw(uint8_t slot_id, uint8_t comp, char *path); +int bic_me_xmit(uint8_t slot_id, uint8_t *txbuf, uint8_t txlen, uint8_t *rxbuf, uint8_t *rxlen); + #ifdef __cplusplus } // extern "C" #endif diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/Makefile index bab4007..c207a7d 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/Makefile +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/Makefile @@ -2,7 +2,7 @@ lib: libpal.so libpal.so: pal.c - $(CC) $(CFLAGS) -fPIC -c -o pal.o pal.c + $(CC) $(CFLAGS) -fPIC -c -pthread -o pal.o pal.c $(CC) -lbic -lyosemite_common -lyosemite_fruid -lyosemite_sensor -shared -o libpal.so pal.o -lc .PHONY: clean diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.c b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.c index 93a5fbf..ec0be12 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.c +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.c @@ -27,6 +27,7 @@ #include <syslog.h> #include <sys/mman.h> #include <string.h> +#include <pthread.h> #include "pal.h" #define BIT(value, index) ((value >> index) & 1) @@ -45,8 +46,11 @@ #define GPIO_RST_BTN 144 #define GPIO_PWR_BTN 24 +#define GPIO_HB_LED 135 + #define GPIO_USB_SW0 36 #define GPIO_USB_SW1 37 +#define GPIO_USB_MUX_EN_N 147 #define GPIO_UART_SEL0 32 #define GPIO_UART_SEL1 33 @@ -68,20 +72,27 @@ #define AST_SCU_BASE 0x1e6e2000 #define PIN_CTRL1_OFFSET 0x80 #define PIN_CTRL2_OFFSET 0x84 +#define AST_WDT_BASE 0x1e785000 +#define WDT_OFFSET 0x10 #define UART1_TXD (1 << 22) #define UART2_TXD (1 << 30) #define UART3_TXD (1 << 22) #define UART4_TXD (1 << 30) -#define BIT(v, i) ((v >> i) & 1) #define DELAY_GRACEFUL_SHUTDOWN 1 -#define DELAY_POWER_OFF 5 - -static uint8_t gpio_rst_btn[5] = { 0, 57, 56, 59, 58 }; -static uint8_t gpio_led[5] = { 0, 97, 96, 99, 98 }; -static uint8_t gpio_prsnt[5] = { 0, 61, 60, 63, 62 }; -static uint8_t gpio_power[5] = { 0, 27, 25, 31, 29 }; +#define DELAY_POWER_OFF 6 +#define DELAY_POWER_CYCLE 10 +#define DELAY_12V_CYCLE 5 + +#define CRASHDUMP_BIN "/usr/local/bin/dump.sh" +#define CRASHDUMP_FILE "/mnt/data/crashdump_" +const static uint8_t gpio_rst_btn[] = { 0, 57, 56, 59, 58 }; +const static uint8_t gpio_led[] = { 0, 97, 96, 99, 98 }; +const static uint8_t gpio_id_led[] = { 0, 41, 40, 43, 42 }; +const static uint8_t gpio_prsnt[] = { 0, 61, 60, 63, 62 }; +const static uint8_t gpio_power[] = { 0, 27, 25, 31, 29 }; +const static uint8_t gpio_12v[] = { 0, 117, 116, 119, 118 }; const char pal_fru_list[] = "all, slot1, slot2, slot3, slot4, spb, nic"; const char pal_server_list[] = "slot1, slot2, slot3, slot4"; @@ -90,6 +101,16 @@ char * key_list[] = { "pwr_server2_last_state", "pwr_server3_last_state", "pwr_server4_last_state", +"sysfw_ver_slot1", +"sysfw_ver_slot2", +"sysfw_ver_slot3", +"sysfw_ver_slot4", +"identify_sled", +"identify_slot1", +"identify_slot2", +"identify_slot3", +"identify_slot4", +"timestamp_sled", "slot1_por_cfg", "slot2_por_cfg", "slot3_por_cfg", @@ -98,6 +119,29 @@ char * key_list[] = { LAST_KEY /* This is the last key of the list */ }; +char * def_val_list[] = { + "on", /* pwr_server1_last_state */ + "on", /* pwr_server2_last_state */ + "on", /* pwr_server3_last_state */ + "on", /* pwr_server4_last_state */ + "0", /* sysfw_ver_slot1 */ + "0", /* sysfw_ver_slot2 */ + "0", /* sysfw_ver_slot3 */ + "0", /* sysfw_ver_slot4 */ + "off", /* identify_sled */ + "off", /* identify_slot1 */ + "off", /* identify_slot2 */ + "off", /* identify_slot3 */ + "off", /* identify_slot4 */ + "0", /* timestamp_sled */ + "on", /* slot1_por_cfg */ + "on", /* slot2_por_cfg */ + "on", /* slot3_por_cfg */ + "on", /* slot4_por_cfg */ + /* Add more def values for the correspoding keys*/ + LAST_KEY /* Same as last entry of the key_list */ +}; + // Helper Functions static int read_device(const char *device, int *value) { @@ -107,15 +151,18 @@ read_device(const char *device, int *value) { fp = fopen(device, "r"); if (!fp) { int err = errno; - +#ifdef DEBUG syslog(LOG_INFO, "failed to open device %s", device); +#endif return err; } rc = fscanf(fp, "%d", value); fclose(fp); if (rc != 1) { +#ifdef DEBUG syslog(LOG_INFO, "failed to read device %s", device); +#endif return ENOENT; } else { return 0; @@ -130,8 +177,9 @@ write_device(const char *device, const char *value) { fp = fopen(device, "w"); if (!fp) { int err = errno; - +#ifdef DEBUG syslog(LOG_INFO, "failed to open device for write %s", device); +#endif return err; } @@ -139,7 +187,9 @@ write_device(const char *device, const char *value) { fclose(fp); if (rc < 0) { +#ifdef DEBUG syslog(LOG_INFO, "failed to write device %s", device); +#endif return ENOENT; } else { return 0; @@ -204,6 +254,42 @@ server_power_off(uint8_t slot_id, bool gs_flag) { return 0; } +// Control 12V to the server in a given slot +static int +server_12v_on(uint8_t slot_id) { + char vpath[64] = {0}; + + if (slot_id < 1 || slot_id > 4) { + return -1; + } + + sprintf(vpath, GPIO_VAL, gpio_12v[slot_id]); + + if (write_device(vpath, "1")) { + return -1; + } + + return 0; +} + +// Turn off 12V for the server in given slot +static int +server_12v_off(uint8_t slot_id) { + char vpath[64] = {0}; + + if (slot_id < 1 || slot_id > 4) { + return -1; + } + + sprintf(vpath, GPIO_VAL, gpio_12v[slot_id]); + + if (write_device(vpath, "0")) { + return -1; + } + + return 0; +} + // Debug Card's UART and BMC/SoL port share UART port and need to enable only // one TXD i.e. either BMC's TXD or Debug Port's TXD. static int @@ -216,7 +302,9 @@ control_sol_txd(uint8_t slot) { scu_fd = open("/dev/mem", O_RDWR | O_SYNC ); if (scu_fd < 0) { - syslog(LOG_ALERT, "control_sol_txd: open fails\n"); +#ifdef DEBUG + syslog(LOG_WARNING, "control_sol_txd: open fails\n"); +#endif return -1; } @@ -295,7 +383,9 @@ pal_post_display(uint8_t status) { int ret; char *val; - syslog(LOG_ALERT, "pal_post_display: status is %d\n", status); +#ifdef DEBUG + syslog(LOG_WARNING, "pal_post_display: status is %d\n", status); +#endif sprintf(path, GPIO_VAL, GPIO_POSTCODE_0); @@ -396,7 +486,9 @@ pal_post_display(uint8_t status) { post_exit: if (ret) { - syslog(LOG_ALERT, "write_device failed for %s\n", path); +#ifdef DEBUG + syslog(LOG_WARNING, "write_device failed for %s\n", path); +#endif return -1; } else { return 0; @@ -453,11 +545,10 @@ pal_is_debug_card_prsnt(uint8_t *status) { return -1; } - // TODO: Logic is reversed until DVT board with h/w fix if (val == 0x0) { - *status = 0; - } else { *status = 1; + } else { + *status = 0; } return 0; @@ -466,11 +557,19 @@ pal_is_debug_card_prsnt(uint8_t *status) { int pal_get_server_power(uint8_t slot_id, uint8_t *status) { int ret; + char value[MAX_VALUE_LEN]; bic_gpio_t gpio; ret = bic_get_gpio(slot_id, &gpio); if (ret) { - return ret; + // Check for if the BIC is irresponsive due to 12V_OFF or 12V_CYCLE + pal_get_last_pwr_state(slot_id, value); + if (!(strcmp(value, "off"))) { + *status = SERVER_POWER_OFF; + return 0; + } else { + return ret; + } } if (gpio.pwrgood_cpu) { @@ -512,10 +611,18 @@ pal_set_server_power(uint8_t slot_id, uint8_t cmd) { break; case SERVER_POWER_CYCLE: - if (status == SERVER_POWER_ON) - return (server_power_off(slot_id, gs_flag) || server_power_on(slot_id)); - else if (status == SERVER_POWER_OFF) + if (status == SERVER_POWER_ON) { + if (server_power_off(slot_id, gs_flag)) + return -1; + + sleep(DELAY_POWER_CYCLE); + + return server_power_on(slot_id); + + } else if (status == SERVER_POWER_OFF) { + return (server_power_on(slot_id)); + } break; case SERVER_GRACEFUL_SHUTDOWN: @@ -525,6 +632,23 @@ pal_set_server_power(uint8_t slot_id, uint8_t cmd) { gs_flag = true; return server_power_off(slot_id, gs_flag); break; + + case SERVER_12V_ON: + return server_12v_on(slot_id); + break; + + case SERVER_12V_OFF: + return server_12v_off(slot_id); + break; + + case SERVER_12V_CYCLE: + if (server_12v_off(slot_id)) { + return -1; + } + + sleep(DELAY_12V_CYCLE); + + return (server_12v_on(slot_id)); default: return -1; } @@ -582,20 +706,20 @@ pal_get_hand_sw(uint8_t *pos) { loc = ((id8 << 3) | (id4 << 2) | (id2 << 1) | (id1)); switch(loc) { + case 0: + case 5: + *pos = HAND_SW_SERVER1; + break; case 1: case 6: - *pos = HAND_SW_SERVER1; + *pos = HAND_SW_SERVER2; break; case 2: case 7: - *pos = HAND_SW_SERVER2; + *pos = HAND_SW_SERVER3; break; case 3: case 8: - *pos = HAND_SW_SERVER3; - break; - case 4: - case 9: *pos = HAND_SW_SERVER4; break; default: @@ -657,9 +781,9 @@ pal_set_rst_btn(uint8_t slot, uint8_t status) { } if (status) { - val = "0"; - } else { val = "1"; + } else { + val = "0"; } sprintf(path, GPIO_VAL, gpio_rst_btn[slot]); @@ -694,6 +818,81 @@ pal_set_led(uint8_t slot, uint8_t status) { return 0; } +// Update Heartbeet LED +int +pal_set_hb_led(uint8_t status) { + char path[64] = {0}; + char *val; + + if (status) { + val = "1"; + } else { + val = "0"; + } + + sprintf(path, GPIO_VAL, GPIO_HB_LED); + if (write_device(path, val)) { + return -1; + } + + return 0; +} + +// Update the Identification LED for the given slot with the status +int +pal_set_id_led(uint8_t slot, uint8_t status) { + char path[64] = {0}; + char *val; + + if (slot < 1 || slot > 4) { + return -1; + } + + if (status) { + val = "1"; + } else { + val = "0"; + } + + sprintf(path, GPIO_VAL, gpio_id_led[slot]); + if (write_device(path, val)) { + return -1; + } + + return 0; +} + +static int +set_usb_mux(uint8_t state) { + int val; + char *new_state; + char path[64] = {0}; + + sprintf(path, GPIO_VAL, GPIO_USB_MUX_EN_N); + + if (read_device(path, &val)) { + return -1; + } + + // This GPIO Pin is active low + if (!val == state) + return 0; + + if (state) + new_state = "0"; + else + new_state = "1"; + + if (write_device(path, new_state) < 0) { +#ifdef DEBUG + syslog(LOG_WARNING, "write_device failed for %s\n", path); +#endif + return -1; + } + + return 0; +} + // Update the USB Mux to the server at given slot int pal_switch_usb_mux(uint8_t slot) { @@ -702,36 +901,49 @@ pal_switch_usb_mux(uint8_t slot) { // Based on the USB mux table in Schematics switch(slot) { - case 1: + case HAND_SW_SERVER1: gpio_sw0 = "1"; gpio_sw1 = "0"; break; - case 2: + case HAND_SW_SERVER2: gpio_sw0 = "0"; gpio_sw1 = "0"; break; - case 3: + case HAND_SW_SERVER3: gpio_sw0 = "1"; gpio_sw1 = "1"; break; - case 4: + case HAND_SW_SERVER4: gpio_sw0 = "0"; gpio_sw1 = "1"; break; + case HAND_SW_BMC: + // Disable the USB MUX + if (set_usb_mux(USB_MUX_OFF) < 0) + return -1; + else + return 0; default: - // Default is for BMC itself return 0; } + // Enable the USB MUX + if (set_usb_mux(USB_MUX_ON) < 0) + return -1; + sprintf(path, GPIO_VAL, GPIO_USB_SW0); if (write_device(path, gpio_sw0) < 0) { - syslog(LOG_ALERT, "write_device failed for %s\n", path); +#ifdef DEBUG + syslog(LOG_WARNING, "write_device failed for %s\n", path); +#endif return -1; } sprintf(path, GPIO_VAL, GPIO_USB_SW1); if (write_device(path, gpio_sw1) < 0) { - syslog(LOG_ALERT, "write_device failed for %s\n", path); +#ifdef DEBUG + syslog(LOG_WARNING, "write_device failed for %s\n", path); +#endif return -1; } @@ -750,25 +962,25 @@ pal_switch_uart_mux(uint8_t slot) { // Refer the UART select table in schematic switch(slot) { - case 1: + case HAND_SW_SERVER1: gpio_uart_sel2 = "0"; gpio_uart_sel1 = "0"; gpio_uart_sel0 = "1"; gpio_uart_rx = "0"; break; - case 2: + case HAND_SW_SERVER2: gpio_uart_sel2 = "0"; gpio_uart_sel1 = "0"; gpio_uart_sel0 = "0"; gpio_uart_rx = "0"; break; - case 3: + case HAND_SW_SERVER3: gpio_uart_sel2 = "0"; gpio_uart_sel1 = "1"; gpio_uart_sel0 = "1"; gpio_uart_rx = "0"; break; - case 4: + case HAND_SW_SERVER4: gpio_uart_sel2 = "0"; gpio_uart_sel1 = "1"; gpio_uart_sel0 = "0"; @@ -816,7 +1028,9 @@ pal_switch_uart_mux(uint8_t slot) { uart_exit: if (ret) { - syslog(LOG_ALERT, "pal_switch_uart_mux: write_device failed: %s\n", path); +#ifdef DEBUG + syslog(LOG_WARNING, "pal_switch_uart_mux: write_device failed: %s\n", path); +#endif return ret; } else { return 0; @@ -833,7 +1047,9 @@ pal_post_enable(uint8_t slot) { ret = bic_get_config(slot, &config); if (ret) { - syslog(LOG_ALERT, "post_enable: bic_get_config failed\n"); +#ifdef DEBUG + syslog(LOG_WARNING, "post_enable: bic_get_config failed for fru: %d\n", slot); +#endif return ret; } @@ -841,7 +1057,9 @@ pal_post_enable(uint8_t slot) { ret = bic_set_config(slot, &config); if (ret) { - syslog(LOG_ALERT, "post_enable: bic_set_config failed\n"); +#ifdef DEBUG + syslog(LOG_WARNING, "post_enable: bic_set_config failed\n"); +#endif return ret; } @@ -937,14 +1155,18 @@ read_kv(char *key, char *value) { fp = fopen(key, "r"); if (!fp) { int err = errno; - syslog(LOG_ALERT, "read_kv: failed to open %s", key); +#ifdef DEBUG + syslog(LOG_WARNING, "read_kv: failed to open %s", key); +#endif return err; } rc = (int) fread(value, 1, MAX_VALUE_LEN, fp); fclose(fp); if (rc <= 0) { +#ifdef DEBUG syslog(LOG_INFO, "read_kv: failed to read %s", key); +#endif return ENOENT; } else { return 0; @@ -960,7 +1182,9 @@ write_kv(char *key, char *value) { fp = fopen(key, "w"); if (!fp) { int err = errno; - syslog(LOG_ALERT, "write_kv: failed to open %s", key); +#ifdef DEBUG + syslog(LOG_WARNING, "write_kv: failed to open %s", key); +#endif return err; } @@ -968,7 +1192,9 @@ write_kv(char *key, char *value) { fclose(fp); if (rc < 0) { - syslog(LOG_ALERT, "write_kv: failed to write to %s", key); +#ifdef DEBUG + syslog(LOG_WARNING, "write_kv: failed to write to %s", key); +#endif return ENOENT; } else { return 0; @@ -982,6 +1208,17 @@ pal_get_fru_id(char *str, uint8_t *fru) { } int +pal_get_fru_name(uint8_t fru, char *name) { + + return yosemite_common_fru_name(fru, name); +} + +int +pal_get_fru_sdr_path(uint8_t fru, char *path) { + return yosemite_sensor_sdr_path(fru, path); +} + +int pal_get_fru_sensor_list(uint8_t fru, uint8_t **sensor_list, int *cnt) { switch(fru) { @@ -997,22 +1234,39 @@ pal_get_fru_sensor_list(uint8_t fru, uint8_t **sensor_list, int *cnt) { *cnt = spb_sensor_cnt; break; case FRU_NIC: - *sensor_list = NULL; // (uint8_t *) nic_sensor_list; - *cnt = 0; //nic_sensor_cnt; + *sensor_list = (uint8_t *) nic_sensor_list; + *cnt = nic_sensor_cnt; break; default: - syslog(LOG_ALERT, "pal_get_fru_sensor_list: Wrong fru id %u", fru); +#ifdef DEBUG + syslog(LOG_WARNING, "pal_get_fru_sensor_list: Wrong fru id %u", fru); +#endif return -1; } return 0; } int +pal_fruid_write(uint8_t fru, char *path) { + return bic_write_fruid(fru, 0, path); +} + +int +pal_sensor_sdr_init(uint8_t fru, sensor_info_t *sinfo) { + return yosemite_sensor_sdr_init(fru, sinfo); +} + +int pal_sensor_read(uint8_t fru, uint8_t sensor_num, void *value) { return yosemite_sensor_read(fru, sensor_num, value); } int +pal_get_sensor_threshold(uint8_t fru, uint8_t sensor_num, uint8_t thresh, void *value) { + return yosemite_sensor_threshold(fru, sensor_num, thresh, value); +} + +int pal_get_sensor_name(uint8_t fru, uint8_t sensor_num, char *name) { return yosemite_sensor_name(fru, sensor_num, name); } @@ -1028,6 +1282,11 @@ pal_get_fruid_path(uint8_t fru, char *path) { } int +pal_get_fruid_eeprom_path(uint8_t fru, char *path) { + return yosemite_get_fruid_eeprom_path(fru, path); +} + +int pal_get_fruid_name(uint8_t fru, char *name) { return yosemite_get_fruid_name(fru, name); } @@ -1073,7 +1332,9 @@ pal_get_key_value(char *key, char *value) { if (!strcmp(key, key_list[i])) { // Key is valid if ((ret = get_key_value(key, value)) < 0 ) { - syslog(LOG_ALERT, "pal_get_key_value: get_key_value failed. %d", ret); +#ifdef DEBUG + syslog(LOG_WARNING, "pal_get_key_value: get_key_value failed. %d", ret); +#endif return ret; } return ret; @@ -1085,6 +1346,31 @@ pal_get_key_value(char *key, char *value) { } int +pal_set_def_key_value() { + + int ret; + int i; + char kpath[64] = {0}; + + i = 0; + while(strcmp(key_list[i], LAST_KEY)) { + + sprintf(kpath, KV_STORE, key_list[i]); + + if (access(kpath, F_OK) == -1) { + if ((ret = set_key_value(key_list[i], def_val_list[i])) < 0) { +#ifdef DEBUG + syslog(LOG_WARNING, "pal_set_def_key_value: set_key_value failed. %d", ret); +#endif + } + } + i++; + } + + return 0; +} + +int pal_set_key_value(char *key, char *value) { int ret; @@ -1096,8 +1382,9 @@ pal_set_key_value(char *key, char *value) { if (!strcmp(key, key_list[i])) { // Key is valid if ((ret = set_key_value(key, value)) < 0) { - syslog(LOG_ALERT, "pal_set_key_value: set_key_value failed. %d", ret); - printf("pal_set_key_value: ret = %d\n", ret); +#ifdef DEBUG + syslog(LOG_WARNING, "pal_set_key_value: set_key_value failed. %d", ret); +#endif return ret; } return ret; @@ -1125,7 +1412,9 @@ pal_get_fru_devtty(uint8_t fru, char *devtty) { sprintf(devtty, "/dev/ttyS3"); break; default: - syslog(LOG_ALERT, "pal_get_fru_devtty: Wrong fru id %u", fru); +#ifdef DEBUG + syslog(LOG_WARNING, "pal_get_fru_devtty: Wrong fru id %u", fru); +#endif return -1; } return 0; @@ -1149,3 +1438,516 @@ pal_dump_key_value(void) { memset(value, 0, MAX_VALUE_LEN); } } + +int +pal_set_last_pwr_state(uint8_t fru, char *state) { + + int ret; + char key[MAX_KEY_LEN] = {0}; + + sprintf(key, "pwr_server%d_last_state", (int) fru); + + ret = pal_set_key_value(key, state); + if (ret < 0) { +#ifdef DEBUG + syslog(LOG_WARNING, "pal_set_last_pwr_state: pal_set_key_value failed for " + "fru %u", fru); +#endif + } + return ret; +} + +int +pal_get_last_pwr_state(uint8_t fru, char *state) { + int ret; + char key[MAX_KEY_LEN] = {0}; + + switch(fru) { + case FRU_SLOT1: + case FRU_SLOT2: + case FRU_SLOT3: + case FRU_SLOT4: + + sprintf(key, "pwr_server%d_last_state", (int) fru); + + ret = pal_get_key_value(key, state); + if (ret < 0) { +#ifdef DEBUG + syslog(LOG_WARNING, "pal_get_last_pwr_state: pal_get_key_value failed for " + "fru %u", fru); +#endif + } + return ret; + case FRU_SPB: + case FRU_NIC: + sprintf(state, "on"); + return 0; + } +} + +int +pal_get_sys_guid(uint8_t slot, char *guid) { + int ret; + + return bic_get_sys_guid(slot, guid); +} + +int +pal_set_sysfw_ver(uint8_t slot, uint8_t *ver) { + int i; + char key[MAX_KEY_LEN] = {0}; + char str[MAX_VALUE_LEN] = {0}; + char tstr[10] = {0}; + + sprintf(key, "sysfw_ver_slot%d", (int) slot); + + for (i = 0; i < SIZE_SYSFW_VER; i++) { + sprintf(tstr, "%02x", ver[i]); + strcat(str, tstr); + } + + return pal_set_key_value(key, str); +} + +int +pal_get_sysfw_ver(uint8_t slot, uint8_t *ver) { + int i; + int j = 0; + int ret; + int msb, lsb; + char key[MAX_KEY_LEN] = {0}; + char str[MAX_VALUE_LEN] = {0}; + char tstr[4] = {0}; + + sprintf(key, "sysfw_ver_slot%d", (int) slot); + + ret = pal_get_key_value(key, str); + if (ret) { + return ret; + } + + for (i = 0; i < 2*SIZE_SYSFW_VER; i += 2) { + sprintf(tstr, "%c\n", str[i]); + msb = strtol(tstr, NULL, 16); + + sprintf(tstr, "%c\n", str[i+1]); + lsb = strtol(tstr, NULL, 16); + ver[j++] = (msb << 4) | lsb; + } + + return 0; +} + +int +pal_is_bmc_por(void) { + uint32_t scu_fd; + uint32_t wdt; + void *scu_reg; + void *scu_wdt; + + scu_fd = open("/dev/mem", O_RDWR | O_SYNC ); + if (scu_fd < 0) { + return 0; + } + + scu_reg = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, scu_fd, + AST_WDT_BASE); + scu_wdt = (char*)scu_reg + WDT_OFFSET; + + wdt = *(volatile uint32_t*) scu_wdt; + + munmap(scu_reg, PAGE_SIZE); + close(scu_fd); + + if (wdt & 0xff00) { + return 0; + } else { + return 1; + } +} + +int +pal_get_fru_discrete_list(uint8_t fru, uint8_t **sensor_list, int *cnt) { + + switch(fru) { + case FRU_SLOT1: + case FRU_SLOT2: + case FRU_SLOT3: + case FRU_SLOT4: + *sensor_list = (uint8_t *) bic_discrete_list; + *cnt = bic_discrete_cnt; + break; + case FRU_SPB: + case FRU_NIC: + return -1; + default: +#ifdef DEBUG + syslog(LOG_WARNING, "pal_get_fru_discrete_list: Wrong fru id %u", fru); +#endif + return -1; + } + return 0; +} + +static void +_print_sensor_discrete_log(uint8_t fru, uint8_t snr_num, char *snr_name, + uint8_t val, char *event) { + if (val) { + syslog(LOG_CRIT, "ASSERT: %s discrete - raised - FRU: %d, num: 0x%X," + " snr: %-16s val: %d", event, fru, snr_num, snr_name, val); + } else { + syslog(LOG_CRIT, "DEASSERT: %s discrete - settled - FRU: %d, num: 0x%X," + " snr: %-16s val: %d", event, fru, snr_num, snr_name, val); + } +} + +int +pal_sensor_discrete_check(uint8_t fru, uint8_t snr_num, char *snr_name, + uint8_t o_val, uint8_t n_val) { + + char name[32]; + bool valid = false; + uint8_t diff = o_val ^ n_val; + + if (GETBIT(diff, 0)) { + switch(snr_num) { + case BIC_SENSOR_SYSTEM_STATUS: + sprintf(name, "SOC_Thermal_Trip"); + valid = true; + break; + case BIC_SENSOR_VR_HOT: + sprintf(name, "SOC_VR_Hot"); + valid = true; + break; + case BIC_SENSOR_CPU_DIMM_HOT: + sprintf(name, "SOC_Hot"); + valid = true; + break; + } + if (valid) { + _print_sensor_discrete_log( fru, snr_num, snr_name, GETBIT(n_val, 0), name); + valid = false; + } + } + + if (GETBIT(diff, 1)) { + switch(snr_num) { + case BIC_SENSOR_SYSTEM_STATUS: + sprintf(name, "SOC_FIVR_Fault"); + valid = true; + break; + case BIC_SENSOR_VR_HOT: + sprintf(name, "SOC_DIMM_VR_Hot"); + valid = true; + break; + case BIC_SENSOR_CPU_DIMM_HOT: + sprintf(name, "SOC_MEMHOT"); + valid = true; + break; + } + if (valid) { + _print_sensor_discrete_log( fru, snr_num, snr_name, GETBIT(n_val, 1), name); + valid = false; + } + } + + if (GETBIT(diff, 2)) { + switch(snr_num) { + case BIC_SENSOR_SYSTEM_STATUS: + sprintf(name, "SOC_Throttle"); + valid = true; + break; + } + if (valid) { + _print_sensor_discrete_log( fru, snr_num, snr_name, GETBIT(n_val, 2), name); + valid = false; + } + } +} + +static int +pal_store_crashdump(uint8_t fru) { + + return yosemite_common_crashdump(fru); +} + +int +pal_sel_handler(uint8_t fru, uint8_t snr_num) { + + switch(snr_num) { + case CATERR: + pal_store_crashdump(fru); + break; + } + + return 0; +} + +int +pal_get_event_sensor_name(uint8_t fru, uint8_t snr_num, char *name) { + + switch(snr_num) { + case SYSTEM_EVENT: + sprintf(name, "SYSTEM_EVENT"); + break; + case THERM_THRESH_EVT: + sprintf(name, "THERM_THRESH_EVT"); + break; + case BUTTON: + sprintf(name, "BUTTON"); + break; + case POWER_STATE: + sprintf(name, "POWER_STATE"); + break; + case CRITICAL_IRQ: + sprintf(name, "CRITICAL_IRQ"); + break; + case POST_ERROR: + sprintf(name, "POST_ERROR"); + break; + case MACHINE_CHK_ERR: + sprintf(name, "MACHINE_CHK_ERR"); + break; + case PCIE_ERR: + sprintf(name, "PCIE_ERR"); + break; + case IIO_ERR: + sprintf(name, "IIO_ERR"); + break; + case MEMORY_ECC_ERR: + sprintf(name, "MEMORY_ECC_ERR"); + break; + case PROCHOT_EXT: + sprintf(name, "PROCHOT_EXT"); + break; + case PWR_ERR: + sprintf(name, "PWR_ERR"); + break; + case CATERR: + sprintf(name, "CATERR"); + break; + default: + sprintf(name, "unknown"); + break; + } + + return 0; +} + +int +pal_parse_sel(uint8_t fru, uint8_t snr_num, uint8_t *event_data, + char *error_log) { + + char *ed = event_data; + char temp_log[128] = {0}; + uint8_t temp; + + switch(snr_num) { + case SYSTEM_EVENT: + sprintf(error_log, "SYSTEM_EVENT"); + if (ed[0] == 0xE5) { + strcat(error_log, ": Cause of Time change"); + + if (ed[2] == 0x00) + strcat(error_log, ": NTP"); + else if (ed[2] == 0x01) + strcat(error_log, ": Host RTL"); + else if (ed[2] == 0x02) + strcat(error_log, ": Set SEL time cmd "); + else if (ed[2] == 0x03) + strcat(error_log, ": Set SEL time UTC offset cmd"); + else + strcat(error_log, ": Unknown"); + + if (ed[1] == 0x00) + strcat(error_log, ": First Time"); + else if(ed[1] == 0x80) + strcat(error_log, ": Second Time"); + + } + break; + + case THERM_THRESH_EVT: + sprintf(error_log, "THERM_THRESH_EVT"); + if (ed[0] == 0x1) + strcat(error_log, ": Limit Exceeded"); + else + strcat(error_log, ": Unknown"); + break; + + case BUTTON: + sprintf(error_log, "BUTTON"); + if (ed[0] == 0x0) + strcat(error_log, ": Power button pressed"); + else if (ed[0] == 0x2) + strcat(error_log, ": Reset button pressed"); + else + strcat(error_log, ": Unknown"); + break; + + case POWER_STATE: + sprintf(error_log, "POWER_STATE"); + if (ed[0] == 0x0) + strcat(error_log, ": Transition to Running"); + else if (ed[0] == 0x2) + strcat(error_log, ": Transition to Power Off"); + else + strcat(error_log, ": Unknown"); + break; + + case CRITICAL_IRQ: + sprintf(error_log, "CRITICAL_IRQ"); + if (ed[0] == 0x0) + strcat(error_log, ": Diagnostic Interrupt"); + else + strcat(error_log, ": Unknown"); + break; + + case POST_ERROR: + sprintf(error_log, "POST_ERROR"); + if ((ed[0] & 0x0F) == 0x0) + strcat(error_log, ": System Firmware Error"); + else + strcat(error_log, ": Unknown"); + if (((ed[0] >> 6) & 0x03) == 0x3) { + // TODO: Need to implement IPMI spec based Post Code + strcat(error_log, ": IPMI Post Code"); + } else if (((ed[0] >> 6) & 0x03) == 0x2) { + sprintf(temp_log, "OEM Post Code: 0x%X 0x%X", ed[2], ed[1]); + strcat(error_log, temp_log); + } + break; + + case MACHINE_CHK_ERR: + sprintf(error_log, "MACHINE_CHK_ERR"); + if ((ed[0] & 0x0F) == 0x0B) { + strcat(error_log, ": Uncorrectable"); + } else if ((ed[0] & 0x0F) == 0x0C) { + strcat(error_log, ": Correctable"); + } else { + strcat(error_log, ": Unknown"); + } + + sprintf(temp_log, "Machine Check bank Number - %d ", ed[1]); + strcat(error_log, temp_log); + sprintf(temp_log, "CPU - %d, Core - %d ", ed[2] >> 5, ed[2] & 0x1F); + strcat(error_log, temp_log); + + break; + + case PCIE_ERR: + sprintf(error_log, "PCIE_ERR"); + if ((ed[0] & 0xF) == 0x4) + strcat(error_log, ": PCI PERR"); + else if ((ed[0] & 0xF) == 0x5) + strcat(error_log, ": PCI SERR"); + else if ((ed[0] & 0xF) == 0x7) + strcat(error_log, ": Correctable"); + else if ((ed[0] & 0xF) == 0x8) + strcat(error_log, ": Uncorrectable"); + else if ((ed[0] & 0xF) == 0xA) + strcat(error_log, ": Bus Fatal"); + else + strcat(error_log, ": Unknown"); + break; + + case IIO_ERR: + sprintf(error_log, "IIO_ERR"); + if ((ed[0] & 0xF) == 0) { + + sprintf(temp_log, ": CPU - %d, Error ID - 0x%X", (ed[2] & 0xE0) >> 5, + ed[1]); + strcat(error_log, temp_log); + + temp = ed[2] & 0x7; + if (temp == 0x0) + strcat(error_log, ": IRP0"); + else if (temp == 0x1) + strcat(error_log, ": IRP1"); + else if (temp == 0x2) + strcat(error_log, ": IIO-Core"); + else if (temp == 0x3) + strcat(error_log, ": VT-d"); + else if (temp == 0x4) + strcat(error_log, ": Intel Quick Data"); + else if (temp == 0x5) + strcat(error_log, ": Misc"); + else + strcat(error_log, ": Reserved"); + } + break; + + case MEMORY_ECC_ERR: + sprintf(error_log, "MEMORY_ECC_ERR"); + if ((ed[0] & 0x0F) == 0x0) + strcat(error_log, ": Correctable"); + else if ((ed[0] & 0x0F) == 0x1) + strcat(error_log, ": Uncorrectable"); + else if ((ed[0] & 0x0F) == 0x5) + strcat(error_log, ": Correctable ECC error Logging Limit Reached"); + else + strcat(error_log, ": Unknown"); + + if (((ed[1] & 0xC) >> 2) == 0x0) { + /* All Info Valid */ + sprintf(temp_log, ": CPU# - %d, CHN# - %d, DIMM# - %d ", + (ed[2] & 0xE0) >> 5, (ed[2] & 0x18) >> 3, ed[2] & 0x7); + } else if (((ed[1] & 0xC) >> 2) == 0x1) { + /* DIMM info not valid */ + sprintf(temp_log, ": CPU# - %d, CHN# - %d", + (ed[2] & 0xE0) >> 5, (ed[2] & 0x18) >> 3); + } else if (((ed[1] & 0xC) >> 2) == 0x2) { + /* CHN info not valid */ + sprintf(temp_log, ": CPU# - %d, DIMM# - %d ", + (ed[2] & 0xE0) >> 5, ed[2] & 0x7); + } else if (((ed[1] & 0xC) >> 2) == 0x3) { + /* CPU info not valid */ + sprintf(temp_log, ": CHN# - %d, DIMM# - %d ", + (ed[2] & 0x18) >> 3, ed[2] & 0x7); + } + strcat(error_log, temp_log); + + break; + + case PROCHOT_EXT: + sprintf(error_log, "PROCHOT_EXT"); + if ((ed[0] & 0xF) == 0xA) + strcat(error_log, ": Processor Thermal Throttling Offset"); + else + strcat(error_log, ": Unknown"); + break; + + if ((ed[1] & 0x3) == 0x1) + strcat(error_log, ": External (VR)"); + else if ((ed[1] & 0x3) == 0x0) + strcat(error_log, ": Native"); + break; + + sprintf(temp_log, ": SOC ID - %d", (ed[2] & 0xE0) >> 5); + strcat(error_log, temp_log); + + case PWR_ERR: + sprintf(error_log, "PWR_ERR"); + if (ed[0] == 0x2) + strcat(error_log, ": PCH_PWROK failure"); + else + strcat(error_log, ": Unknown"); + break; + + case CATERR: + sprintf(error_log, "CATERR"); + if (ed[0] == 0x0) + strcat(error_log, ": IERR"); + else if (ed[0] == 0xB) + strcat(error_log, ": MCERR"); + else + strcat(error_log, ": Unknown"); + break; + + default: + sprintf(error_log, "unknown"); + break; + } + + return 0; +} diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.h b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.h index 1d9f3b9..b3f542a 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.h +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.h @@ -30,13 +30,17 @@ extern "C" { #include <facebook/yosemite_fruid.h> #include <facebook/yosemite_sensor.h> -#define MAX_NUM_FRUS 6 #define MAX_KEY_LEN 64 #define MAX_VALUE_LEN 64 #define KV_STORE "/mnt/data/kv_store/%s" #define KV_STORE_PATH "/mnt/data/kv_store" +#define SETBIT(x, y) (x | (1 << y)) +#define GETBIT(x, y) ((x & (1 << y)) > y) +#define CLEARBIT(x, y) (x & (~(1 << y))) +#define GETMASK(y) (1 << y) + extern char * key_list[]; extern const char pal_fru_list[]; extern const char pal_server_list[]; @@ -47,10 +51,18 @@ enum { }; enum { + USB_MUX_OFF, + USB_MUX_ON, +}; + +enum { SERVER_POWER_OFF, SERVER_POWER_ON, SERVER_POWER_CYCLE, SERVER_GRACEFUL_SHUTDOWN, + SERVER_12V_OFF, + SERVER_12V_ON, + SERVER_12V_CYCLE, }; enum { @@ -61,6 +73,22 @@ enum { HAND_SW_BMC }; +enum { + SYSTEM_EVENT = 0xE9, + THERM_THRESH_EVT = 0x7D, + BUTTON = 0xAA, + POWER_STATE = 0xAB, + CRITICAL_IRQ = 0xEA, + POST_ERROR = 0x2B, + MACHINE_CHK_ERR = 0x40, + PCIE_ERR = 0x41, + IIO_ERR = 0x43, + MEMORY_ECC_ERR = 0X63, + PROCHOT_EXT = 0X51, + PWR_ERR = 0X56, + CATERR= 0xEB, +}; + int pal_get_platform_name(char *name); int pal_get_num_slots(uint8_t *num); int pal_is_server_prsnt(uint8_t slot_id, uint8_t *status); @@ -79,17 +107,40 @@ int pal_get_pwr_btn(uint8_t *status); int pal_get_rst_btn(uint8_t *status); int pal_set_rst_btn(uint8_t slot, uint8_t status); int pal_set_led(uint8_t slot, uint8_t status); +int pal_set_hb_led(uint8_t status); +int pal_set_id_led(uint8_t slot, uint8_t status); int pal_get_fru_id(char *fru_str, uint8_t *fru); +int pal_get_fru_name(uint8_t fru, char *name); int pal_get_fruid_path(uint8_t fru, char *path); +int pal_get_fruid_eeprom_path(uint8_t fru, char *path); int pal_get_fruid_name(uint8_t fru, char *name); +int pal_get_fru_sdr_path(uint8_t fru, char *path); int pal_get_sensor_units(uint8_t fru, uint8_t sensor_num, char *units); int pal_get_fru_sensor_list(uint8_t fru, uint8_t **sensor_list, int *cnt); +int pal_get_fru_discrete_list(uint8_t fru, uint8_t **sensor_list, int *cnt); +int pal_sensor_sdr_init(uint8_t fru, sensor_info_t *sinfo); int pal_sensor_read(uint8_t fru, uint8_t sensor_num, void *value); int pal_get_sensor_name(uint8_t fru, uint8_t sensor_num, char *name); +int pal_get_sensor_threshold(uint8_t fru, uint8_t sensor_num, uint8_t thresh, + void *value); int pal_get_key_value(char *key, char *value); int pal_set_key_value(char *key, char *value); +int pal_set_def_key_value(); void pal_dump_key_value(void); int pal_get_fru_devtty(uint8_t fru, char *devtty); +int pal_get_last_pwr_state(uint8_t fru, char *state); +int pal_set_last_pwr_state(uint8_t fru, char *state); +int pal_get_sys_guid(uint8_t slot, char *guid); +int pal_set_sysfw_ver(uint8_t slot, uint8_t *ver); +int pal_get_sysfw_ver(uint8_t slot, uint8_t *ver); +int pal_fruid_write(uint8_t slot, char *path); +int pal_is_bmc_por(void); +int pal_sensor_discrete_check(uint8_t fru, uint8_t snr_num, char *snr_name, + uint8_t o_val, uint8_t n_val); +int pal_get_event_sensor_name(uint8_t fru, uint8_t snr_num, char *name); +int pal_parse_sel(uint8_t fru, uint8_t snr_num, uint8_t *event_data, + char *error_log); +int pal_sel_handler(uint8_t fru, uint8_t snr_num); #ifdef __cplusplus } // extern "C" diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/Makefile index 76bf61f..40ea2a8 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/Makefile +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/Makefile @@ -2,8 +2,8 @@ lib: libyosemite_common.so libyosemite_common.so: yosemite_common.c - $(CC) $(CFLAGS) -fPIC -c -o yosemite_common.o yosemite_common.c - $(CC) -shared -o libyosemite_common.so yosemite_common.o -lc + $(CC) $(CFLAGS) -fPIC -pthread -c -o yosemite_common.o yosemite_common.c + $(CC) -lpthread -shared -o libyosemite_common.so yosemite_common.o -lc .PHONY: clean diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.c b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.c index e41690f..c638809 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.c +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.c @@ -27,8 +27,51 @@ #include <fcntl.h> #include <errno.h> #include <syslog.h> +#include <pthread.h> +#include <string.h> #include "yosemite_common.h" +#define CRASHDUMP_BIN "/usr/local/bin/dump.sh" +#define CRASHDUMP_FILE "/mnt/data/crashdump_" + +int +yosemite_common_fru_name(uint8_t fru, char *str) { + + switch(fru) { + case FRU_SLOT1: + sprintf(str, "slot1"); + break; + + case FRU_SLOT2: + sprintf(str, "slot2"); + break; + + case FRU_SLOT3: + sprintf(str, "slot3"); + break; + + case FRU_SLOT4: + sprintf(str, "slot4"); + break; + + case FRU_SPB: + sprintf(str, "spb"); + break; + + case FRU_NIC: + sprintf(str, "nic"); + break; + + default: +#ifdef DEBUG + syslog(LOG_WARNING, "yosemite_common_fru_id: Wrong fru id"); +#endif + return -1; + } + + return 0; +} + int yosemite_common_fru_id(char *str, uint8_t *fru) { @@ -47,9 +90,61 @@ yosemite_common_fru_id(char *str, uint8_t *fru) { } else if (!strcmp(str, "nic")) { *fru = FRU_NIC; } else { - syslog(LOG_ALERT, "yosemite_common_fru_id: Wrong fru id"); +#ifdef DEBUG + syslog(LOG_WARNING, "yosemite_common_fru_id: Wrong fru id"); +#endif return -1; } return 0; } + +void * +generate_dump(void *arg) { + + uint8_t fru = *(uint8_t *) arg; + char cmd[128]; + char fruname[16]; + + yosemite_common_fru_name(fru, fruname); + + // HEADER LINE for the dump + memset(cmd, 0, 128); + sprintf(cmd, "%s time > %s%s", CRASHDUMP_BIN, CRASHDUMP_FILE, fruname); + system(cmd); + + // COREID dump + memset(cmd, 0, 128); + sprintf(cmd, "%s %s 48 coreid >> %s%s", CRASHDUMP_BIN, fruname, + CRASHDUMP_FILE, fruname); + system(cmd); + + // MSR dump + memset(cmd, 0, 128); + sprintf(cmd, "%s %s 48 msr >> %s%s", CRASHDUMP_BIN, fruname, + CRASHDUMP_FILE, fruname); + system(cmd); + + syslog(LOG_CRIT, "Crashdump for FRU: %d is generated.", fru); +} + +int +yosemite_common_crashdump(uint8_t fru) { + + if (access(CRASHDUMP_BIN, F_OK) == -1) { + syslog(LOG_CRIT, "Crashdump for FRU: %d failed : " + "crashdump binary is not preset", fru); + return 0; + } + + pthread_t t_dump; + + if (pthread_create(&t_dump, NULL, generate_dump, (void*) &fru) < 0) { + syslog(LOG_WARNING, "pal_store_crashdump: pthread_create for" + " FRU %d failed\n", fru); + } + + syslog(LOG_INFO, "Crashdump for FRU: %d is being generated.", fru); + + return 0; +} diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.h b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.h index 85d8638..f2128ef 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.h +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.h @@ -25,6 +25,7 @@ extern "C" { #endif +#define MAX_NUM_FRUS 6 enum { FRU_ALL = 0, FRU_SLOT1 = 1, @@ -35,7 +36,9 @@ enum { FRU_NIC = 6, }; +int yosemite_common_fru_name(uint8_t fru, char *str); int yosemite_common_fru_id(char *str, uint8_t *fru); +int yosemite_common_crashdump(uint8_t fru); #ifdef __cplusplus } // extern "C" diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.c b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.c index 226f2f8..d431d34 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.c +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.c @@ -48,13 +48,42 @@ yosemite_get_fruid_path(uint8_t fru, char *path) { sprintf(fname, "nic"); break; default: - syslog(LOG_ALERT, "yosemite_get_fruid_path: wrong fruid"); +#ifdef DEBUG + syslog(LOG_WARNING, "yosemite_get_fruid_path: wrong fruid"); +#endif return -1; } sprintf(path, YOSEMITE_FRU_PATH, fname); return 0; } + +int +yosemite_get_fruid_eeprom_path(uint8_t fru, char *path) { + char fname[16] = {0}; + + switch(fru) { + case FRU_SLOT1: + case FRU_SLOT2: + case FRU_SLOT3: + case FRU_SLOT4: + return -1; + case FRU_SPB: + sprintf(path, "/sys/class/i2c-adapter/i2c-8/8-0051/eeprom"); + break; + case FRU_NIC: + sprintf(path, "/sys/class/i2c-adapter/i2c-12/12-0051/eeprom"); + break; + default: +#ifdef DEBUG + syslog(LOG_WARNING, "yosemite_get_fruid_eeprom_path: wrong fruid"); +#endif + return -1; + } + + return 0; +} + /* Populate char name[] with the path to the fru's name */ int yosemite_get_fruid_name(uint8_t fru, char *name) { @@ -79,7 +108,9 @@ yosemite_get_fruid_name(uint8_t fru, char *name) { sprintf(name, "CX4 NIC"); break; default: - syslog(LOG_ALERT, "yosemite_get_fruid_name: wrong fruid"); +#ifdef DEBUG + syslog(LOG_WARNING, "yosemite_get_fruid_name: wrong fruid"); +#endif return -1; } return 0; diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.h b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.h index 5c01267..78cdbe4 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.h +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.h @@ -28,6 +28,7 @@ extern "C" { #endif int yosemite_get_fruid_path(uint8_t fru, char *path); +int yosemite_get_fruid_eeprom_path(uint8_t fru, char *path); int yosemite_get_fruid_name(uint8_t fru, char *name); #ifdef __cplusplus diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.c b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.c index ac2c820..4f22500 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.c +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.c @@ -102,12 +102,16 @@ yosemite_get_gpio_name(uint8_t fru, uint8_t gpio, char *name) { //TODO: Add support for BMC GPIO pins if (fru < 1 || fru > 4) { - syslog(LOG_ALERT, "yosemite_get_gpio_name: Wrong fru %u", fru); +#ifdef DEBUG + syslog(LOG_WARNING, "yosemite_get_gpio_name: Wrong fru %u", fru); +#endif return -1; } if (gpio < 0 || gpio > MAX_GPIO_PINS) { - syslog(LOG_ALERT, "yosemite_get_gpio_name: Wrong gpio pin %u", gpio); +#ifdef DEBUG + syslog(LOG_WARNING, "yosemite_get_gpio_name: Wrong gpio pin %u", gpio); +#endif return -1; } diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/Makefile index 63b334c..dd013a9 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/Makefile +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/Makefile @@ -3,7 +3,7 @@ lib: libyosemite_sensor.so libyosemite_sensor.so: yosemite_sensor.c $(CC) $(CFLAGS) -fPIC -c -o yosemite_sensor.o yosemite_sensor.c - $(CC) -lm -lbic -lsdr -lipmi -lipmb -lyosemite_common -shared -o libyosemite_sensor.so yosemite_sensor.o -lc + $(CC) -lm -lbic -lipmi -lipmb -lyosemite_common -shared -o libyosemite_sensor.so yosemite_sensor.o -lc .PHONY: clean diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.c b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.c index 0f25e54..9d075ce 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.c +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.c @@ -24,6 +24,7 @@ #include <stdint.h> #include <stdbool.h> #include <math.h> +#include <string.h> #include <fcntl.h> #include <errno.h> #include <syslog.h> @@ -51,6 +52,10 @@ #define UNIT_DIV 1000 +#define MEZZ_SENSOR_I2CBUS "11" +#define MEZZ_SENSOR_I2C_BUS_ADDR "0x1f" +#define MEZZ_SENSOR_TEMP_REGISTER "0x01" + #define BIC_SENSOR_READ_NA 0x20 #define MAX_SENSOR_NUM 0xFF @@ -77,6 +82,7 @@ const uint8_t bic_sensor_list[] = { BIC_SENSOR_VCCIN_VR_CURR, BIC_SENSOR_VCCIN_VR_VOL, BIC_SENSOR_INA230_POWER, + BIC_SENSOR_INA230_VOL, BIC_SENSOR_SOC_PACKAGE_PWR, BIC_SENSOR_SOC_TJMAX, BIC_SENSOR_VDDR_VR_POUT, @@ -88,6 +94,7 @@ const uint8_t bic_sensor_list[] = { BIC_SENSOR_VCC_SCSUS_VR_POUT, BIC_SENSOR_VCC_GBE_VR_POUT, BIC_SENSOR_VCC_GBE_VR_VOL, + BIC_SENSOR_1V05_PCH_VR_POUT, BIC_SENSOR_1V05_PCH_VR_VOL, BIC_SENSOR_SOC_DIMMA0_TEMP, BIC_SENSOR_SOC_DIMMA1_TEMP, @@ -101,22 +108,13 @@ const uint8_t bic_sensor_list[] = { BIC_SENSOR_PV_BAT, BIC_SENSOR_PVDDR, BIC_SENSOR_PVCC_GBE, +}; + +const uint8_t bic_discrete_list[] = { /* Discrete sensors */ - //BIC_SENSOR_SYSTEM_STATUS, - //BIC_SENSOR_SYS_BOOT_STAT, - //BIC_SENSOR_CPU_DIMM_HOT, - //BIC_SENSOR_PROC_FAIL, - //BIC_SENSOR_VR_HOT, - /* Event-only sensors */ - //BIC_SENSOR_POST_ERR, - //BIC_SENSOR_SPS_FW_HLTH, - //BIC_SENSOR_POWER_THRESH_EVENT, - //BIC_SENSOR_MACHINE_CHK_ERR, - //BIC_SENSOR_PCIE_ERR, - //BIC_SENSOR_OTHER_IIO_ERR, - //BIC_SENSOR_PROC_HOT_EXT, - //BIC_SENSOR_POWER_ERR, - //BIC_SENSOR_CAT_ERR, + BIC_SENSOR_SYSTEM_STATUS, + BIC_SENSOR_VR_HOT, + BIC_SENSOR_CPU_DIMM_HOT, }; // List of SPB sensors to be monitored @@ -130,10 +128,10 @@ const uint8_t spb_sensor_list[] = { SP_SENSOR_P5V, SP_SENSOR_P12V, SP_SENSOR_P3V3_STBY, - SP_SENSOR_P12V_SLOT0, SP_SENSOR_P12V_SLOT1, SP_SENSOR_P12V_SLOT2, SP_SENSOR_P12V_SLOT3, + SP_SENSOR_P12V_SLOT4, SP_SENSOR_P3V3, SP_SENSOR_HSC_IN_VOLT, SP_SENSOR_HSC_OUT_CURR, @@ -141,10 +139,63 @@ const uint8_t spb_sensor_list[] = { SP_SENSOR_HSC_IN_POWER, }; +// List of NIC sensors to be monitored +const uint8_t nic_sensor_list[] = { + MEZZ_SENSOR_TEMP, +}; + +float spb_sensor_threshold[MAX_SENSOR_NUM][MAX_SENSOR_THRESHOLD + 1] = {0}; +float nic_sensor_threshold[MAX_SENSOR_NUM][MAX_SENSOR_THRESHOLD + 1] = {0}; + +static void +sensor_thresh_array_init() { + static bool init_done = false; + + if (init_done) + return; + + spb_sensor_threshold[SP_SENSOR_INLET_TEMP][UCR_THRESH] = 40; + spb_sensor_threshold[SP_SENSOR_OUTLET_TEMP][UCR_THRESH] = 70; + spb_sensor_threshold[SP_SENSOR_FAN0_TACH][UCR_THRESH] = 10000; + spb_sensor_threshold[SP_SENSOR_FAN0_TACH][LCR_THRESH] = 500; + spb_sensor_threshold[SP_SENSOR_FAN1_TACH][UCR_THRESH] = 10000; + spb_sensor_threshold[SP_SENSOR_FAN1_TACH][LCR_THRESH] = 500; + //spb_sensor_threshold[SP_SENSOR_AIR_FLOW][UCR_THRESH] = {75.0, 0, 0, 0, 0, 0, 0, 0}; + spb_sensor_threshold[SP_SENSOR_P5V][UCR_THRESH] = 5.493; + spb_sensor_threshold[SP_SENSOR_P5V][LCR_THRESH] = 4.501; + spb_sensor_threshold[SP_SENSOR_P12V][UCR_THRESH] = 13.216; + spb_sensor_threshold[SP_SENSOR_P12V][LCR_THRESH] = 11.269; + spb_sensor_threshold[SP_SENSOR_P3V3_STBY][UCR_THRESH] = 3.625; + spb_sensor_threshold[SP_SENSOR_P3V3_STBY][LCR_THRESH] = 2.973; + spb_sensor_threshold[SP_SENSOR_P12V_SLOT1][UCR_THRESH] = 13.216; + spb_sensor_threshold[SP_SENSOR_P12V_SLOT1][LCR_THRESH] = 11.269; + spb_sensor_threshold[SP_SENSOR_P12V_SLOT2][UCR_THRESH] = 13.216; + spb_sensor_threshold[SP_SENSOR_P12V_SLOT2][LCR_THRESH] = 11.269; + spb_sensor_threshold[SP_SENSOR_P12V_SLOT3][UCR_THRESH] = 13.216; + spb_sensor_threshold[SP_SENSOR_P12V_SLOT3][LCR_THRESH] = 11.269; + spb_sensor_threshold[SP_SENSOR_P12V_SLOT4][UCR_THRESH] = 13.216; + spb_sensor_threshold[SP_SENSOR_P12V_SLOT4][LCR_THRESH] = 11.269; + spb_sensor_threshold[SP_SENSOR_P3V3][UCR_THRESH] = 3.625; + spb_sensor_threshold[SP_SENSOR_P3V3][LCR_THRESH] = 2.973; + spb_sensor_threshold[SP_SENSOR_HSC_IN_VOLT][UCR_THRESH] = 13.2; + spb_sensor_threshold[SP_SENSOR_HSC_IN_VOLT][LCR_THRESH] = 10.8; + spb_sensor_threshold[SP_SENSOR_HSC_OUT_CURR][UCR_THRESH] = 47.705; + spb_sensor_threshold[SP_SENSOR_HSC_TEMP][UCR_THRESH] = 120; + spb_sensor_threshold[SP_SENSOR_HSC_IN_POWER][UCR_THRESH] = 525; + + nic_sensor_threshold[MEZZ_SENSOR_TEMP][UCR_THRESH] = 80; + + init_done = true; +} + size_t bic_sensor_cnt = sizeof(bic_sensor_list)/sizeof(uint8_t); +size_t bic_discrete_cnt = sizeof(bic_discrete_list)/sizeof(uint8_t); + size_t spb_sensor_cnt = sizeof(spb_sensor_list)/sizeof(uint8_t); +size_t nic_sensor_cnt = sizeof(nic_sensor_list)/sizeof(uint8_t); + enum { FAN0 = 0, FAN1, @@ -161,12 +212,7 @@ enum { ADC_PIN7, }; -static sensor_info_t g_sinfo1[MAX_SENSOR_NUM] = {0}; -static sensor_info_t g_sinfo2[MAX_SENSOR_NUM] = {0}; -static sensor_info_t g_sinfo3[MAX_SENSOR_NUM] = {0}; -static sensor_info_t g_sinfo4[MAX_SENSOR_NUM] = {0}; -static sensor_info_t g_sinfo_spb[MAX_SENSOR_NUM] = {0}; -static sensor_info_t g_sinfo_nic[MAX_SENSOR_NUM] = {0}; +static sensor_info_t g_sinfo[MAX_NUM_FRUS][MAX_SENSOR_NUM] = {0}; static int read_device(const char *device, int *value) { @@ -177,7 +223,9 @@ read_device(const char *device, int *value) { if (!fp) { int err = errno; +#ifdef DEBUG syslog(LOG_INFO, "failed to open device %s", device); +#endif return err; } @@ -185,7 +233,9 @@ read_device(const char *device, int *value) { fclose(fp); if (rc != 1) { +#ifdef DEBUG syslog(LOG_INFO, "failed to read device %s", device); +#endif return ENOENT; } else { return 0; @@ -201,8 +251,9 @@ read_device_float(const char *device, float *value) { fp = fopen(device, "r"); if (!fp) { int err = errno; - +#ifdef DEBUG syslog(LOG_INFO, "failed to open device %s", device); +#endif return err; } @@ -210,7 +261,9 @@ read_device_float(const char *device, float *value) { fclose(fp); if (rc != 1) { +#ifdef DEBUG syslog(LOG_INFO, "failed to read device %s", device); +#endif return ENOENT; } @@ -271,46 +324,52 @@ read_hsc_value(const char *device, float *value) { } static int -bic_read_sensor_wrapper(uint8_t slot_id, uint8_t sensor_num, void *value) { +read_nic_temp(uint8_t snr_num, float *value) { + char command[64]; + char tmp[8]; + + if (snr_num == MEZZ_SENSOR_TEMP) { + sprintf(command, "i2cget -y %s %s %s b", MEZZ_SENSOR_I2CBUS, + MEZZ_SENSOR_I2C_BUS_ADDR, MEZZ_SENSOR_TEMP_REGISTER); + + FILE *fp = popen(command, "r"); + fscanf(fp, "%s", tmp); + pclose(fp); + + *value = (float) strtol(tmp, NULL, 16); + } + + return 0; +} + +static int +bic_read_sensor_wrapper(uint8_t fru, uint8_t sensor_num, bool discrete, + void *value) { + int ret; + sdr_full_t *sdr; ipmi_sensor_reading_t sensor; - ret = bic_read_sensor(slot_id, sensor_num, &sensor); + ret = bic_read_sensor(fru, sensor_num, &sensor); if (ret) { return ret; } if (sensor.flags & BIC_SENSOR_READ_NA) { +#ifdef DEBUG syslog(LOG_ERR, "bic_read_sensor_wrapper: Reading Not Available"); syslog(LOG_ERR, "bic_read_sensor_wrapper: sensor_num: 0x%X, flag: 0x%X", sensor_num, sensor.flags); +#endif return -1; } - if (sensor.status) { - //printf("bic_read_sensor_wrapper: Status Asserted: 0x%X\n", sensor.status); + if (discrete) { + *(float *) value = (float) sensor.status; + return 0; } - // Check SDR to convert raw value to actual - sdr_full_t *sdr; - - switch (slot_id) { - case 1: - sdr = &g_sinfo1[sensor_num].sdr; - break; - case 2: - sdr = &g_sinfo2[sensor_num].sdr; - break; - case 3: - sdr = &g_sinfo3[sensor_num].sdr; - break; - case 4: - sdr = &g_sinfo4[sensor_num].sdr; - break; - default: - syslog(LOG_ALERT, "bic_read_sensor_wrapper: Wrong Slot ID\n"); - return -1; - } + sdr = &g_sinfo[fru-1][sensor_num].sdr; // If the SDR is not type1, no need for conversion if (sdr->type !=1) { @@ -350,106 +409,148 @@ bic_read_sensor_wrapper(uint8_t slot_id, uint8_t sensor_num, void *value) { * (float *) value = ((m * x) + (b * pow(10, b_exp))) * (pow(10, r_exp)); + if ((sensor_num == BIC_SENSOR_SOC_THERM_MARGIN) && (* (float *) value > 0)) { + * (float *) value -= (float) THERMAL_CONSTANT; + } + return 0; } -/* Returns the all the SDRs for the particular fru# */ -static sensor_info_t * -get_struct_sensor_info(uint8_t fru) { - sensor_info_t *sinfo; - switch(fru) { +int +yosemite_sensor_sdr_path(uint8_t fru, char *path) { + +char fru_name[16] = {0}; + +switch(fru) { case FRU_SLOT1: - sinfo = g_sinfo1; + sprintf(fru_name, "%s", "slot1"); break; case FRU_SLOT2: - sinfo = g_sinfo2; + sprintf(fru_name, "%s", "slot2"); break; case FRU_SLOT3: - sinfo = g_sinfo3; + sprintf(fru_name, "%s", "slot3"); break; case FRU_SLOT4: - sinfo = g_sinfo4; + sprintf(fru_name, "%s", "slot4"); break; case FRU_SPB: - sinfo = g_sinfo_spb; + sprintf(fru_name, "%s", "spb"); break; case FRU_NIC: - sinfo = g_sinfo_nic; + sprintf(fru_name, "%s", "nic"); break; default: - syslog(LOG_ALERT, "yosemite_sdr_init: Wrong Slot ID\n"); - return NULL; - } - return sinfo; +#ifdef DEBUG + syslog(LOG_WARNING, "yosemite_sensor_sdr_path: Wrong Slot ID\n"); +#endif + return -1; } +sprintf(path, YOSEMITE_SDR_PATH, fru_name); + +if (access(path, F_OK) == -1) { + return -1; +} + +return 0; +} + +/* Populates all sensor_info_t struct using the path to SDR dump */ int -get_fru_sdr_path(uint8_t fru, char *path) { +sdr_init(char *path, sensor_info_t *sinfo) { +int fd; +uint8_t buf[MAX_SDR_LEN] = {0}; +uint8_t bytes_rd = 0; +uint8_t snr_num = 0; +sdr_full_t *sdr; + +while (access(path, F_OK) == -1) { + sleep(5); +} + +fd = open(path, O_RDONLY); +if (fd < 0) { + syslog(LOG_ERR, "sdr_init: open failed for %s\n", path); + return -1; +} + +while ((bytes_rd = read(fd, buf, sizeof(sdr_full_t))) > 0) { + if (bytes_rd != sizeof(sdr_full_t)) { + syslog(LOG_ERR, "sdr_init: read returns %d bytes\n", bytes_rd); + return -1; + } + + sdr = (sdr_full_t *) buf; + snr_num = sdr->sensor_num; + sinfo[snr_num].valid = true; + memcpy(&sinfo[snr_num].sdr, sdr, sizeof(sdr_full_t)); +} + +return 0; +} - char fru_name[16] = {0}; +int +yosemite_sensor_sdr_init(uint8_t fru, sensor_info_t *sinfo) { + int fd; + uint8_t buf[MAX_SDR_LEN] = {0}; + uint8_t bytes_rd = 0; + uint8_t sn = 0; + char path[64] = {0}; switch(fru) { case FRU_SLOT1: - sprintf(fru_name, "%s", "slot1"); - break; case FRU_SLOT2: - sprintf(fru_name, "%s", "slot2"); - break; case FRU_SLOT3: - sprintf(fru_name, "%s", "slot3"); - break; case FRU_SLOT4: - sprintf(fru_name, "%s", "slot4"); + if (yosemite_sensor_sdr_path(fru, path) < 0) { +#ifdef DEBUG + syslog(LOG_WARNING, "yosemite_sensor_sdr_init: get_fru_sdr_path failed\n"); +#endif + return ERR_NOT_READY; + } + + if (sdr_init(path, sinfo) < 0) { +#ifdef DEBUG + syslog(LOG_ERR, "yosemite_sensor_sdr_init: sdr_init failed for FRU %d", fru); +#endif + } break; + case FRU_SPB: - sprintf(fru_name, "%s", "spb"); - break; case FRU_NIC: - sprintf(fru_name, "%s", "nic"); - break; - default: - syslog(LOG_ALERT, "yosemite_sdr_init: Wrong Slot ID\n"); return -1; + break; } - sprintf(path, YOSEMITE_SDR_PATH, fru_name); - return 0; } static int yosemite_sdr_init(uint8_t fru) { - int fd; - uint8_t buf[MAX_SDR_LEN] = {0}; - uint8_t bytes_rd = 0; - uint8_t sn = 0; - char path[64] = {0}; - sensor_info_t *sinfo; - if (get_fru_sdr_path(fru, path) < 0) { - syslog(LOG_ALERT, "yosemite_sdr_init: get_fru_sdr_path failed\n"); - return -1; - } - sinfo = get_struct_sensor_info(fru); - if (sinfo == NULL) { - syslog(LOG_ALERT, "yosemite_sdr_init: get_struct_sensor_info failed\n"); - return -1; - } + static bool init_done[MAX_NUM_FRUS] = {false}; + + if (!init_done[fru - 1]) { + + sensor_info_t *sinfo = g_sinfo[fru-1]; + + if (yosemite_sensor_sdr_init(fru, sinfo) < 0) + return ERR_NOT_READY; - if (sdr_init(path, sinfo) < 0) { - syslog(LOG_ERR, "yosemite_sdr_init: sdr_init failed for FRU %d", fru); + init_done[fru - 1] = true; } return 0; } static bool -is_server_prsnt(uint8_t slot_id) { +is_server_prsnt(uint8_t fru) { uint8_t gpio; int val; char path[64] = {0}; - switch(slot_id) { + switch(fru) { case 1: gpio = 61; break; @@ -482,44 +583,21 @@ is_server_prsnt(uint8_t slot_id) { /* Get the units for the sensor */ int yosemite_sensor_units(uint8_t fru, uint8_t sensor_num, char *units) { - static bool init_done = false; uint8_t op, modifier; sensor_info_t *sinfo; - if (!init_done) { - - if (is_server_prsnt(1) && (yosemite_sdr_init(FRU_SLOT1) != 0)) { + if (is_server_prsnt(fru) && (yosemite_sdr_init(fru) != 0)) { return -1; } - if (is_server_prsnt(2) && (yosemite_sdr_init(FRU_SLOT2) != 0)) { - return -1; - } - if (is_server_prsnt(3) && (yosemite_sdr_init(FRU_SLOT3) != 0)) { - return -1; - } - if (is_server_prsnt(4) && (yosemite_sdr_init(FRU_SLOT4) != 0)) { - return -1; - } - init_done = true; - } switch(fru) { case FRU_SLOT1: case FRU_SLOT2: case FRU_SLOT3: case FRU_SLOT4: - sinfo = get_struct_sensor_info(fru); - if (sinfo == NULL) { - syslog(LOG_ALERT, "yosemite_sensor_units: get_struct_sensor_info failed\n"); - return -1; - } + sprintf(units, ""); + break; - if (sdr_get_sensor_units(&sinfo[sensor_num].sdr, &op, &modifier, units)) { - syslog(LOG_ALERT, "yosemite_sensor_units: FRU %d: num 0x%2X: reading units" - " from SDR failed.", fru, sensor_num); - return -1; - } - break; case FRU_SPB: switch(sensor_num) { case SP_SENSOR_INLET_TEMP: @@ -549,16 +627,10 @@ yosemite_sensor_units(uint8_t fru, uint8_t sensor_num, char *units) { case SP_SENSOR_P3V3_STBY: sprintf(units, "Volts"); break; - case SP_SENSOR_P12V_SLOT0: - sprintf(units, "Volts"); - break; case SP_SENSOR_P12V_SLOT1: - sprintf(units, "Volts"); - break; case SP_SENSOR_P12V_SLOT2: - sprintf(units, "Volts"); - break; case SP_SENSOR_P12V_SLOT3: + case SP_SENSOR_P12V_SLOT4: sprintf(units, "Volts"); break; case SP_SENSOR_P3V3: @@ -579,114 +651,132 @@ yosemite_sensor_units(uint8_t fru, uint8_t sensor_num, char *units) { } break; case FRU_NIC: - sprintf(units, ""); - break; + switch(sensor_num) { + case MEZZ_SENSOR_TEMP: + sprintf(units, "C"); + break; + } + break; } return 0; } -/* Get the name for the sensor */ int -yosemite_sensor_name(uint8_t fru, uint8_t sensor_num, char *name) { - static bool init_done = false; - uint8_t op, modifier; - sensor_info_t *sinfo; +yosemite_sensor_threshold(uint8_t fru, uint8_t sensor_num, uint8_t thresh, float *value) { - if (!init_done) { + sensor_thresh_array_init(); - if (is_server_prsnt(1) && (yosemite_sdr_init(FRU_SLOT1) != 0)) { - return -1; - } - if (is_server_prsnt(2) && (yosemite_sdr_init(FRU_SLOT2) != 0)) { - return -1; - } - if (is_server_prsnt(3) && (yosemite_sdr_init(FRU_SLOT3) != 0)) { - return -1; - } - if (is_server_prsnt(4) && (yosemite_sdr_init(FRU_SLOT4) != 0)) { - return -1; - } - init_done = true; + switch(fru) { + case FRU_SLOT1: + case FRU_SLOT2: + case FRU_SLOT3: + case FRU_SLOT4: + break; + case FRU_SPB: + *value = spb_sensor_threshold[sensor_num][thresh]; + break; + case FRU_NIC: + *value = nic_sensor_threshold[sensor_num][thresh]; + break; } + return 0; +} + +/* Get the name for the sensor */ +int +yosemite_sensor_name(uint8_t fru, uint8_t sensor_num, char *name) { switch(fru) { case FRU_SLOT1: case FRU_SLOT2: case FRU_SLOT3: case FRU_SLOT4: - sinfo = get_struct_sensor_info(fru); - if (sinfo == NULL) { - syslog(LOG_ALERT, "yosemite_sensor_name: get_struct_sensor_info failed\n"); - return -1; - } - - if (sdr_get_sensor_name(&sinfo[sensor_num].sdr, name)) { - syslog(LOG_ALERT, "yosemite_sensor_name: FRU %d: num 0x%2X: reading units" - " from SDR failed.", fru, sensor_num); - return -1; + switch(sensor_num) { + case BIC_SENSOR_SYSTEM_STATUS: + sprintf(name, "SYSTEM_STATUS"); + break; + case BIC_SENSOR_SYS_BOOT_STAT: + sprintf(name, "SYS_BOOT_STAT"); + break; + case BIC_SENSOR_CPU_DIMM_HOT: + sprintf(name, "CPU_DIMM_HOT"); + break; + case BIC_SENSOR_PROC_FAIL: + sprintf(name, "PROC_FAIL"); + break; + case BIC_SENSOR_VR_HOT: + sprintf(name, "VR_HOT"); + break; + default: + sprintf(name, ""); + break; } - break; + case FRU_SPB: switch(sensor_num) { case SP_SENSOR_INLET_TEMP: - sprintf(name, "SP_SENSOR_INLET_TEMP"); + sprintf(name, "SP_INLET_TEMP"); break; case SP_SENSOR_OUTLET_TEMP: - sprintf(name, "SP_SENSOR_OUTLET_TEMP"); + sprintf(name, "SP_OUTLET_TEMP"); break; case SP_SENSOR_MEZZ_TEMP: - sprintf(name, "SP_SENSOR_MEZZ_TEMP"); + sprintf(name, "SP_MEZZ_TEMP"); break; case SP_SENSOR_FAN0_TACH: - sprintf(name, "SP_SENSOR_FAN0_TACH"); + sprintf(name, "SP_FAN0_TACH"); break; case SP_SENSOR_FAN1_TACH: - sprintf(name, "SP_SENSOR_FAN1_TACH"); + sprintf(name, "SP_FAN1_TACH"); break; case SP_SENSOR_AIR_FLOW: - sprintf(name, "SP_SENSOR_AIR_FLOW"); + sprintf(name, "SP_AIR_FLOW"); break; case SP_SENSOR_P5V: - sprintf(name, "SP_SENSOR_P5V"); + sprintf(name, "SP_P5V"); break; case SP_SENSOR_P12V: - sprintf(name, "SP_SENSOR_P12V"); + sprintf(name, "SP_P12V"); break; case SP_SENSOR_P3V3_STBY: - sprintf(name, "SP_SENSOR_P3V3_STBY"); - break; - case SP_SENSOR_P12V_SLOT0: - sprintf(name, "SP_SENSOR_P12V_SLOT0"); + sprintf(name, "SP_P3V3_STBY"); break; case SP_SENSOR_P12V_SLOT1: - sprintf(name, "SP_SENSOR_P12V_SLOT1"); + sprintf(name, "SP_P12V_SLOT1"); break; case SP_SENSOR_P12V_SLOT2: - sprintf(name, "SP_SENSOR_P12V_SLOT2"); + sprintf(name, "SP_P12V_SLOT2"); break; case SP_SENSOR_P12V_SLOT3: - sprintf(name, "SP_SENSOR_P12V_SLOT3"); + sprintf(name, "SP_P12V_SLOT3"); + break; + case SP_SENSOR_P12V_SLOT4: + sprintf(name, "SP_P12V_SLOT4"); break; case SP_SENSOR_P3V3: - sprintf(name, "SP_SENSOR_P3V3"); + sprintf(name, "SP_P3V3"); break; case SP_SENSOR_HSC_IN_VOLT: - sprintf(name, "SP_SENSOR_HSC_IN_VOLT"); + sprintf(name, "SP_HSC_IN_VOLT"); break; case SP_SENSOR_HSC_OUT_CURR: - sprintf(name, "SP_SENSOR_HSC_OUT_CURR"); + sprintf(name, "SP_HSC_OUT_CURR"); break; case SP_SENSOR_HSC_TEMP: - sprintf(name, "SP_SENSOR_HSC_TEMP"); + sprintf(name, "SP_HSC_TEMP"); break; case SP_SENSOR_HSC_IN_POWER: - sprintf(name, "SP_SENSOR_HSC_IN_POWER"); + sprintf(name, "SP_HSC_IN_POWER"); break; } break; case FRU_NIC: - sprintf(name, ""); + switch(sensor_num) { + case MEZZ_SENSOR_TEMP: + sprintf(name, "MEZZ_SENSOR_TEMP"); + break; + } break; } return 0; @@ -694,85 +784,100 @@ yosemite_sensor_name(uint8_t fru, uint8_t sensor_num, char *name) { int -yosemite_sensor_read(uint8_t slot_id, uint8_t sensor_num, void *value) { - static bool init_done = false; +yosemite_sensor_read(uint8_t fru, uint8_t sensor_num, void *value) { + float volt; float curr; + int ret; + bool discrete; + int i; - if (!init_done) { + switch (fru) { + case FRU_SLOT1: + case FRU_SLOT2: + case FRU_SLOT3: + case FRU_SLOT4: - if (is_server_prsnt(1) && (yosemite_sdr_init(FRU_SLOT1) != 0)) { - return -1; - } + if (!(is_server_prsnt(fru))) { + return -1; + } - if (is_server_prsnt(2) && (yosemite_sdr_init(FRU_SLOT2) != 0)) { - return -1; - } + ret = yosemite_sdr_init(fru); + if (ret < 0) { + return ret; + } - if (is_server_prsnt(3) && (yosemite_sdr_init(FRU_SLOT3) != 0)) { - return -1; - } + discrete = false; - if (is_server_prsnt(4) && (yosemite_sdr_init(FRU_SLOT4) != 0)) { - return -1; - } + i = 0; + while (i < bic_discrete_cnt) { + if (sensor_num == bic_discrete_list[i++]) { + discrete = true; + break; + } + } - init_done = true; - } + return bic_read_sensor_wrapper(fru, sensor_num, discrete, value); - switch(sensor_num) { - // Inlet, Outlet Temp - - case SP_SENSOR_INLET_TEMP: - return read_temp(SP_INLET_TEMP_DEVICE, (float*) value); - case SP_SENSOR_OUTLET_TEMP: - return read_temp(SP_OUTLET_TEMP_DEVICE, (float*) value); - - // Fan Tach Values - case SP_SENSOR_FAN0_TACH: - return read_fan_value(FAN0, FAN_TACH_RPM, (float*) value); - case SP_SENSOR_FAN1_TACH: - return read_fan_value(FAN1, FAN_TACH_RPM, (float*) value); - - // Various Voltages - case SP_SENSOR_P5V: - return read_adc_value(ADC_PIN0, ADC_VALUE, (float*) value); - case SP_SENSOR_P12V: - return read_adc_value(ADC_PIN1, ADC_VALUE, (float*) value); - case SP_SENSOR_P3V3_STBY: - return read_adc_value(ADC_PIN2, ADC_VALUE, (float*) value); - case SP_SENSOR_P12V_SLOT0: - return read_adc_value(ADC_PIN3, ADC_VALUE, (float*) value); - case SP_SENSOR_P12V_SLOT1: - return read_adc_value(ADC_PIN4, ADC_VALUE, (float*) value); - case SP_SENSOR_P12V_SLOT2: - return read_adc_value(ADC_PIN5, ADC_VALUE, (float*) value); - case SP_SENSOR_P12V_SLOT3: - return read_adc_value(ADC_PIN6, ADC_VALUE, (float*) value); - case SP_SENSOR_P3V3: - return read_adc_value(ADC_PIN7, ADC_VALUE, (float*) value); - - // Hot Swap Controller - case SP_SENSOR_HSC_IN_VOLT: - return read_hsc_value(HSC_IN_VOLT, (float*) value); - case SP_SENSOR_HSC_OUT_CURR: - return read_hsc_value(HSC_OUT_CURR, (float*) value); - case SP_SENSOR_HSC_TEMP: - return read_hsc_value(HSC_TEMP, (float*) value); - case SP_SENSOR_HSC_IN_POWER: - if (read_hsc_value(HSC_IN_VOLT, &volt)) { - return -1; - } + case FRU_SPB: + switch(sensor_num) { - if (read_hsc_value(HSC_OUT_CURR, &curr)) { - return -1; - } + // Inlet, Outlet Temp + case SP_SENSOR_INLET_TEMP: + return read_temp(SP_INLET_TEMP_DEVICE, (float*) value); + case SP_SENSOR_OUTLET_TEMP: + return read_temp(SP_OUTLET_TEMP_DEVICE, (float*) value); - * (float*) value = volt * curr; - return 0; - default: - // For all others we assume the sensors are on Monolake - return bic_read_sensor_wrapper(slot_id, sensor_num, value); + // Fan Tach Values + case SP_SENSOR_FAN0_TACH: + return read_fan_value(FAN0, FAN_TACH_RPM, (float*) value); + case SP_SENSOR_FAN1_TACH: + return read_fan_value(FAN1, FAN_TACH_RPM, (float*) value); + + // Various Voltages + case SP_SENSOR_P5V: + return read_adc_value(ADC_PIN0, ADC_VALUE, (float*) value); + case SP_SENSOR_P12V: + return read_adc_value(ADC_PIN1, ADC_VALUE, (float*) value); + case SP_SENSOR_P3V3_STBY: + return read_adc_value(ADC_PIN2, ADC_VALUE, (float*) value); + case SP_SENSOR_P12V_SLOT1: + return read_adc_value(ADC_PIN4, ADC_VALUE, (float*) value); + case SP_SENSOR_P12V_SLOT2: + return read_adc_value(ADC_PIN3, ADC_VALUE, (float*) value); + case SP_SENSOR_P12V_SLOT3: + return read_adc_value(ADC_PIN6, ADC_VALUE, (float*) value); + case SP_SENSOR_P12V_SLOT4: + return read_adc_value(ADC_PIN5, ADC_VALUE, (float*) value); + case SP_SENSOR_P3V3: + return read_adc_value(ADC_PIN7, ADC_VALUE, (float*) value); + + // Hot Swap Controller + case SP_SENSOR_HSC_IN_VOLT: + return read_hsc_value(HSC_IN_VOLT, (float*) value); + case SP_SENSOR_HSC_OUT_CURR: + return read_hsc_value(HSC_OUT_CURR, (float*) value); + case SP_SENSOR_HSC_TEMP: + return read_hsc_value(HSC_TEMP, (float*) value); + case SP_SENSOR_HSC_IN_POWER: + if (read_hsc_value(HSC_IN_VOLT, &volt)) { + return -1; + } + if (read_hsc_value(HSC_OUT_CURR, &curr)) { + return -1; + } + * (float*) value = volt * curr; + return 0; + } + break; + + case FRU_NIC: + switch(sensor_num) { + // Mezz Temp + case MEZZ_SENSOR_TEMP: + return read_nic_temp(MEZZ_SENSOR_TEMP, (float*) value); + } + break; } } diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.h b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.h index 0a33173..8775f15 100644 --- a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.h +++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.h @@ -24,7 +24,6 @@ #include <stdbool.h> #include <openbmc/ipmi.h> #include <openbmc/ipmb.h> -#include <openbmc/sdr.h> #include <facebook/bic.h> #include <facebook/yosemite_common.h> @@ -32,6 +31,30 @@ extern "C" { #endif +#define MAX_SDR_LEN 64 +#define MAX_SENSOR_NUM 0xFF +#define MAX_SENSOR_THRESHOLD 8 +#define MAX_RETRIES_SDR_INIT 30 +#define THERMAL_CONSTANT 255 +#define ERR_NOT_READY -2 + +typedef struct _sensor_info_t { + bool valid; + sdr_full_t sdr; +} sensor_info_t; + +/* Enum for type of Upper and Lower threshold values */ +enum { + UCR_THRESH = 0x01, + UNC_THRESH, + UNR_THRESH, + LCR_THRESH, + LNC_THRESH, + LNR_THRESH, + POS_HYST, + NEG_HYST, +}; + // Sensors under Bridge IC enum { BIC_SENSOR_MB_OUTLET_TEMP = 0x01, @@ -51,6 +74,7 @@ enum { BIC_SENSOR_VCCIN_VR_CURR = 0x23, BIC_SENSOR_VCCIN_VR_VOL = 0x24, BIC_SENSOR_INA230_POWER = 0x29, + BIC_SENSOR_INA230_VOL = 0x2A, BIC_SENSOR_POST_ERR = 0x2B, //Event-only BIC_SENSOR_SOC_PACKAGE_PWR = 0x2C, BIC_SENSOR_SOC_TJMAX = 0x30, @@ -63,9 +87,9 @@ enum { BIC_SENSOR_VCC_SCSUS_VR_POUT = 0x38, BIC_SENSOR_VCC_GBE_VR_POUT = 0x39, BIC_SENSOR_POWER_THRESH_EVENT = 0x3B, //Event-only - //BIC_SENSOR_1V05_PCH_VR_POUT = 0x40, BIC_SENSOR_MACHINE_CHK_ERR = 0x40, //Event-only BIC_SENSOR_PCIE_ERR = 0x41, //Event-only + BIC_SENSOR_1V05_PCH_VR_POUT = 0x42, BIC_SENSOR_OTHER_IIO_ERR = 0x43, //Event-only BIC_SENSOR_PROC_HOT_EXT = 0x51, //Event-only BIC_SENSOR_VCC_GBE_VR_VOL = 0x54, @@ -102,10 +126,10 @@ enum { SP_SENSOR_P5V = 0xE0, SP_SENSOR_P12V = 0xE1, SP_SENSOR_P3V3_STBY = 0xE2, - SP_SENSOR_P12V_SLOT0 = 0xE3, - SP_SENSOR_P12V_SLOT1 = 0xE4, - SP_SENSOR_P12V_SLOT2 = 0xE5, - SP_SENSOR_P12V_SLOT3 = 0xE6, + SP_SENSOR_P12V_SLOT1 = 0xE3, + SP_SENSOR_P12V_SLOT2 = 0xE4, + SP_SENSOR_P12V_SLOT3 = 0xE5, + SP_SENSOR_P12V_SLOT4 = 0xE6, SP_SENSOR_P3V3 = 0xE7, SP_SENSOR_HSC_IN_VOLT = 0xC0, SP_SENSOR_HSC_OUT_CURR = 0xC1, @@ -113,18 +137,36 @@ enum { SP_SENSOR_HSC_IN_POWER = 0xC3, }; +enum{ + MEZZ_SENSOR_TEMP = 0x01, +}; extern const uint8_t bic_sensor_list[]; +extern const uint8_t bic_discrete_list[]; + extern const uint8_t spb_sensor_list[]; +extern const uint8_t nic_sensor_list[]; + +//extern float spb_sensor_threshold[MAX_SENSOR_NUM][MAX_SENSOR_THRESHOLD + 1]; + +//extern float nic_sensor_threshold[MAX_SENSOR_NUM][MAX_SENSOR_THRESHOLD + 1]; + extern size_t bic_sensor_cnt; +extern size_t bic_discrete_cnt; + extern size_t spb_sensor_cnt; -int yosemite_sensor_read(uint8_t slot_id, uint8_t sensor_num, void *value); +extern size_t nic_sensor_cnt; + +int yosemite_sensor_read(uint8_t fru, uint8_t sensor_num, void *value); int yosemite_sensor_name(uint8_t fru, uint8_t sensor_num, char *name); int yosemite_sensor_units(uint8_t fru, uint8_t sensor_num, char *units); -int get_fru_sdr_path(uint8_t fru, char *path); +int yosemite_sensor_sdr_path(uint8_t fru, char *path); +int yosemite_sensor_threshold(uint8_t fru, uint8_t sensor_num, uint8_t thresh, float *value); +int yosemite_sensor_sdr_init(uint8_t fru, sensor_info_t *sinfo); + #ifdef __cplusplus } // extern "C" |