From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56165) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zz7fb-0003GI-HI for qemu-devel@nongnu.org; Wed, 18 Nov 2015 13:41:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zz7fY-0006yG-54 for qemu-devel@nongnu.org; Wed, 18 Nov 2015 13:41:27 -0500 Received: from mail-wm0-x234.google.com ([2a00:1450:400c:c09::234]:33209) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zz7fX-0006xu-Fm for qemu-devel@nongnu.org; Wed, 18 Nov 2015 13:41:23 -0500 Received: by wmec201 with SMTP id c201so293050054wme.0 for ; Wed, 18 Nov 2015 10:41:20 -0800 (PST) MIME-Version: 1.0 In-Reply-To: <1447354953-18893-3-git-send-email-minyard@acm.org> References: <1447354953-18893-1-git-send-email-minyard@acm.org> <1447354953-18893-3-git-send-email-minyard@acm.org> Date: Wed, 18 Nov 2015 12:41:20 -0600 Message-ID: From: Corey Minyard Content-Type: multipart/alternative; boundary=001a114b2e44089c5e0524d4fd8f Subject: Re: [Qemu-devel] [PATCH v4 02/17] Add a base IPMI interface List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Corey Minyard Cc: Igor Mammedov , Paolo Bonzini , qemu-devel@nongnu.org, "Michael S. Tsirkin" --001a114b2e44089c5e0524d4fd8f Content-Type: text/plain; charset=UTF-8 I haven't heard any more comments on this series, should I resubmit with the one shutdown change? -corey On Nov 12, 2015 1:02 PM, wrote: > From: Corey Minyard > > Add the basic IPMI types and infrastructure to QEMU. Low-level > interfaces and simulation interfaces will register with this; it's > kind of the go-between to tie them together. > > Signed-off-by: Corey Minyard > --- > default-configs/i386-softmmu.mak | 1 + > default-configs/x86_64-softmmu.mak | 1 + > hw/Makefile.objs | 1 + > hw/ipmi/Makefile.objs | 1 + > hw/ipmi/ipmi.c | 125 ++++++++++++++++++++++++++ > include/hw/ipmi/ipmi.h | 178 > +++++++++++++++++++++++++++++++++++++ > qemu-doc.texi | 2 + > 7 files changed, 309 insertions(+) > create mode 100644 hw/ipmi/Makefile.objs > create mode 100644 hw/ipmi/ipmi.c > create mode 100644 include/hw/ipmi/ipmi.h > > diff --git a/default-configs/i386-softmmu.mak > b/default-configs/i386-softmmu.mak > index 43c96d1..8fa751a 100644 > --- a/default-configs/i386-softmmu.mak > +++ b/default-configs/i386-softmmu.mak > @@ -9,6 +9,7 @@ CONFIG_VGA_CIRRUS=y > CONFIG_VMWARE_VGA=y > CONFIG_VIRTIO_VGA=y > CONFIG_VMMOUSE=y > +CONFIG_IPMI=y > CONFIG_SERIAL=y > CONFIG_PARALLEL=y > CONFIG_I8254=y > diff --git a/default-configs/x86_64-softmmu.mak > b/default-configs/x86_64-softmmu.mak > index dfb8095..6767f4f 100644 > --- a/default-configs/x86_64-softmmu.mak > +++ b/default-configs/x86_64-softmmu.mak > @@ -9,6 +9,7 @@ CONFIG_VGA_CIRRUS=y > CONFIG_VMWARE_VGA=y > CONFIG_VIRTIO_VGA=y > CONFIG_VMMOUSE=y > +CONFIG_IPMI=y > CONFIG_SERIAL=y > CONFIG_PARALLEL=y > CONFIG_I8254=y > diff --git a/hw/Makefile.objs b/hw/Makefile.objs > index 7e7c241..4a07ed4 100644 > --- a/hw/Makefile.objs > +++ b/hw/Makefile.objs > @@ -13,6 +13,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += ide/ > devices-dirs-$(CONFIG_SOFTMMU) += input/ > devices-dirs-$(CONFIG_SOFTMMU) += intc/ > devices-dirs-$(CONFIG_IPACK) += ipack/ > +devices-dirs-$(CONFIG_IPMI) += ipmi/ > devices-dirs-$(CONFIG_SOFTMMU) += isa/ > devices-dirs-$(CONFIG_SOFTMMU) += misc/ > devices-dirs-$(CONFIG_SOFTMMU) += net/ > diff --git a/hw/ipmi/Makefile.objs b/hw/ipmi/Makefile.objs > new file mode 100644 > index 0000000..65bde11 > --- /dev/null > +++ b/hw/ipmi/Makefile.objs > @@ -0,0 +1 @@ > +common-obj-$(CONFIG_IPMI) += ipmi.o > diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c > new file mode 100644 > index 0000000..7d17469 > --- /dev/null > +++ b/hw/ipmi/ipmi.c > @@ -0,0 +1,125 @@ > +/* > + * QEMU IPMI emulation > + * > + * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC > + * > + * Permission is hereby granted, free of charge, to any person obtaining > a copy > + * of this software and associated documentation files (the "Software"), > to deal > + * in the Software without restriction, including without limitation the > rights > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or > sell > + * copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be > included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR > OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > ARISING FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS > IN > + * THE SOFTWARE. > + */ > + > +#include "hw/hw.h" > +#include "hw/ipmi/ipmi.h" > +#include "sysemu/sysemu.h" > +#include "qmp-commands.h" > +#include "qom/object_interfaces.h" > +#include "qapi/visitor.h" > + > +static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly) > +{ > + switch (op) { > + case IPMI_RESET_CHASSIS: > + if (checkonly) { > + return 0; > + } > + qemu_system_reset_request(); > + return 0; > + > + case IPMI_POWEROFF_CHASSIS: > + if (checkonly) { > + return 0; > + } > + qemu_system_powerdown_request(); > + return 0; > + > + case IPMI_SEND_NMI: > + if (checkonly) { > + return 0; > + } > + qemu_mutex_lock_iothread(); > + qmp_inject_nmi(NULL); > + qemu_mutex_unlock_iothread(); > + return 0; > + > + case IPMI_POWERCYCLE_CHASSIS: > + case IPMI_PULSE_DIAG_IRQ: > + case IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP: > + case IPMI_POWERON_CHASSIS: > + default: > + return IPMI_CC_COMMAND_NOT_SUPPORTED; > + } > +} > + > +static void ipmi_interface_class_init(ObjectClass *class, void *data) > +{ > + IPMIInterfaceClass *ik = IPMI_INTERFACE_CLASS(class); > + > + ik->do_hw_op = ipmi_do_hw_op; > +} > + > +static TypeInfo ipmi_interface_type_info = { > + .name = TYPE_IPMI_INTERFACE, > + .parent = TYPE_INTERFACE, > + .class_size = sizeof(IPMIInterfaceClass), > + .class_init = ipmi_interface_class_init, > +}; > + > +static void isa_ipmi_bmc_check(Object *obj, const char *name, > + Object *val, Error **errp) > +{ > + IPMIBmc *bmc = IPMI_BMC(val); > + > + if (bmc->intf) > + error_setg(errp, "BMC object is already in use"); > +} > + > +void ipmi_bmc_find_and_link(Object *obj, Object **bmc) > +{ > + object_property_add_link(obj, "bmc", TYPE_IPMI_BMC, bmc, > + isa_ipmi_bmc_check, > + OBJ_PROP_LINK_UNREF_ON_RELEASE, > + &error_abort); > +} > + > +static Property ipmi_bmc_properties[] = { > + DEFINE_PROP_UINT8("slave_addr", IPMIBmc, slave_addr, 0x20), > + DEFINE_PROP_END_OF_LIST(), > +}; > + > +static void bmc_class_init(ObjectClass *oc, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(oc); > + > + dc->props = ipmi_bmc_properties; > +} > + > +static TypeInfo ipmi_bmc_type_info = { > + .name = TYPE_IPMI_BMC, > + .parent = TYPE_DEVICE, > + .instance_size = sizeof(IPMIBmc), > + .abstract = true, > + .class_size = sizeof(IPMIBmcClass), > + .class_init = bmc_class_init, > +}; > + > +static void ipmi_register_types(void) > +{ > + type_register_static(&ipmi_interface_type_info); > + type_register_static(&ipmi_bmc_type_info); > +} > + > +type_init(ipmi_register_types) > diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h > new file mode 100644 > index 0000000..e4f7738 > --- /dev/null > +++ b/include/hw/ipmi/ipmi.h > @@ -0,0 +1,178 @@ > +/* > + * IPMI base class > + * > + * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC > + * > + * Permission is hereby granted, free of charge, to any person obtaining > a copy > + * of this software and associated documentation files (the "Software"), > to deal > + * in the Software without restriction, including without limitation the > rights > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or > sell > + * copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be > included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR > OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > ARISING FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS > IN > + * THE SOFTWARE. > + */ > + > +#ifndef HW_IPMI_H > +#define HW_IPMI_H > + > +#include "exec/memory.h" > +#include "qemu-common.h" > +#include "hw/qdev.h" > + > +#define MAX_IPMI_MSG_SIZE 300 > + > +enum ipmi_op { > + IPMI_RESET_CHASSIS, > + IPMI_POWEROFF_CHASSIS, > + IPMI_POWERON_CHASSIS, > + IPMI_POWERCYCLE_CHASSIS, > + IPMI_PULSE_DIAG_IRQ, > + IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP, > + IPMI_SEND_NMI > +}; > + > +#define IPMI_CC_INVALID_CMD 0xc1 > +#define IPMI_CC_COMMAND_INVALID_FOR_LUN 0xc2 > +#define IPMI_CC_TIMEOUT 0xc3 > +#define IPMI_CC_OUT_OF_SPACE 0xc4 > +#define IPMI_CC_INVALID_RESERVATION 0xc5 > +#define IPMI_CC_REQUEST_DATA_TRUNCATED 0xc6 > +#define IPMI_CC_REQUEST_DATA_LENGTH_INVALID 0xc7 > +#define IPMI_CC_PARM_OUT_OF_RANGE 0xc9 > +#define IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES 0xca > +#define IPMI_CC_REQ_ENTRY_NOT_PRESENT 0xcb > +#define IPMI_CC_INVALID_DATA_FIELD 0xcc > +#define IPMI_CC_BMC_INIT_IN_PROGRESS 0xd2 > +#define IPMI_CC_COMMAND_NOT_SUPPORTED 0xd5 > + > +#define IPMI_NETFN_APP 0x06 > + > +#define IPMI_DEBUG 1 > + > +/* Specified in the SMBIOS spec. */ > +#define IPMI_SMBIOS_KCS 0x01 > +#define IPMI_SMBIOS_SMIC 0x02 > +#define IPMI_SMBIOS_BT 0x03 > +#define IPMI_SMBIOS_SSIF 0x04 > + > +/* IPMI Interface types (KCS, SMIC, BT) are prefixed with this */ > +#define TYPE_IPMI_INTERFACE_PREFIX "ipmi-interface-" > + > +/* > + * An IPMI Interface, the interface for talking between the target > + * and the BMC. > + */ > +#define TYPE_IPMI_INTERFACE "ipmi-interface" > +#define IPMI_INTERFACE(obj) \ > + INTERFACE_CHECK(IPMIInterface, (obj), TYPE_IPMI_INTERFACE) > +#define IPMI_INTERFACE_CLASS(class) \ > + OBJECT_CLASS_CHECK(IPMIInterfaceClass, (class), TYPE_IPMI_INTERFACE) > +#define IPMI_INTERFACE_GET_CLASS(class) \ > + OBJECT_GET_CLASS(IPMIInterfaceClass, (class), TYPE_IPMI_INTERFACE) > + > +typedef struct IPMIInterface { > + Object parent; > +} IPMIInterface; > + > +typedef struct IPMIInterfaceClass { > + InterfaceClass parent; > + > + void (*init)(struct IPMIInterface *s, Error **errp); > + > + /* > + * Perform various operations on the hardware. If checkonly is > + * true, it will return if the operation can be performed, but it > + * will not do the operation. > + */ > + int (*do_hw_op)(struct IPMIInterface *s, enum ipmi_op op, int > checkonly); > + > + /* > + * Enable/disable irqs on the interface when the BMC requests this. > + */ > + void (*set_irq_enable)(struct IPMIInterface *s, int val); > + > + /* > + * Handle an event that occurred on the interface, generally the. > + * target writing to a register. > + */ > + void (*handle_if_event)(struct IPMIInterface *s); > + > + /* > + * The interfaces use this to perform certain ops > + */ > + void (*set_atn)(struct IPMIInterface *s, int val, int irq); > + > + /* > + * Got an IPMI warm/cold reset. > + */ > + void (*reset)(struct IPMIInterface *s, bool is_cold); > + > + /* > + * Handle a response from the bmc. > + */ > + void (*handle_rsp)(struct IPMIInterface *s, uint8_t msg_id, > + unsigned char *rsp, unsigned int rsp_len); > + > + /* > + * Set by the owner to hold the backend data for the interface. > + */ > + void *(*get_backend_data)(struct IPMIInterface *s); > +} IPMIInterfaceClass; > + > +/* > + * Define a BMC simulator (or perhaps a connection to a real BMC) > + */ > +#define TYPE_IPMI_BMC "ipmi-bmc" > +#define IPMI_BMC(obj) \ > + OBJECT_CHECK(IPMIBmc, (obj), TYPE_IPMI_BMC) > +#define IPMI_BMC_CLASS(obj_class) \ > + OBJECT_CLASS_CHECK(IPMIBmcClass, (obj_class), TYPE_IPMI_BMC) > +#define IPMI_BMC_GET_CLASS(obj) \ > + OBJECT_GET_CLASS(IPMIBmcClass, (obj), TYPE_IPMI_BMC) > + > +typedef struct IPMIBmc { > + DeviceState parent; > + > + uint8_t slave_addr; > + > + IPMIInterface *intf; > +} IPMIBmc; > + > +typedef struct IPMIBmcClass { > + DeviceClass parent; > + > + /* Called when the system resets to report to the bmc. */ > + void (*handle_reset)(struct IPMIBmc *s); > + > + /* > + * Handle a command to the bmc. > + */ > + void (*handle_command)(struct IPMIBmc *s, > + uint8_t *cmd, unsigned int cmd_len, > + unsigned int max_cmd_len, > + uint8_t msg_id); > +} IPMIBmcClass; > + > +/* > + * Add a link property to obj that points to a BMC. > + */ > +void ipmi_bmc_find_and_link(Object *obj, Object **bmc); > + > +#ifdef IPMI_DEBUG > +#define ipmi_debug(fs, ...) \ > + fprintf(stderr, "IPMI (%s): " fs, __func__, ##__VA_ARGS__) > +#else > +#define ipmi_debug(fs, ...) > +#endif > + > +#endif > diff --git a/qemu-doc.texi b/qemu-doc.texi > index 460ab71..3c82d30 100644 > --- a/qemu-doc.texi > +++ b/qemu-doc.texi > @@ -195,6 +195,8 @@ PCI and ISA network adapters > @item > Serial ports > @item > +IPMI BMC, either and internal or external one > +@item > Creative SoundBlaster 16 sound card > @item > ENSONIQ AudioPCI ES1370 sound card > -- > 1.8.3.1 > > --001a114b2e44089c5e0524d4fd8f Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

I haven't heard any more comments on this series, should= I resubmit with the one shutdown change?

-corey

On Nov 12, 2015 1:02 PM, <minyard@acm.org> wrote:
From: Corey Minyard <cminyard@mvista.com>

Add the basic IPMI types and infrastructure to QEMU.=C2=A0 Low-level
interfaces and simulation interfaces will register with this; it's
kind of the go-between to tie them together.

Signed-off-by: Corey Minyard <cmi= nyard@mvista.com>
---
=C2=A0default-configs/i386-softmmu.mak=C2=A0 =C2=A0|=C2=A0 =C2=A01 +
=C2=A0default-configs/x86_64-softmmu.mak |=C2=A0 =C2=A01 +
=C2=A0hw/Makefile.objs=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0|=C2=A0 =C2=A01 +
=C2=A0hw/ipmi/Makefile.objs=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= |=C2=A0 =C2=A01 +
=C2=A0hw/ipmi/ipmi.c=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0| 125 ++++++++++++++++++++++++++
=C2=A0include/hw/ipmi/ipmi.h=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0| 178 +++++++++++++++++++++++++++++++++++++
=C2=A0qemu-doc.texi=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A02 +
=C2=A07 files changed, 309 insertions(+)
=C2=A0create mode 100644 hw/ipmi/Makefile.objs
=C2=A0create mode 100644 hw/ipmi/ipmi.c
=C2=A0create mode 100644 include/hw/ipmi/ipmi.h

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmm= u.mak
index 43c96d1..8fa751a 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -9,6 +9,7 @@ CONFIG_VGA_CIRRUS=3Dy
=C2=A0CONFIG_VMWARE_VGA=3Dy
=C2=A0CONFIG_VIRTIO_VGA=3Dy
=C2=A0CONFIG_VMMOUSE=3Dy
+CONFIG_IPMI=3Dy
=C2=A0CONFIG_SERIAL=3Dy
=C2=A0CONFIG_PARALLEL=3Dy
=C2=A0CONFIG_I8254=3Dy
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-so= ftmmu.mak
index dfb8095..6767f4f 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -9,6 +9,7 @@ CONFIG_VGA_CIRRUS=3Dy
=C2=A0CONFIG_VMWARE_VGA=3Dy
=C2=A0CONFIG_VIRTIO_VGA=3Dy
=C2=A0CONFIG_VMMOUSE=3Dy
+CONFIG_IPMI=3Dy
=C2=A0CONFIG_SERIAL=3Dy
=C2=A0CONFIG_PARALLEL=3Dy
=C2=A0CONFIG_I8254=3Dy
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 7e7c241..4a07ed4 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -13,6 +13,7 @@ devices-dirs-$(CONFIG_SOFTMMU) +=3D ide/
=C2=A0devices-dirs-$(CONFIG_SOFTMMU) +=3D input/
=C2=A0devices-dirs-$(CONFIG_SOFTMMU) +=3D intc/
=C2=A0devices-dirs-$(CONFIG_IPACK) +=3D ipack/
+devices-dirs-$(CONFIG_IPMI) +=3D ipmi/
=C2=A0devices-dirs-$(CONFIG_SOFTMMU) +=3D isa/
=C2=A0devices-dirs-$(CONFIG_SOFTMMU) +=3D misc/
=C2=A0devices-dirs-$(CONFIG_SOFTMMU) +=3D net/
diff --git a/hw/ipmi/Makefile.objs b/hw/ipmi/Makefile.objs
new file mode 100644
index 0000000..65bde11
--- /dev/null
+++ b/hw/ipmi/Makefile.objs
@@ -0,0 +1 @@
+common-obj-$(CONFIG_IPMI) +=3D ipmi.o
diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c
new file mode 100644
index 0000000..7d17469
--- /dev/null
+++ b/hw/ipmi/ipmi.c
@@ -0,0 +1,125 @@
+/*
+ * QEMU IPMI emulation
+ *
+ * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a= copy
+ * of this software and associated documentation files (the "Software= "), to deal
+ * in the Software without restriction, including without limitation the r= ights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll
+ * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included= in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIN= D, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY= ,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL=
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/hw.h"
+#include "hw/ipmi/ipmi.h"
+#include "sysemu/sysemu.h"
+#include "qmp-commands.h"
+#include "qom/object_interfaces.h"
+#include "qapi/visitor.h"
+
+static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly)=
+{
+=C2=A0 =C2=A0 switch (op) {
+=C2=A0 =C2=A0 case IPMI_RESET_CHASSIS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (checkonly) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 0;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 qemu_system_reset_request();
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return 0;
+
+=C2=A0 =C2=A0 case IPMI_POWEROFF_CHASSIS:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (checkonly) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 0;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 qemu_system_powerdown_request();
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return 0;
+
+=C2=A0 =C2=A0 case IPMI_SEND_NMI:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (checkonly) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 0;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 qemu_mutex_lock_iothread();
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 qmp_inject_nmi(NULL);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 qemu_mutex_unlock_iothread();
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return 0;
+
+=C2=A0 =C2=A0 case IPMI_POWERCYCLE_CHASSIS:
+=C2=A0 =C2=A0 case IPMI_PULSE_DIAG_IRQ:
+=C2=A0 =C2=A0 case IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP:
+=C2=A0 =C2=A0 case IPMI_POWERON_CHASSIS:
+=C2=A0 =C2=A0 default:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return IPMI_CC_COMMAND_NOT_SUPPORTED;
+=C2=A0 =C2=A0 }
+}
+
+static void ipmi_interface_class_init(ObjectClass *class, void *data)
+{
+=C2=A0 =C2=A0 IPMIInterfaceClass *ik =3D IPMI_INTERFACE_CLASS(class);
+
+=C2=A0 =C2=A0 ik->do_hw_op =3D ipmi_do_hw_op;
+}
+
+static TypeInfo ipmi_interface_type_info =3D {
+=C2=A0 =C2=A0 .name =3D TYPE_IPMI_INTERFACE,
+=C2=A0 =C2=A0 .parent =3D TYPE_INTERFACE,
+=C2=A0 =C2=A0 .class_size =3D sizeof(IPMIInterfaceClass),
+=C2=A0 =C2=A0 .class_init =3D ipmi_interface_class_init,
+};
+
+static void isa_ipmi_bmc_check(Object *obj, const char *name,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Object *val, Error **errp)
+{
+=C2=A0 =C2=A0 IPMIBmc *bmc =3D IPMI_BMC(val);
+
+=C2=A0 =C2=A0 if (bmc->intf)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 error_setg(errp, "BMC object is already i= n use");
+}
+
+void ipmi_bmc_find_and_link(Object *obj, Object **bmc)
+{
+=C2=A0 =C2=A0 object_property_add_link(obj, "bmc", TYPE_IPMI_BMC= , bmc,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0isa_ipmi_bmc_check,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0OBJ_PROP_LINK_UNREF_ON_RELEASE,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&error_abort);
+}
+
+static Property ipmi_bmc_properties[] =3D {
+=C2=A0 =C2=A0 DEFINE_PROP_UINT8("slave_addr",=C2=A0 IPMIBmc, sla= ve_addr, 0x20),
+=C2=A0 =C2=A0 DEFINE_PROP_END_OF_LIST(),
+};
+
+static void bmc_class_init(ObjectClass *oc, void *data)
+{
+=C2=A0 =C2=A0 DeviceClass *dc =3D DEVICE_CLASS(oc);
+
+=C2=A0 =C2=A0 dc->props =3D ipmi_bmc_properties;
+}
+
+static TypeInfo ipmi_bmc_type_info =3D {
+=C2=A0 =C2=A0 .name =3D TYPE_IPMI_BMC,
+=C2=A0 =C2=A0 .parent =3D TYPE_DEVICE,
+=C2=A0 =C2=A0 .instance_size =3D sizeof(IPMIBmc),
+=C2=A0 =C2=A0 .abstract =3D true,
+=C2=A0 =C2=A0 .class_size =3D sizeof(IPMIBmcClass),
+=C2=A0 =C2=A0 .class_init =3D bmc_class_init,
+};
+
+static void ipmi_register_types(void)
+{
+=C2=A0 =C2=A0 type_register_static(&ipmi_interface_type_info);
+=C2=A0 =C2=A0 type_register_static(&ipmi_bmc_type_info);
+}
+
+type_init(ipmi_register_types)
diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h
new file mode 100644
index 0000000..e4f7738
--- /dev/null
+++ b/include/hw/ipmi/ipmi.h
@@ -0,0 +1,178 @@
+/*
+ * IPMI base class
+ *
+ * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a= copy
+ * of this software and associated documentation files (the "Software= "), to deal
+ * in the Software without restriction, including without limitation the r= ights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll
+ * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included= in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIN= D, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY= ,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL=
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_IPMI_H
+#define HW_IPMI_H
+
+#include "exec/memory.h"
+#include "qemu-common.h"
+#include "hw/qdev.h"
+
+#define MAX_IPMI_MSG_SIZE 300
+
+enum ipmi_op {
+=C2=A0 =C2=A0 IPMI_RESET_CHASSIS,
+=C2=A0 =C2=A0 IPMI_POWEROFF_CHASSIS,
+=C2=A0 =C2=A0 IPMI_POWERON_CHASSIS,
+=C2=A0 =C2=A0 IPMI_POWERCYCLE_CHASSIS,
+=C2=A0 =C2=A0 IPMI_PULSE_DIAG_IRQ,
+=C2=A0 =C2=A0 IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP,
+=C2=A0 =C2=A0 IPMI_SEND_NMI
+};
+
+#define IPMI_CC_INVALID_CMD=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0xc1
+#define IPMI_CC_COMMAND_INVALID_FOR_LUN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 0xc2
+#define IPMI_CC_TIMEOUT=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0xc3<= br> +#define IPMI_CC_OUT_OF_SPACE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00xc4
+#define IPMI_CC_INVALID_RESERVATION=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0xc5
+#define IPMI_CC_REQUEST_DATA_TRUNCATED=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00xc6
+#define IPMI_CC_REQUEST_DATA_LENGTH_INVALID=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 0xc7
+#define IPMI_CC_PARM_OUT_OF_RANGE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0xc9
+#define IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 0xca
+#define IPMI_CC_REQ_ENTRY_NOT_PRESENT=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0xcb
+#define IPMI_CC_INVALID_DATA_FIELD=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00xcc
+#define IPMI_CC_BMC_INIT_IN_PROGRESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00xd2
+#define IPMI_CC_COMMAND_NOT_SUPPORTED=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0xd5
+
+#define IPMI_NETFN_APP=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 0x06
+
+#define IPMI_DEBUG 1
+
+/* Specified in the SMBIOS spec. */
+#define IPMI_SMBIOS_KCS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00x01
+#define IPMI_SMBIOS_SMIC=C2=A0 =C2=A0 =C2=A0 =C2=A0 0x02
+#define IPMI_SMBIOS_BT=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0x03
+#define IPMI_SMBIOS_SSIF=C2=A0 =C2=A0 =C2=A0 =C2=A0 0x04
+
+/* IPMI Interface types (KCS, SMIC, BT) are prefixed with this */
+#define TYPE_IPMI_INTERFACE_PREFIX "ipmi-interface-"
+
+/*
+ * An IPMI Interface, the interface for talking between the target
+ * and the BMC.
+ */
+#define TYPE_IPMI_INTERFACE "ipmi-interface"
+#define IPMI_INTERFACE(obj) \
+=C2=A0 =C2=A0 =C2=A0INTERFACE_CHECK(IPMIInterface, (obj), TYPE_IPMI_INTERF= ACE)
+#define IPMI_INTERFACE_CLASS(class) \
+=C2=A0 =C2=A0 =C2=A0OBJECT_CLASS_CHECK(IPMIInterfaceClass, (class), TYPE_I= PMI_INTERFACE)
+#define IPMI_INTERFACE_GET_CLASS(class) \
+=C2=A0 =C2=A0 =C2=A0OBJECT_GET_CLASS(IPMIInterfaceClass, (class), TYPE_IPM= I_INTERFACE)
+
+typedef struct IPMIInterface {
+=C2=A0 =C2=A0 Object parent;
+} IPMIInterface;
+
+typedef struct IPMIInterfaceClass {
+=C2=A0 =C2=A0 InterfaceClass parent;
+
+=C2=A0 =C2=A0 void (*init)(struct IPMIInterface *s, Error **errp);
+
+=C2=A0 =C2=A0 /*
+=C2=A0 =C2=A0 =C2=A0* Perform various operations on the hardware.=C2=A0 If= checkonly is
+=C2=A0 =C2=A0 =C2=A0* true, it will return if the operation can be perform= ed, but it
+=C2=A0 =C2=A0 =C2=A0* will not do the operation.
+=C2=A0 =C2=A0 =C2=A0*/
+=C2=A0 =C2=A0 int (*do_hw_op)(struct IPMIInterface *s, enum ipmi_op op, in= t checkonly);
+
+=C2=A0 =C2=A0 /*
+=C2=A0 =C2=A0 =C2=A0* Enable/disable irqs on the interface when the BMC re= quests this.
+=C2=A0 =C2=A0 =C2=A0*/
+=C2=A0 =C2=A0 void (*set_irq_enable)(struct IPMIInterface *s, int val); +
+=C2=A0 =C2=A0 /*
+=C2=A0 =C2=A0 =C2=A0* Handle an event that occurred on the interface, gene= rally the.
+=C2=A0 =C2=A0 =C2=A0* target writing to a register.
+=C2=A0 =C2=A0 =C2=A0*/
+=C2=A0 =C2=A0 void (*handle_if_event)(struct IPMIInterface *s);
+
+=C2=A0 =C2=A0 /*
+=C2=A0 =C2=A0 =C2=A0* The interfaces use this to perform certain ops
+=C2=A0 =C2=A0 =C2=A0*/
+=C2=A0 =C2=A0 void (*set_atn)(struct IPMIInterface *s, int val, int irq);<= br> +
+=C2=A0 =C2=A0 /*
+=C2=A0 =C2=A0 =C2=A0* Got an IPMI warm/cold reset.
+=C2=A0 =C2=A0 =C2=A0*/
+=C2=A0 =C2=A0 void (*reset)(struct IPMIInterface *s, bool is_cold);
+
+=C2=A0 =C2=A0 /*
+=C2=A0 =C2=A0 =C2=A0* Handle a response from the bmc.
+=C2=A0 =C2=A0 =C2=A0*/
+=C2=A0 =C2=A0 void (*handle_rsp)(struct IPMIInterface *s, uint8_t msg_id,<= br> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0unsigned char *rsp, unsigned int rsp_len);
+
+=C2=A0 =C2=A0 /*
+=C2=A0 =C2=A0 =C2=A0* Set by the owner to hold the backend data for the in= terface.
+=C2=A0 =C2=A0 =C2=A0*/
+=C2=A0 =C2=A0 void *(*get_backend_data)(struct IPMIInterface *s);
+} IPMIInterfaceClass;
+
+/*
+ * Define a BMC simulator (or perhaps a connection to a real BMC)
+ */
+#define TYPE_IPMI_BMC "ipmi-bmc"
+#define IPMI_BMC(obj) \
+=C2=A0 =C2=A0 =C2=A0OBJECT_CHECK(IPMIBmc, (obj), TYPE_IPMI_BMC)
+#define IPMI_BMC_CLASS(obj_class) \
+=C2=A0 =C2=A0 =C2=A0OBJECT_CLASS_CHECK(IPMIBmcClass, (obj_class), TYPE_IPM= I_BMC)
+#define IPMI_BMC_GET_CLASS(obj) \
+=C2=A0 =C2=A0 =C2=A0OBJECT_GET_CLASS(IPMIBmcClass, (obj), TYPE_IPMI_BMC) +
+typedef struct IPMIBmc {
+=C2=A0 =C2=A0 DeviceState parent;
+
+=C2=A0 =C2=A0 uint8_t slave_addr;
+
+=C2=A0 =C2=A0 IPMIInterface *intf;
+} IPMIBmc;
+
+typedef struct IPMIBmcClass {
+=C2=A0 =C2=A0 DeviceClass parent;
+
+=C2=A0 =C2=A0 /* Called when the system resets to report to the bmc. */ +=C2=A0 =C2=A0 void (*handle_reset)(struct IPMIBmc *s);
+
+=C2=A0 =C2=A0 /*
+=C2=A0 =C2=A0 =C2=A0* Handle a command to the bmc.
+=C2=A0 =C2=A0 =C2=A0*/
+=C2=A0 =C2=A0 void (*handle_command)(struct IPMIBmc *s,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0uint8_t *cmd, unsigned int cmd_len,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0unsigned int max_cmd_len,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0uint8_t msg_id);
+} IPMIBmcClass;
+
+/*
+ * Add a link property to obj that points to a BMC.
+ */
+void ipmi_bmc_find_and_link(Object *obj, Object **bmc);
+
+#ifdef IPMI_DEBUG
+#define ipmi_debug(fs, ...) \
+=C2=A0 =C2=A0 fprintf(stderr, "IPMI (%s): " fs, __func__, ##__VA= _ARGS__)
+#else
+#define ipmi_debug(fs, ...)
+#endif
+
+#endif
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 460ab71..3c82d30 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -195,6 +195,8 @@ PCI and ISA network adapters
=C2=A0@item
=C2=A0Serial ports
=C2=A0@item
+IPMI BMC, either and internal or external one
+@item
=C2=A0Creative SoundBlaster 16 sound card
=C2=A0@item
=C2=A0ENSONIQ AudioPCI ES1370 sound card
--
1.8.3.1

--001a114b2e44089c5e0524d4fd8f--