summaryrefslogtreecommitdiffstats
path: root/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files
diff options
context:
space:
mode:
Diffstat (limited to 'meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files')
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/Makefile11
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.c466
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.h156
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/Makefile11
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.c1151
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.h98
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/Makefile11
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.c55
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.h44
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/Makefile27
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.c86
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.h37
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/Makefile27
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.c116
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.h39
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/Makefile11
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.c778
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.h133
18 files changed, 3257 insertions, 0 deletions
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/Makefile
new file mode 100644
index 0000000..12cb085
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+lib: libbic.so
+
+libbic.so: bic.c
+ $(CC) $(CFLAGS) -fPIC -c -o bic.o bic.c
+ $(CC) -lipmb -shared -o libbic.so bic.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libbic.so
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
new file mode 100644
index 0000000..55cd56b
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.c
@@ -0,0 +1,466 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include "bic.h"
+
+#define FRUID_READ_COUNT_MAX 0x30
+#define SDR_READ_COUNT_MAX 0x1A
+
+enum {
+ IPMB_BUS_SLOT1 = 3,
+ IPMB_BUS_SLOT2 = 1,
+ IPMB_BUS_SLOT3 = 7,
+ IPMB_BUS_SLOT4 = 5,
+};
+
+#pragma pack(push, 1)
+typedef struct _sdr_rec_hdr_t {
+ uint16_t rec_id;
+ uint8_t ver;
+ uint8_t type;
+ uint8_t len;
+} sdr_rec_hdr_t;
+#pragma pack(pop)
+
+// Common IPMB Wrapper function
+
+static int
+get_ipmb_bus_id(uint8_t slot_id) {
+ int bus_id;
+
+ switch(slot_id) {
+ case 1:
+ bus_id = IPMB_BUS_SLOT1;
+ break;
+ case 2:
+ bus_id = IPMB_BUS_SLOT2;
+ break;
+ case 3:
+ bus_id = IPMB_BUS_SLOT3;
+ break;
+ case 4:
+ bus_id = IPMB_BUS_SLOT4;
+ break;
+ default:
+ bus_id = -1;
+ break;
+ }
+
+ return bus_id;
+}
+
+static int
+bic_ipmb_wrapper(uint8_t slot_id, uint8_t netfn, uint8_t cmd,
+ uint8_t *txbuf, uint8_t txlen,
+ uint8_t *rxbuf, uint8_t *rxlen) {
+ ipmb_req_t *req;
+ ipmb_res_t *res;
+ uint8_t rbuf[MAX_IPMB_RES_LEN] = {0};
+ uint8_t tbuf[MAX_IPMB_RES_LEN] = {0};
+ uint8_t tlen = 0;
+ uint8_t rlen = 0;
+ int count = 0;
+ int i = 0;
+ int ret;
+ uint8_t bus_id;
+
+ ret = get_ipmb_bus_id(slot_id);
+ if (ret < 0) {
+ printf("bic_ipmb_wrapper: Wrong Slot ID %d\n", slot_id);
+ return ret;
+ }
+
+ bus_id = (uint8_t) ret;
+
+ req = (ipmb_req_t*)tbuf;
+
+ req->res_slave_addr = BRIDGE_SLAVE_ADDR << 1;
+ req->netfn_lun = netfn << LUN_OFFSET;
+ req->hdr_cksum = req->res_slave_addr +
+ req->netfn_lun;
+ req->hdr_cksum = ZERO_CKSUM_CONST - req->hdr_cksum;
+
+ req->req_slave_addr = BMC_SLAVE_ADDR << 1;
+ req->seq_lun = 0x00;
+ req->cmd = cmd;
+
+ //copy the data to be send
+ if (txlen) {
+ memcpy(req->data, txbuf, txlen);
+ }
+
+ tlen = IPMB_HDR_SIZE + IPMI_REQ_HDR_SIZE + txlen;
+
+ // Invoke IPMB library handler
+ lib_ipmb_handle(bus_id, tbuf, tlen, &rbuf, &rlen);
+ if (rlen == 0) {
+ printf("bic_ipmb_wrapper: Zero bytes received\n");
+ return -1;
+ }
+
+ // Handle IPMB response
+ res = (ipmb_res_t*) rbuf;
+
+ if (res->cc) {
+ printf("bic_ipmb_wrapper: Completion Code: 0x%X\n", res->cc);
+ return -1;
+ }
+
+ // copy the received data back to caller
+ *rxlen = rlen - IPMB_HDR_SIZE - IPMI_RESP_HDR_SIZE;
+ memcpy(rxbuf, res->data, *rxlen);
+
+ return 0;
+}
+
+// Get Device ID
+int
+bic_get_dev_id(uint8_t slot_id, ipmi_dev_id_t *dev_id) {
+ uint8_t rlen = 0;
+ int ret;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_APP_REQ, CMD_APP_GET_DEVICE_ID, NULL, 0, (uint8_t *) dev_id, &rlen);
+
+ return ret;
+}
+
+// Get GPIO value and configuration
+int
+bic_get_gpio(uint8_t slot_id, bic_gpio_t *gpio) {
+ 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);
+
+ 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 rlen = 0;
+ uint8_t tlen = 0;
+ uint32_t pin;
+ int ret;
+
+ pin = 1 << gpio;
+
+ tbuf[0] = pin & 0xFF;
+ tbuf[1] = (pin >> 8) & 0xFF;
+ tbuf[2] = (pin >> 16) & 0xFF;
+ tbuf[3] = (pin >> 24) & 0xFF;
+
+ tlen = 4;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_GPIO_CONFIG, tbuf, tlen, (uint8_t *) gpio_config, &rlen);
+
+ 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 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;
+
+ tlen = 5;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_SET_GPIO_CONFIG,
+ tbuf, tlen, &res, &rlen);
+ return ret;
+}
+
+// Get BIC Configuration
+int
+bic_get_config(uint8_t slot_id, bic_config_t *cfg) {
+ 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);
+ return ret;
+}
+
+// Set BIC Configuration
+int
+bic_set_config(uint8_t slot_id, bic_config_t *cfg) {
+ uint8_t rlen = 0;
+ uint8_t rbuf[4] = {0};
+ int ret;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_SET_CONFIG,
+ (uint8_t *) cfg, 1, rbuf, &rlen);
+ return ret;
+}
+
+// Read POST Buffer
+int
+bic_get_post_buf(uint8_t slot_id, uint8_t *buf, uint8_t *len) {
+ int ret;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_POST_BUF, NULL, 0, buf, len);
+
+ return ret;
+}
+
+// Read 1S server's FRUID
+int
+bic_get_fruid_info(uint8_t slot_id, uint8_t fru_id, ipmi_fruid_info_t *info) {
+ int ret;
+ uint8_t rlen = 0;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_GET_FRUID_INFO, &fru_id, 1, (uint8_t *) info, &rlen);
+
+ return ret;
+}
+
+static int
+_read_fruid(uint8_t slot_id, uint8_t fru_id, uint32_t offset, uint8_t count, uint8_t *rbuf, uint8_t *rlen) {
+ int ret;
+ uint8_t tbuf[4] = {0};
+ uint8_t tlen = 0;
+
+ tbuf[0] = fru_id;
+ tbuf[1] = offset & 0xFF;
+ tbuf[2] = (offset >> 8) & 0xFF;
+ tbuf[3] = count;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_READ_FRUID_DATA, tbuf, 4, rbuf, rlen);
+
+ return ret;
+}
+
+int
+bic_read_fruid(uint8_t slot_id, uint8_t fru_id, const char *path) {
+ int ret;
+ uint32_t nread;
+ uint32_t offset;
+ uint8_t count;
+ uint8_t rbuf[256] = {0};
+ uint8_t rlen = 0;
+ int fd;
+ ipmi_fruid_info_t info;
+
+ // Remove the file if exists already
+ unlink(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);
+ 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);
+ goto error_exit;
+ }
+
+ // Indicates the size of the FRUID
+ nread = (info.size_msb << 8) + (info.size_lsb);
+
+ // Read chunks of FRUID binary data in a loop
+ offset = 0;
+ while (nread > 0) {
+ if (nread > FRUID_READ_COUNT_MAX) {
+ count = FRUID_READ_COUNT_MAX;
+ } else {
+ count = nread;
+ }
+
+ ret = _read_fruid(slot_id, fru_id, offset, count, rbuf, &rlen);
+ if (ret) {
+ printf("bic_read_fruid: ipmb_wrapper fails\n");
+ goto error_exit;
+ }
+
+ // Ignore the first byte as it indicates length of response
+ write(fd, &rbuf[1], rlen-1);
+
+ // Update offset
+ offset += (rlen-1);
+ nread -= (rlen-1);
+ }
+
+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) {
+ int ret;
+ uint8_t rlen = 0;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_GET_SEL_INFO, NULL, 0, (uint8_t *)info, &rlen);
+
+ return ret;
+}
+
+static int
+_get_sel_rsv(uint8_t slot_id, uint16_t *rsv) {
+ int ret;
+ uint8_t rlen = 0;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_RSV_SEL, NULL, 0, (uint8_t *) rsv, &rlen);
+ return ret;
+}
+
+int
+bic_get_sel(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *res, uint8_t *rlen) {
+
+ int ret;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_GET_SEL, (uint8_t *)req, sizeof(ipmi_sel_sdr_req_t), (uint8_t*)res, rlen);
+
+ return ret;
+}
+
+// Read Sensor Data Records (SDR)
+int
+bic_get_sdr_info(uint8_t slot_id, ipmi_sel_sdr_info_t *info) {
+ int ret;
+ uint8_t rlen = 0;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_GET_SDR_INFO, NULL, 0, (uint8_t *) info, &rlen);
+
+ return ret;
+}
+
+static int
+_get_sdr_rsv(uint8_t slot_id, uint16_t *rsv) {
+ int ret;
+ uint8_t rlen = 0;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_RSV_SDR, NULL, 0, (uint8_t *) rsv, &rlen);
+
+ return ret;
+}
+
+static int
+_get_sdr(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *res, uint8_t *rlen) {
+ int ret;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_GET_SDR, (uint8_t *)req, sizeof(ipmi_sel_sdr_req_t), (uint8_t*)res, rlen);
+
+ return ret;
+}
+
+int
+bic_get_sdr(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *res, uint8_t *rlen) {
+ int ret;
+ uint8_t tbuf[MAX_IPMB_RES_LEN] = {0};
+ uint8_t tlen;
+ uint8_t len;
+ ipmi_sel_sdr_res_t *tres;
+ sdr_rec_hdr_t *hdr;
+
+ tres = (ipmi_sel_sdr_res_t *) tbuf;
+
+ // 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);
+ return ret;
+ }
+
+ // Initialize the response length to zero
+ *rlen = 0;
+
+ // Read SDR Record Header
+ req->offset = 0;
+ req->nbytes = sizeof(sdr_rec_hdr_t);
+
+ ret = _get_sdr(slot_id, req, tbuf, &tlen);
+ if (ret) {
+ printf("bic_read_sdr: _get_sdr returns %d\n", ret);
+ return ret;
+ }
+
+ // Copy the next record id to response
+ res->next_rec_id = tres->next_rec_id;
+
+ // Copy the header excluding first two bytes(next_rec_id)
+ memcpy(res->data, tres->data, tlen-2);
+
+ // Update response length and offset for next request
+ *rlen += tlen-2;
+ req->offset = tlen-2;
+
+ // Find length of data from header info
+ hdr = (sdr_rec_hdr_t *) tres->data;
+ len = hdr->len;
+
+ // Keep reading chunks of SDR record in a loop
+ while (len > 0) {
+ if (len > SDR_READ_COUNT_MAX) {
+ req->nbytes = SDR_READ_COUNT_MAX;
+ } else {
+ req->nbytes = len;
+ }
+
+ ret = _get_sdr(slot_id, req, tbuf, &tlen);
+ if (ret) {
+ printf("bic_read_sdr: _get_sdr returns %d\n", ret);
+ return ret;
+ }
+
+ // Copy the data excluding the first two bytes(next_rec_id)
+ memcpy(&res->data[req->offset], tres->data, tlen-2);
+
+ // Update response length, offset for next request, and remaining length
+ *rlen += tlen-2;
+ req->offset += tlen-2;
+ len -= tlen-2;
+ }
+
+ return 0;
+}
+
+int
+bic_read_sensor(uint8_t slot_id, uint8_t sensor_num, ipmi_sensor_reading_t *sensor) {
+ int ret;
+ int rlen = 0;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_SENSOR_REQ, CMD_SENSOR_GET_SENSOR_READING, (uint8_t *)&sensor_num, 1, (uint8_t *)sensor, &rlen);
+
+ 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
new file mode 100644
index 0000000..47b0baa
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.h
@@ -0,0 +1,156 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __BIC_H__
+#define __BIC_H__
+
+#include <openbmc/ipmi.h>
+#include <openbmc/ipmb.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_GPIO_PINS 32
+
+// GPIO PINS
+enum {
+ PWRGOOD_CPU = 0x0,
+ PWRGD_PCH_PWROK,
+ PVDDR_VRHOT_N,
+ PVCCIN_VRHOT_N,
+ FM_FAST_PROCHOT_N,
+ PCHHOT_CPU_N,
+ FM_CPLD_CPU_DIMM_EVENT_CO_N,
+ FM_CPLD_BDXDE_THERMTRIP_N,
+ THERMTRIP_PCH_N,
+ FM_CPLD_FIVR_FAULT,
+ FM_BDXDE_CATERR_LVT3_N,
+ FM_BDXDE_ERR2_LVT3_N,
+ FM_BDXDE_ERR1_LVT3_N,
+ FM_BDXDE_ERR0_LVT3_N,
+ SLP_S4_N,
+ FM_NMI_EVENT_BMC_N,
+ FM_SMI_BMC_N,
+ RST_PLTRST_BMC_N,
+ FP_RST_BTN_BUF_N,
+ BMC_RST_BTN_OUT_N,
+ FM_BDE_POST_CMPLT_N,
+ FM_BDXDE_SLP3_N,
+ FM_PWR_LED_N,
+ PWRGD_PVCCIN,
+ SVR_ID0,
+ SVR_ID1,
+ SVR_ID2,
+ SVR_ID3,
+ BMC_READY_N,
+ RESERVED_29,
+ RESERVED_30,
+ RESERVED_31,
+};
+
+// Bridge IC Spec
+typedef struct _bic_gpio_t {
+ uint32_t pwrgood_cpu:1;
+ uint32_t pwrgd_pch_pwrok:1;
+ uint32_t pvddr_vrhot_n:1;
+ uint32_t pvccin_vrhot_n:1;
+ uint32_t fm_fast_prochot_n:1;
+ uint32_t pchhot_cpu_n:1;
+ uint32_t fm_cpld_cpu_dimm_event_c0_n:1;
+ uint32_t fm_cpld_bdxde_thermtrip_n:1;
+ uint32_t thermtrip_pch_n:1;
+ uint32_t fm_cpld_fivr_fault:1;
+ uint32_t fm_bdxde_caterr_lvt3_n:1;
+ uint32_t fm_bdxde_err_lvt3_n:3;
+ uint32_t slp_s4_n:1;
+ uint32_t fm_nmi_event_bmc_n:1;
+ uint32_t fm_smi_bmc_n:1;
+ uint32_t rst_pltrst_bmc_n:1;
+ uint32_t fp_rst_btn_buf_n:1;
+ uint32_t bmc_rst_btn_out_n:1;
+ uint32_t fm_bde_post_cmplt_n:1;
+ uint32_t fm_bdxde_slp3_n:1;
+ uint32_t fm_pwr_led_n:1;
+ uint32_t pwrgd_pvccin:1;
+ uint32_t svr_id:4;
+ uint32_t bmc_ready_n:1;
+ uint32_t bmc_com_sw_n:1;
+ uint32_t rsvd:2;
+} bic_gpio_t;
+
+typedef union _bic_gpio_u {
+ uint8_t gpio[4];
+ bic_gpio_t bits;
+} bic_gpio_u;
+
+typedef struct _bic_gpio_config_t {
+ uint8_t dir:1;
+ uint8_t ie:1;
+ uint8_t edge:1;
+ uint8_t trig:2;
+} bic_gpio_config_t;
+
+typedef union _bic_gpio_config_u {
+ uint8_t config;
+ bic_gpio_config_t bits;
+} bic_gpio_config_u;
+
+typedef struct _bic_config_t {
+ uint8_t sol:1;
+ uint8_t post:1;
+ uint8_t kcs:1;
+ uint8_t ipmb:1;
+ uint8_t rsvd:4;
+} bic_config_t;
+
+typedef union _bic_config_u {
+ uint8_t config;
+ bic_config_t bits;
+} bic_config_u;
+
+int bic_get_dev_id(uint8_t slot_id, ipmi_dev_id_t *id);
+
+int bic_get_bic_config(uint8_t slot_id, bic_config_t *cfg);
+int bic_set_bic_config(uint8_t slot_id, bic_config_t *cfg);
+
+int bic_get_gpio(uint8_t slot_id, bic_gpio_t *gpio);
+int bic_get_gpio_config(uint8_t slot_id, uint8_t gpio, bic_gpio_config_t *gpio_config);
+int bic_set_gpio_config(uint8_t slot_id, uint8_t gpio, bic_gpio_config_t *gpio_config);
+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_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);
+int bic_get_sel(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *res, uint8_t *rlen);
+
+int bic_get_sdr_info(uint8_t slot_id, ipmi_sel_sdr_info_t *info);
+int bic_get_sdr_rsv(uint8_t slot_id, uint16_t *rsv);
+int bic_get_sdr(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *res, uint8_t *rlen);
+
+int bic_read_sensor(uint8_t slot_id, uint8_t sensor_num, ipmi_sensor_reading_t *sensor);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __BIC_H__ */
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/Makefile
new file mode 100644
index 0000000..bab4007
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+lib: libpal.so
+
+libpal.so: pal.c
+ $(CC) $(CFLAGS) -fPIC -c -o pal.o pal.c
+ $(CC) -lbic -lyosemite_common -lyosemite_fruid -lyosemite_sensor -shared -o libpal.so pal.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libpal.so
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
new file mode 100644
index 0000000..93a5fbf
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.c
@@ -0,0 +1,1151 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
+#include <sys/mman.h>
+#include <string.h>
+#include "pal.h"
+
+#define BIT(value, index) ((value >> index) & 1)
+
+#define YOSEMITE_PLATFORM_NAME "Yosemite"
+#define LAST_KEY "last_key"
+#define YOSEMITE_MAX_NUM_SLOTS 4
+#define GPIO_VAL "/sys/class/gpio/gpio%d/value"
+#define GPIO_DIR "/sys/class/gpio/gpio%d/direction"
+
+#define GPIO_HAND_SW_ID1 138
+#define GPIO_HAND_SW_ID2 139
+#define GPIO_HAND_SW_ID4 140
+#define GPIO_HAND_SW_ID8 141
+
+#define GPIO_RST_BTN 144
+#define GPIO_PWR_BTN 24
+
+#define GPIO_USB_SW0 36
+#define GPIO_USB_SW1 37
+
+#define GPIO_UART_SEL0 32
+#define GPIO_UART_SEL1 33
+#define GPIO_UART_SEL2 34
+#define GPIO_UART_RX 35
+
+#define GPIO_POSTCODE_0 48
+#define GPIO_POSTCODE_1 49
+#define GPIO_POSTCODE_2 50
+#define GPIO_POSTCODE_3 51
+#define GPIO_POSTCODE_4 124
+#define GPIO_POSTCODE_5 125
+#define GPIO_POSTCODE_6 126
+#define GPIO_POSTCODE_7 127
+
+#define GPIO_DBG_CARD_PRSNT 137
+
+#define PAGE_SIZE 0x1000
+#define AST_SCU_BASE 0x1e6e2000
+#define PIN_CTRL1_OFFSET 0x80
+#define PIN_CTRL2_OFFSET 0x84
+
+#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 };
+const char pal_fru_list[] = "all, slot1, slot2, slot3, slot4, spb, nic";
+const char pal_server_list[] = "slot1, slot2, slot3, slot4";
+
+char * key_list[] = {
+"pwr_server1_last_state",
+"pwr_server2_last_state",
+"pwr_server3_last_state",
+"pwr_server4_last_state",
+"slot1_por_cfg",
+"slot2_por_cfg",
+"slot3_por_cfg",
+"slot4_por_cfg",
+/* Add more Keys here */
+LAST_KEY /* This is the last key of the list */
+};
+
+// Helper Functions
+static int
+read_device(const char *device, int *value) {
+ FILE *fp;
+ int rc;
+
+ fp = fopen(device, "r");
+ if (!fp) {
+ int err = errno;
+
+ syslog(LOG_INFO, "failed to open device %s", device);
+ return err;
+ }
+
+ rc = fscanf(fp, "%d", value);
+ fclose(fp);
+ if (rc != 1) {
+ syslog(LOG_INFO, "failed to read device %s", device);
+ return ENOENT;
+ } else {
+ return 0;
+ }
+}
+
+static int
+write_device(const char *device, const char *value) {
+ FILE *fp;
+ int rc;
+
+ fp = fopen(device, "w");
+ if (!fp) {
+ int err = errno;
+
+ syslog(LOG_INFO, "failed to open device for write %s", device);
+ return err;
+ }
+
+ rc = fputs(value, fp);
+ fclose(fp);
+
+ if (rc < 0) {
+ syslog(LOG_INFO, "failed to write device %s", device);
+ return ENOENT;
+ } else {
+ return 0;
+ }
+}
+
+// Power On the server in a given slot
+static int
+server_power_on(uint8_t slot_id) {
+ char vpath[64] = {0};
+
+ sprintf(vpath, GPIO_VAL, gpio_power[slot_id]);
+
+ if (write_device(vpath, "1")) {
+ return -1;
+ }
+
+ if (write_device(vpath, "0")) {
+ return -1;
+ }
+
+ sleep(1);
+
+ if (write_device(vpath, "1")) {
+ return -1;
+ }
+
+ return 0;
+}
+
+// Power Off the server in given slot
+static int
+server_power_off(uint8_t slot_id, bool gs_flag) {
+ char vpath[64] = {0};
+
+ if (slot_id < 1 || slot_id > 4) {
+ return -1;
+ }
+
+ sprintf(vpath, GPIO_VAL, gpio_power[slot_id]);
+
+ if (write_device(vpath, "1")) {
+ return -1;
+ }
+
+ sleep(1);
+
+ if (write_device(vpath, "0")) {
+ return -1;
+ }
+
+ if (gs_flag) {
+ sleep(DELAY_GRACEFUL_SHUTDOWN);
+ } else {
+ sleep(DELAY_POWER_OFF);
+ }
+
+ if (write_device(vpath, "1")) {
+ 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
+control_sol_txd(uint8_t slot) {
+ uint32_t scu_fd;
+ uint32_t ctrl;
+ void *scu_reg;
+ void *scu_pin_ctrl1;
+ void *scu_pin_ctrl2;
+
+ scu_fd = open("/dev/mem", O_RDWR | O_SYNC );
+ if (scu_fd < 0) {
+ syslog(LOG_ALERT, "control_sol_txd: open fails\n");
+ return -1;
+ }
+
+ scu_reg = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, scu_fd,
+ AST_SCU_BASE);
+ scu_pin_ctrl1 = (char*)scu_reg + PIN_CTRL1_OFFSET;
+ scu_pin_ctrl2 = (char*)scu_reg + PIN_CTRL2_OFFSET;
+
+ switch(slot) {
+ case 1:
+ // Disable UART2's TXD and enable others
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl2;
+ ctrl |= UART1_TXD;
+ ctrl &= (~UART2_TXD); //Disable
+ *(volatile uint32_t*) scu_pin_ctrl2 = ctrl;
+
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl1;
+ ctrl |= UART3_TXD | UART4_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl1 = ctrl;
+ break;
+ case 2:
+ // Disable UART1's TXD and enable others
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl2;
+ ctrl &= (~UART1_TXD); // Disable
+ ctrl |= UART2_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl2 = ctrl;
+
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl1;
+ ctrl |= UART3_TXD | UART4_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl1 = ctrl;
+ break;
+ case 3:
+ // Disable UART4's TXD and enable others
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl2;
+ ctrl |= UART1_TXD | UART2_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl2 = ctrl;
+
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl1;
+ ctrl |= UART3_TXD;
+ ctrl &= (~UART4_TXD); // Disable
+ *(volatile uint32_t*) scu_pin_ctrl1 = ctrl;
+ break;
+ case 4:
+ // Disable UART3's TXD and enable others
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl2;
+ ctrl |= UART1_TXD | UART2_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl2 = ctrl;
+
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl1;
+ ctrl &= (~UART3_TXD); // Disable
+ ctrl |= UART4_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl1 = ctrl;
+ break;
+ default:
+ // Any other slots we need to enable all TXDs
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl2;
+ ctrl |= UART1_TXD | UART2_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl2 = ctrl;
+
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl1;
+ ctrl |= UART3_TXD | UART4_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl1 = ctrl;
+ break;
+ }
+
+ munmap(scu_reg, PAGE_SIZE);
+ close(scu_fd);
+
+ return 0;
+}
+
+// Display the given POST code using GPIO port
+static int
+pal_post_display(uint8_t status) {
+ char path[64] = {0};
+ int ret;
+ char *val;
+
+ syslog(LOG_ALERT, "pal_post_display: status is %d\n", status);
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_0);
+
+ if (BIT(status, 0)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_1);
+ if (BIT(status, 1)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_2);
+ if (BIT(status, 2)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_3);
+ if (BIT(status, 3)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_4);
+ if (BIT(status, 4)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_5);
+ if (BIT(status, 5)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_6);
+ if (BIT(status, 6)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_7);
+ if (BIT(status, 7)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+post_exit:
+ if (ret) {
+ syslog(LOG_ALERT, "write_device failed for %s\n", path);
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+// Platform Abstraction Layer (PAL) Functions
+int
+pal_get_platform_name(char *name) {
+ strcpy(name, YOSEMITE_PLATFORM_NAME);
+
+ return 0;
+}
+
+int
+pal_get_num_slots(uint8_t *num) {
+ *num = YOSEMITE_MAX_NUM_SLOTS;
+
+ return 0;
+}
+
+int
+pal_is_server_prsnt(uint8_t slot_id, uint8_t *status) {
+ int val;
+ char path[64] = {0};
+
+ if (slot_id < 1 || slot_id > 4) {
+ return -1;
+ }
+
+ sprintf(path, GPIO_VAL, gpio_prsnt[slot_id]);
+
+ if (read_device(path, &val)) {
+ return -1;
+ }
+
+ if (val == 0x0) {
+ *status = 1;
+ } else {
+ *status = 0;
+ }
+
+ return 0;
+}
+
+int
+pal_is_debug_card_prsnt(uint8_t *status) {
+ int val;
+ char path[64] = {0};
+
+ sprintf(path, GPIO_VAL, GPIO_DBG_CARD_PRSNT);
+
+ if (read_device(path, &val)) {
+ return -1;
+ }
+
+ // TODO: Logic is reversed until DVT board with h/w fix
+ if (val == 0x0) {
+ *status = 0;
+ } else {
+ *status = 1;
+ }
+
+ return 0;
+}
+
+int
+pal_get_server_power(uint8_t slot_id, uint8_t *status) {
+ int ret;
+ bic_gpio_t gpio;
+
+ ret = bic_get_gpio(slot_id, &gpio);
+ if (ret) {
+ return ret;
+ }
+
+ if (gpio.pwrgood_cpu) {
+ *status = SERVER_POWER_ON;
+ } else {
+ *status = SERVER_POWER_OFF;
+ }
+
+ return 0;
+}
+
+// Power Off, Power On, or Power Reset the server in given slot
+int
+pal_set_server_power(uint8_t slot_id, uint8_t cmd) {
+ uint8_t status;
+ bool gs_flag = false;
+
+ if (slot_id < 1 || slot_id > 4) {
+ return -1;
+ }
+
+ if (pal_get_server_power(slot_id, &status) < 0) {
+ return -1;
+ }
+
+ switch(cmd) {
+ case SERVER_POWER_ON:
+ if (status == SERVER_POWER_ON)
+ return 1;
+ else
+ return server_power_on(slot_id);
+ break;
+
+ case SERVER_POWER_OFF:
+ if (status == SERVER_POWER_OFF)
+ return 1;
+ else
+ return server_power_off(slot_id, gs_flag);
+ 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)
+ return (server_power_on(slot_id));
+ break;
+
+ case SERVER_GRACEFUL_SHUTDOWN:
+ if (status == SERVER_POWER_OFF)
+ return 1;
+ else
+ gs_flag = true;
+ return server_power_off(slot_id, gs_flag);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+pal_sled_cycle(void) {
+ // Remove the adm1275 module as the HSC device is busy
+ system("rmmod adm1275");
+
+ // Send command to HSC power cycle
+ system("i2cset -y 10 0x40 0xd9 c");
+
+ return 0;
+}
+
+// Read the Front Panel Hand Switch and return the position
+int
+pal_get_hand_sw(uint8_t *pos) {
+ char path[64] = {0};
+ int id1, id2, id4, id8;
+ uint8_t loc;
+ // Read 4 GPIOs to read the current position
+ // id1: GPIOR2(138)
+ // id2: GPIOR3(139)
+ // id4: GPIOR4(140)
+ // id8: GPIOR5(141)
+
+ // Read ID1
+ sprintf(path, GPIO_VAL, GPIO_HAND_SW_ID1);
+ if (read_device(path, &id1)) {
+ return -1;
+ }
+
+ // Read ID2
+ sprintf(path, GPIO_VAL, GPIO_HAND_SW_ID2);
+ if (read_device(path, &id2)) {
+ return -1;
+ }
+
+ // Read ID4
+ sprintf(path, GPIO_VAL, GPIO_HAND_SW_ID4);
+ if (read_device(path, &id4)) {
+ return -1;
+ }
+
+ // Read ID8
+ sprintf(path, GPIO_VAL, GPIO_HAND_SW_ID8);
+ if (read_device(path, &id8)) {
+ return -1;
+ }
+
+ loc = ((id8 << 3) | (id4 << 2) | (id2 << 1) | (id1));
+
+ switch(loc) {
+ case 1:
+ case 6:
+ *pos = HAND_SW_SERVER1;
+ break;
+ case 2:
+ case 7:
+ *pos = HAND_SW_SERVER2;
+ break;
+ case 3:
+ case 8:
+ *pos = HAND_SW_SERVER3;
+ break;
+ case 4:
+ case 9:
+ *pos = HAND_SW_SERVER4;
+ break;
+ default:
+ *pos = HAND_SW_BMC;
+ break;
+ }
+
+ return 0;
+}
+
+// Return the Front panel Power Button
+int
+pal_get_pwr_btn(uint8_t *status) {
+ char path[64] = {0};
+ int val;
+
+ sprintf(path, GPIO_VAL, GPIO_PWR_BTN);
+ if (read_device(path, &val)) {
+ return -1;
+ }
+
+ if (val) {
+ *status = 0x0;
+ } else {
+ *status = 0x1;
+ }
+
+ return 0;
+}
+
+// Return the front panel's Reset Button status
+int
+pal_get_rst_btn(uint8_t *status) {
+ char path[64] = {0};
+ int val;
+
+ sprintf(path, GPIO_VAL, GPIO_RST_BTN);
+ if (read_device(path, &val)) {
+ return -1;
+ }
+
+ if (val) {
+ *status = 0x0;
+ } else {
+ *status = 0x1;
+ }
+
+ return 0;
+}
+
+// Update the Reset button input to the server at given slot
+int
+pal_set_rst_btn(uint8_t slot, uint8_t status) {
+ char path[64] = {0};
+ char *val;
+
+ if (slot < 1 || slot > 4) {
+ return -1;
+ }
+
+ if (status) {
+ val = "0";
+ } else {
+ val = "1";
+ }
+
+ sprintf(path, GPIO_VAL, gpio_rst_btn[slot]);
+ if (write_device(path, val)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+// Update the LED for the given slot with the status
+int
+pal_set_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_led[slot]);
+ if (write_device(path, val)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+// Update the USB Mux to the server at given slot
+int
+pal_switch_usb_mux(uint8_t slot) {
+ char *gpio_sw0, *gpio_sw1;
+ char path[64] = {0};
+
+ // Based on the USB mux table in Schematics
+ switch(slot) {
+ case 1:
+ gpio_sw0 = "1";
+ gpio_sw1 = "0";
+ break;
+ case 2:
+ gpio_sw0 = "0";
+ gpio_sw1 = "0";
+ break;
+ case 3:
+ gpio_sw0 = "1";
+ gpio_sw1 = "1";
+ break;
+ case 4:
+ gpio_sw0 = "0";
+ gpio_sw1 = "1";
+ break;
+ default:
+ // Default is for BMC itself
+ return 0;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_USB_SW0);
+ if (write_device(path, gpio_sw0) < 0) {
+ syslog(LOG_ALERT, "write_device failed for %s\n", path);
+ 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);
+ return -1;
+ }
+
+ return 0;
+}
+
+// Switch the UART mux to the given slot
+int
+pal_switch_uart_mux(uint8_t slot) {
+ char * gpio_uart_sel0;
+ char * gpio_uart_sel1;
+ char * gpio_uart_sel2;
+ char * gpio_uart_rx;
+ char path[64] = {0};
+ int ret;
+
+ // Refer the UART select table in schematic
+ switch(slot) {
+ case 1:
+ gpio_uart_sel2 = "0";
+ gpio_uart_sel1 = "0";
+ gpio_uart_sel0 = "1";
+ gpio_uart_rx = "0";
+ break;
+ case 2:
+ gpio_uart_sel2 = "0";
+ gpio_uart_sel1 = "0";
+ gpio_uart_sel0 = "0";
+ gpio_uart_rx = "0";
+ break;
+ case 3:
+ gpio_uart_sel2 = "0";
+ gpio_uart_sel1 = "1";
+ gpio_uart_sel0 = "1";
+ gpio_uart_rx = "0";
+ break;
+ case 4:
+ gpio_uart_sel2 = "0";
+ gpio_uart_sel1 = "1";
+ gpio_uart_sel0 = "0";
+ gpio_uart_rx = "0";
+ break;
+ default:
+ // for all other cases, assume BMC
+ gpio_uart_sel2 = "1";
+ gpio_uart_sel1 = "0";
+ gpio_uart_sel0 = "0";
+ gpio_uart_rx = "1";
+ break;
+ }
+
+ // Diable TXD path from BMC to avoid conflict with SoL
+ ret = control_sol_txd(slot);
+ if (ret) {
+ goto uart_exit;
+ }
+
+ // Enable Debug card path
+ sprintf(path, GPIO_VAL, GPIO_UART_SEL2);
+ ret = write_device(path, gpio_uart_sel2);
+ if (ret) {
+ goto uart_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_UART_SEL1);
+ ret = write_device(path, gpio_uart_sel1);
+ if (ret) {
+ goto uart_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_UART_SEL0);
+ ret = write_device(path, gpio_uart_sel0);
+ if (ret) {
+ goto uart_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_UART_RX);
+ ret = write_device(path, gpio_uart_rx);
+ if (ret) {
+ goto uart_exit;
+ }
+
+uart_exit:
+ if (ret) {
+ syslog(LOG_ALERT, "pal_switch_uart_mux: write_device failed: %s\n", path);
+ return ret;
+ } else {
+ return 0;
+ }
+}
+
+// Enable POST buffer for the server in given slot
+int
+pal_post_enable(uint8_t slot) {
+ int ret;
+ int i;
+ bic_config_t config = {0};
+ bic_config_u *t = (bic_config_u *) &config;
+
+ ret = bic_get_config(slot, &config);
+ if (ret) {
+ syslog(LOG_ALERT, "post_enable: bic_get_config failed\n");
+ return ret;
+ }
+
+ t->bits.post = 1;
+
+ ret = bic_set_config(slot, &config);
+ if (ret) {
+ syslog(LOG_ALERT, "post_enable: bic_set_config failed\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+// Disable POST buffer for the server in given slot
+int
+pal_post_disable(uint8_t slot) {
+ int ret;
+ int i;
+ bic_config_t config = {0};
+ bic_config_u *t = (bic_config_u *) &config;
+
+ ret = bic_get_config(slot, &config);
+ if (ret) {
+ return ret;
+ }
+
+ t->bits.post = 0;
+
+ ret = bic_set_config(slot, &config);
+ if (ret) {
+ return ret;
+ }
+
+ return 0;
+}
+
+// Get the last post code of the given slot
+int
+pal_post_get_last(uint8_t slot, uint8_t *status) {
+ int ret;
+ uint8_t buf[MAX_IPMB_RES_LEN] = {0x0};
+ uint8_t len;
+ int i;
+
+ ret = bic_get_post_buf(slot, buf, &len);
+ if (ret) {
+ return ret;
+ }
+
+ // The post buffer is LIFO and the first byte gives the latest post code
+ *status = buf[0];
+
+ return 0;
+}
+
+// Handle the received post code, for now display it on debug card
+int
+pal_post_handle(uint8_t slot, uint8_t status) {
+ uint8_t prsnt, pos;
+ int ret;
+
+ // Check for debug card presence
+ ret = pal_is_debug_card_prsnt(&prsnt);
+ if (ret) {
+ return ret;
+ }
+
+ // No debug card present, return
+ if (!prsnt) {
+ return 0;
+ }
+
+ // Get the hand switch position
+ ret = pal_get_hand_sw(&pos);
+ if (ret) {
+ return ret;
+ }
+
+ // If the give server is not selected, return
+ if (pos != slot) {
+ return 0;
+ }
+
+ // Display the post code in the debug card
+ ret = pal_post_display(status);
+ if (ret) {
+ return ret;
+ }
+
+ return 0;
+}
+
+
+static int
+read_kv(char *key, char *value) {
+
+ FILE *fp;
+ int rc;
+
+ fp = fopen(key, "r");
+ if (!fp) {
+ int err = errno;
+ syslog(LOG_ALERT, "read_kv: failed to open %s", key);
+ return err;
+ }
+
+ rc = (int) fread(value, 1, MAX_VALUE_LEN, fp);
+ fclose(fp);
+ if (rc <= 0) {
+ syslog(LOG_INFO, "read_kv: failed to read %s", key);
+ return ENOENT;
+ } else {
+ return 0;
+ }
+}
+
+static int
+write_kv(char *key, char *value) {
+
+ FILE *fp;
+ int rc;
+
+ fp = fopen(key, "w");
+ if (!fp) {
+ int err = errno;
+ syslog(LOG_ALERT, "write_kv: failed to open %s", key);
+ return err;
+ }
+
+ rc = fwrite(value, 1, strlen(value), fp);
+ fclose(fp);
+
+ if (rc < 0) {
+ syslog(LOG_ALERT, "write_kv: failed to write to %s", key);
+ return ENOENT;
+ } else {
+ return 0;
+ }
+}
+
+int
+pal_get_fru_id(char *str, uint8_t *fru) {
+
+ return yosemite_common_fru_id(str, fru);
+}
+
+int
+pal_get_fru_sensor_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_sensor_list;
+ *cnt = bic_sensor_cnt;
+ break;
+ case FRU_SPB:
+ *sensor_list = (uint8_t *) spb_sensor_list;
+ *cnt = spb_sensor_cnt;
+ break;
+ case FRU_NIC:
+ *sensor_list = NULL; // (uint8_t *) nic_sensor_list;
+ *cnt = 0; //nic_sensor_cnt;
+ break;
+ default:
+ syslog(LOG_ALERT, "pal_get_fru_sensor_list: Wrong fru id %u", fru);
+ return -1;
+ }
+ return 0;
+}
+
+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_name(uint8_t fru, uint8_t sensor_num, char *name) {
+ return yosemite_sensor_name(fru, sensor_num, name);
+}
+
+int
+pal_get_sensor_units(uint8_t fru, uint8_t sensor_num, char *units) {
+ return yosemite_sensor_units(fru, sensor_num, units);
+}
+
+int
+pal_get_fruid_path(uint8_t fru, char *path) {
+ return yosemite_get_fruid_path(fru, path);
+}
+
+int
+pal_get_fruid_name(uint8_t fru, char *name) {
+ return yosemite_get_fruid_name(fru, name);
+}
+
+
+static int
+get_key_value(char* key, char *value) {
+
+ char kpath[64] = {0};
+
+ sprintf(kpath, KV_STORE, key);
+
+ if (access(KV_STORE_PATH, F_OK) == -1) {
+ mkdir(KV_STORE_PATH, 0777);
+ }
+
+ return read_kv(kpath, value);
+}
+
+static int
+set_key_value(char *key, char *value) {
+
+ char kpath[64] = {0};
+
+ sprintf(kpath, KV_STORE, key);
+
+ if (access(KV_STORE_PATH, F_OK) == -1) {
+ mkdir(KV_STORE_PATH, 0777);
+ }
+
+ return write_kv(kpath, value);
+}
+
+int
+pal_get_key_value(char *key, char *value) {
+
+ int ret;
+ int i;
+
+ i = 0;
+ while(strcmp(key_list[i], LAST_KEY)) {
+
+ 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);
+ return ret;
+ }
+ return ret;
+ }
+ i++;
+ }
+
+ return -1;
+}
+
+int
+pal_set_key_value(char *key, char *value) {
+
+ int ret;
+ int i;
+
+ i = 0;
+ while(strcmp(key_list[i], LAST_KEY)) {
+
+ 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);
+ return ret;
+ }
+ return ret;
+ }
+ i++;
+ }
+
+ return -1;
+}
+
+int
+pal_get_fru_devtty(uint8_t fru, char *devtty) {
+
+ switch(fru) {
+ case FRU_SLOT1:
+ sprintf(devtty, "/dev/ttyS2");
+ break;
+ case FRU_SLOT2:
+ sprintf(devtty, "/dev/ttyS1");
+ break;
+ case FRU_SLOT3:
+ sprintf(devtty, "/dev/ttyS4");
+ break;
+ case FRU_SLOT4:
+ sprintf(devtty, "/dev/ttyS3");
+ break;
+ default:
+ syslog(LOG_ALERT, "pal_get_fru_devtty: Wrong fru id %u", fru);
+ return -1;
+ }
+ return 0;
+}
+
+void
+pal_dump_key_value(void) {
+ int i;
+ int ret;
+
+ char value[MAX_VALUE_LEN] = {0x0};
+
+ while (strcmp(key_list[i], LAST_KEY)) {
+ printf("%s:", key_list[i]);
+ if (ret = get_key_value(key_list[i], value) < 0) {
+ printf("\n");
+ } else {
+ printf("%s\n", value);
+ }
+ i++;
+ memset(value, 0, MAX_VALUE_LEN);
+ }
+}
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
new file mode 100644
index 0000000..1d9f3b9
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.h
@@ -0,0 +1,98 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __PAL_H__
+#define __PAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <facebook/bic.h>
+#include <facebook/yosemite_common.h>
+#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"
+
+extern char * key_list[];
+extern const char pal_fru_list[];
+extern const char pal_server_list[];
+
+enum {
+ LED_STATE_OFF,
+ LED_STATE_ON,
+};
+
+enum {
+ SERVER_POWER_OFF,
+ SERVER_POWER_ON,
+ SERVER_POWER_CYCLE,
+ SERVER_GRACEFUL_SHUTDOWN,
+};
+
+enum {
+ HAND_SW_SERVER1 = 1,
+ HAND_SW_SERVER2,
+ HAND_SW_SERVER3,
+ HAND_SW_SERVER4,
+ HAND_SW_BMC
+};
+
+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);
+int pal_get_server_power(uint8_t slot_id, uint8_t *status);
+int pal_set_server_power(uint8_t slot_id, uint8_t cmd);
+int pal_sled_cycle(void);
+int pal_is_debug_card_prsnt(uint8_t *status);
+int pal_get_hand_sw(uint8_t *pos);
+int pal_switch_usb_mux(uint8_t slot);
+int pal_switch_uart_mux(uint8_t slot);
+int pal_post_enable(uint8_t slot);
+int pal_post_disable(uint8_t slot);
+int pal_post_get_last(uint8_t slot, uint8_t *post);
+int pal_post_handle(uint8_t slot, uint8_t status);
+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_get_fru_id(char *fru_str, uint8_t *fru);
+int pal_get_fruid_path(uint8_t fru, char *path);
+int pal_get_fruid_name(uint8_t fru, char *name);
+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_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_key_value(char *key, char *value);
+int pal_set_key_value(char *key, char *value);
+void pal_dump_key_value(void);
+int pal_get_fru_devtty(uint8_t fru, char *devtty);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __PAL_H__ */
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
new file mode 100644
index 0000000..76bf61f
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+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
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libyosemite_common.so
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
new file mode 100644
index 0000000..e41690f
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.c
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <math.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
+#include "yosemite_common.h"
+
+int
+yosemite_common_fru_id(char *str, uint8_t *fru) {
+
+ if (!strcmp(str, "all")) {
+ *fru = FRU_ALL;
+ } else if (!strcmp(str, "slot1")) {
+ *fru = FRU_SLOT1;
+ } else if (!strcmp(str, "slot2")) {
+ *fru = FRU_SLOT2;
+ } else if (!strcmp(str, "slot3")) {
+ *fru = FRU_SLOT3;
+ } else if (!strcmp(str, "slot4")) {
+ *fru = FRU_SLOT4;
+ } else if (!strcmp(str, "spb")) {
+ *fru = FRU_SPB;
+ } else if (!strcmp(str, "nic")) {
+ *fru = FRU_NIC;
+ } else {
+ syslog(LOG_ALERT, "yosemite_common_fru_id: Wrong fru id");
+ return -1;
+ }
+
+ 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
new file mode 100644
index 0000000..85d8638
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __YOSEMITE_COMMON_H__
+#define __YOSEMITE_COMMON_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ FRU_ALL = 0,
+ FRU_SLOT1 = 1,
+ FRU_SLOT2 = 2,
+ FRU_SLOT3 = 3,
+ FRU_SLOT4 = 4,
+ FRU_SPB = 5,
+ FRU_NIC = 6,
+};
+
+int yosemite_common_fru_id(char *str, uint8_t *fru);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __YOSEMITE_COMMON_H__ */
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/Makefile
new file mode 100644
index 0000000..eda01dc
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/Makefile
@@ -0,0 +1,27 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+# This program file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+lib: libyosemite_fruid.so
+
+libyosemite_fruid.so: yosemite_fruid.c
+ $(CC) $(CFLAGS) -fPIC -c -o yosemite_fruid.o yosemite_fruid.c
+ $(CC) -lyosemite_common -shared -o libyosemite_fruid.so yosemite_fruid.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libyosemite_fruid.so
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
new file mode 100644
index 0000000..226f2f8
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.c
@@ -0,0 +1,86 @@
+/* Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <syslog.h>
+#include "yosemite_fruid.h"
+
+/* Populate char path[] with the path to the fru's fruid binary dump */
+int
+yosemite_get_fruid_path(uint8_t fru, char *path) {
+ char fname[16] = {0};
+
+ switch(fru) {
+ case FRU_SLOT1:
+ sprintf(fname, "slot1");
+ break;
+ case FRU_SLOT2:
+ sprintf(fname, "slot2");
+ break;
+ case FRU_SLOT3:
+ sprintf(fname, "slot3");
+ break;
+ case FRU_SLOT4:
+ sprintf(fname, "slot4");
+ break;
+ case FRU_SPB:
+ sprintf(fname, "spb");
+ break;
+ case FRU_NIC:
+ sprintf(fname, "nic");
+ break;
+ default:
+ syslog(LOG_ALERT, "yosemite_get_fruid_path: wrong fruid");
+ return -1;
+ }
+
+ sprintf(path, YOSEMITE_FRU_PATH, fname);
+ return 0;
+}
+/* Populate char name[] with the path to the fru's name */
+int
+yosemite_get_fruid_name(uint8_t fru, char *name) {
+
+ switch(fru) {
+ case FRU_SLOT1:
+ sprintf(name, "MonoLake Board 1");
+ break;
+ case FRU_SLOT2:
+ sprintf(name, "MonoLake Board 2");
+ break;
+ case FRU_SLOT3:
+ sprintf(name, "MonoLake Board 3");
+ break;
+ case FRU_SLOT4:
+ sprintf(name, "MonoLake Board 4");
+ break;
+ case FRU_SPB:
+ sprintf(name, "Side Plane Board");
+ break;
+ case FRU_NIC:
+ sprintf(name, "CX4 NIC");
+ break;
+ default:
+ syslog(LOG_ALERT, "yosemite_get_fruid_name: wrong fruid");
+ 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
new file mode 100644
index 0000000..5c01267
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.h
@@ -0,0 +1,37 @@
+/* Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __YOSEMITE_FRUID_H__
+#define __YOSEMITE_FRUID_H__
+
+#include <facebook/yosemite_common.h>
+
+#define YOSEMITE_FRU_PATH "/tmp/fruid_%s.bin"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int yosemite_get_fruid_path(uint8_t fru, char *path);
+int yosemite_get_fruid_name(uint8_t fru, char *name);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __YOSEMITE_FRUID_H__ */
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/Makefile
new file mode 100644
index 0000000..66c0005
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/Makefile
@@ -0,0 +1,27 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+# This program file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program in a file named COPYING; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+
+lib: libyosemite_gpio.so
+
+libyosemite_gpio.so: yosemite_gpio.c
+ $(CC) $(CFLAGS) -fPIC -c -o yosemite_gpio.o yosemite_gpio.c
+ $(CC) -shared -o libyosemite_gpio.so yosemite_gpio.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libyosemite_gpio.so
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
new file mode 100644
index 0000000..ac2c820
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.c
@@ -0,0 +1,116 @@
+/* Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <syslog.h>
+#include "yosemite_gpio.h"
+
+// List of GPIO pins to be monitored
+const uint8_t gpio_pin_list[] = {
+ PWRGOOD_CPU,
+ PWRGD_PCH_PWROK,
+ PVDDR_VRHOT_N,
+ PVCCIN_VRHOT_N,
+ FM_FAST_PROCHOT_N,
+ PCHHOT_CPU_N,
+ FM_CPLD_CPU_DIMM_EVENT_CO_N,
+ FM_CPLD_BDXDE_THERMTRIP_N,
+ THERMTRIP_PCH_N,
+ FM_CPLD_FIVR_FAULT,
+ FM_BDXDE_CATERR_LVT3_N,
+ FM_BDXDE_ERR2_LVT3_N,
+ FM_BDXDE_ERR1_LVT3_N,
+ FM_BDXDE_ERR0_LVT3_N,
+ //SLP_S4_N,
+ FM_NMI_EVENT_BMC_N,
+ FM_SMI_BMC_N,
+ RST_PLTRST_BMC_N,
+ FP_RST_BTN_BUF_N,
+ BMC_RST_BTN_OUT_N,
+ FM_BDE_POST_CMPLT_N,
+ //FM_BDXDE_SLP3_N,
+ //FM_PWR_LED_N,
+ PWRGD_PVCCIN,
+ //SVR_ID0,
+ //SVR_ID1,
+ //SVR_ID2,
+ //SVR_ID3,
+ //BMC_READY_N,
+ //RESERVED_29,
+ //RESERVED_30,
+ //RESERVED_31,
+};
+
+size_t gpio_pin_cnt = sizeof(gpio_pin_list)/sizeof(uint8_t);
+const uint32_t gpio_ass_val = 0x0 | (1 << FM_CPLD_FIVR_FAULT);
+
+const char *gpio_pin_name[] = {
+ "PWRGOOD_CPU",
+ "PWRGD_PCH_PWROK",
+ "PVDDR_VRHOT_N",
+ "PVCCIN_VRHOT_N",
+ "FM_FAST_PROCHOT_N",
+ "PCHHOT_CPU_N",
+ "FM_CPLD_CPU_DIMM_EVENT_CO_N",
+ "FM_CPLD_BDXDE_THERMTRIP_N",
+ "THERMTRIP_PCH_N",
+ "FM_CPLD_FIVR_FAULT",
+ "FM_BDXDE_CATERR_LVT3_N",
+ "FM_BDXDE_ERR2_LVT3_N",
+ "FM_BDXDE_ERR1_LVT3_N",
+ "FM_BDXDE_ERR0_LVT3_N",
+ "SLP_S4_N",
+ "FM_NMI_EVENT_BMC_N",
+ "FM_SMI_BMC_N",
+ "RST_PLTRST_BMC_N",
+ "FP_RST_BTN_BUF_N",
+ "BMC_RST_BTN_OUT_N",
+ "FM_BDE_POST_CMPLT_N",
+ "FM_BDXDE_SLP3_N",
+ "FM_PWR_LED_N",
+ "PWRGD_PVCCIN",
+ "SVR_ID0",
+ "SVR_ID1",
+ "SVR_ID2",
+ "SVR_ID3",
+ "BMC_READY_N",
+ "RESERVED_29",
+ "RESERVED_30",
+ "RESERVED_31"
+};
+
+int
+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);
+ return -1;
+ }
+
+ if (gpio < 0 || gpio > MAX_GPIO_PINS) {
+ syslog(LOG_ALERT, "yosemite_get_gpio_name: Wrong gpio pin %u", gpio);
+ return -1;
+ }
+
+ sprintf(name, "%s", gpio_pin_name[gpio]);
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.h b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.h
new file mode 100644
index 0000000..77808a8
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.h
@@ -0,0 +1,39 @@
+/* Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __YOSEMITE_GPIO_H__
+#define __YOSEMITE_GPIO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <facebook/bic.h>
+
+extern const uint8_t gpio_pin_list[];
+extern const char *gpio_pin_name[];
+extern const uint32_t gpio_ass_val;
+extern size_t gpio_pin_cnt;
+
+int yosemite_get_gpio_name(uint8_t fru, uint8_t gpio, char *name);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __YOSEMITE_GPIO_H__ */
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
new file mode 100644
index 0000000..63b334c
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+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
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libyosemite_sensor.so
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
new file mode 100644
index 0000000..0f25e54
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.c
@@ -0,0 +1,778 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <math.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
+#include "yosemite_sensor.h"
+
+#define LARGEST_DEVICE_NAME 120
+
+#define GPIO_VAL "/sys/class/gpio/gpio%d/value"
+
+#define I2C_BUS_9_DIR "/sys/class/i2c-adapter/i2c-9/"
+#define I2C_BUS_10_DIR "/sys/class/i2c-adapter/i2c-10/"
+
+#define TACH_DIR "/sys/devices/platform/ast_pwm_tacho.0"
+#define ADC_DIR "/sys/devices/platform/ast_adc.0"
+
+#define SP_INLET_TEMP_DEVICE I2C_BUS_9_DIR "9-004e"
+#define SP_OUTLET_TEMP_DEVICE I2C_BUS_9_DIR "9-004f"
+#define HSC_DEVICE I2C_BUS_10_DIR "10-0040"
+
+#define FAN_TACH_RPM "tacho%d_rpm"
+#define ADC_VALUE "adc%d_value"
+#define HSC_IN_VOLT "in1_input"
+#define HSC_OUT_CURR "curr1_input"
+#define HSC_TEMP "temp1_input"
+
+#define UNIT_DIV 1000
+
+#define BIC_SENSOR_READ_NA 0x20
+
+#define MAX_SENSOR_NUM 0xFF
+#define ALL_BYTES 0xFF
+#define LAST_REC_ID 0xFFFF
+
+#define YOSEMITE_SDR_PATH "/tmp/sdr_%s.bin"
+
+// List of BIC sensors to be monitored
+const uint8_t bic_sensor_list[] = {
+ /* Threshold sensors */
+ BIC_SENSOR_MB_OUTLET_TEMP,
+ BIC_SENSOR_VCCIN_VR_TEMP,
+ BIC_SENSOR_VCC_GBE_VR_TEMP,
+ BIC_SENSOR_1V05PCH_VR_TEMP,
+ BIC_SENSOR_SOC_TEMP,
+ BIC_SENSOR_MB_INLET_TEMP,
+ BIC_SENSOR_PCH_TEMP,
+ BIC_SENSOR_SOC_THERM_MARGIN,
+ BIC_SENSOR_VDDR_VR_TEMP,
+ BIC_SENSOR_VCC_GBE_VR_CURR,
+ BIC_SENSOR_1V05_PCH_VR_CURR,
+ BIC_SENSOR_VCCIN_VR_POUT,
+ BIC_SENSOR_VCCIN_VR_CURR,
+ BIC_SENSOR_VCCIN_VR_VOL,
+ BIC_SENSOR_INA230_POWER,
+ BIC_SENSOR_SOC_PACKAGE_PWR,
+ BIC_SENSOR_SOC_TJMAX,
+ BIC_SENSOR_VDDR_VR_POUT,
+ BIC_SENSOR_VDDR_VR_CURR,
+ BIC_SENSOR_VDDR_VR_VOL,
+ BIC_SENSOR_VCC_SCSUS_VR_CURR,
+ BIC_SENSOR_VCC_SCSUS_VR_VOL,
+ BIC_SENSOR_VCC_SCSUS_VR_TEMP,
+ BIC_SENSOR_VCC_SCSUS_VR_POUT,
+ BIC_SENSOR_VCC_GBE_VR_POUT,
+ BIC_SENSOR_VCC_GBE_VR_VOL,
+ BIC_SENSOR_1V05_PCH_VR_VOL,
+ BIC_SENSOR_SOC_DIMMA0_TEMP,
+ BIC_SENSOR_SOC_DIMMA1_TEMP,
+ BIC_SENSOR_SOC_DIMMB0_TEMP,
+ BIC_SENSOR_SOC_DIMMB1_TEMP,
+ BIC_SENSOR_P3V3_MB,
+ BIC_SENSOR_P12V_MB,
+ BIC_SENSOR_P1V05_PCH,
+ BIC_SENSOR_P3V3_STBY_MB,
+ BIC_SENSOR_P5V_STBY_MB,
+ BIC_SENSOR_PV_BAT,
+ BIC_SENSOR_PVDDR,
+ BIC_SENSOR_PVCC_GBE,
+ /* 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,
+};
+
+// List of SPB sensors to be monitored
+const uint8_t spb_sensor_list[] = {
+ SP_SENSOR_INLET_TEMP,
+ SP_SENSOR_OUTLET_TEMP,
+ //SP_SENSOR_MEZZ_TEMP
+ SP_SENSOR_FAN0_TACH,
+ SP_SENSOR_FAN1_TACH,
+ //SP_SENSOR_AIR_FLOW,
+ 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_P3V3,
+ SP_SENSOR_HSC_IN_VOLT,
+ SP_SENSOR_HSC_OUT_CURR,
+ SP_SENSOR_HSC_TEMP,
+ SP_SENSOR_HSC_IN_POWER,
+};
+
+size_t bic_sensor_cnt = sizeof(bic_sensor_list)/sizeof(uint8_t);
+
+size_t spb_sensor_cnt = sizeof(spb_sensor_list)/sizeof(uint8_t);
+
+enum {
+ FAN0 = 0,
+ FAN1,
+};
+
+enum {
+ ADC_PIN0 = 0,
+ ADC_PIN1,
+ ADC_PIN2,
+ ADC_PIN3,
+ ADC_PIN4,
+ ADC_PIN5,
+ ADC_PIN6,
+ 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 int
+read_device(const char *device, int *value) {
+ FILE *fp;
+ int rc;
+
+ fp = fopen(device, "r");
+ if (!fp) {
+ int err = errno;
+
+ syslog(LOG_INFO, "failed to open device %s", device);
+ return err;
+ }
+
+ rc = fscanf(fp, "%d", value);
+ fclose(fp);
+
+ if (rc != 1) {
+ syslog(LOG_INFO, "failed to read device %s", device);
+ return ENOENT;
+ } else {
+ return 0;
+ }
+}
+
+static int
+read_device_float(const char *device, float *value) {
+ FILE *fp;
+ int rc;
+ char tmp[10];
+
+ fp = fopen(device, "r");
+ if (!fp) {
+ int err = errno;
+
+ syslog(LOG_INFO, "failed to open device %s", device);
+ return err;
+ }
+
+ rc = fscanf(fp, "%s", tmp);
+ fclose(fp);
+
+ if (rc != 1) {
+ syslog(LOG_INFO, "failed to read device %s", device);
+ return ENOENT;
+ }
+
+ *value = atof(tmp);
+
+ return 0;
+}
+
+static int
+read_temp(const char *device, float *value) {
+ char full_name[LARGEST_DEVICE_NAME + 1];
+ int tmp;
+
+ snprintf(
+ full_name, LARGEST_DEVICE_NAME, "%s/temp1_input", device);
+ if (read_device(full_name, &tmp)) {
+ return -1;
+ }
+
+ *value = ((float)tmp)/UNIT_DIV;
+
+ return 0;
+}
+
+static int
+read_fan_value(const int fan, const char *device, float *value) {
+ char device_name[LARGEST_DEVICE_NAME];
+ char full_name[LARGEST_DEVICE_NAME];
+
+ snprintf(device_name, LARGEST_DEVICE_NAME, device, fan);
+ snprintf(full_name, LARGEST_DEVICE_NAME, "%s/%s", TACH_DIR, device_name);
+ return read_device_float(full_name, value);
+}
+
+static int
+read_adc_value(const int pin, const char *device, float *value) {
+ char device_name[LARGEST_DEVICE_NAME];
+ char full_name[LARGEST_DEVICE_NAME];
+
+ snprintf(device_name, LARGEST_DEVICE_NAME, device, pin);
+ snprintf(full_name, LARGEST_DEVICE_NAME, "%s/%s", ADC_DIR, device_name);
+ return read_device_float(full_name, value);
+}
+
+static int
+read_hsc_value(const char *device, float *value) {
+ char full_name[LARGEST_DEVICE_NAME];
+ int tmp;
+
+ snprintf(full_name, LARGEST_DEVICE_NAME, "%s/%s", HSC_DEVICE, device);
+ if(read_device(full_name, &tmp)) {
+ return -1;
+ }
+
+ *value = ((float) tmp)/UNIT_DIV;
+
+ return 0;
+}
+
+static int
+bic_read_sensor_wrapper(uint8_t slot_id, uint8_t sensor_num, void *value) {
+ int ret;
+ ipmi_sensor_reading_t sensor;
+
+ ret = bic_read_sensor(slot_id, sensor_num, &sensor);
+ if (ret) {
+ return ret;
+ }
+
+ if (sensor.flags & BIC_SENSOR_READ_NA) {
+ 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);
+ return -1;
+ }
+
+ if (sensor.status) {
+ //printf("bic_read_sensor_wrapper: Status Asserted: 0x%X\n", sensor.status);
+ }
+
+ // 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;
+ }
+
+ // If the SDR is not type1, no need for conversion
+ if (sdr->type !=1) {
+ *(float *) value = sensor.value;
+ return 0;
+ }
+
+ // y = (mx + b * 10^b_exp) * 10^r_exp
+ uint8_t x;
+ uint8_t m_lsb, m_msb, m;
+ uint8_t b_lsb, b_msb, b;
+ int8_t b_exp, r_exp;
+
+ x = sensor.value;
+
+ m_lsb = sdr->m_val;
+ m_msb = sdr->m_tolerance >> 6;
+ m = (m_msb << 8) | m_lsb;
+
+ b_lsb = sdr->b_val;
+ b_msb = sdr->b_accuracy >> 6;
+ b = (b_msb << 8) | b_lsb;
+
+ // exponents are 2's complement 4-bit number
+ b_exp = sdr->rb_exp & 0xF;
+ if (b_exp > 7) {
+ b_exp = (~b_exp + 1) & 0xF;
+ b_exp = -b_exp;
+ }
+ r_exp = (sdr->rb_exp >> 4) & 0xF;
+ if (r_exp > 7) {
+ r_exp = (~r_exp + 1) & 0xF;
+ r_exp = -r_exp;
+ }
+
+ //printf("m:%d, x:%d, b:%d, b_exp:%d, r_exp:%d\n", m, x, b, b_exp, r_exp);
+
+ * (float *) value = ((m * x) + (b * pow(10, b_exp))) * (pow(10, r_exp));
+
+ 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) {
+ case FRU_SLOT1:
+ sinfo = g_sinfo1;
+ break;
+ case FRU_SLOT2:
+ sinfo = g_sinfo2;
+ break;
+ case FRU_SLOT3:
+ sinfo = g_sinfo3;
+ break;
+ case FRU_SLOT4:
+ sinfo = g_sinfo4;
+ break;
+ case FRU_SPB:
+ sinfo = g_sinfo_spb;
+ break;
+ case FRU_NIC:
+ sinfo = g_sinfo_nic;
+ break;
+ default:
+ syslog(LOG_ALERT, "yosemite_sdr_init: Wrong Slot ID\n");
+ return NULL;
+ }
+ return sinfo;
+}
+
+int
+get_fru_sdr_path(uint8_t fru, char *path) {
+
+ char fru_name[16] = {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");
+ 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;
+ }
+
+ 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;
+ }
+
+ if (sdr_init(path, sinfo) < 0) {
+ syslog(LOG_ERR, "yosemite_sdr_init: sdr_init failed for FRU %d", fru);
+ }
+
+ return 0;
+}
+
+static bool
+is_server_prsnt(uint8_t slot_id) {
+ uint8_t gpio;
+ int val;
+ char path[64] = {0};
+
+ switch(slot_id) {
+ case 1:
+ gpio = 61;
+ break;
+ case 2:
+ gpio = 60;
+ break;
+ case 3:
+ gpio = 63;
+ break;
+ case 4:
+ gpio = 62;
+ break;
+ default:
+ return 0;
+ }
+
+ sprintf(path, GPIO_VAL, gpio);
+
+ if (read_device(path, &val)) {
+ return -1;
+ }
+
+ if (val == 0x0) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/* 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)) {
+ 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;
+ }
+
+ 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:
+ sprintf(units, "C");
+ break;
+ case SP_SENSOR_OUTLET_TEMP:
+ sprintf(units, "C");
+ break;
+ case SP_SENSOR_MEZZ_TEMP:
+ sprintf(units, "C");
+ break;
+ case SP_SENSOR_FAN0_TACH:
+ sprintf(units, "RPM");
+ break;
+ case SP_SENSOR_FAN1_TACH:
+ sprintf(units, "RPM");
+ break;
+ case SP_SENSOR_AIR_FLOW:
+ sprintf(units, "");
+ break;
+ case SP_SENSOR_P5V:
+ sprintf(units, "Volts");
+ break;
+ case SP_SENSOR_P12V:
+ sprintf(units, "Volts");
+ break;
+ 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:
+ sprintf(units, "Volts");
+ break;
+ case SP_SENSOR_P3V3:
+ sprintf(units, "Volts");
+ break;
+ case SP_SENSOR_HSC_IN_VOLT:
+ sprintf(units, "Volts");
+ break;
+ case SP_SENSOR_HSC_OUT_CURR:
+ sprintf(units, "Amps");
+ break;
+ case SP_SENSOR_HSC_TEMP:
+ sprintf(units, "C");
+ break;
+ case SP_SENSOR_HSC_IN_POWER:
+ sprintf(units, "Watts");
+ break;
+ }
+ break;
+ case FRU_NIC:
+ sprintf(units, "");
+ 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;
+
+ if (!init_done) {
+
+ 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:
+ 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;
+ }
+
+ break;
+ case FRU_SPB:
+ switch(sensor_num) {
+ case SP_SENSOR_INLET_TEMP:
+ sprintf(name, "SP_SENSOR_INLET_TEMP");
+ break;
+ case SP_SENSOR_OUTLET_TEMP:
+ sprintf(name, "SP_SENSOR_OUTLET_TEMP");
+ break;
+ case SP_SENSOR_MEZZ_TEMP:
+ sprintf(name, "SP_SENSOR_MEZZ_TEMP");
+ break;
+ case SP_SENSOR_FAN0_TACH:
+ sprintf(name, "SP_SENSOR_FAN0_TACH");
+ break;
+ case SP_SENSOR_FAN1_TACH:
+ sprintf(name, "SP_SENSOR_FAN1_TACH");
+ break;
+ case SP_SENSOR_AIR_FLOW:
+ sprintf(name, "SP_SENSOR_AIR_FLOW");
+ break;
+ case SP_SENSOR_P5V:
+ sprintf(name, "SP_SENSOR_P5V");
+ break;
+ case SP_SENSOR_P12V:
+ sprintf(name, "SP_SENSOR_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");
+ break;
+ case SP_SENSOR_P12V_SLOT1:
+ sprintf(name, "SP_SENSOR_P12V_SLOT1");
+ break;
+ case SP_SENSOR_P12V_SLOT2:
+ sprintf(name, "SP_SENSOR_P12V_SLOT2");
+ break;
+ case SP_SENSOR_P12V_SLOT3:
+ sprintf(name, "SP_SENSOR_P12V_SLOT3");
+ break;
+ case SP_SENSOR_P3V3:
+ sprintf(name, "SP_SENSOR_P3V3");
+ break;
+ case SP_SENSOR_HSC_IN_VOLT:
+ sprintf(name, "SP_SENSOR_HSC_IN_VOLT");
+ break;
+ case SP_SENSOR_HSC_OUT_CURR:
+ sprintf(name, "SP_SENSOR_HSC_OUT_CURR");
+ break;
+ case SP_SENSOR_HSC_TEMP:
+ sprintf(name, "SP_SENSOR_HSC_TEMP");
+ break;
+ case SP_SENSOR_HSC_IN_POWER:
+ sprintf(name, "SP_SENSOR_HSC_IN_POWER");
+ break;
+ }
+ break;
+ case FRU_NIC:
+ sprintf(name, "");
+ break;
+ }
+ return 0;
+}
+
+
+int
+yosemite_sensor_read(uint8_t slot_id, uint8_t sensor_num, void *value) {
+ static bool init_done = false;
+ float volt;
+ float curr;
+
+ if (!init_done) {
+
+ 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(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;
+ }
+
+ if (read_hsc_value(HSC_OUT_CURR, &curr)) {
+ return -1;
+ }
+
+ * (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);
+ }
+}
+
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
new file mode 100644
index 0000000..0a33173
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.h
@@ -0,0 +1,133 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __YOSEMITE_SENSOR_H__
+#define __YOSEMITE_SENSOR_H__
+
+#include <stdbool.h>
+#include <openbmc/ipmi.h>
+#include <openbmc/ipmb.h>
+#include <openbmc/sdr.h>
+#include <facebook/bic.h>
+#include <facebook/yosemite_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Sensors under Bridge IC
+enum {
+ BIC_SENSOR_MB_OUTLET_TEMP = 0x01,
+ BIC_SENSOR_VCCIN_VR_TEMP = 0x02,
+ BIC_SENSOR_VCC_GBE_VR_TEMP = 0x03,
+ BIC_SENSOR_1V05PCH_VR_TEMP = 0x04,
+ BIC_SENSOR_SOC_TEMP = 0x05,
+ BIC_SENSOR_MB_INLET_TEMP = 0x07,
+ BIC_SENSOR_PCH_TEMP = 0x08,
+ BIC_SENSOR_SOC_THERM_MARGIN = 0x09,
+ BIC_SENSOR_VDDR_VR_TEMP = 0x0B,
+ BIC_SENSOR_SYSTEM_STATUS = 0x10, //Discrete
+ BIC_SENSOR_SPS_FW_HLTH = 0x17, //Event-only
+ BIC_SENSOR_VCC_GBE_VR_CURR = 0x20,
+ BIC_SENSOR_1V05_PCH_VR_CURR = 0x21,
+ BIC_SENSOR_VCCIN_VR_POUT = 0x22,
+ BIC_SENSOR_VCCIN_VR_CURR = 0x23,
+ BIC_SENSOR_VCCIN_VR_VOL = 0x24,
+ BIC_SENSOR_INA230_POWER = 0x29,
+ BIC_SENSOR_POST_ERR = 0x2B, //Event-only
+ BIC_SENSOR_SOC_PACKAGE_PWR = 0x2C,
+ BIC_SENSOR_SOC_TJMAX = 0x30,
+ BIC_SENSOR_VDDR_VR_POUT = 0x32,
+ BIC_SENSOR_VDDR_VR_CURR = 0x33,
+ BIC_SENSOR_VDDR_VR_VOL = 0x34,
+ BIC_SENSOR_VCC_SCSUS_VR_CURR = 0x35,
+ BIC_SENSOR_VCC_SCSUS_VR_VOL = 0x36,
+ BIC_SENSOR_VCC_SCSUS_VR_TEMP = 0x37,
+ 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_OTHER_IIO_ERR = 0x43, //Event-only
+ BIC_SENSOR_PROC_HOT_EXT = 0x51, //Event-only
+ BIC_SENSOR_VCC_GBE_VR_VOL = 0x54,
+ BIC_SENSOR_1V05_PCH_VR_VOL = 0x55,
+ BIC_SENSOR_POWER_ERR = 0x56, //Event-only
+ BIC_SENSOR_MEM_ECC_ERR = 0x63, //Event-only
+ BIC_SENSOR_PROC_FAIL = 0x65, //Discrete
+ BIC_SENSOR_SYS_BOOT_STAT = 0x7E, //Discrete
+ BIC_SENSOR_VR_HOT = 0xB2, //Discrete
+ BIC_SENSOR_CPU_DIMM_HOT = 0xB3, //Discrete
+ BIC_SENSOR_SOC_DIMMA0_TEMP = 0xB4,
+ BIC_SENSOR_SOC_DIMMA1_TEMP = 0xB5,
+ BIC_SENSOR_SOC_DIMMB0_TEMP = 0xB6,
+ BIC_SENSOR_SOC_DIMMB1_TEMP = 0xB7,
+ BIC_SENSOR_P3V3_MB = 0xD0,
+ BIC_SENSOR_P12V_MB = 0xD2,
+ BIC_SENSOR_P1V05_PCH = 0xD3,
+ BIC_SENSOR_P3V3_STBY_MB = 0xD5,
+ BIC_SENSOR_P5V_STBY_MB = 0xD6,
+ BIC_SENSOR_PV_BAT = 0xD7,
+ BIC_SENSOR_PVDDR = 0xD8,
+ BIC_SENSOR_PVCC_GBE = 0xD9,
+ BIC_SENSOR_CAT_ERR = 0xEB, //Event-only
+};
+
+// Sensors Under Side Plane
+enum {
+ SP_SENSOR_INLET_TEMP = 0x81,
+ SP_SENSOR_OUTLET_TEMP = 0x80,
+ SP_SENSOR_MEZZ_TEMP = 0x82,
+ SP_SENSOR_FAN0_TACH = 0x46,
+ SP_SENSOR_FAN1_TACH = 0x47,
+ SP_SENSOR_AIR_FLOW = 0x4A,
+ 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_P3V3 = 0xE7,
+ SP_SENSOR_HSC_IN_VOLT = 0xC0,
+ SP_SENSOR_HSC_OUT_CURR = 0xC1,
+ SP_SENSOR_HSC_TEMP = 0xC2,
+ SP_SENSOR_HSC_IN_POWER = 0xC3,
+};
+
+extern const uint8_t bic_sensor_list[];
+
+extern const uint8_t spb_sensor_list[];
+
+extern size_t bic_sensor_cnt;
+
+extern size_t spb_sensor_cnt;
+
+int yosemite_sensor_read(uint8_t slot_id, 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);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __YOSEMITE_SENSOR_H__ */
OpenPOWER on IntegriCloud