ipmi: use a file to load SDRs

The IPMI BMC simulator populates the sdr/sensor tables with a minimal
set of entries (Watchdog). But some qemu platforms might want to use
extra entries for their custom needs.

This patch modifies slighty the initializing routine to take into
account a larger set read from a file. The name of the file to use is
defined through a new 'sdr' property of the simulator device.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Acked-by: Corey Minyard <cminyard@mvista.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Cédric Le Goater 2017-04-05 14:41:31 +02:00 committed by David Gibson
parent 4a44fd26db
commit 8c6fd7f341
2 changed files with 31 additions and 3 deletions

View File

@ -27,6 +27,7 @@
#include "qemu/timer.h" #include "qemu/timer.h"
#include "hw/ipmi/ipmi.h" #include "hw/ipmi/ipmi.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "hw/loader.h"
#define IPMI_NETFN_CHASSIS 0x00 #define IPMI_NETFN_CHASSIS 0x00
@ -213,6 +214,7 @@ struct IPMIBmcSim {
IPMISel sel; IPMISel sel;
IPMISdr sdr; IPMISdr sdr;
IPMISensor sensors[MAX_SENSORS]; IPMISensor sensors[MAX_SENSORS];
char *sdr_filename;
/* Odd netfns are for responses, so we only need the even ones. */ /* Odd netfns are for responses, so we only need the even ones. */
const IPMINetfn *netfns[MAX_NETFNS / 2]; const IPMINetfn *netfns[MAX_NETFNS / 2];
@ -1696,22 +1698,33 @@ static void ipmi_sdr_init(IPMIBmcSim *ibs)
sdrs_size = sizeof(init_sdrs); sdrs_size = sizeof(init_sdrs);
sdrs = init_sdrs; sdrs = init_sdrs;
if (ibs->sdr_filename &&
!g_file_get_contents(ibs->sdr_filename, (gchar **) &sdrs, &sdrs_size,
NULL)) {
error_report("failed to load sdr file '%s'", ibs->sdr_filename);
sdrs_size = sizeof(init_sdrs);
sdrs = init_sdrs;
}
for (i = 0; i < sdrs_size; i += len) { for (i = 0; i < sdrs_size; i += len) {
struct ipmi_sdr_header *sdrh; struct ipmi_sdr_header *sdrh;
if (i + IPMI_SDR_HEADER_SIZE > sdrs_size) { if (i + IPMI_SDR_HEADER_SIZE > sdrs_size) {
error_report("Problem with recid 0x%4.4x", i); error_report("Problem with recid 0x%4.4x", i);
return; break;
} }
sdrh = (struct ipmi_sdr_header *) &sdrs[i]; sdrh = (struct ipmi_sdr_header *) &sdrs[i];
len = ipmi_sdr_length(sdrh); len = ipmi_sdr_length(sdrh);
if (i + len > sdrs_size) { if (i + len > sdrs_size) {
error_report("Problem with recid 0x%4.4x", i); error_report("Problem with recid 0x%4.4x", i);
return; break;
} }
sdr_add_entry(ibs, sdrh, len, NULL); sdr_add_entry(ibs, sdrh, len, NULL);
} }
if (sdrs != init_sdrs) {
g_free(sdrs);
}
} }
static const VMStateDescription vmstate_ipmi_sim = { static const VMStateDescription vmstate_ipmi_sim = {
@ -1780,6 +1793,11 @@ static void ipmi_sim_realize(DeviceState *dev, Error **errp)
vmstate_register(NULL, 0, &vmstate_ipmi_sim, ibs); vmstate_register(NULL, 0, &vmstate_ipmi_sim, ibs);
} }
static Property ipmi_sim_properties[] = {
DEFINE_PROP_STRING("sdrfile", IPMIBmcSim, sdr_filename),
DEFINE_PROP_END_OF_LIST(),
};
static void ipmi_sim_class_init(ObjectClass *oc, void *data) static void ipmi_sim_class_init(ObjectClass *oc, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc);
@ -1787,6 +1805,7 @@ static void ipmi_sim_class_init(ObjectClass *oc, void *data)
dc->hotpluggable = false; dc->hotpluggable = false;
dc->realize = ipmi_sim_realize; dc->realize = ipmi_sim_realize;
dc->props = ipmi_sim_properties;
bk->handle_command = ipmi_sim_handle_command; bk->handle_command = ipmi_sim_handle_command;
} }

View File

@ -425,7 +425,7 @@ possible drivers and properties, use @code{-device help} and
@code{-device @var{driver},help}. @code{-device @var{driver},help}.
Some drivers are: Some drivers are:
@item -device ipmi-bmc-sim,id=@var{id}[,slave_addr=@var{val}] @item -device ipmi-bmc-sim,id=@var{id}[,slave_addr=@var{val}][,sdrfile=@var{file}]
Add an IPMI BMC. This is a simulation of a hardware management Add an IPMI BMC. This is a simulation of a hardware management
interface processor that normally sits on a system. It provides interface processor that normally sits on a system. It provides
@ -437,6 +437,15 @@ This address is the BMC's address on the I2C network of management
controllers. If you don't know what this means, it is safe to ignore controllers. If you don't know what this means, it is safe to ignore
it. it.
@table @option
@item bmc=@var{id}
The BMC to connect to, one of ipmi-bmc-sim or ipmi-bmc-extern above.
@item slave_addr=@var{val}
Define slave address to use for the BMC. The default is 0x20.
@item sdrfile=@var{file}
file containing raw Sensor Data Records (SDR) data. The default is none.
@end table
@item -device ipmi-bmc-extern,id=@var{id},chardev=@var{id}[,slave_addr=@var{val}] @item -device ipmi-bmc-extern,id=@var{id},chardev=@var{id}[,slave_addr=@var{val}]
Add a connection to an external IPMI BMC simulator. Instead of Add a connection to an external IPMI BMC simulator. Instead of