Skip to content

Commit 13878e5

Browse files
Vasant Hegdestewartsmith
Vasant Hegde
authored andcommitted
ipmi: Add BMC firmware version to device tree
BMC Get device ID command gives BMC firmware version details. Lets add this to device tree. User space tools will use this information to display BMC version details. Stewart, I have added bmc information under /ibm,firmware-version node as its firmware version. But may be we should add new node (/bmc/firmware). So that we can keep BMC related information separately. Let me know your thoughts on this. Signed-off-by: Vasant Hegde <[email protected]> Signed-off-by: Stewart Smith <[email protected]>
1 parent c5bff43 commit 13878e5

File tree

4 files changed

+126
-1
lines changed

4 files changed

+126
-1
lines changed

hw/ipmi/Makefile.inc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
SUBDIRS += hw/ipmi
22

33
IPMI_OBJS = ipmi-rtc.o ipmi-power.o ipmi-fru.o ipmi-sel.o
4-
IPMI_OBJS += ipmi-watchdog.o ipmi-sensor.o ipmi-attn.o
4+
IPMI_OBJS += ipmi-watchdog.o ipmi-sensor.o ipmi-attn.o ipmi-info.o
55

66
IPMI = hw/ipmi/built-in.a
77
$(IPMI): $(IPMI_OBJS:%=hw/ipmi/%)

hw/ipmi/ipmi-info.c

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/* Copyright 2018 IBM Corp.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12+
* implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <device.h>
18+
#include <skiboot.h>
19+
#include <stdlib.h>
20+
#include <ipmi.h>
21+
#include <mem_region-malloc.h>
22+
#include <opal.h>
23+
#include <timebase.h>
24+
25+
/*
26+
* Respones data from IPMI Get device ID command (As defined in
27+
* Section 20.1 Get Device ID Command - IPMI standard spec).
28+
*/
29+
struct ipmi_dev_id {
30+
uint8_t dev_id;
31+
uint8_t dev_revision;
32+
uint8_t fw_rev1;
33+
uint8_t fw_rev2;
34+
uint8_t ipmi_ver;
35+
uint8_t add_dev_support;
36+
uint8_t manufactur_id[3];
37+
uint8_t product_id[2];
38+
uint8_t aux_fw_rev[4];
39+
};
40+
static struct ipmi_dev_id *ipmi_dev_id;
41+
42+
/* Got response from BMC? */
43+
static bool bmc_info_waiting = false;
44+
static bool bmc_info_valid = false;
45+
46+
/* This will free ipmi_dev_id structure */
47+
void ipmi_dt_add_bmc_info(void)
48+
{
49+
char buf[8];
50+
struct dt_node *dt_fw_version;
51+
52+
while (bmc_info_waiting)
53+
time_wait_ms(5);
54+
55+
if (!bmc_info_valid)
56+
return;
57+
58+
dt_fw_version = dt_find_by_name(dt_root, "ibm,firmware-versions");
59+
if (!dt_fw_version) {
60+
free(ipmi_dev_id);
61+
return;
62+
}
63+
64+
memset(buf, 0, sizeof(buf));
65+
snprintf(buf, sizeof(buf), "%x.%02x",
66+
ipmi_dev_id->fw_rev1, ipmi_dev_id->fw_rev2);
67+
dt_add_property_string(dt_fw_version, "bmc-firmware-version", buf);
68+
69+
free(ipmi_dev_id);
70+
}
71+
72+
static void ipmi_get_bmc_info_resp(struct ipmi_msg *msg)
73+
{
74+
bmc_info_waiting = false;
75+
76+
if (msg->cc != IPMI_CC_NO_ERROR) {
77+
prlog(PR_ERR, "IPMI: IPMI_BMC_GET_DEVICE_ID cmd returned error"
78+
" [rc : 0x%x]\n", msg->data[0]);
79+
return;
80+
}
81+
82+
bmc_info_valid = true;
83+
memcpy(ipmi_dev_id, msg->data, msg->resp_size);
84+
ipmi_free_msg(msg);
85+
}
86+
87+
int ipmi_get_bmc_info_request(void)
88+
{
89+
int rc;
90+
struct ipmi_msg *msg;
91+
92+
ipmi_dev_id = zalloc(sizeof(struct ipmi_dev_id));
93+
assert(ipmi_dev_id);
94+
95+
msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_BMC_GET_DEVICE_ID,
96+
ipmi_get_bmc_info_resp, NULL, NULL,
97+
0, sizeof(struct ipmi_dev_id));
98+
if (!msg)
99+
return OPAL_NO_MEM;
100+
101+
msg->error = ipmi_get_bmc_info_resp;
102+
prlog(PR_INFO, "IPMI: Requesting IPMI_BMC_GET_DEVICE_ID\n");
103+
rc = ipmi_queue_msg(msg);
104+
if (rc) {
105+
prlog(PR_ERR, "IPMI: Failed to queue IPMI_BMC_GET_DEVICE_ID\n");
106+
ipmi_free_msg(msg);
107+
return rc;
108+
}
109+
110+
bmc_info_waiting = true;
111+
return rc;
112+
}

include/ipmi.h

+7
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
#define IPMI_GET_SEL_TIME IPMI_CODE(IPMI_NETFN_STORAGE, 0x48)
110110
#define IPMI_SET_SEL_TIME IPMI_CODE(IPMI_NETFN_STORAGE, 0x49)
111111
#define IPMI_CHASSIS_CONTROL IPMI_CODE(IPMI_NETFN_CHASSIS, 0x02)
112+
#define IPMI_BMC_GET_DEVICE_ID IPMI_CODE(IPMI_NETFN_APP, 0x01)
112113
#define IPMI_SET_POWER_STATE IPMI_CODE(IPMI_NETFN_APP, 0x06)
113114
#define IPMI_GET_POWER_STATE IPMI_CODE(IPMI_NETFN_APP, 0x07)
114115
#define IPMI_RESET_WDT IPMI_CODE(IPMI_NETFN_APP, 0x22)
@@ -278,4 +279,10 @@ int ipmi_set_boot_count(void);
278279
/* Terminate immediate */
279280
void __attribute__((noreturn)) ipmi_terminate(const char *msg);
280281

282+
/* Get BMC firmware info */
283+
extern int ipmi_get_bmc_info_request(void);
284+
285+
/* Add BMC firmware info to device tree */
286+
extern void ipmi_dt_add_bmc_info(void);
287+
281288
#endif

platforms/astbmc/common.c

+6
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ void astbmc_init(void)
137137
/* Preload PNOR VERSION section */
138138
flash_fw_version_preload();
139139

140+
/* Request BMC information */
141+
ipmi_get_bmc_info_request();
142+
140143
/* As soon as IPMI is up, inform BMC we are in "S0" */
141144
ipmi_set_power_state(IPMI_PWR_SYS_S0_WORKING, IPMI_PWR_NOCHANGE);
142145

@@ -150,6 +153,9 @@ void astbmc_init(void)
150153

151154
/* Add ibm,firmware-versions node */
152155
flash_dt_add_fw_version();
156+
157+
/* Add BMC firmware info to device tree */
158+
ipmi_dt_add_bmc_info();
153159
}
154160

155161
int64_t astbmc_ipmi_power_down(uint64_t request)

0 commit comments

Comments
 (0)