meta-facebook/meta-fby35/recipes-fby35/show-sys-config/files/show_sys_config.c (235 lines of code) (raw):

/* * show_bmc_config * * 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 <syslog.h> #include <stdint.h> #include <string.h> #include <facebook/bic.h> #include <openbmc/ipmi.h> #include <openbmc/pal.h> #include <jansson.h> #define MAX_RETRY 3 enum { CLASS1 = 1, CLASS2, UNKNOWN_CONFIG = 0xff, }; typedef struct server { uint8_t is_server_present; uint8_t config; uint8_t is_mgmt_cbl_present; uint8_t cbl_sts_val; uint8_t is_1ou_present; uint8_t is_2ou_present; } server_conf; typedef struct conf { uint8_t type; uint8_t sys_config; uint8_t fru_cnt; server_conf server_info[4]; } sys_conf; static const char *prsnt_sts[] = {"Present", "Not Present", "Abnormal state"}; static bool verbosed = false; static bool output_json = false; static bool record_slot_mapping = false; static int get_server_config(uint8_t slot_id, uint8_t *data, uint8_t bmc_location) { int ret = UTIL_EXECUTION_FAIL; int retry = MAX_RETRY; uint8_t tbuf[4] = {0x03, 0x42, 0x01, 0x05}; uint8_t rbuf[1] = {0x00}; uint8_t tlen = 4; uint8_t rlen = 0; uint8_t bic_ready; ret = fby35_common_is_bic_ready(slot_id, &bic_ready); if ( ret < 0 || bic_ready != 1 ) { return UTIL_EXECUTION_FAIL; } do { ret = bic_ipmb_wrapper(slot_id, NETFN_APP_REQ, CMD_APP_MASTER_WRITE_READ, tbuf, tlen, rbuf, &rlen); } while ( ret < 0 && retry-- > 0 ); if ( ret < 0 ) { return UTIL_EXECUTION_FAIL; } data[0] = rbuf[0]; if (record_slot_mapping) { ret = pal_check_sled_mgmt_cbl_id(slot_id, tbuf, true, bmc_location); } else { ret = pal_check_sled_mgmt_cbl_id(slot_id, tbuf, false, bmc_location); } if ( ret < 0 ) { return UTIL_EXECUTION_FAIL; } data[1] = tbuf[0]; data[2] = tbuf[1]; return UTIL_EXECUTION_OK; } static int show_sys_configuration(sys_conf *system) { uint8_t fru_cnt = system->fru_cnt; uint8_t i = 0; uint8_t sts = 0; char config_str[8] = "\0"; char cable_str[64] = "\0"; json_t *root = NULL; json_t *server_info = NULL; json_t *data[4] = {NULL, NULL, NULL, NULL}; if ( system->sys_config == UNKNOWN_CONFIG ) { snprintf(config_str, sizeof(config_str), "%s", "Unknown"); } else { snprintf(config_str, sizeof(config_str), "%X", system->sys_config); } if ( output_json == true ) { //create the object root = json_object(); server_info = json_object(); //set the basic configuration json_object_set_new(root, "Type", json_string((system->type == CLASS1)?"Class 1":"Class 2")); json_object_set_new(root, "Config", json_string(config_str)); //prepare the data for ( i = FRU_SLOT1; i <= fru_cnt; i++) { if ( (system->sys_config == 0xB) || (system->sys_config == 0xD) ) { if ( i == FRU_SLOT2 || i == FRU_SLOT4) { continue; } } //create the object data[i-1] = json_object(); sts = system->server_info[i-1].is_server_present; if ( sts != STATUS_PRSNT ) { json_object_set_new(data[i-1], "Type", json_string("Abnormal - slot not detected")); } else { snprintf(config_str, sizeof(config_str), "%X", system->server_info[i-1].config); json_object_set_new(data[i-1], "Type", json_string(config_str)); sts = system->server_info[i-1].is_mgmt_cbl_present; if (sts == STATUS_ABNORMAL) { snprintf(cable_str, sizeof(cable_str), "Abnormal - Slot%d instead of Slot%d", (system->server_info[i-1].cbl_sts_val >> 4), (system->server_info[i-1].cbl_sts_val & 0x0f)); } else { snprintf(cable_str, sizeof(cable_str), "%s", prsnt_sts[sts]); } json_object_set_new(data[i-1], "SledManagementCable", json_string(cable_str)); sts = system->server_info[i-1].is_1ou_present; json_object_set_new(data[i-1], "FrontExpansionCard", json_string(prsnt_sts[sts])); sts = system->server_info[i-1].is_2ou_present; json_object_set_new(data[i-1], "RiserExpansionCard", json_string(prsnt_sts[sts])); } snprintf(config_str, sizeof(config_str), "slot%X", i); //set up the object info json_object_set_new(server_info, config_str, data[i-1]); } //set up the root info json_object_set_new(root, "server_config", server_info); json_dumpf(root, stdout, 4); //release the resource for ( i = FRU_SLOT1; i <= fru_cnt; i++ ) { json_decref(data[i-1]); } json_decref(server_info); json_decref(root); } else { printf("Type : Class %d, Config: %s\n", system->type, config_str); printf("---------------------------\n"); for ( i = FRU_SLOT1; i <= fru_cnt; i++) { if ( (system->sys_config == 0xB) || (system->sys_config == 0xD) ) { if ( i == FRU_SLOT2 || i == FRU_SLOT4) { continue; } } sts = system->server_info[i-1].is_server_present; if ( sts != STATUS_PRSNT ) { printf("Slot%d : Abnormal - slot not detected\n\n", i); continue; } printf("Slot%d : %s, Config %X\n", i, prsnt_sts[sts], system->server_info[i-1].config); if ( verbosed == true ) { sts = system->server_info[i-1].is_mgmt_cbl_present; if (sts == STATUS_ABNORMAL) { snprintf(cable_str, sizeof(cable_str), "Abnormal - Slot%d instead of Slot%d", (system->server_info[i-1].cbl_sts_val >> 4), (system->server_info[i-1].cbl_sts_val & 0x0f)); } else { snprintf(cable_str, sizeof(cable_str), "%s", prsnt_sts[sts]); } printf(" SledManagementCable: %s\n", cable_str); sts = system->server_info[i-1].is_1ou_present; printf(" FrontExpansionCard: %s\n", prsnt_sts[sts]); sts = system->server_info[i-1].is_2ou_present; printf(" RiserExpansionCard: %s\n", prsnt_sts[sts]); } printf("\n"); } } return UTIL_EXECUTION_OK; } int main(int argc, char **argv) { uint8_t bmc_location = 0; uint8_t is_fru_present = 0; int ret = UTIL_EXECUTION_OK; int i = 0; uint8_t total_fru = 0; uint8_t data[3] = {0}; uint8_t check_sys_config = UNKNOWN_CONFIG; sys_conf sys_info = {0}; for ( i = 1; i < argc; i++ ) { if ( strcmp("-v", argv[i]) == 0 ) { verbosed = true; } else if ( strcmp("-r", argv[i]) == 0 ) { record_slot_mapping = true; } else if ( strcmp("-json", argv[i]) == 0 ) { output_json = true; } } ret = fby35_common_get_bmc_location(&bmc_location); if ( ret < 0 ) { printf("%s() Cannot get the location of BMC", __func__); return UTIL_EXECUTION_FAIL; } if ( bmc_location == BB_BMC ) { total_fru = FRU_SLOT4; sys_info.type = CLASS1; } else { total_fru = FRU_SLOT1; sys_info.type = CLASS2; } sys_info.fru_cnt = total_fru; for ( i = FRU_SLOT1; i <= total_fru; i++ ) { ret = pal_is_fru_prsnt(i, &is_fru_present); if ( ret < 0 || is_fru_present == 0 ) { //the server is not present sys_info.server_info[i-1].is_server_present = STATUS_NOT_PRSNT; } else { ret = get_server_config(i, data, bmc_location); if ( ret < 0 ) { sys_info.server_info[i-1].is_server_present = STATUS_ABNORMAL; } else { uint8_t front_exp_bit = GETBIT(data[0], 2); uint8_t riser_exp_bit = GETBIT(data[0], 3); uint8_t server_config = UNKNOWN_CONFIG; sys_info.server_info[i-1].is_server_present = STATUS_PRSNT; sys_info.server_info[i-1].is_mgmt_cbl_present = data[1]; sys_info.server_info[i-1].cbl_sts_val = data[2]; if ( sys_info.type == CLASS1 ) { sys_info.server_info[i-1].is_1ou_present = (front_exp_bit == 0)?STATUS_PRSNT:STATUS_NOT_PRSNT; } else { sys_info.server_info[i-1].is_1ou_present = STATUS_NOT_PRSNT; front_exp_bit = STATUS_NOT_PRSNT; } sys_info.server_info[i-1].is_2ou_present = (riser_exp_bit == 0)?STATUS_PRSNT:STATUS_NOT_PRSNT; if ( sys_info.type == CLASS2 ) { server_config = 0xD; } else if ( riser_exp_bit == STATUS_PRSNT ) { server_config = 0xB; } else if ( front_exp_bit == STATUS_PRSNT && riser_exp_bit == STATUS_NOT_PRSNT ) { server_config = 0xC; } else { server_config = 0xA; } sys_info.server_info[i-1].config = server_config; } } } //check the sys config for ( i = FRU_SLOT1; i <= total_fru; i++ ) { if ( sys_info.server_info[i-1].is_server_present != STATUS_PRSNT ) { continue; } if ( check_sys_config == UNKNOWN_CONFIG ) { check_sys_config = sys_info.server_info[i-1].config; } else { if ( check_sys_config != sys_info.server_info[i-1].config ) { check_sys_config = UNKNOWN_CONFIG; break; } } } sys_info.sys_config = check_sys_config; return show_sys_configuration(&sys_info); }