summaryrefslogtreecommitdiffstats
path: root/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor
diff options
context:
space:
mode:
Diffstat (limited to 'meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor')
-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
3 files changed, 922 insertions, 0 deletions
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