summaryrefslogtreecommitdiffstats
path: root/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files
diff options
context:
space:
mode:
authorTian Fang <tfang@fb.com>2015-12-14 22:08:40 -0800
committerTian Fang <tfang@fb.com>2015-12-15 09:49:21 -0800
commite65a7944211c70f6b5cfb6cedd73cc31105319de (patch)
tree067082251bc52bc6c09ca87feaa1352d0468a5ac /meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files
parent8a67fbdd0e251bb34d55992b0771edba1837d589 (diff)
downloadast2050-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')
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.c349
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.h25
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/Makefile2
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.c904
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.h53
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/Makefile4
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.c97
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.h3
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.c35
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.h1
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.c8
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/Makefile2
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.c609
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.h58
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"
OpenPOWER on IntegriCloud