@@ -27,6 +27,8 @@ CONFIG_GUMSTIX=y
CONFIG_SPITZ=y
CONFIG_TOSA=y
CONFIG_Z2=y
+CONFIG_IPMI=y
+CONFIG_IPMI_HOST=y
CONFIG_NPCM7XX=y
CONFIG_COLLIE=y
CONFIG_ASPEED_SOC=y
@@ -6,6 +6,11 @@ config IPMI_LOCAL
default y
depends on IPMI
+config IPMI_HOST
+ bool
+ default y
+ depends on IPMI
+
config IPMI_EXTERN
bool
default y
new file mode 100644
@@ -0,0 +1,40 @@
+/*
+ * IPMI Host emulation
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "hw/ipmi/ipmi_host.h"
+#include "hw/ipmi/ipmi_responder.h"
+
+static TypeInfo ipmi_responder_type_info = {
+ .name = TYPE_IPMI_RESPONDER,
+ .parent = TYPE_INTERFACE,
+ .class_size = sizeof(IPMIResponderClass),
+};
+
+static TypeInfo ipmi_host_type_info = {
+ .name = TYPE_IPMI_HOST,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(IPMIHost),
+ .abstract = true,
+ .class_size = sizeof(IPMIHostClass),
+};
+
+static void ipmi_register_types(void)
+{
+ type_register_static(&ipmi_responder_type_info);
+ type_register_static(&ipmi_host_type_info);
+}
+
+type_init(ipmi_register_types)
@@ -7,5 +7,6 @@ ipmi_ss.add(when: 'CONFIG_PCI_IPMI_KCS', if_true: files('pci_ipmi_kcs.c'))
ipmi_ss.add(when: 'CONFIG_ISA_IPMI_BT', if_true: files('isa_ipmi_bt.c'))
ipmi_ss.add(when: 'CONFIG_PCI_IPMI_BT', if_true: files('pci_ipmi_bt.c'))
ipmi_ss.add(when: 'CONFIG_IPMI_SSIF', if_true: files('smbus_ipmi.c'))
+ipmi_ss.add(when: 'CONFIG_IPMI_HOST', if_true: files('ipmi_host.c'))
softmmu_ss.add_all(when: 'CONFIG_IPMI', if_true: ipmi_ss)
new file mode 100644
@@ -0,0 +1,56 @@
+/*
+ * IPMI host interface
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef HW_IPMI_HOST_H
+#define HW_IPMI_HOST_H
+
+#include "hw/ipmi/ipmi_responder.h"
+
+#define TYPE_IPMI_HOST "ipmi-host"
+#define IPMI_HOST(obj) \
+ OBJECT_CHECK(IPMIHost, (obj), TYPE_IPMI_HOST)
+#define IPMI_HOST_CLASS(obj_class) \
+ OBJECT_CLASS_CHECK(IPMIHostClass, (obj_class), TYPE_IPMI_HOST)
+#define IPMI_HOST_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(IPMIHostClass, (obj), TYPE_IPMI_HOST)
+
+/**
+ * struct IPMIHost defines an IPMI host interface. It can be a simulator or a
+ * connection to an emulated or real host.
+ * @responder: The IPMI responder that handles an IPMI message.
+ */
+typedef struct IPMIHost {
+ DeviceState parent;
+
+ IPMIResponder *responder;
+} IPMIHost;
+
+/**
+ * struct IPMIHostClass defines an IPMI host class.
+ * @handle_command: Handle a command to the host.
+ */
+typedef struct IPMIHostClass {
+ DeviceClass parent;
+
+ /*
+ * Handle a command to the bmc.
+ */
+ void (*handle_command)(struct IPMIHost *s,
+ uint8_t *cmd, unsigned int cmd_len,
+ unsigned int max_cmd_len, uint8_t msg_id);
+} IPMIHostClass;
+
+#endif /* HW_IPMI_HOST_H */
new file mode 100644
@@ -0,0 +1,66 @@
+/*
+ * IPMI responder interface
+ *
+ * Copyright 2020 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef HW_IPMI_RESPONDER_H
+#define HW_IPMI_RESPONDER_H
+
+#include "qemu/osdep.h"
+#include "hw/qdev-core.h"
+#include "qom/object.h"
+
+#define TYPE_IPMI_RESPONDER_PREFIX "ipmi-responder-"
+#define TYPE_IPMI_RESPONDER "ipmi-responder"
+#define IPMI_RESPONDER(obj) \
+ INTERFACE_CHECK(IPMIResponder, (obj), TYPE_IPMI_RESPONDER)
+#define IPMI_RESPONDER_CLASS(class) \
+ OBJECT_CLASS_CHECK(IPMIResponderClass, (class), TYPE_IPMI_RESPONDER)
+#define IPMI_RESPONDER_GET_CLASS(class) \
+ OBJECT_GET_CLASS(IPMIResponderClass, (class), TYPE_IPMI_RESPONDER)
+
+struct IPMIHost;
+
+/**
+ * This interface is implemented by each IPMI responder device (KCS, BT, PCI,
+ * etc.) An IPMI host device uses it to transfer data to the emulated BMC.
+ */
+typedef struct IPMIResponder IPMIResponder;
+
+/**
+ * struct IPMIResponderClass implemented by an IPMI responder device like KCS to
+ * handle commands from connected IPMI host device.
+ * @get_host: Return the IPMI host (e.g. ipmi-host-extern) that uses this
+ * responder.
+ * @set_host: Set the IPMI host (e.g. ipmi-host-extern) that uses this
+ * responder.
+ * @get_backend_data: Return the backend device (e.g. KCS, BT) of the
+ * corresponding responder.
+ * @handle_req: The IPMI Host device calls this function when it receives a sane
+ * IPMI message. A responder should handle this message.
+ */
+typedef struct IPMIResponderClass {
+ InterfaceClass parent;
+
+ struct IPMIHost *(*get_host)(struct IPMIResponder *s);
+
+ void (*set_host)(struct IPMIResponder *s, struct IPMIHost *h);
+
+ void *(*get_backend_data)(struct IPMIResponder *s);
+
+ void (*handle_req)(struct IPMIResponder *s, uint8_t msg_id,
+ unsigned char *req, unsigned req_len);
+} IPMIResponderClass;
+
+#endif /* HW_IPMI_RESPONDER_H */