summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--discover/ipmi.h4
-rw-r--r--discover/platform-powerpc.c91
-rw-r--r--lib/pb-protocol/pb-protocol.c40
-rw-r--r--lib/types/types.h4
-rw-r--r--ui/ncurses/nc-sysinfo.c16
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"));
OpenPOWER on IntegriCloud