meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bic-util/bic-util.c (288 lines of code) (raw):

/* * bic-util * * 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. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <syslog.h> #include <stdint.h> #include <pthread.h> #include <facebook/bic.h> #include <facebook/yosemite_gpio.h> #include <openbmc/ipmi.h> #define LAST_RECORD_ID 0xFFFF #define MAX_SENSOR_NUM 0xFF #define BYTES_ENTIRE_RECORD 0xFF static const char *option_list[] = { "--get_dev_id", "--get_gpio", "--get_gpio_config", "--get_config", "--get_post_code", "--read_fruid", "--get_sdr", "--read_sensor" }; static void print_usage_help(void) { int i; printf("Usage: bic-util <slot1|slot2|slot3|slot4> <[0..n]data_bytes_to_send>\n"); printf("Usage: bic-util <slot1|slot2|slot3|slot4> <option>\n"); printf(" option:\n"); for (i = 0; i < sizeof(option_list)/sizeof(option_list[0]); i++) printf(" %s\n", option_list[i]); } // Test to Get device ID static int util_get_device_id(uint8_t slot_id) { int ret = 0; ipmi_dev_id_t id = {0}; ret = bic_get_dev_id(slot_id, &id); if (ret) { printf("util_get_device_id: bic_get_dev_id returns %d\n", ret); return ret; } // Print response printf("Device ID: 0x%X\n", id.dev_id); printf("Device Revision: 0x%X\n", id.dev_rev); printf("Firmware Revision: 0x%X:0x%X\n", id.fw_rev1, id.fw_rev2); printf("IPMI Version: 0x%X\n", id.ipmi_ver); printf("Device Support: 0x%X\n", id.dev_support); printf("Manufacturer ID: 0x%X:0x%X:0x%X\n", id.mfg_id[2], id.mfg_id[1], id.mfg_id[0]); printf("Product ID: 0x%X:0x%X\n", id.prod_id[1], id.prod_id[0]); printf("Aux. FW Rev: 0x%X:0x%X:0x%X:0x%X\n", id.aux_fw_rev[0], id.aux_fw_rev[1],id.aux_fw_rev[2],id.aux_fw_rev[3]); return ret; } // Tests for reading GPIO values and configuration static int util_get_gpio(uint8_t slot_id) { int ret = 0; bic_gpio_t gpio = {0}; ret = bic_get_gpio(slot_id, &gpio); if (ret) { printf("util_get_gpio: bic_get_gpio returns %d\n", ret); return ret; } bic_gpio_u *t = (bic_gpio_u*) &gpio; // Print response printf("XDP_CPU_SYSPWROK: %d\n", t->bits.pwrgood_cpu); printf("PWRGD_PCH_PWROK: %d\n", t->bits.pwrgd_pch_pwrok); printf("PVDDR_VRHOT_N: %d\n", t->bits.pvddr_vrhot_n); printf("PVCCIN_VRHOT_N: %d\n", t->bits.pvccin_vrhot_n); printf("FM_FAST_PROCHOT_N: %d\n", t->bits.fm_fast_prochot_n); printf("PCHHOT_CPU_N: %d\n", t->bits.pchhot_cpu_n); printf("FM_CPLD_CPU_DIMM_EVENT_CO_N: %d\n", t->bits.fm_cpld_cpu_dimm_event_c0_n); printf("FM_CPLD_BDXDE_THERMTRIP_N: %d\n", t->bits.fm_cpld_bdxde_thermtrip_n); printf("THERMTRIP_PCH_N: %d\n", t->bits.thermtrip_pch_n); printf("FM_CPLD_FIVR_FAULT: %d\n", t->bits.fm_cpld_fivr_fault); printf("FM_BDXDE_CATERR_LVT3_N: %d\n", t->bits.fm_bdxde_caterr_lvt3_n); printf("FM_BDXDE_ERR_LVT3_N: %d\n", t->bits.fm_bdxde_err_lvt3_n); printf("SLP_S4_N: %d\n", t->bits.slp_s4_n); printf("FM_NMI_EVENT_BMC_N: %d\n", t->bits.fm_nmi_event_bmc_n); printf("FM_SMI_BMC_N: %d\n", t->bits.fm_smi_bmc_n); printf("RST_PLTRST_BMC_N: %d\n", t->bits.rst_pltrst_bmc_n); printf("FP_RST_BTN_BUF_N: %d\n", t->bits.fp_rst_btn_buf_n); printf("BMC_RST_BTN_OUT_N: %d\n", t->bits.bmc_rst_btn_out_n); printf("FM_BDE_POST_CMPLT_N: %d\n", t->bits.fm_bde_post_cmplt_n); printf("FM_BDXDE_SLP3_N: %d\n", t->bits.fm_bdxde_slp3_n); printf("FM_PWR_LED_N: %d\n", t->bits.fm_pwr_led_n); printf("PWRGD_PVCCIN: %d\n", t->bits.pwrgd_pvccin); printf("SVR_ID: %d\n", t->bits.svr_id); printf("BMC_READY_N: %d\n", t->bits.bmc_ready_n); printf("BMC_COM_SW_N: %d\n", t->bits.bmc_com_sw_n); printf("rsvd: %d\n", t->bits.rsvd); return ret; } static int util_get_gpio_config(uint8_t slot_id) { int ret = 0; int i; bic_gpio_config_t gpio_config = {0}; bic_gpio_config_u *t = (bic_gpio_config_u *) &gpio_config; char gpio_name[32]; // Read configuration of all bits for (i = 0; i < gpio_pin_cnt; i++) { ret = bic_get_gpio_config(slot_id, i, &gpio_config); if (ret == -1) { continue; } yosemite_get_gpio_name(slot_id, i, gpio_name); printf("gpio_config for pin#%d (%s):\n", i, gpio_pin_name[i]); printf("Direction: %s", t->bits.dir?"Output,":"Input, "); printf(" Interrupt: %s", t->bits.ie?"Enabled, ":"Disabled,"); printf(" Trigger: %s", t->bits.edge?"Level ":"Edge "); if (t->bits.trig == 0x0) { printf("Trigger, Edge: %s\n", "Falling Edge"); } else if (t->bits.trig == 0x1) { printf("Trigger, Edge: %s\n", "Rising Edge"); } else if (t->bits.trig == 0x2) { printf("Trigger, Edge: %s\n", "Both Edges"); } else { printf("Trigger, Edge: %s\n", "Reserved"); } } return ret; } static int util_get_config(uint8_t slot_id) { int ret = 0; bic_config_t config = {0}; bic_config_u *t = (bic_config_u *) &config; ret = bic_get_config(slot_id, &config); if (ret) { printf("util_get_config: bic_get_config failed\n"); return ret; } printf("SoL Enabled: %s\n", t->bits.sol ? "Enabled" : "Disabled"); printf("POST Enabled: %s\n", t->bits.post ? "Enabled" : "Disabled"); return ret; } // Test to get the POST buffer static int util_get_post_buf(uint8_t slot_id) { int ret = 0; uint8_t buf[MAX_IPMB_RES_LEN] = {0x0}; uint8_t len; int i; ret = bic_get_post_buf(slot_id, buf, &len); if (ret) { printf("util_get_post_buf: bic_get_post_buf returns %d\n", ret); return ret; } printf("util_get_post_buf: returns %d bytes\n", len); for (i = 0; i < len; i++) { if (!(i % 16) && i) printf("\n"); printf("%02X ", buf[i]); } printf("\n"); return ret; } static int util_read_fruid(uint8_t slot_id) { int ret = 0; int fru_size = 0; char path[64] = {0}; sprintf(path, "/tmp/fruid_slot%d.bin", slot_id); ret = bic_read_fruid(slot_id, 0, path, &fru_size); if (ret) { printf("util_read_fruid: bic_read_fruid returns %d, fru_size: %d\n", ret, fru_size); } return ret; } static int util_get_sdr(uint8_t slot_id) { int ret = 0; uint8_t rlen; uint8_t rbuf[MAX_IPMB_RES_LEN] = {0}; ipmi_sel_sdr_req_t req; ipmi_sel_sdr_res_t *res = (ipmi_sel_sdr_res_t *) rbuf; req.rsv_id = 0; req.rec_id = 0; req.offset = 0; req.nbytes = BYTES_ENTIRE_RECORD; while (1) { ret = bic_get_sdr(slot_id, &req, res, &rlen); if (ret) { printf("util_get_sdr:bic_get_sdr returns %d\n", ret); continue; } sdr_full_t *sdr = (sdr_full_t *)res->data; printf("type: %d, ", sdr->type); printf("sensor_num: %d, ", sdr->sensor_num); printf("sensor_type: %d, ", sdr->sensor_type); printf("evt_read_type: %d, ", sdr->evt_read_type); printf("m_val: %d, ", sdr->m_val); printf("m_tolerance: %d, ", sdr->m_tolerance); printf("b_val: %d, ", sdr->b_val); printf("b_accuracy: %d, ", sdr->b_accuracy); printf("accuracy_dir: %d, ", sdr->accuracy_dir); printf("rb_exp: %d,\n", sdr->rb_exp); req.rec_id = res->next_rec_id; if (req.rec_id == LAST_RECORD_ID) { printf("This record is LAST record\n"); break; } } return ret; } // Test to read all Sensors from Monolake Server static int util_read_sensor(uint8_t slot_id) { int ret = 0; int i; ipmi_sensor_reading_t sensor; for (i = 0; i < MAX_SENSOR_NUM; i++) { ret = bic_read_sensor(slot_id, i, &sensor); if (ret) { continue; } printf("sensor#%d: value: 0x%X, flags: 0x%X, status: 0x%X, ext_status: 0x%X\n", i, sensor.value, sensor.flags, sensor.status, sensor.ext_status); } return ret; } static int process_command(uint8_t slot_id, int argc, char **argv) { int i, ret, retry = 2; uint8_t tbuf[256] = {0x00}; uint8_t rbuf[256] = {0x00}; uint8_t tlen = 0; uint8_t rlen = 0; for (i = 0; i < argc; i++) { tbuf[tlen++] = (uint8_t)strtoul(argv[i], NULL, 0); } while (retry >= 0) { ret = bic_ipmb_wrapper(slot_id, tbuf[0]>>2, tbuf[1], &tbuf[2], tlen-2, rbuf, &rlen); if (ret == 0) break; retry--; } if (ret) { printf("BIC no response!\n"); return ret; } for (i = 0; i < rlen; i++) { if (!(i % 16) && i) printf("\n"); printf("%02X ", rbuf[i]); } printf("\n"); return 0; } // TODO: Make it as User selectable tests to run int main(int argc, char **argv) { uint8_t slot_id; int ret = 0; if (argc < 3) { goto err_exit; } if (!strcmp(argv[1], "slot1")) { slot_id = 1; } else if (!strcmp(argv[1] , "slot2")) { slot_id = 2; } else if (!strcmp(argv[1] , "slot3")) { slot_id = 3; } else if (!strcmp(argv[1] , "slot4")) { slot_id = 4; } else { goto err_exit; } if (!strcmp(argv[2], "--get_dev_id")) { ret = util_get_device_id(slot_id); } else if (!strcmp(argv[2], "--get_gpio")) { ret = util_get_gpio(slot_id); } else if (!strcmp(argv[2], "--get_gpio_config")) { ret = util_get_gpio_config(slot_id); } else if (!strcmp(argv[2], "--get_config")) { ret = util_get_config(slot_id); } else if (!strcmp(argv[2], "--get_post_code")) { ret = util_get_post_buf(slot_id); } else if (!strcmp(argv[2], "--read_fruid")) { ret = util_read_fruid(slot_id); } else if (!strcmp(argv[2], "--get_sdr")) { ret = util_get_sdr(slot_id); } else if (!strcmp(argv[2], "--read_sensor")) { ret = util_read_sensor(slot_id); } else if (argc >= 4) { return process_command(slot_id, (argc - 2), (argv + 2)); } else { goto err_exit; } return ret; err_exit: print_usage_help(); return -1; }