@@ -65,6 +65,40 @@ enum ipmi_op {
#define IPMI_SMBIOS_BT 0x03
#define IPMI_SMBIOS_SSIF 0x04
+/*
+ * Used for transferring information to interfaces that add
+ * entries to firmware tables.
+ */
+typedef struct IPMIFwInfo {
+ const char *interface_name;
+ int interface_type;
+ uint8_t ipmi_spec_major_revision;
+ uint8_t ipmi_spec_minor_revision;
+ uint8_t i2c_slave_address;
+ uint32_t uuid;
+
+ uint64_t base_address;
+ uint64_t register_length;
+ uint8_t register_spacing;
+ enum {
+ IPMI_MEMSPACE_IO,
+ IPMI_MEMSPACE_MEM32,
+ IPMI_MEMSPACE_MEM64,
+ IPMI_MEMSPACE_SMBUS
+ } memspace;
+
+ int interrupt_number;
+ enum {
+ IPMI_LEVEL_IRQ,
+ IPMI_EDGE_IRQ
+ } irq_type;
+} IPMIFwInfo;
+
+/*
+ * Called by each instantiated IPMI interface device to get it's uuid.
+ */
+uint32_t ipmi_next_uuid(void);
+
/* IPMI Interface types (KCS, SMIC, BT) are prefixed with this */
#define TYPE_IPMI_INTERFACE_PREFIX "ipmi-interface-"
@@ -127,6 +161,11 @@ typedef struct IPMIInterfaceClass {
* Set by the owner to hold the backend data for the interface.
*/
void *(*get_backend_data)(struct IPMIInterface *s);
+
+ /*
+ * Return the firmware info for a device.
+ */
+ void (*get_fwinfo)(struct IPMIInterface *s, IPMIFwInfo *info);
} IPMIInterfaceClass;
/*
@@ -168,41 +207,6 @@ typedef struct IPMIBmcClass {
*/
void ipmi_bmc_find_and_link(Object *obj, Object **bmc);
-/*
- * Used for transferring information to interfaces that add
- * entries to firmware tables.
- */
-typedef struct IPMIFwInfo {
- const char *interface_name;
- int interface_type;
- uint8_t ipmi_spec_major_revision;
- uint8_t ipmi_spec_minor_revision;
- uint8_t i2c_slave_address;
- uint32_t uuid;
-
- uint64_t base_address;
- uint64_t register_length;
- uint8_t register_spacing;
- enum {
- IPMI_MEMSPACE_IO,
- IPMI_MEMSPACE_MEM32,
- IPMI_MEMSPACE_MEM64,
- IPMI_MEMSPACE_SMBUS
- } memspace;
-
- int interrupt_number;
- enum {
- IPMI_LEVEL_IRQ,
- IPMI_EDGE_IRQ
- } irq_type;
-
- const char *acpi_parent;
-} IPMIFwInfo;
-
-void ipmi_add_fwinfo(IPMIFwInfo *info, Error **errp);
-IPMIFwInfo *ipmi_first_fwinfo(void);
-IPMIFwInfo *ipmi_next_fwinfo(IPMIFwInfo *current);
-
#ifdef IPMI_DEBUG
#define ipmi_debug(fs, ...) \
fprintf(stderr, "IPMI (%s): " fs, __func__, ##__VA_ARGS__)
@@ -30,6 +30,13 @@
#include "qom/object_interfaces.h"
#include "qapi/visitor.h"
+static uint32_t ipmi_current_uuid = 1;
+
+uint32_t ipmi_next_uuid(void)
+{
+ return ipmi_current_uuid++;
+}
+
static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly)
{
switch (op) {
@@ -122,30 +129,3 @@ static void ipmi_register_types(void)
}
type_init(ipmi_register_types)
-
-static IPMIFwInfo *ipmi_fw_info;
-static unsigned int ipmi_fw_info_len;
-
-static uint32_t current_uuid = 1;
-
-void ipmi_add_fwinfo(IPMIFwInfo *info, Error **errp)
-{
- info->uuid = current_uuid++;
- ipmi_fw_info = g_realloc(ipmi_fw_info,
- sizeof(*ipmi_fw_info) * (ipmi_fw_info_len + 1));
- ipmi_fw_info[ipmi_fw_info_len] = *info;
-}
-
-IPMIFwInfo *ipmi_first_fwinfo(void)
-{
- return ipmi_fw_info;
-}
-
-IPMIFwInfo *ipmi_next_fwinfo(IPMIFwInfo *current)
-{
- current++;
- if (current >= &ipmi_fw_info[ipmi_fw_info_len]) {
- return NULL;
- }
- return current;
-}
@@ -390,16 +390,6 @@ static void ipmi_bt_init(IPMIInterface *ii, Error **errp)
memory_region_init_io(&ib->io, NULL, &ipmi_bt_io_ops, ii, "ipmi-bt", 3);
}
-static void ipmi_bt_class_init(IPMIInterfaceClass *iic)
-{
- iic->init = ipmi_bt_init;
- iic->set_atn = ipmi_bt_set_atn;
- iic->handle_rsp = ipmi_bt_handle_rsp;
- iic->handle_if_event = ipmi_bt_handle_event;
- iic->set_irq_enable = ipmi_bt_set_irq_enable;
- iic->reset = ipmi_bt_handle_reset;
-}
-
#define TYPE_ISA_IPMI_BT "isa-ipmi-bt"
#define ISA_IPMI_BT(obj) OBJECT_CHECK(ISAIPMIBTDevice, (obj), \
@@ -409,9 +399,38 @@ typedef struct ISAIPMIBTDevice {
ISADevice dev;
int32_t isairq;
IPMIBT bt;
- IPMIFwInfo fwinfo;
+ uint32_t uuid;
} ISAIPMIBTDevice;
+static void ipmi_bt_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info)
+{
+ ISAIPMIBTDevice *iib = ISA_IPMI_BT(ii);
+
+ info->interface_name = "bt";
+ info->interface_type = IPMI_SMBIOS_BT;
+ info->ipmi_spec_major_revision = 2;
+ info->ipmi_spec_minor_revision = 0;
+ info->base_address = iib->bt.io_base;
+ info->register_length = iib->bt.io_length;
+ info->register_spacing = 1;
+ info->memspace = IPMI_MEMSPACE_IO;
+ info->irq_type = IPMI_LEVEL_IRQ;
+ info->interrupt_number = iib->isairq;
+ info->i2c_slave_address = iib->bt.bmc->slave_addr;
+ info->uuid = iib->uuid;
+}
+
+static void ipmi_bt_class_init(IPMIInterfaceClass *iic)
+{
+ iic->init = ipmi_bt_init;
+ iic->set_atn = ipmi_bt_set_atn;
+ iic->handle_rsp = ipmi_bt_handle_rsp;
+ iic->handle_if_event = ipmi_bt_handle_event;
+ iic->set_irq_enable = ipmi_bt_set_irq_enable;
+ iic->reset = ipmi_bt_handle_reset;
+ iic->get_fwinfo = ipmi_bt_get_fwinfo;
+}
+
static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
{
ISADevice *isadev = ISA_DEVICE(dev);
@@ -424,6 +443,8 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
return;
}
+ iib->uuid = ipmi_next_uuid();
+
iib->bt.bmc->intf = ii;
iic->init(ii, errp);
@@ -438,20 +459,6 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
qdev_set_legacy_instance_id(dev, iib->bt.io_base, iib->bt.io_length);
isa_register_ioport(isadev, &iib->bt.io, iib->bt.io_base);
-
- iib->fwinfo.interface_name = "bt";
- iib->fwinfo.interface_type = IPMI_SMBIOS_BT;
- iib->fwinfo.ipmi_spec_major_revision = 2;
- iib->fwinfo.ipmi_spec_minor_revision = 0;
- iib->fwinfo.base_address = iib->bt.io_base;
- iib->fwinfo.register_length = iib->bt.io_length;
- iib->fwinfo.register_spacing = 1;
- iib->fwinfo.memspace = IPMI_MEMSPACE_IO;
- iib->fwinfo.irq_type = IPMI_LEVEL_IRQ;
- iib->fwinfo.interrupt_number = iib->isairq;
- iib->fwinfo.acpi_parent = "\\_SB.PCI0.ISA";
- iib->fwinfo.i2c_slave_address = iib->bt.bmc->slave_addr;
- ipmi_add_fwinfo(&iib->fwinfo, errp);
}
static const VMStateDescription vmstate_ISAIPMIBTDevice = {
@@ -354,16 +354,6 @@ static void ipmi_kcs_init(IPMIInterface *ii, Error **errp)
memory_region_init_io(&ik->io, NULL, &ipmi_kcs_io_ops, ii, "ipmi-kcs", 2);
}
-static void ipmi_kcs_class_init(IPMIInterfaceClass *iic)
-{
- iic->init = ipmi_kcs_init;
- iic->set_atn = ipmi_kcs_set_atn;
- iic->handle_rsp = ipmi_kcs_handle_rsp;
- iic->handle_if_event = ipmi_kcs_handle_event;
- iic->set_irq_enable = ipmi_kcs_set_irq_enable;
-}
-
-
#define TYPE_ISA_IPMI_KCS "isa-ipmi-kcs"
#define ISA_IPMI_KCS(obj) OBJECT_CHECK(ISAIPMIKCSDevice, (obj), \
TYPE_ISA_IPMI_KCS)
@@ -372,9 +362,37 @@ typedef struct ISAIPMIKCSDevice {
ISADevice dev;
int32_t isairq;
IPMIKCS kcs;
- IPMIFwInfo fwinfo;
+ uint32_t uuid;
} ISAIPMIKCSDevice;
+static void ipmi_kcs_get_fwinfo(IPMIInterface *ii, IPMIFwInfo *info)
+{
+ ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(ii);
+
+ info->interface_name = "kcs";
+ info->interface_type = IPMI_SMBIOS_KCS;
+ info->ipmi_spec_major_revision = 2;
+ info->ipmi_spec_minor_revision = 0;
+ info->base_address = iik->kcs.io_base;
+ info->i2c_slave_address = iik->kcs.bmc->slave_addr;
+ info->register_length = iik->kcs.io_length;
+ info->register_spacing = 1;
+ info->memspace = IPMI_MEMSPACE_IO;
+ info->irq_type = IPMI_LEVEL_IRQ;
+ info->interrupt_number = iik->isairq;
+ info->uuid = iik->uuid;
+}
+
+static void ipmi_kcs_class_init(IPMIInterfaceClass *iic)
+{
+ iic->init = ipmi_kcs_init;
+ iic->set_atn = ipmi_kcs_set_atn;
+ iic->handle_rsp = ipmi_kcs_handle_rsp;
+ iic->handle_if_event = ipmi_kcs_handle_event;
+ iic->set_irq_enable = ipmi_kcs_set_irq_enable;
+ iic->get_fwinfo = ipmi_kcs_get_fwinfo;
+}
+
static void ipmi_isa_realize(DeviceState *dev, Error **errp)
{
ISADevice *isadev = ISA_DEVICE(dev);
@@ -387,6 +405,8 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp)
return;
}
+ iik->uuid = ipmi_next_uuid();
+
iik->kcs.bmc->intf = ii;
iic->init(ii, errp);
@@ -401,20 +421,6 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp)
qdev_set_legacy_instance_id(dev, iik->kcs.io_base, iik->kcs.io_length);
isa_register_ioport(isadev, &iik->kcs.io, iik->kcs.io_base);
-
- iik->fwinfo.interface_name = "kcs";
- iik->fwinfo.interface_type = IPMI_SMBIOS_KCS;
- iik->fwinfo.ipmi_spec_major_revision = 2;
- iik->fwinfo.ipmi_spec_minor_revision = 0;
- iik->fwinfo.base_address = iik->kcs.io_base;
- iik->fwinfo.i2c_slave_address = iik->kcs.bmc->slave_addr;
- iik->fwinfo.register_length = iik->kcs.io_length;
- iik->fwinfo.register_spacing = 1;
- iik->fwinfo.memspace = IPMI_MEMSPACE_IO;
- iik->fwinfo.irq_type = IPMI_LEVEL_IRQ;
- iik->fwinfo.interrupt_number = iik->isairq;
- iik->fwinfo.acpi_parent = "\\_SB.PCI0.ISA";
- ipmi_add_fwinfo(&iik->fwinfo, errp);
}
const VMStateDescription vmstate_ISAIPMIKCSDevice = {