* [Qemu-devel] [PATCH v6 1/6] ipmi: rework the fwinfo to be fetched from the interface
2016-05-23 17:40 [Qemu-devel] [PATCH v6 0/6] Add IPMI to firmware tables minyard
@ 2016-05-23 17:40 ` minyard
2016-05-23 17:40 ` [Qemu-devel] [PATCH v6 2/6] pc: Postpone SMBIOS table installation to post machine init minyard
` (4 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: minyard @ 2016-05-23 17:40 UTC (permalink / raw)
To: Igor Mammedov, Michael S . Tsirkin, Paolo Bonzini, qemu-devel,
minyard, cminyard
From: Corey Minyard <cminyard@mvista.com>
Instead of scanning IPMI devices from a fwinfo list, allow
the fwinfo to be fetched from the IPMI interface class.
Then the code looking for IPMI fwinfo can scan devices on a
bus and look for ones that implement the IPMI class.
This will let the ACPI scope be defined by the calling
code so the IPMI code doesn't have to know the scope.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
hw/ipmi/ipmi.c | 34 +++++------------------
hw/ipmi/isa_ipmi_bt.c | 57 +++++++++++++++++++++-----------------
hw/ipmi/isa_ipmi_kcs.c | 56 +++++++++++++++++++++-----------------
include/hw/ipmi/ipmi.h | 74 ++++++++++++++++++++++++++------------------------
4 files changed, 109 insertions(+), 112 deletions(-)
diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c
index 6adec1e..f09f217 100644
--- a/hw/ipmi/ipmi.c
+++ b/hw/ipmi/ipmi.c
@@ -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;
-}
diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c
index aaea12e..f036617 100644
--- a/hw/ipmi/isa_ipmi_bt.c
+++ b/hw/ipmi/isa_ipmi_bt.c
@@ -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 = {
diff --git a/hw/ipmi/isa_ipmi_kcs.c b/hw/ipmi/isa_ipmi_kcs.c
index 2742ce0..9a38f8a 100644
--- a/hw/ipmi/isa_ipmi_kcs.c
+++ b/hw/ipmi/isa_ipmi_kcs.c
@@ -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 = {
diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h
index 74a2b5a..91b83b5 100644
--- a/include/hw/ipmi/ipmi.h
+++ b/include/hw/ipmi/ipmi.h
@@ -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__)
--
2.7.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH v6 2/6] pc: Postpone SMBIOS table installation to post machine init
2016-05-23 17:40 [Qemu-devel] [PATCH v6 0/6] Add IPMI to firmware tables minyard
2016-05-23 17:40 ` [Qemu-devel] [PATCH v6 1/6] ipmi: rework the fwinfo to be fetched from the interface minyard
@ 2016-05-23 17:40 ` minyard
2016-05-23 17:40 ` [Qemu-devel] [PATCH v6 3/6] smbios: Move table build tools into an include file minyard
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: minyard @ 2016-05-23 17:40 UTC (permalink / raw)
To: Igor Mammedov, Michael S . Tsirkin, Paolo Bonzini, qemu-devel,
minyard, cminyard
From: Corey Minyard <cminyard@mvista.com>
This is the same place that the ACPI SSDT table gets added, so that
devices can add themselves to the SMBIOS table.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
hw/i386/pc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 99437e0..c2bc4af 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -764,8 +764,6 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms)
acpi_tables, acpi_tables_len);
fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, kvm_allows_irq0_override());
- pc_build_smbios(fw_cfg);
-
fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE,
&e820_reserve, sizeof(e820_reserve));
fw_cfg_add_file(fw_cfg, "etc/e820", e820_table,
@@ -1181,6 +1179,9 @@ void pc_machine_done(Notifier *notifier, void *data)
}
acpi_setup();
+ if (pcms->fw_cfg) {
+ pc_build_smbios(pcms->fw_cfg);
+ }
}
void pc_guest_info_init(PCMachineState *pcms)
--
2.7.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH v6 3/6] smbios: Move table build tools into an include file.
2016-05-23 17:40 [Qemu-devel] [PATCH v6 0/6] Add IPMI to firmware tables minyard
2016-05-23 17:40 ` [Qemu-devel] [PATCH v6 1/6] ipmi: rework the fwinfo to be fetched from the interface minyard
2016-05-23 17:40 ` [Qemu-devel] [PATCH v6 2/6] pc: Postpone SMBIOS table installation to post machine init minyard
@ 2016-05-23 17:40 ` minyard
2016-05-23 17:40 ` [Qemu-devel] [PATCH v6 4/6] ipmi: Add SMBIOS table entry minyard
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: minyard @ 2016-05-23 17:40 UTC (permalink / raw)
To: Igor Mammedov, Michael S . Tsirkin, Paolo Bonzini, qemu-devel,
minyard, cminyard
From: Corey Minyard <cminyard@mvista.com>
This will let things in other files (like IPMI) build SMBIOS tables.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
hw/smbios/smbios.c | 70 ++++---------------------------------------
hw/smbios/smbios_build.h | 77 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 83 insertions(+), 64 deletions(-)
create mode 100644 hw/smbios/smbios_build.h
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index cb8a111..5dc3e43 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -24,6 +24,7 @@
#include "hw/smbios/smbios.h"
#include "hw/loader.h"
#include "exec/cpu-common.h"
+#include "smbios_build.h"
/* legacy structures and constants for <= 2.0 machines */
struct smbios_header {
@@ -53,10 +54,10 @@ static bool smbios_uuid_encoded = true;
/* end: legacy structures & constants for <= 2.0 machines */
-static uint8_t *smbios_tables;
-static size_t smbios_tables_len;
-static unsigned smbios_table_max;
-static unsigned smbios_table_cnt;
+uint8_t *smbios_tables;
+size_t smbios_tables_len;
+unsigned smbios_table_max;
+unsigned smbios_table_cnt;
static SmbiosEntryPointType smbios_ep_type = SMBIOS_ENTRY_POINT_21;
static SmbiosEntryPoint ep;
@@ -429,7 +430,7 @@ uint8_t *smbios_get_table_legacy(size_t *length)
/* end: legacy setup functions for <= 2.0 machines */
-static bool smbios_skip_table(uint8_t type, bool required_table)
+bool smbios_skip_table(uint8_t type, bool required_table)
{
if (test_bit(type, have_binfile_bitmap)) {
return true; /* user provided their own binary blob(s) */
@@ -443,65 +444,6 @@ static bool smbios_skip_table(uint8_t type, bool required_table)
return true;
}
-#define SMBIOS_BUILD_TABLE_PRE(tbl_type, tbl_handle, tbl_required) \
- struct smbios_type_##tbl_type *t; \
- size_t t_off; /* table offset into smbios_tables */ \
- int str_index = 0; \
- do { \
- /* should we skip building this table ? */ \
- if (smbios_skip_table(tbl_type, tbl_required)) { \
- return; \
- } \
- \
- /* use offset of table t within smbios_tables */ \
- /* (pointer must be updated after each realloc) */ \
- t_off = smbios_tables_len; \
- smbios_tables_len += sizeof(*t); \
- smbios_tables = g_realloc(smbios_tables, smbios_tables_len); \
- t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \
- \
- t->header.type = tbl_type; \
- t->header.length = sizeof(*t); \
- t->header.handle = cpu_to_le16(tbl_handle); \
- } while (0)
-
-#define SMBIOS_TABLE_SET_STR(tbl_type, field, value) \
- do { \
- int len = (value != NULL) ? strlen(value) + 1 : 0; \
- if (len > 1) { \
- smbios_tables = g_realloc(smbios_tables, \
- smbios_tables_len + len); \
- memcpy(smbios_tables + smbios_tables_len, value, len); \
- smbios_tables_len += len; \
- /* update pointer post-realloc */ \
- t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \
- t->field = ++str_index; \
- } else { \
- t->field = 0; \
- } \
- } while (0)
-
-#define SMBIOS_BUILD_TABLE_POST \
- do { \
- size_t term_cnt, t_size; \
- \
- /* add '\0' terminator (add two if no strings defined) */ \
- term_cnt = (str_index == 0) ? 2 : 1; \
- smbios_tables = g_realloc(smbios_tables, \
- smbios_tables_len + term_cnt); \
- memset(smbios_tables + smbios_tables_len, 0, term_cnt); \
- smbios_tables_len += term_cnt; \
- \
- /* update smbios max. element size */ \
- t_size = smbios_tables_len - t_off; \
- if (t_size > smbios_table_max) { \
- smbios_table_max = t_size; \
- } \
- \
- /* update smbios element count */ \
- smbios_table_cnt++; \
- } while (0)
-
static void smbios_build_type_0_table(void)
{
SMBIOS_BUILD_TABLE_PRE(0, 0x000, false); /* optional, leave up to BIOS */
diff --git a/hw/smbios/smbios_build.h b/hw/smbios/smbios_build.h
new file mode 100644
index 0000000..2257721
--- /dev/null
+++ b/hw/smbios/smbios_build.h
@@ -0,0 +1,77 @@
+/*
+ * SMBIOS Support
+ *
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ * Copyright (C) 2013 Red Hat, Inc.
+ */
+
+#ifndef QEMU_SMBIOS_BUILD_H
+#define QEMU_SMBIOS_BUILD_H
+
+bool smbios_skip_table(uint8_t type, bool required_table);
+
+extern uint8_t *smbios_tables;
+extern size_t smbios_tables_len;
+extern unsigned smbios_table_max;
+extern unsigned smbios_table_cnt;
+
+#define SMBIOS_BUILD_TABLE_PRE(tbl_type, tbl_handle, tbl_required) \
+ struct smbios_type_##tbl_type *t; \
+ size_t t_off; /* table offset into smbios_tables */ \
+ int str_index = 0; \
+ do { \
+ /* should we skip building this table ? */ \
+ if (smbios_skip_table(tbl_type, tbl_required)) { \
+ return; \
+ } \
+ \
+ /* use offset of table t within smbios_tables */ \
+ /* (pointer must be updated after each realloc) */ \
+ t_off = smbios_tables_len; \
+ smbios_tables_len += sizeof(*t); \
+ smbios_tables = g_realloc(smbios_tables, smbios_tables_len); \
+ t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \
+ \
+ t->header.type = tbl_type; \
+ t->header.length = sizeof(*t); \
+ t->header.handle = cpu_to_le16(tbl_handle); \
+ } while (0)
+
+#define SMBIOS_TABLE_SET_STR(tbl_type, field, value) \
+ do { \
+ int len = (value != NULL) ? strlen(value) + 1 : 0; \
+ if (len > 1) { \
+ smbios_tables = g_realloc(smbios_tables, \
+ smbios_tables_len + len); \
+ memcpy(smbios_tables + smbios_tables_len, value, len); \
+ smbios_tables_len += len; \
+ /* update pointer post-realloc */ \
+ t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \
+ t->field = ++str_index; \
+ } else { \
+ t->field = 0; \
+ } \
+ } while (0)
+
+#define SMBIOS_BUILD_TABLE_POST \
+ do { \
+ size_t term_cnt, t_size; \
+ \
+ /* add '\0' terminator (add two if no strings defined) */ \
+ term_cnt = (str_index == 0) ? 2 : 1; \
+ smbios_tables = g_realloc(smbios_tables, \
+ smbios_tables_len + term_cnt); \
+ memset(smbios_tables + smbios_tables_len, 0, term_cnt); \
+ smbios_tables_len += term_cnt; \
+ \
+ /* update smbios max. element size */ \
+ t_size = smbios_tables_len - t_off; \
+ if (t_size > smbios_table_max) { \
+ smbios_table_max = t_size; \
+ } \
+ \
+ /* update smbios element count */ \
+ smbios_table_cnt++; \
+ } while (0)
+
+#endif /* QEMU_SMBIOS_BUILD_H */
--
2.7.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH v6 4/6] ipmi: Add SMBIOS table entry
2016-05-23 17:40 [Qemu-devel] [PATCH v6 0/6] Add IPMI to firmware tables minyard
` (2 preceding siblings ...)
2016-05-23 17:40 ` [Qemu-devel] [PATCH v6 3/6] smbios: Move table build tools into an include file minyard
@ 2016-05-23 17:40 ` minyard
2016-05-23 17:40 ` [Qemu-devel] [PATCH v6 5/6] acpi: Add IPMI table entries minyard
2016-05-23 17:40 ` [Qemu-devel] [PATCH v6 6/6] bios: Add tests for the IPMI ACPI and SMBIOS entries minyard
5 siblings, 0 replies; 10+ messages in thread
From: minyard @ 2016-05-23 17:40 UTC (permalink / raw)
To: Igor Mammedov, Michael S . Tsirkin, Paolo Bonzini, qemu-devel,
minyard, cminyard
From: Corey Minyard <cminyard@mvista.com>
Add an IPMI table entry to the SMBIOS.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
---
Makefile.objs | 2 +-
hw/Makefile.objs | 2 +
hw/smbios/Makefile.objs | 1 +
hw/smbios/smbios.c | 2 +
hw/smbios/smbios_type_38.c | 114 +++++++++++++++++++++++++++++++++++++++++++++
hw/stubs/Makefile.objs | 1 +
hw/stubs/smbios_type_38.c | 14 ++++++
include/hw/smbios/ipmi.h | 15 ++++++
8 files changed, 150 insertions(+), 1 deletion(-)
create mode 100644 hw/smbios/smbios_type_38.c
create mode 100644 hw/stubs/Makefile.objs
create mode 100644 hw/stubs/smbios_type_38.c
create mode 100644 include/hw/smbios/ipmi.h
diff --git a/Makefile.objs b/Makefile.objs
index 8f705f6..fe4a47f 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -1,6 +1,6 @@
#######################################################################
# Common libraries for tools and emulators
-stub-obj-y = stubs/ crypto/
+stub-obj-y = stubs/ crypto/ hw/
util-obj-y = util/ qobject/ qapi/
util-obj-y += qmp-introspect.o qapi-types.o qapi-visit.o qapi-event.o
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 4a07ed4..83a979b 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -36,3 +36,5 @@ devices-dirs-$(CONFIG_SMBIOS) += smbios/
devices-dirs-y += core/
common-obj-y += $(devices-dirs-y)
obj-y += $(devices-dirs-y)
+
+stub-obj-y += stubs/
diff --git a/hw/smbios/Makefile.objs b/hw/smbios/Makefile.objs
index f69a92f..c3d3753 100644
--- a/hw/smbios/Makefile.objs
+++ b/hw/smbios/Makefile.objs
@@ -1 +1,2 @@
common-obj-$(CONFIG_SMBIOS) += smbios.o
+common-obj-$(call land,$(CONFIG_SMBIOS),$(CONFIG_IPMI)) += smbios_type_38.o
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 5dc3e43..74c7102 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -25,6 +25,7 @@
#include "hw/loader.h"
#include "exec/cpu-common.h"
#include "smbios_build.h"
+#include "hw/smbios/ipmi.h"
/* legacy structures and constants for <= 2.0 machines */
struct smbios_header {
@@ -848,6 +849,7 @@ void smbios_get_tables(const struct smbios_phys_mem_area *mem_array,
}
smbios_build_type_32_table();
+ smbios_build_type_38_table();
smbios_build_type_127_table();
smbios_validate_table();
diff --git a/hw/smbios/smbios_type_38.c b/hw/smbios/smbios_type_38.c
new file mode 100644
index 0000000..e9cd824
--- /dev/null
+++ b/hw/smbios/smbios_type_38.c
@@ -0,0 +1,114 @@
+/*
+ * IPMI SMBIOS firmware handling
+ *
+ * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/ipmi/ipmi.h"
+#include "hw/smbios/ipmi.h"
+#include "hw/smbios/smbios.h"
+#include "qemu/error-report.h"
+#include "smbios_build.h"
+
+/* SMBIOS type 38 - IPMI */
+struct smbios_type_38 {
+ struct smbios_structure_header header;
+ uint8_t interface_type;
+ uint8_t ipmi_spec_revision;
+ uint8_t i2c_slave_address;
+ uint8_t nv_storage_device_address;
+ uint64_t base_address;
+ uint8_t base_address_modifier;
+ uint8_t interrupt_number;
+} QEMU_PACKED;
+
+static void smbios_build_one_type_38(IPMIFwInfo *info)
+{
+ uint64_t baseaddr = info->base_address;
+ SMBIOS_BUILD_TABLE_PRE(38, 0x3000, true);
+
+ t->interface_type = info->interface_type;
+ t->ipmi_spec_revision = ((info->ipmi_spec_major_revision << 4)
+ | info->ipmi_spec_minor_revision);
+ t->i2c_slave_address = info->i2c_slave_address;
+ t->nv_storage_device_address = 0;
+
+ /* or 1 to set it to I/O space */
+ switch (info->memspace) {
+ case IPMI_MEMSPACE_IO:
+ baseaddr |= 1;
+ break;
+ case IPMI_MEMSPACE_MEM32:
+ case IPMI_MEMSPACE_MEM64:
+ break;
+ case IPMI_MEMSPACE_SMBUS:
+ baseaddr <<= 1;
+ break;
+ }
+
+ t->base_address = cpu_to_le64(baseaddr);
+
+ t->base_address_modifier = 0;
+ if (info->irq_type == IPMI_LEVEL_IRQ) {
+ t->base_address_modifier |= 1;
+ }
+ switch (info->register_spacing) {
+ case 1:
+ break;
+ case 4:
+ t->base_address_modifier |= 1 << 6;
+ break;
+ case 16:
+ t->base_address_modifier |= 2 << 6;
+ break;
+ default:
+ error_report("IPMI register spacing %d is not compatible with"
+ " SMBIOS, ignoring this entry.", info->register_spacing);
+ return;
+ }
+ t->interrupt_number = info->interrupt_number;
+
+ SMBIOS_BUILD_TABLE_POST;
+}
+
+static void smbios_add_ipmi_devices(BusState *bus)
+{
+ BusChild *kid;
+
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ DeviceState *dev = kid->child;
+ Object *obj = object_dynamic_cast(OBJECT(dev), TYPE_IPMI_INTERFACE);
+ BusState *childbus;
+
+ if (obj) {
+ IPMIInterface *ii;
+ IPMIInterfaceClass *iic;
+ IPMIFwInfo info;
+
+ ii = IPMI_INTERFACE(obj);
+ iic = IPMI_INTERFACE_GET_CLASS(obj);
+ memset(&info, 0, sizeof(info));
+ iic->get_fwinfo(ii, &info);
+ smbios_build_one_type_38(&info);
+ continue;
+ }
+
+ QLIST_FOREACH(childbus, &dev->child_bus, sibling) {
+ smbios_add_ipmi_devices(childbus);
+ }
+ }
+}
+
+void smbios_build_type_38_table(void)
+{
+ BusState *bus;
+
+ bus = sysbus_get_default();
+ if (bus) {
+ smbios_add_ipmi_devices(bus);
+ }
+}
diff --git a/hw/stubs/Makefile.objs b/hw/stubs/Makefile.objs
new file mode 100644
index 0000000..60047e6
--- /dev/null
+++ b/hw/stubs/Makefile.objs
@@ -0,0 +1 @@
+stub-obj-$(CONFIG_SMBIOS) += smbios_type_38.o
diff --git a/hw/stubs/smbios_type_38.c b/hw/stubs/smbios_type_38.c
new file mode 100644
index 0000000..ad669a4
--- /dev/null
+++ b/hw/stubs/smbios_type_38.c
@@ -0,0 +1,14 @@
+/*
+ * IPMI SMBIOS firmware handling
+ *
+ * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "hw/smbios/ipmi.h"
+
+void smbios_build_type_38_table(void)
+{
+}
diff --git a/include/hw/smbios/ipmi.h b/include/hw/smbios/ipmi.h
new file mode 100644
index 0000000..fd53c96
--- /dev/null
+++ b/include/hw/smbios/ipmi.h
@@ -0,0 +1,15 @@
+/*
+ * IPMI SMBIOS firmware handling
+ *
+ * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QEMU_SMBIOS_IPMI_H
+#define QEMU_SMBIOS_IPMI_H
+
+void smbios_build_type_38_table(void);
+
+#endif /* QEMU_SMBIOS_IPMI_H */
--
2.7.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH v6 5/6] acpi: Add IPMI table entries
2016-05-23 17:40 [Qemu-devel] [PATCH v6 0/6] Add IPMI to firmware tables minyard
` (3 preceding siblings ...)
2016-05-23 17:40 ` [Qemu-devel] [PATCH v6 4/6] ipmi: Add SMBIOS table entry minyard
@ 2016-05-23 17:40 ` minyard
2016-05-24 7:49 ` Igor Mammedov
2016-05-23 17:40 ` [Qemu-devel] [PATCH v6 6/6] bios: Add tests for the IPMI ACPI and SMBIOS entries minyard
5 siblings, 1 reply; 10+ messages in thread
From: minyard @ 2016-05-23 17:40 UTC (permalink / raw)
To: Igor Mammedov, Michael S . Tsirkin, Paolo Bonzini, qemu-devel,
minyard, cminyard
From: Corey Minyard <cminyard@mvista.com>
Use the new ACPI table construction tools to create an ACPI
entry for IPMI. This adds a function called from build_dsdt
to add an DSDT entry for IPMI if IPMI is compiled in and has
registered firmware. It also adds a dummy function if IPMI
is not compiled in.
This conforms to section "C3-2 Locating IPMI System Interfaces in
ACPI Name Space" in the IPMI 2.0 specification.
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
hw/acpi/Makefile.objs | 2 +
hw/acpi/ipmi.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++
hw/i386/acpi-build.c | 24 +++++++++--
hw/stubs/Makefile.objs | 1 +
hw/stubs/acpi_ipmi.c | 14 +++++++
include/hw/acpi/ipmi.h | 22 +++++++++++
6 files changed, 165 insertions(+), 3 deletions(-)
create mode 100644 hw/acpi/ipmi.c
create mode 100644 hw/stubs/acpi_ipmi.c
create mode 100644 include/hw/acpi/ipmi.h
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index faee86c..95824e8 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -6,3 +6,5 @@ obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
common-obj-$(CONFIG_ACPI) += acpi_interface.o
common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
common-obj-$(CONFIG_ACPI) += aml-build.o
+common-obj-$(call land,$(CONFIG_ACPI),$(CONFIG_IPMI)) += ipmi.o
+
diff --git a/hw/acpi/ipmi.c b/hw/acpi/ipmi.c
new file mode 100644
index 0000000..201f824
--- /dev/null
+++ b/hw/acpi/ipmi.c
@@ -0,0 +1,105 @@
+/*
+ * IPMI ACPI firmware handling
+ *
+ * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/ipmi/ipmi.h"
+#include "hw/acpi/aml-build.h"
+#include "hw/acpi/acpi.h"
+#include "hw/acpi/ipmi.h"
+
+static Aml *aml_ipmi_crs(IPMIFwInfo *info)
+{
+ Aml *crs = aml_resource_template();
+ uint8_t regspacing = info->register_spacing;
+
+ /*
+ * The base address is fixed and cannot change. That may be different
+ * if someone does PCI, but we aren't there yet.
+ */
+ switch (info->memspace) {
+ case IPMI_MEMSPACE_IO:
+ aml_append(crs, aml_io(AML_DECODE16, info->base_address,
+ info->base_address + info->register_length - 1,
+ regspacing, info->register_length));
+ break;
+ case IPMI_MEMSPACE_MEM32:
+ aml_append(crs,
+ aml_dword_memory(AML_POS_DECODE,
+ AML_MIN_FIXED, AML_MAX_FIXED,
+ AML_NON_CACHEABLE, AML_READ_WRITE,
+ 0xffffffff,
+ info->base_address,
+ info->base_address + info->register_length - 1,
+ regspacing, info->register_length));
+ break;
+ case IPMI_MEMSPACE_MEM64:
+ aml_append(crs,
+ aml_qword_memory(AML_POS_DECODE,
+ AML_MIN_FIXED, AML_MAX_FIXED,
+ AML_NON_CACHEABLE, AML_READ_WRITE,
+ 0xffffffffffffffffULL,
+ info->base_address,
+ info->base_address + info->register_length - 1,
+ regspacing, info->register_length));
+ break;
+ case IPMI_MEMSPACE_SMBUS:
+ aml_append(crs, aml_return(aml_int(info->base_address)));
+ break;
+ default:
+ abort();
+ }
+
+ if (info->interrupt_number) {
+ aml_append(crs, aml_irq_no_flags(info->interrupt_number));
+ }
+
+ return crs;
+}
+
+static Aml *aml_ipmi_device(IPMIFwInfo *info)
+{
+ Aml *dev;
+ uint16_t version = ((info->ipmi_spec_major_revision << 8)
+ | (info->ipmi_spec_minor_revision << 4));
+
+ dev = aml_device("MI%d", info->uuid);
+ aml_append(dev, aml_name_decl("_HID", aml_eisaid("IPI0001")));
+ aml_append(dev, aml_name_decl("_STR", aml_string("ipmi_%s",
+ info->interface_name)));
+ aml_append(dev, aml_name_decl("_UID", aml_int(info->uuid)));
+ aml_append(dev, aml_name_decl("_CRS", aml_ipmi_crs(info)));
+ aml_append(dev, aml_name_decl("_IFT", aml_int(info->interface_type)));
+ aml_append(dev, aml_name_decl("_SRV", aml_int(version)));
+
+ return dev;
+}
+
+void build_acpi_ipmi_devices(Aml *scope, BusState *bus)
+{
+
+ BusChild *kid;
+
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ DeviceState *dev = kid->child;
+ Object *obj = object_dynamic_cast(OBJECT(dev), TYPE_IPMI_INTERFACE);
+ IPMIInterface *ii;
+ IPMIInterfaceClass *iic;
+ IPMIFwInfo info;
+
+ if (!obj) {
+ continue;
+ }
+
+ ii = IPMI_INTERFACE(obj);
+ iic = IPMI_INTERFACE_GET_CLASS(obj);
+ memset(&info, 0, sizeof(info));
+ iic->get_fwinfo(ii, &info);
+ aml_append(scope, aml_ipmi_device(&info));
+ }
+}
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 279f0d7..bf9253d 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -59,6 +59,8 @@
#include "qapi/qmp/qint.h"
#include "qom/qom-qobject.h"
+#include "hw/acpi/ipmi.h"
+
/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
* -M pc-i440fx-2.0. Even if the actual amount of AML generated grows
* a little bit, there should be plenty of free space since the DSDT
@@ -1445,7 +1447,21 @@ static Aml *build_com_device_aml(uint8_t uid)
return dev;
}
-static void build_isa_devices_aml(Aml *table)
+static void build_isa_ipmi_aml(Aml *scope)
+{
+ bool ambiguous;
+ Object *obj = object_resolve_path_type("", TYPE_ISA_BUS, &ambiguous);
+
+ if (ambiguous) {
+ error_report("Multiple ISA busses, unable to define IPMI ACPI data");
+ } else if (!obj) {
+ error_report("No ISA bus, unable to define IPMI ACPI data");
+ } else {
+ build_acpi_ipmi_devices(scope, BUS(obj));
+ }
+}
+
+static void build_isa_devices_aml(Aml *table, PCMachineState *pcms)
{
ISADevice *fdc = pc_find_fdc0();
@@ -1461,6 +1477,8 @@ static void build_isa_devices_aml(Aml *table)
aml_append(scope, build_com_device_aml(1));
aml_append(scope, build_com_device_aml(2));
+ build_isa_ipmi_aml(scope);
+
aml_append(table, scope);
}
@@ -2011,7 +2029,7 @@ build_dsdt(GArray *table_data, GArray *linker,
build_hpet_aml(dsdt);
build_piix4_pm(dsdt);
build_piix4_isa_bridge(dsdt);
- build_isa_devices_aml(dsdt);
+ build_isa_devices_aml(dsdt, pcms);
build_piix4_pci_hotplug(dsdt);
build_piix4_pci0_int(dsdt);
} else {
@@ -2039,7 +2057,7 @@ build_dsdt(GArray *table_data, GArray *linker,
build_hpet_aml(dsdt);
build_q35_isa_bridge(dsdt);
- build_isa_devices_aml(dsdt);
+ build_isa_devices_aml(dsdt, pcms);
build_q35_pci0_int(dsdt);
}
diff --git a/hw/stubs/Makefile.objs b/hw/stubs/Makefile.objs
index 60047e6..f09ea33 100644
--- a/hw/stubs/Makefile.objs
+++ b/hw/stubs/Makefile.objs
@@ -1 +1,2 @@
stub-obj-$(CONFIG_SMBIOS) += smbios_type_38.o
+stub-obj-$(CONFIG_ACPI) += acpi_ipmi.o
\ No newline at end of file
diff --git a/hw/stubs/acpi_ipmi.c b/hw/stubs/acpi_ipmi.c
new file mode 100644
index 0000000..e83fc19
--- /dev/null
+++ b/hw/stubs/acpi_ipmi.c
@@ -0,0 +1,14 @@
+/*
+ * IPMI ACPI firmware handling
+ *
+ * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "hw/acpi/ipmi.h"
+
+void build_acpi_ipmi_devices(Aml *table, BusState *bus)
+{
+}
diff --git a/include/hw/acpi/ipmi.h b/include/hw/acpi/ipmi.h
new file mode 100644
index 0000000..ca5043a
--- /dev/null
+++ b/include/hw/acpi/ipmi.h
@@ -0,0 +1,22 @@
+/*
+ * QEMU IPMI ACPI handling
+ *
+ * Copyright (c) 2015 Corey Minyard <cminyard@mvista.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef HW_ACPI_IPMI_H
+#define HW_ACPI_IPMI_H
+
+#include "qemu/osdep.h"
+#include "hw/acpi/aml-build.h"
+
+/*
+ * Add ACPI IPMI entries for all registered IPMI devices whose parent
+ * bus matches the given bus. The resource is the ACPI resource that
+ * contains the IPMI device, this is required for the I2C CRS.
+ */
+void build_acpi_ipmi_devices(Aml *table, BusState *bus);
+
+#endif /* HW_ACPI_IPMI_H */
--
2.7.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH v6 5/6] acpi: Add IPMI table entries
2016-05-23 17:40 ` [Qemu-devel] [PATCH v6 5/6] acpi: Add IPMI table entries minyard
@ 2016-05-24 7:49 ` Igor Mammedov
2016-05-24 12:41 ` Corey Minyard
0 siblings, 1 reply; 10+ messages in thread
From: Igor Mammedov @ 2016-05-24 7:49 UTC (permalink / raw)
To: minyard; +Cc: Michael S . Tsirkin, Paolo Bonzini, qemu-devel, cminyard
On Mon, 23 May 2016 12:40:16 -0500
minyard@acm.org wrote:
> From: Corey Minyard <cminyard@mvista.com>
>
> Use the new ACPI table construction tools to create an ACPI
> entry for IPMI. This adds a function called from build_dsdt
> to add an DSDT entry for IPMI if IPMI is compiled in and has
> registered firmware. It also adds a dummy function if IPMI
> is not compiled in.
>
> This conforms to section "C3-2 Locating IPMI System Interfaces in
> ACPI Name Space" in the IPMI 2.0 specification.
>
> Signed-off-by: Corey Minyard <cminyard@mvista.com>
> ---
> hw/acpi/Makefile.objs | 2 +
> hw/acpi/ipmi.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++
> hw/i386/acpi-build.c | 24 +++++++++--
> hw/stubs/Makefile.objs | 1 +
> hw/stubs/acpi_ipmi.c | 14 +++++++
> include/hw/acpi/ipmi.h | 22 +++++++++++
> 6 files changed, 165 insertions(+), 3 deletions(-)
> create mode 100644 hw/acpi/ipmi.c
> create mode 100644 hw/stubs/acpi_ipmi.c
> create mode 100644 include/hw/acpi/ipmi.h
>
> diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
> index faee86c..95824e8 100644
> --- a/hw/acpi/Makefile.objs
> +++ b/hw/acpi/Makefile.objs
> @@ -6,3 +6,5 @@ obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
> common-obj-$(CONFIG_ACPI) += acpi_interface.o
> common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
> common-obj-$(CONFIG_ACPI) += aml-build.o
> +common-obj-$(call land,$(CONFIG_ACPI),$(CONFIG_IPMI)) += ipmi.o
> +
> diff --git a/hw/acpi/ipmi.c b/hw/acpi/ipmi.c
> new file mode 100644
> index 0000000..201f824
> --- /dev/null
> +++ b/hw/acpi/ipmi.c
> @@ -0,0 +1,105 @@
> +/*
> + * IPMI ACPI firmware handling
> + *
> + * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/ipmi/ipmi.h"
> +#include "hw/acpi/aml-build.h"
> +#include "hw/acpi/acpi.h"
> +#include "hw/acpi/ipmi.h"
> +
> +static Aml *aml_ipmi_crs(IPMIFwInfo *info)
> +{
> + Aml *crs = aml_resource_template();
> + uint8_t regspacing = info->register_spacing;
nit about naming,
why not s/regspacing|register_spacing/reg_alignment/
> +
> + /*
> + * The base address is fixed and cannot change. That may be different
> + * if someone does PCI, but we aren't there yet.
> + */
> + switch (info->memspace) {
> + case IPMI_MEMSPACE_IO:
> + aml_append(crs, aml_io(AML_DECODE16, info->base_address,
> + info->base_address + info->register_length - 1,
> + regspacing, info->register_length));
> + break;
> + case IPMI_MEMSPACE_MEM32:
> + aml_append(crs,
> + aml_dword_memory(AML_POS_DECODE,
> + AML_MIN_FIXED, AML_MAX_FIXED,
> + AML_NON_CACHEABLE, AML_READ_WRITE,
> + 0xffffffff,
> + info->base_address,
> + info->base_address + info->register_length - 1,
> + regspacing, info->register_length));
> + break;
> + case IPMI_MEMSPACE_MEM64:
> + aml_append(crs,
> + aml_qword_memory(AML_POS_DECODE,
> + AML_MIN_FIXED, AML_MAX_FIXED,
> + AML_NON_CACHEABLE, AML_READ_WRITE,
> + 0xffffffffffffffffULL,
> + info->base_address,
> + info->base_address + info->register_length - 1,
> + regspacing, info->register_length));
> + break;
> + case IPMI_MEMSPACE_SMBUS:
> + aml_append(crs, aml_return(aml_int(info->base_address)));
> + break;
> + default:
> + abort();
> + }
> +
> + if (info->interrupt_number) {
> + aml_append(crs, aml_irq_no_flags(info->interrupt_number));
> + }
> +
> + return crs;
> +}
> +
> +static Aml *aml_ipmi_device(IPMIFwInfo *info)
> +{
> + Aml *dev;
> + uint16_t version = ((info->ipmi_spec_major_revision << 8)
> + | (info->ipmi_spec_minor_revision << 4));
revisions potentially could silently overlap when ORed,
add assert to make sure the it won't go unnoticed.
> +
> + dev = aml_device("MI%d", info->uuid);
> + aml_append(dev, aml_name_decl("_HID", aml_eisaid("IPI0001")));
> + aml_append(dev, aml_name_decl("_STR", aml_string("ipmi_%s",
> + info->interface_name)));
> + aml_append(dev, aml_name_decl("_UID", aml_int(info->uuid)));
> + aml_append(dev, aml_name_decl("_CRS", aml_ipmi_crs(info)));
> + aml_append(dev, aml_name_decl("_IFT", aml_int(info->interface_type)));
> + aml_append(dev, aml_name_decl("_SRV", aml_int(version)));
> +
> + return dev;
> +}
> +
> +void build_acpi_ipmi_devices(Aml *scope, BusState *bus)
> +{
> +
> + BusChild *kid;
> +
> + QTAILQ_FOREACH(kid, &bus->children, sibling) {
> + DeviceState *dev = kid->child;
another nit,
not necessary just use OBJECT(kid->child)
> + Object *obj = object_dynamic_cast(OBJECT(dev), TYPE_IPMI_INTERFACE);
put it below IPMIFwInfo info; to make it prettier :)
> + IPMIInterface *ii;
> + IPMIInterfaceClass *iic;
> + IPMIFwInfo info;
> +
> + if (!obj) {
> + continue;
> + }
> +
> + ii = IPMI_INTERFACE(obj);
> + iic = IPMI_INTERFACE_GET_CLASS(obj);
> + memset(&info, 0, sizeof(info));
why not to put memset() inside iic->get_fwinfo(),
that way every caller won't have to do it (SMBIOS call site).
> + iic->get_fwinfo(ii, &info);
> + aml_append(scope, aml_ipmi_device(&info));
> + }
> +}
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 279f0d7..bf9253d 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -59,6 +59,8 @@
> #include "qapi/qmp/qint.h"
> #include "qom/qom-qobject.h"
>
> +#include "hw/acpi/ipmi.h"
> +
> /* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
> * -M pc-i440fx-2.0. Even if the actual amount of AML generated grows
> * a little bit, there should be plenty of free space since the DSDT
> @@ -1445,7 +1447,21 @@ static Aml *build_com_device_aml(uint8_t uid)
> return dev;
> }
>
> -static void build_isa_devices_aml(Aml *table)
> +static void build_isa_ipmi_aml(Aml *scope)
> +{
> + bool ambiguous;
> + Object *obj = object_resolve_path_type("", TYPE_ISA_BUS, &ambiguous);
> +
> + if (ambiguous) {
> + error_report("Multiple ISA busses, unable to define IPMI ACPI data");
> + } else if (!obj) {
> + error_report("No ISA bus, unable to define IPMI ACPI data");
> + } else {
> + build_acpi_ipmi_devices(scope, BUS(obj));
> + }
> +}
I'd fold this function into build_acpi_ipmi_devices() if there aren't any plans
for IPMI devices being present on another bus.
> +
> +static void build_isa_devices_aml(Aml *table, PCMachineState *pcms)
why is pcms is added here, it doesn't seem to be used?
> {
> ISADevice *fdc = pc_find_fdc0();
>
> @@ -1461,6 +1477,8 @@ static void build_isa_devices_aml(Aml *table)
> aml_append(scope, build_com_device_aml(1));
> aml_append(scope, build_com_device_aml(2));
>
> + build_isa_ipmi_aml(scope);
> +
> aml_append(table, scope);
> }
>
> @@ -2011,7 +2029,7 @@ build_dsdt(GArray *table_data, GArray *linker,
> build_hpet_aml(dsdt);
> build_piix4_pm(dsdt);
> build_piix4_isa_bridge(dsdt);
> - build_isa_devices_aml(dsdt);
> + build_isa_devices_aml(dsdt, pcms);
> build_piix4_pci_hotplug(dsdt);
> build_piix4_pci0_int(dsdt);
> } else {
> @@ -2039,7 +2057,7 @@ build_dsdt(GArray *table_data, GArray *linker,
>
> build_hpet_aml(dsdt);
> build_q35_isa_bridge(dsdt);
> - build_isa_devices_aml(dsdt);
> + build_isa_devices_aml(dsdt, pcms);
> build_q35_pci0_int(dsdt);
> }
>
> diff --git a/hw/stubs/Makefile.objs b/hw/stubs/Makefile.objs
> index 60047e6..f09ea33 100644
> --- a/hw/stubs/Makefile.objs
> +++ b/hw/stubs/Makefile.objs
> @@ -1 +1,2 @@
> stub-obj-$(CONFIG_SMBIOS) += smbios_type_38.o
> +stub-obj-$(CONFIG_ACPI) += acpi_ipmi.o
> \ No newline at end of file
> diff --git a/hw/stubs/acpi_ipmi.c b/hw/stubs/acpi_ipmi.c
> new file mode 100644
> index 0000000..e83fc19
> --- /dev/null
> +++ b/hw/stubs/acpi_ipmi.c
> @@ -0,0 +1,14 @@
> +/*
> + * IPMI ACPI firmware handling
> + *
> + * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#include "hw/acpi/ipmi.h"
> +
> +void build_acpi_ipmi_devices(Aml *table, BusState *bus)
> +{
> +}
> diff --git a/include/hw/acpi/ipmi.h b/include/hw/acpi/ipmi.h
> new file mode 100644
> index 0000000..ca5043a
> --- /dev/null
> +++ b/include/hw/acpi/ipmi.h
> @@ -0,0 +1,22 @@
> +/*
> + * QEMU IPMI ACPI handling
> + *
> + * Copyright (c) 2015 Corey Minyard <cminyard@mvista.com>
s/2015/2016/ throughout series???
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +#ifndef HW_ACPI_IPMI_H
> +#define HW_ACPI_IPMI_H
> +
> +#include "qemu/osdep.h"
> +#include "hw/acpi/aml-build.h"
> +
> +/*
> + * Add ACPI IPMI entries for all registered IPMI devices whose parent
> + * bus matches the given bus. The resource is the ACPI resource that
> + * contains the IPMI device, this is required for the I2C CRS.
> + */
> +void build_acpi_ipmi_devices(Aml *table, BusState *bus);
> +
> +#endif /* HW_ACPI_IPMI_H */
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [PATCH v6 5/6] acpi: Add IPMI table entries
2016-05-24 7:49 ` Igor Mammedov
@ 2016-05-24 12:41 ` Corey Minyard
0 siblings, 0 replies; 10+ messages in thread
From: Corey Minyard @ 2016-05-24 12:41 UTC (permalink / raw)
To: Igor Mammedov; +Cc: Michael S . Tsirkin, Paolo Bonzini, qemu-devel, cminyard
On 05/24/2016 02:49 AM, Igor Mammedov wrote:
> On Mon, 23 May 2016 12:40:16 -0500
> minyard@acm.org wrote:
>
>> From: Corey Minyard <cminyard@mvista.com>
>>
>> Use the new ACPI table construction tools to create an ACPI
>> entry for IPMI. This adds a function called from build_dsdt
>> to add an DSDT entry for IPMI if IPMI is compiled in and has
>> registered firmware. It also adds a dummy function if IPMI
>> is not compiled in.
>>
>> This conforms to section "C3-2 Locating IPMI System Interfaces in
>> ACPI Name Space" in the IPMI 2.0 specification.
>>
>> Signed-off-by: Corey Minyard <cminyard@mvista.com>
>> ---
>> hw/acpi/Makefile.objs | 2 +
>> hw/acpi/ipmi.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++
>> hw/i386/acpi-build.c | 24 +++++++++--
>> hw/stubs/Makefile.objs | 1 +
>> hw/stubs/acpi_ipmi.c | 14 +++++++
>> include/hw/acpi/ipmi.h | 22 +++++++++++
>> 6 files changed, 165 insertions(+), 3 deletions(-)
>> create mode 100644 hw/acpi/ipmi.c
>> create mode 100644 hw/stubs/acpi_ipmi.c
>> create mode 100644 include/hw/acpi/ipmi.h
>>
>> diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
>> index faee86c..95824e8 100644
>> --- a/hw/acpi/Makefile.objs
>> +++ b/hw/acpi/Makefile.objs
>> @@ -6,3 +6,5 @@ obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
>> common-obj-$(CONFIG_ACPI) += acpi_interface.o
>> common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
>> common-obj-$(CONFIG_ACPI) += aml-build.o
>> +common-obj-$(call land,$(CONFIG_ACPI),$(CONFIG_IPMI)) += ipmi.o
>> +
>> diff --git a/hw/acpi/ipmi.c b/hw/acpi/ipmi.c
>> new file mode 100644
>> index 0000000..201f824
>> --- /dev/null
>> +++ b/hw/acpi/ipmi.c
>> @@ -0,0 +1,105 @@
>> +/*
>> + * IPMI ACPI firmware handling
>> + *
>> + * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> + * See the COPYING file in the top-level directory.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "hw/ipmi/ipmi.h"
>> +#include "hw/acpi/aml-build.h"
>> +#include "hw/acpi/acpi.h"
>> +#include "hw/acpi/ipmi.h"
>> +
>> +static Aml *aml_ipmi_crs(IPMIFwInfo *info)
>> +{
>> + Aml *crs = aml_resource_template();
>> + uint8_t regspacing = info->register_spacing;
> nit about naming,
> why not s/regspacing|register_spacing/reg_alignment/
"Register spacing" comes from the SMBIOS definition in the IPMI spec.
Since I did SMBIOS first, it won.
There's no reason to have a local for this now (I think there was at
some point).
.
.
.
>> +
>> + if (!obj) {
>> + continue;
>> + }
>> +
>> + ii = IPMI_INTERFACE(obj);
>> + iic = IPMI_INTERFACE_GET_CLASS(obj);
>> + memset(&info, 0, sizeof(info));
> why not to put memset() inside iic->get_fwinfo(),
> that way every caller won't have to do it (SMBIOS call site).
I debated on that, but there are actually fewer call sites than
implementers here. Well, they are equal now, but with SMBus
there will be more implementers.
>> + iic->get_fwinfo(ii, &info);
>> + aml_append(scope, aml_ipmi_device(&info));
>> + }
>> +}
>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>> index 279f0d7..bf9253d 100644
>> --- a/hw/i386/acpi-build.c
>> +++ b/hw/i386/acpi-build.c
>> @@ -59,6 +59,8 @@
>> #include "qapi/qmp/qint.h"
>> #include "qom/qom-qobject.h"
>>
>> +#include "hw/acpi/ipmi.h"
>> +
>> /* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
>> * -M pc-i440fx-2.0. Even if the actual amount of AML generated grows
>> * a little bit, there should be plenty of free space since the DSDT
>> @@ -1445,7 +1447,21 @@ static Aml *build_com_device_aml(uint8_t uid)
>> return dev;
>> }
>>
>> -static void build_isa_devices_aml(Aml *table)
>> +static void build_isa_ipmi_aml(Aml *scope)
>> +{
>> + bool ambiguous;
>> + Object *obj = object_resolve_path_type("", TYPE_ISA_BUS, &ambiguous);
>> +
>> + if (ambiguous) {
>> + error_report("Multiple ISA busses, unable to define IPMI ACPI data");
>> + } else if (!obj) {
>> + error_report("No ISA bus, unable to define IPMI ACPI data");
>> + } else {
>> + build_acpi_ipmi_devices(scope, BUS(obj));
>> + }
>> +}
> I'd fold this function into build_acpi_ipmi_devices() if there aren't any plans
> for IPMI devices being present on another bus.
Ok, it looked a little neater this way to me, but that's fine.
>> +
>> +static void build_isa_devices_aml(Aml *table, PCMachineState *pcms)
> why is pcms is added here, it doesn't seem to be used?
I forgot to remove it when I removed the isa_bus from PCMachineState.
Thanks,
-corey
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Qemu-devel] [PATCH v6 6/6] bios: Add tests for the IPMI ACPI and SMBIOS entries
2016-05-23 17:40 [Qemu-devel] [PATCH v6 0/6] Add IPMI to firmware tables minyard
` (4 preceding siblings ...)
2016-05-23 17:40 ` [Qemu-devel] [PATCH v6 5/6] acpi: Add IPMI table entries minyard
@ 2016-05-23 17:40 ` minyard
5 siblings, 0 replies; 10+ messages in thread
From: minyard @ 2016-05-23 17:40 UTC (permalink / raw)
To: Igor Mammedov, Michael S . Tsirkin, Paolo Bonzini, qemu-devel,
minyard, cminyard
From: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
---
tests/acpi-test-data/pc/DSDT.ipmikcs | Bin 0 -> 5659 bytes
tests/acpi-test-data/q35/DSDT.ipmibt | Bin 0 -> 8432 bytes
tests/bios-tables-test.c | 60 ++++++++++++++++++++++++++++++++---
3 files changed, 56 insertions(+), 4 deletions(-)
create mode 100644 tests/acpi-test-data/pc/DSDT.ipmikcs
create mode 100644 tests/acpi-test-data/q35/DSDT.ipmibt
diff --git a/tests/acpi-test-data/pc/DSDT.ipmikcs b/tests/acpi-test-data/pc/DSDT.ipmikcs
new file mode 100644
index 0000000000000000000000000000000000000000..b715983862972b4d02b488d4317434aa55bac244
GIT binary patch
literal 5659
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
R|K89M;$64Fh697k{{=@~V@v=5
literal 0
HcmV?d00001
diff --git a/tests/acpi-test-data/q35/DSDT.ipmibt b/tests/acpi-test-data/q35/DSDT.ipmibt
new file mode 100644
index 0000000000000000000000000000000000000000..74fc9b69204df80de3855657d3a4ff74e0eb964c
GIT binary patch
literal 8432
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
literal 0
HcmV?d00001
diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
index 0352814..6de4e13 100644
--- a/tests/bios-tables-test.c
+++ b/tests/bios-tables-test.c
@@ -50,6 +50,8 @@ typedef struct {
GArray *tables;
uint32_t smbios_ep_addr;
struct smbios_21_entry_point smbios_ep_table;
+ uint8_t *required_struct_types;
+ int required_struct_types_len;
} test_data;
#define ACPI_READ_FIELD(field, addr) \
@@ -335,7 +337,7 @@ static void test_acpi_tables(test_data *data)
for (i = 0; i < tables_nr; i++) {
AcpiSdtTable ssdt_table;
- memset(&ssdt_table, 0 , sizeof(ssdt_table));
+ memset(&ssdt_table, 0, sizeof(ssdt_table));
uint32_t addr = data->rsdt_tables_addr[i + 1]; /* fadt is first */
test_dst_table(&ssdt_table, addr);
g_array_append_val(data->tables, ssdt_table);
@@ -654,7 +656,6 @@ static void test_smbios_structs(test_data *data)
uint32_t addr = ep_table->structure_table_address;
int i, len, max_len = 0;
uint8_t type, prv, crt;
- uint8_t required_struct_types[] = {0, 1, 3, 4, 16, 17, 19, 32, 127};
/* walk the smbios tables */
for (i = 0; i < ep_table->number_of_structures; i++) {
@@ -694,8 +695,8 @@ static void test_smbios_structs(test_data *data)
g_assert_cmpuint(ep_table->max_structure_size, ==, max_len);
/* required struct types must all be present */
- for (i = 0; i < ARRAY_SIZE(required_struct_types); i++) {
- g_assert(test_bit(required_struct_types[i], struct_bitmap));
+ for (i = 0; i < data->required_struct_types_len; i++) {
+ g_assert(test_bit(data->required_struct_types[i], struct_bitmap));
}
}
@@ -735,6 +736,10 @@ static void test_acpi_one(const char *params, test_data *data)
g_free(args);
}
+static uint8_t base_required_struct_types[] = {
+ 0, 1, 3, 4, 16, 17, 19, 32, 127
+};
+
static void test_acpi_piix4_tcg(void)
{
test_data data;
@@ -744,6 +749,8 @@ static void test_acpi_piix4_tcg(void)
*/
memset(&data, 0, sizeof(data));
data.machine = MACHINE_PC;
+ data.required_struct_types = base_required_struct_types;
+ data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
test_acpi_one("-machine accel=tcg", &data);
free_test_data(&data);
}
@@ -755,6 +762,8 @@ static void test_acpi_piix4_tcg_bridge(void)
memset(&data, 0, sizeof(data));
data.machine = MACHINE_PC;
data.variant = ".bridge";
+ data.required_struct_types = base_required_struct_types;
+ data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
test_acpi_one("-machine accel=tcg -device pci-bridge,chassis_nr=1", &data);
free_test_data(&data);
}
@@ -765,6 +774,8 @@ static void test_acpi_q35_tcg(void)
memset(&data, 0, sizeof(data));
data.machine = MACHINE_Q35;
+ data.required_struct_types = base_required_struct_types;
+ data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
test_acpi_one("-machine q35,accel=tcg", &data);
free_test_data(&data);
}
@@ -776,11 +787,50 @@ static void test_acpi_q35_tcg_bridge(void)
memset(&data, 0, sizeof(data));
data.machine = MACHINE_Q35;
data.variant = ".bridge";
+ data.required_struct_types = base_required_struct_types;
+ data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
test_acpi_one("-machine q35,accel=tcg -device pci-bridge,chassis_nr=1",
&data);
free_test_data(&data);
}
+static uint8_t ipmi_required_struct_types[] = {
+ 0, 1, 3, 4, 16, 17, 19, 32, 38, 127
+};
+
+static void test_acpi_q35_tcg_ipmi(void)
+{
+ test_data data;
+
+ memset(&data, 0, sizeof(data));
+ data.machine = MACHINE_Q35;
+ data.variant = ".ipmibt";
+ data.required_struct_types = ipmi_required_struct_types;
+ data.required_struct_types_len = ARRAY_SIZE(ipmi_required_struct_types);
+ test_acpi_one("-machine q35,accel=tcg -device ipmi-bmc-sim,id=bmc0"
+ " -device isa-ipmi-bt,bmc=bmc0",
+ &data);
+ free_test_data(&data);
+}
+
+static void test_acpi_piix4_tcg_ipmi(void)
+{
+ test_data data;
+
+ /* Supplying -machine accel argument overrides the default (qtest).
+ * This is to make guest actually run.
+ */
+ memset(&data, 0, sizeof(data));
+ data.machine = MACHINE_PC;
+ data.variant = ".ipmikcs";
+ data.required_struct_types = ipmi_required_struct_types;
+ data.required_struct_types_len = ARRAY_SIZE(ipmi_required_struct_types);
+ test_acpi_one("-machine accel=tcg -device ipmi-bmc-sim,id=bmc0"
+ " -device isa-ipmi-kcs,irq=0,bmc=bmc0",
+ &data);
+ free_test_data(&data);
+}
+
int main(int argc, char *argv[])
{
const char *arch = qtest_get_arch();
@@ -797,6 +847,8 @@ int main(int argc, char *argv[])
qtest_add_func("acpi/piix4/tcg/bridge", test_acpi_piix4_tcg_bridge);
qtest_add_func("acpi/q35/tcg", test_acpi_q35_tcg);
qtest_add_func("acpi/q35/tcg/bridge", test_acpi_q35_tcg_bridge);
+ qtest_add_func("acpi/piix4/tcg/ipmi", test_acpi_piix4_tcg_ipmi);
+ qtest_add_func("acpi/q35/tcg/ipmi", test_acpi_q35_tcg_ipmi);
}
ret = g_test_run();
boot_sector_cleanup(disk);
--
2.7.4
^ permalink raw reply related [flat|nested] 10+ messages in thread