diff options
-rw-r--r-- | discover/ipmi.h | 4 | ||||
-rw-r--r-- | discover/platform-powerpc.c | 91 | ||||
-rw-r--r-- | lib/pb-protocol/pb-protocol.c | 40 | ||||
-rw-r--r-- | lib/types/types.h | 4 | ||||
-rw-r--r-- | ui/ncurses/nc-sysinfo.c | 16 |
5 files changed, 154 insertions, 1 deletions
diff --git a/discover/ipmi.h b/discover/ipmi.h index eb2a183..611cd49 100644 --- a/discover/ipmi.h +++ b/discover/ipmi.h @@ -9,7 +9,9 @@ enum ipmi_netfn { IPMI_NETFN_CHASSIS = 0x0, IPMI_NETFN_SE = 0x04, + IPMI_NETFN_APP = 0x06, IPMI_NETFN_TRANSPORT = 0x0c, + IPMI_NETFN_AMI = 0x3a, }; enum ipmi_cmd { @@ -17,6 +19,8 @@ enum ipmi_cmd { IPMI_CMD_CHASSIS_GET_SYSTEM_BOOT_OPTIONS = 0x09, IPMI_CMD_SENSOR_SET = 0x30, IPMI_CMD_TRANSPORT_GET_LAN_PARAMS = 0x02, + IPMI_CMD_APP_GET_DEVICE_ID = 0x01, + IPMI_CMD_APP_GET_DEVICE_ID_GOLDEN = 0x1a, }; enum ipmi_sensor_ids { diff --git a/discover/platform-powerpc.c b/discover/platform-powerpc.c index 46f81d2..78b76d3 100644 --- a/discover/platform-powerpc.c +++ b/discover/platform-powerpc.c @@ -1023,6 +1023,94 @@ static void get_ipmi_bmc_mac(struct platform *p, uint8_t *buf) } pb_debug("\n"); } + +} + +/* + * Retrieve info from the "Get Device ID" IPMI commands. + * See Chapter 20.1 in the IPMIv2 specification. + */ +static void get_ipmi_bmc_versions(struct platform *p, struct system_info *info) +{ + struct platform_powerpc *platform = p->platform_data; + uint16_t resp_len = 16; + uint8_t resp[16], bcd; + uint32_t aux_version; + int i, rc; + + /* Retrieve info from current side */ + rc = ipmi_transaction(platform->ipmi, IPMI_NETFN_APP, + IPMI_CMD_APP_GET_DEVICE_ID, + NULL, 0, + resp, &resp_len, + ipmi_timeout); + + pb_debug("BMC version resp [%d][%d]:\n", rc, resp_len); + if (resp_len > 0) { + for (i = 0; i < resp_len; i++) { + pb_debug(" %x", resp[i]); + } + pb_debug("\n"); + } + + if (rc == 0 && resp_len == 16) { + info->bmc_current = talloc_array(info, char *, 4); + info->n_bmc_current = 4; + + info->bmc_current[0] = talloc_asprintf(info, "Device ID: 0x%x", + resp[1]); + info->bmc_current[1] = talloc_asprintf(info, "Device Rev: 0x%x", + resp[2]); + bcd = resp[4] & 0x0f; + bcd += 10 * (resp[4] >> 4); + memcpy(&aux_version, &resp[12], sizeof(aux_version)); + info->bmc_current[2] = talloc_asprintf(info, + "Firmware version: %u.%u.%u", + resp[3], bcd, aux_version); + bcd = resp[5] & 0x0f; + bcd += 10 * (resp[5] >> 4); + info->bmc_current[3] = talloc_asprintf(info, "IPMI version: %u", + bcd); + } else + pb_log("Failed to retrieve Device ID from IPMI\n"); + + /* Retrieve info from golden side */ + memset(resp, 0, sizeof(resp)); + resp_len = 16; + rc = ipmi_transaction(platform->ipmi, IPMI_NETFN_AMI, + IPMI_CMD_APP_GET_DEVICE_ID_GOLDEN, + NULL, 0, + resp, &resp_len, + ipmi_timeout); + + pb_debug("BMC golden resp [%d][%d]:\n", rc, resp_len); + if (resp_len > 0) { + for (i = 0; i < resp_len; i++) { + pb_debug(" %x", resp[i]); + } + pb_debug("\n"); + } + + if (rc == 0 && resp_len == 16) { + info->bmc_golden = talloc_array(info, char *, 4); + info->n_bmc_golden = 4; + + info->bmc_golden[0] = talloc_asprintf(info, "Device ID: 0x%x", + resp[1]); + info->bmc_golden[1] = talloc_asprintf(info, "Device Rev: 0x%x", + resp[2]); + bcd = resp[4] & 0x0f; + bcd += 10 * (resp[4] >> 4); + memcpy(&aux_version, &resp[12], sizeof(aux_version)); + info->bmc_golden[2] = talloc_asprintf(info, + "Firmware version: %u.%u.%u", + resp[3], bcd, aux_version); + bcd = resp[5] & 0x0f; + bcd += 10 * (resp[5] >> 4); + info->bmc_golden[3] = talloc_asprintf(info, "IPMI version: %u", + bcd); + } else + pb_log("Failed to retrieve Golden Device ID from IPMI\n"); } static int load_config(struct platform *p, struct config *config) @@ -1097,6 +1185,9 @@ static int get_sysinfo(struct platform *p, struct system_info *sysinfo) if (platform->ipmi) get_ipmi_bmc_mac(p, sysinfo->bmc_mac); + if (platform->ipmi) + get_ipmi_bmc_versions(p, sysinfo); + if (platform->get_platform_versions) platform->get_platform_versions(sysinfo); diff --git a/lib/pb-protocol/pb-protocol.c b/lib/pb-protocol/pb-protocol.c index e99ce86..3953ee1 100644 --- a/lib/pb-protocol/pb-protocol.c +++ b/lib/pb-protocol/pb-protocol.c @@ -232,6 +232,13 @@ int pb_protocol_system_info_len(const struct system_info *sysinfo) for (i = 0; i < sysinfo->n_other; i++) len += 4 + optional_strlen(sysinfo->platform_other[i]); + len += 4; + for (i = 0; i < sysinfo->n_bmc_current; i++) + len += 4 + optional_strlen(sysinfo->bmc_current[i]); + len += 4; + for (i = 0; i < sysinfo->n_bmc_golden; i++) + len += 4 + optional_strlen(sysinfo->bmc_golden[i]); + for (i = 0; i < sysinfo->n_interfaces; i++) { struct interface_info *if_info = sysinfo->interfaces[i]; len += 4 + if_info->hwaddr_size + @@ -412,6 +419,16 @@ int pb_protocol_serialise_system_info(const struct system_info *sysinfo, for (i = 0; i < sysinfo->n_other; i++) pos += pb_protocol_serialise_string(pos, sysinfo->platform_other[i]); + *(uint32_t *)pos = __cpu_to_be32(sysinfo->n_bmc_current); + pos += sizeof(uint32_t); + for (i = 0; i < sysinfo->n_bmc_current; i++) + pos += pb_protocol_serialise_string(pos, sysinfo->bmc_current[i]); + + *(uint32_t *)pos = __cpu_to_be32(sysinfo->n_bmc_golden); + pos += sizeof(uint32_t); + for (i = 0; i < sysinfo->n_bmc_golden; i++) + pos += pb_protocol_serialise_string(pos, sysinfo->bmc_golden[i]); + *(uint32_t *)pos = __cpu_to_be32(sysinfo->n_interfaces); pos += sizeof(uint32_t); @@ -827,7 +844,7 @@ int pb_protocol_deserialise_system_info(struct system_info *sysinfo, if (read_string(sysinfo, &pos, &len, &sysinfo->identifier)) goto out; - /* versions strings for openpower platforms */ + /* Platform version strings for openpower platforms */ if (read_u32(&pos, &len, &sysinfo->n_current)) goto out; sysinfo->platform_current = talloc_array(sysinfo, char *, @@ -848,6 +865,27 @@ int pb_protocol_deserialise_system_info(struct system_info *sysinfo, sysinfo->platform_other[i] = talloc_strdup(sysinfo, tmp); } + /* BMC version strings for openpower platforms */ + if (read_u32(&pos, &len, &sysinfo->n_bmc_current)) + goto out; + sysinfo->bmc_current = talloc_array(sysinfo, char *, + sysinfo->n_bmc_current); + for (i = 0; i < sysinfo->n_bmc_current; i++) { + if (read_string(sysinfo, &pos, &len, &tmp)) + goto out; + sysinfo->bmc_current[i] = talloc_strdup(sysinfo, tmp); + } + + if (read_u32(&pos, &len, &sysinfo->n_bmc_golden)) + goto out; + sysinfo->bmc_golden = talloc_array(sysinfo, char *, + sysinfo->n_bmc_golden); + for (i = 0; i < sysinfo->n_bmc_golden; i++) { + if (read_string(sysinfo, &pos, &len, &tmp)) + goto out; + sysinfo->bmc_golden[i] = talloc_strdup(sysinfo, tmp); + } + /* number of interfaces */ if (read_u32(&pos, &len, &sysinfo->n_interfaces)) goto out; diff --git a/lib/types/types.h b/lib/types/types.h index db4d892..63c1c7c 100644 --- a/lib/types/types.h +++ b/lib/types/types.h @@ -97,6 +97,10 @@ struct system_info { char **platform_other; unsigned int n_current; unsigned int n_other; + char **bmc_current; + char **bmc_golden; + unsigned int n_bmc_current; + unsigned int n_bmc_golden; uint8_t *bmc_mac; struct interface_info **interfaces; unsigned int n_interfaces; diff --git a/ui/ncurses/nc-sysinfo.c b/ui/ncurses/nc-sysinfo.c index c01b352..ca609cc 100644 --- a/ui/ncurses/nc-sysinfo.c +++ b/ui/ncurses/nc-sysinfo.c @@ -81,6 +81,22 @@ static void sysinfo_screen_populate(struct sysinfo_screen *screen, } } + if (sysinfo->n_bmc_current) { + line(NULL); + line("%s", _("BMC current side:")); + for (i = 0; i < sysinfo->n_bmc_current; i++) { + line("\t%s", sysinfo->bmc_current[i] ?: ""); + } + } + + if (sysinfo->n_bmc_golden) { + line(NULL); + line("%s", _("BMC golden side:")); + for (i = 0; i < sysinfo->n_bmc_golden; i++) { + line("\t%s", sysinfo->bmc_golden[i] ?: ""); + } + } + if (sysinfo->n_blockdevs) { line(NULL); line(_("Storage devices")); |