The IPMI host interface is used to emulate IPMI related devices on a System-on-Chip (SoC) used for Baseband Management Controller (BMC). This interface consists of two components: IPMI host and IPMI responder. An IPMI responder is a device to intercept reads and writes to the system interface registers in the host. An IPMI host emulates the host behavior on a BMC emulation.
For more information see docs/spec/ipmi.rst. Reviewed-by: Havard Skinnemoen <hskinnem...@google.com> Reviewed-by: Tyrone Ting <kft...@nuvoton.com> Signed-off-by: Hao Wu <wuhao...@google.com> --- default-configs/devices/arm-softmmu.mak | 2 + hw/ipmi/Kconfig | 5 ++ hw/ipmi/ipmi_host.c | 40 +++++++++++++++ hw/ipmi/meson.build | 1 + include/hw/ipmi/ipmi_host.h | 56 +++++++++++++++++++++ include/hw/ipmi/ipmi_responder.h | 66 +++++++++++++++++++++++++ 6 files changed, 170 insertions(+) create mode 100644 hw/ipmi/ipmi_host.c create mode 100644 include/hw/ipmi/ipmi_host.h create mode 100644 include/hw/ipmi/ipmi_responder.h diff --git a/default-configs/devices/arm-softmmu.mak b/default-configs/devices/arm-softmmu.mak index 08a32123b4..864bac4501 100644 --- a/default-configs/devices/arm-softmmu.mak +++ b/default-configs/devices/arm-softmmu.mak @@ -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 diff --git a/hw/ipmi/Kconfig b/hw/ipmi/Kconfig index 9befd4f422..9e487eb42f 100644 --- a/hw/ipmi/Kconfig +++ b/hw/ipmi/Kconfig @@ -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 diff --git a/hw/ipmi/ipmi_host.c b/hw/ipmi/ipmi_host.c new file mode 100644 index 0000000000..7a6d4eb323 --- /dev/null +++ b/hw/ipmi/ipmi_host.c @@ -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) diff --git a/hw/ipmi/meson.build b/hw/ipmi/meson.build index 9622ea2a2c..9ec4dcb957 100644 --- a/hw/ipmi/meson.build +++ b/hw/ipmi/meson.build @@ -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) diff --git a/include/hw/ipmi/ipmi_host.h b/include/hw/ipmi/ipmi_host.h new file mode 100644 index 0000000000..a703cc3854 --- /dev/null +++ b/include/hw/ipmi/ipmi_host.h @@ -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 */ diff --git a/include/hw/ipmi/ipmi_responder.h b/include/hw/ipmi/ipmi_responder.h new file mode 100644 index 0000000000..e3e4ef39d4 --- /dev/null +++ b/include/hw/ipmi/ipmi_responder.h @@ -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 */ -- 2.29.2.684.gfbc64c5ab5-goog