qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 4/8] hw/ipmi: Refactor IPMI interface


From: Corey Minyard
Subject: Re: [PATCH 4/8] hw/ipmi: Refactor IPMI interface
Date: Thu, 9 Sep 2021 19:26:48 -0500

On Thu, Sep 09, 2021 at 04:06:16PM -0700, Hao Wu wrote:
> This patch refactors the IPMI interface so that it can be used by both
> the BMC side and core-side simulation.
> 
> Detail changes:
> (1) rename handle_rsp -> handle_msg so the name fits both BMC side and
>     Core side.
> (2) Add a new class IPMICore. This class represents a simulator/external
>     connection for both BMC and Core side emulation. The old IPMIBmc is
>     a sub-class of IPMICore.
> (3) Change all ibe->parent.intf in hw/ipmi/ipmi_bmc_*.c to use type
>     cast to IPMICore. Directly accessing parent QOM is against QEMU
>     guide and by using type casting the code can fit both core side and
>     BMC side emulation.

I think I'm ok with this.  It fixes some fundamental issues (maybe that
should be separate patches, but I think it's ok here).

I was kind of against this at first, I was thinking a completely
separate code for the BMC-side hardware emulation.  But I can see that
so much code would be duplicated that it would be silly.

It would be better if there was an ipmi_bmc.[ch] that had the
BMC-specific things, split out from the ipmi.[ch] code.  I'm not 100%
sure how important that is, but it would be less confusing.  Do you
agree?

A couple of comments inline...

-corey

> 
> Signed-off-by: Hao Wu <wuhaotsh@google.com>
> ---
>  hw/ipmi/ipmi.c            | 15 +++++++++++---
>  hw/ipmi/ipmi_bmc_extern.c | 37 +++++++++++++++++++++--------------
>  hw/ipmi/ipmi_bmc_sim.c    | 41 ++++++++++++++++++++++++++-------------
>  hw/ipmi/ipmi_bt.c         |  2 +-
>  hw/ipmi/ipmi_kcs.c        |  2 +-
>  hw/ipmi/isa_ipmi_bt.c     |  4 +++-
>  hw/ipmi/isa_ipmi_kcs.c    |  4 +++-
>  hw/ipmi/pci_ipmi_bt.c     |  4 +++-
>  hw/ipmi/pci_ipmi_kcs.c    |  4 +++-
>  hw/ipmi/smbus_ipmi.c      |  6 ++++--
>  include/hw/ipmi/ipmi.h    | 40 ++++++++++++++++++++++++++++++--------
>  11 files changed, 111 insertions(+), 48 deletions(-)
> 
> diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c
> index 8d35c9fdd6..7da1b36fab 100644
> --- a/hw/ipmi/ipmi.c
> +++ b/hw/ipmi/ipmi.c
> @@ -92,13 +92,21 @@ static TypeInfo ipmi_interface_type_info = {
>      .class_init = ipmi_interface_class_init,
>  };
>  
> +static TypeInfo ipmi_core_type_info = {
> +    .name = TYPE_IPMI_CORE,
> +    .parent = TYPE_DEVICE,
> +    .instance_size = sizeof(IPMICore),
> +    .abstract = true,
> +};
> +
>  static void isa_ipmi_bmc_check(const Object *obj, const char *name,
>                                 Object *val, Error **errp)
>  {
> -    IPMIBmc *bmc = IPMI_BMC(val);
> +    IPMICore *ic = IPMI_CORE(val);
>  
> -    if (bmc->intf)
> +    if (ic->intf) {
>          error_setg(errp, "BMC object is already in use");
> +    }
>  }
>  
>  void ipmi_bmc_find_and_link(Object *obj, Object **bmc)
> @@ -122,7 +130,7 @@ static void bmc_class_init(ObjectClass *oc, void *data)
>  
>  static TypeInfo ipmi_bmc_type_info = {
>      .name = TYPE_IPMI_BMC,
> -    .parent = TYPE_DEVICE,
> +    .parent = TYPE_IPMI_CORE,
>      .instance_size = sizeof(IPMIBmc),
>      .abstract = true,
>      .class_size = sizeof(IPMIBmcClass),
> @@ -132,6 +140,7 @@ static TypeInfo ipmi_bmc_type_info = {
>  static void ipmi_register_types(void)
>  {
>      type_register_static(&ipmi_interface_type_info);
> +    type_register_static(&ipmi_core_type_info);
>      type_register_static(&ipmi_bmc_type_info);
>  }
>  
> diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
> index acf2bab35f..a0c3a40e7c 100644
> --- a/hw/ipmi/ipmi_bmc_extern.c
> +++ b/hw/ipmi/ipmi_bmc_extern.c
> @@ -147,8 +147,9 @@ static void continue_send(IPMIBmcExtern *ibe)
>  
>  static void extern_timeout(void *opaque)
>  {
> +    IPMICore *ic = opaque;
>      IPMIBmcExtern *ibe = opaque;

Shouldn't the above be a cast from ic?

> -    IPMIInterface *s = ibe->parent.intf;
> +    IPMIInterface *s = ic->intf;
>  
>      if (ibe->connected) {
>          if (ibe->waiting_rsp && (ibe->outlen == 0)) {
> @@ -158,7 +159,7 @@ static void extern_timeout(void *opaque)
>              ibe->inbuf[1] = ibe->outbuf[1] | 0x04;
>              ibe->inbuf[2] = ibe->outbuf[2];
>              ibe->inbuf[3] = IPMI_CC_TIMEOUT;
> -            k->handle_rsp(s, ibe->outbuf[0], ibe->inbuf + 1, 3);
> +            k->handle_msg(s, ibe->outbuf[0], ibe->inbuf + 1, 3);
>          } else {
>              continue_send(ibe);
>          }
> @@ -186,8 +187,9 @@ static void ipmi_bmc_extern_handle_command(IPMIBmc *b,
>                                         unsigned int max_cmd_len,
>                                         uint8_t msg_id)
>  {
> +    IPMICore *ic = IPMI_CORE(b);
>      IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(b);
> -    IPMIInterface *s = ibe->parent.intf;
> +    IPMIInterface *s = ic->intf;
>      uint8_t err = 0, csum;
>      unsigned int i;
>  
> @@ -213,7 +215,7 @@ static void ipmi_bmc_extern_handle_command(IPMIBmc *b,
>          rsp[1] = cmd[1];
>          rsp[2] = err;
>          ibe->waiting_rsp = false;
> -        k->handle_rsp(s, msg_id, rsp, 3);
> +        k->handle_msg(s, msg_id, rsp, 3);
>          goto out;
>      }
>  
> @@ -236,7 +238,8 @@ static void ipmi_bmc_extern_handle_command(IPMIBmc *b,
>  
>  static void handle_hw_op(IPMIBmcExtern *ibe, unsigned char hw_op)
>  {
> -    IPMIInterface *s = ibe->parent.intf;
> +    IPMICore *ic = IPMI_CORE(ibe);
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>  
>      switch (hw_op) {
> @@ -284,7 +287,9 @@ static void handle_hw_op(IPMIBmcExtern *ibe, unsigned 
> char hw_op)
>  
>  static void handle_msg(IPMIBmcExtern *ibe)
>  {
> -    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(ibe->parent.intf);
> +    IPMICore *ic = IPMI_CORE(ibe);
> +    IPMIInterface *s = ic->intf;
> +    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>  
>      if (ibe->in_escape) {
>          ipmi_debug("msg escape not ended\n");
> @@ -306,7 +311,7 @@ static void handle_msg(IPMIBmcExtern *ibe)
>  
>      timer_del(ibe->extern_timer);
>      ibe->waiting_rsp = false;
> -    k->handle_rsp(ibe->parent.intf, ibe->inbuf[0], ibe->inbuf + 1, 
> ibe->inpos - 1);
> +    k->handle_msg(s, ibe->inbuf[0], ibe->inbuf + 1, ibe->inpos - 1);
>  }
>  
>  static int can_receive(void *opaque)
> @@ -382,8 +387,9 @@ static void receive(void *opaque, const uint8_t *buf, int 
> size)
>  
>  static void chr_event(void *opaque, QEMUChrEvent event)
>  {
> +    IPMICore *ic = opaque;
>      IPMIBmcExtern *ibe = opaque;

Shouldn't the above be a cast from ic?

> -    IPMIInterface *s = ibe->parent.intf;
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>      unsigned char v;
>  
> @@ -398,17 +404,17 @@ static void chr_event(void *opaque, QEMUChrEvent event)
>          ibe->outlen++;
>          addchar(ibe, VM_CMD_CAPABILITIES);
>          v = VM_CAPABILITIES_IRQ | VM_CAPABILITIES_ATTN;
> -        if (k->do_hw_op(ibe->parent.intf, IPMI_POWEROFF_CHASSIS, 1) == 0) {
> +        if (k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 1) == 0) {
>              v |= VM_CAPABILITIES_POWER;
>          }
> -        if (k->do_hw_op(ibe->parent.intf, IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP, 1)
> +        if (k->do_hw_op(s, IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP, 1)
>              == 0) {
>              v |= VM_CAPABILITIES_GRACEFUL_SHUTDOWN;
>          }
> -        if (k->do_hw_op(ibe->parent.intf, IPMI_RESET_CHASSIS, 1) == 0) {
> +        if (k->do_hw_op(s, IPMI_RESET_CHASSIS, 1) == 0) {
>              v |= VM_CAPABILITIES_RESET;
>          }
> -        if (k->do_hw_op(ibe->parent.intf, IPMI_SEND_NMI, 1) == 0) {
> +        if (k->do_hw_op(s, IPMI_SEND_NMI, 1) == 0) {
>              v |= VM_CAPABILITIES_NMI;
>          }
>          addchar(ibe, v);
> @@ -433,7 +439,7 @@ static void chr_event(void *opaque, QEMUChrEvent event)
>              ibe->inbuf[1] = ibe->outbuf[1] | 0x04;
>              ibe->inbuf[2] = ibe->outbuf[2];
>              ibe->inbuf[3] = IPMI_CC_BMC_INIT_IN_PROGRESS;
> -            k->handle_rsp(s, ibe->outbuf[0], ibe->inbuf + 1, 3);
> +            k->handle_msg(s, ibe->outbuf[0], ibe->inbuf + 1, 3);
>          }
>          break;
>  
> @@ -475,14 +481,15 @@ static int ipmi_bmc_extern_post_migrate(void *opaque, 
> int version_id)
>       * error on the interface if a response was being waited for.
>       */
>      if (ibe->waiting_rsp) {
> -        IPMIInterface *ii = ibe->parent.intf;
> +        IPMICore *ic = opaque;
> +        IPMIInterface *ii = ic->intf;
>          IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);
>  
>          ibe->waiting_rsp = false;
>          ibe->inbuf[1] = ibe->outbuf[1] | 0x04;
>          ibe->inbuf[2] = ibe->outbuf[2];
>          ibe->inbuf[3] = IPMI_CC_BMC_INIT_IN_PROGRESS;
> -        iic->handle_rsp(ii, ibe->outbuf[0], ibe->inbuf + 1, 3);
> +        iic->handle_msg(ii, ibe->outbuf[0], ibe->inbuf + 1, 3);
>      }
>      return 0;
>  }
> diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
> index 905e091094..7cc4a22456 100644
> --- a/hw/ipmi/ipmi_bmc_sim.c
> +++ b/hw/ipmi/ipmi_bmc_sim.c
> @@ -451,7 +451,8 @@ static int attn_irq_enabled(IPMIBmcSim *ibs)
>  void ipmi_bmc_gen_event(IPMIBmc *b, uint8_t *evt, bool log)
>  {
>      IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
> -    IPMIInterface *s = ibs->parent.intf;
> +    IPMICore *ic = IPMI_CORE(ibs);
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>  
>      if (!IPMI_BMC_EVENT_MSG_BUF_ENABLED(ibs)) {
> @@ -475,7 +476,8 @@ void ipmi_bmc_gen_event(IPMIBmc *b, uint8_t *evt, bool 
> log)
>  static void gen_event(IPMIBmcSim *ibs, unsigned int sens_num, uint8_t 
> deassert,
>                        uint8_t evd1, uint8_t evd2, uint8_t evd3)
>  {
> -    IPMIInterface *s = ibs->parent.intf;
> +    IPMICore *ic = IPMI_CORE(ibs);
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>      uint8_t evt[16];
>      IPMISensor *sens = ibs->sensors + sens_num;
> @@ -644,7 +646,8 @@ static void ipmi_sim_handle_command(IPMIBmc *b,
>                                      uint8_t msg_id)
>  {
>      IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
> -    IPMIInterface *s = ibs->parent.intf;
> +    IPMICore *ic = IPMI_CORE(ibs);
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>      const IPMICmdHandler *hdl;
>      RspBuffer rsp = RSP_BUFFER_INITIALIZER;
> @@ -690,14 +693,15 @@ static void ipmi_sim_handle_command(IPMIBmc *b,
>      hdl->cmd_handler(ibs, cmd, cmd_len, &rsp);
>  
>   out:
> -    k->handle_rsp(s, msg_id, rsp.buffer, rsp.len);
> +    k->handle_msg(s, msg_id, rsp.buffer, rsp.len);
>  
>      next_timeout(ibs);
>  }
>  
>  static void ipmi_sim_handle_timeout(IPMIBmcSim *ibs)
>  {
> -    IPMIInterface *s = ibs->parent.intf;
> +    IPMICore *ic = IPMI_CORE(ibs);
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>  
>      if (!ibs->watchdog_running) {
> @@ -788,7 +792,8 @@ static void chassis_control(IPMIBmcSim *ibs,
>                              uint8_t *cmd, unsigned int cmd_len,
>                              RspBuffer *rsp)
>  {
> -    IPMIInterface *s = ibs->parent.intf;
> +    IPMICore *ic = IPMI_CORE(ibs);
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>  
>      switch (cmd[2] & 0xf) {
> @@ -845,7 +850,8 @@ static void get_device_id(IPMIBmcSim *ibs,
>  
>  static void set_global_enables(IPMIBmcSim *ibs, uint8_t val)
>  {
> -    IPMIInterface *s = ibs->parent.intf;
> +    IPMICore *ic = IPMI_CORE(ibs);
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>      bool irqs_on;
>  
> @@ -861,7 +867,8 @@ static void cold_reset(IPMIBmcSim *ibs,
>                         uint8_t *cmd, unsigned int cmd_len,
>                         RspBuffer *rsp)
>  {
> -    IPMIInterface *s = ibs->parent.intf;
> +    IPMICore *ic = IPMI_CORE(ibs);
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>  
>      /* Disable all interrupts */
> @@ -876,7 +883,8 @@ static void warm_reset(IPMIBmcSim *ibs,
>                         uint8_t *cmd, unsigned int cmd_len,
>                         RspBuffer *rsp)
>  {
> -    IPMIInterface *s = ibs->parent.intf;
> +    IPMICore *ic = IPMI_CORE(ibs);
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>  
>      if (k->reset) {
> @@ -939,7 +947,8 @@ static void clr_msg_flags(IPMIBmcSim *ibs,
>                            uint8_t *cmd, unsigned int cmd_len,
>                            RspBuffer *rsp)
>  {
> -    IPMIInterface *s = ibs->parent.intf;
> +    IPMICore *ic = IPMI_CORE(ibs);
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>  
>      ibs->msg_flags &= ~cmd[2];
> @@ -957,7 +966,8 @@ static void read_evt_msg_buf(IPMIBmcSim *ibs,
>                               uint8_t *cmd, unsigned int cmd_len,
>                               RspBuffer *rsp)
>  {
> -    IPMIInterface *s = ibs->parent.intf;
> +    IPMICore *ic = IPMI_CORE(ibs);
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>      unsigned int i;
>  
> @@ -989,7 +999,8 @@ static void get_msg(IPMIBmcSim *ibs,
>      g_free(msg);
>  
>      if (QTAILQ_EMPTY(&ibs->rcvbufs)) {
> -        IPMIInterface *s = ibs->parent.intf;
> +        IPMICore *ic = IPMI_CORE(ibs);
> +        IPMIInterface *s = ic->intf;
>          IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>  
>          ibs->msg_flags &= ~IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE;
> @@ -1014,7 +1025,8 @@ static void send_msg(IPMIBmcSim *ibs,
>                       uint8_t *cmd, unsigned int cmd_len,
>                       RspBuffer *rsp)
>  {
> -    IPMIInterface *s = ibs->parent.intf;
> +    IPMICore *ic = IPMI_CORE(ibs);
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>      IPMIRcvBufEntry *msg;
>      uint8_t *buf;
> @@ -1130,7 +1142,8 @@ static void set_watchdog_timer(IPMIBmcSim *ibs,
>                                 uint8_t *cmd, unsigned int cmd_len,
>                                 RspBuffer *rsp)
>  {
> -    IPMIInterface *s = ibs->parent.intf;
> +    IPMICore *ic = IPMI_CORE(ibs);
> +    IPMIInterface *s = ic->intf;
>      IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
>      unsigned int val;
>  
> diff --git a/hw/ipmi/ipmi_bt.c b/hw/ipmi/ipmi_bt.c
> index 22f94fb98d..f76c369e4a 100644
> --- a/hw/ipmi/ipmi_bt.c
> +++ b/hw/ipmi/ipmi_bt.c
> @@ -430,7 +430,7 @@ 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_msg = 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;
> diff --git a/hw/ipmi/ipmi_kcs.c b/hw/ipmi/ipmi_kcs.c
> index a77612946a..e0f870e13a 100644
> --- a/hw/ipmi/ipmi_kcs.c
> +++ b/hw/ipmi/ipmi_kcs.c
> @@ -417,7 +417,7 @@ 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_msg = ipmi_kcs_handle_rsp;
>      iic->handle_if_event = ipmi_kcs_handle_event;
>      iic->set_irq_enable = ipmi_kcs_set_irq_enable;
>  }
> diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c
> index 02625eb94e..0f52fc4262 100644
> --- a/hw/ipmi/isa_ipmi_bt.c
> +++ b/hw/ipmi/isa_ipmi_bt.c
> @@ -74,6 +74,7 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error 
> **errp)
>      ISAIPMIBTDevice *iib = ISA_IPMI_BT(dev);
>      IPMIInterface *ii = IPMI_INTERFACE(dev);
>      IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);
> +    IPMICore *ic;
>  
>      if (!iib->bt.bmc) {
>          error_setg(errp, "IPMI device requires a bmc attribute to be set");
> @@ -82,7 +83,8 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error 
> **errp)
>  
>      iib->uuid = ipmi_next_uuid();
>  
> -    iib->bt.bmc->intf = ii;
> +    ic = IPMI_CORE(iib->bt.bmc);
> +    ic->intf = ii;
>      iib->bt.opaque = iib;
>  
>      iic->init(ii, 0, &err);
> diff --git a/hw/ipmi/isa_ipmi_kcs.c b/hw/ipmi/isa_ipmi_kcs.c
> index 3b23ad08b3..60cab90a21 100644
> --- a/hw/ipmi/isa_ipmi_kcs.c
> +++ b/hw/ipmi/isa_ipmi_kcs.c
> @@ -73,6 +73,7 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp)
>      ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(dev);
>      IPMIInterface *ii = IPMI_INTERFACE(dev);
>      IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);
> +    IPMICore *ic;
>  
>      if (!iik->kcs.bmc) {
>          error_setg(errp, "IPMI device requires a bmc attribute to be set");
> @@ -81,7 +82,8 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp)
>  
>      iik->uuid = ipmi_next_uuid();
>  
> -    iik->kcs.bmc->intf = ii;
> +    ic = IPMI_CORE(iik->kcs.bmc);
> +    ic->intf = ii;
>      iik->kcs.opaque = iik;
>  
>      iic->init(ii, 0, &err);
> diff --git a/hw/ipmi/pci_ipmi_bt.c b/hw/ipmi/pci_ipmi_bt.c
> index b6e52730d3..751c15a31f 100644
> --- a/hw/ipmi/pci_ipmi_bt.c
> +++ b/hw/ipmi/pci_ipmi_bt.c
> @@ -58,6 +58,7 @@ static void pci_ipmi_bt_realize(PCIDevice *pd, Error **errp)
>      PCIIPMIBTDevice *pik = PCI_IPMI_BT(pd);
>      IPMIInterface *ii = IPMI_INTERFACE(pd);
>      IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);
> +    IPMICore *ic;
>  
>      if (!pik->bt.bmc) {
>          error_setg(errp, "IPMI device requires a bmc attribute to be set");
> @@ -66,7 +67,8 @@ static void pci_ipmi_bt_realize(PCIDevice *pd, Error **errp)
>  
>      pik->uuid = ipmi_next_uuid();
>  
> -    pik->bt.bmc->intf = ii;
> +    ic = IPMI_CORE(pik->bt.bmc);
> +    ic->intf = ii;
>      pik->bt.opaque = pik;
>  
>      pci_config_set_prog_interface(pd->config, 0x02); /* BT */
> diff --git a/hw/ipmi/pci_ipmi_kcs.c b/hw/ipmi/pci_ipmi_kcs.c
> index de13418862..44a645723c 100644
> --- a/hw/ipmi/pci_ipmi_kcs.c
> +++ b/hw/ipmi/pci_ipmi_kcs.c
> @@ -58,6 +58,7 @@ static void pci_ipmi_kcs_realize(PCIDevice *pd, Error 
> **errp)
>      PCIIPMIKCSDevice *pik = PCI_IPMI_KCS(pd);
>      IPMIInterface *ii = IPMI_INTERFACE(pd);
>      IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);
> +    IPMICore *ic;
>  
>      if (!pik->kcs.bmc) {
>          error_setg(errp, "IPMI device requires a bmc attribute to be set");
> @@ -66,7 +67,8 @@ static void pci_ipmi_kcs_realize(PCIDevice *pd, Error 
> **errp)
>  
>      pik->uuid = ipmi_next_uuid();
>  
> -    pik->kcs.bmc->intf = ii;
> +    ic = IPMI_CORE(pik->kcs.bmc);
> +    ic->intf = ii;
>      pik->kcs.opaque = pik;
>  
>      pci_config_set_prog_interface(pd->config, 0x01); /* KCS */
> diff --git a/hw/ipmi/smbus_ipmi.c b/hw/ipmi/smbus_ipmi.c
> index 1fdf0a66b6..a2383f1212 100644
> --- a/hw/ipmi/smbus_ipmi.c
> +++ b/hw/ipmi/smbus_ipmi.c
> @@ -315,6 +315,7 @@ static void smbus_ipmi_realize(DeviceState *dev, Error 
> **errp)
>  {
>      SMBusIPMIDevice *sid = SMBUS_IPMI(dev);
>      IPMIInterface *ii = IPMI_INTERFACE(dev);
> +    IPMICore *ic;
>  
>      if (!sid->bmc) {
>          error_setg(errp, "IPMI device requires a bmc attribute to be set");
> @@ -323,7 +324,8 @@ static void smbus_ipmi_realize(DeviceState *dev, Error 
> **errp)
>  
>      sid->uuid = ipmi_next_uuid();
>  
> -    sid->bmc->intf = ii;
> +    ic = IPMI_CORE(sid->bmc);
> +    ic->intf = ii;
>  }
>  
>  static void smbus_ipmi_init(Object *obj)
> @@ -359,7 +361,7 @@ static void smbus_ipmi_class_init(ObjectClass *oc, void 
> *data)
>      dc->vmsd = &vmstate_smbus_ipmi;
>      dc->realize = smbus_ipmi_realize;
>      iic->set_atn = smbus_ipmi_set_atn;
> -    iic->handle_rsp = smbus_ipmi_handle_rsp;
> +    iic->handle_msg = smbus_ipmi_handle_rsp;
>      iic->handle_if_event = smbus_ipmi_handle_event;
>      iic->set_irq_enable = smbus_ipmi_set_irq_enable;
>      iic->get_fwinfo = smbus_ipmi_get_fwinfo;
> diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h
> index 77a7213ed9..1fa8cd12e5 100644
> --- a/include/hw/ipmi/ipmi.h
> +++ b/include/hw/ipmi/ipmi.h
> @@ -111,11 +111,11 @@ uint32_t ipmi_next_uuid(void);
>  #define TYPE_IPMI_INTERFACE "ipmi-interface"
>  #define IPMI_INTERFACE(obj) \
>       INTERFACE_CHECK(IPMIInterface, (obj), TYPE_IPMI_INTERFACE)
> +typedef struct IPMIInterface IPMIInterface;
>  typedef struct IPMIInterfaceClass IPMIInterfaceClass;
>  DECLARE_CLASS_CHECKERS(IPMIInterfaceClass, IPMI_INTERFACE,
>                         TYPE_IPMI_INTERFACE)
> -
> -typedef struct IPMIInterface IPMIInterface;
> +struct IPMICore;
>  
>  struct IPMIInterfaceClass {
>      InterfaceClass parent;
> @@ -156,9 +156,9 @@ struct IPMIInterfaceClass {
>      void (*reset)(struct IPMIInterface *s, bool is_cold);
>  
>      /*
> -     * Handle a response from the bmc.
> +     * Handle an IPMI message.

Could you add a little more explaination here.  Like:

Handle an IPMI message from the remote side.  This is either a message
from the BMC being handled by an IPMI interface on the host side, or a
message from the host side being handled by a BMC emulator running in
this VM.

>       */
> -    void (*handle_rsp)(struct IPMIInterface *s, uint8_t msg_id,
> +    void (*handle_msg)(struct IPMIInterface *s, uint8_t msg_id,
>                         unsigned char *rsp, unsigned int rsp_len);
>  
>      /*
> @@ -166,12 +166,38 @@ struct IPMIInterfaceClass {
>       */
>      void *(*get_backend_data)(struct IPMIInterface *s);
>  
> +    /*
> +     * Set the IPMI core.
> +     */
> +    void (*set_ipmi_handler)(struct IPMIInterface *s, struct IPMICore *ic);
> +
>      /*
>       * Return the firmware info for a device.
>       */
>      void (*get_fwinfo)(struct IPMIInterface *s, IPMIFwInfo *info);
>  };
>  
> +/*
> + * Define an IPMI core (Either BMC or Host simulator.)
> + */
> +#define TYPE_IPMI_CORE "ipmi-core"
> +OBJECT_DECLARE_TYPE(IPMICore, IPMICoreClass, IPMI_CORE)
> +
> +struct IPMICore {
> +    DeviceState parent;
> +
> +    IPMIInterface *intf;
> +};
> +
> +struct IPMICoreClass {
> +    DeviceClass parent;
> +
> +    /*
> +     * Handle a hardware command.
> +     */
> +    void (*handle_hw_op)(struct IPMICore *s, uint8_t hw_op, uint8_t operand);
> +};
> +
>  /*
>   * Define a BMC simulator (or perhaps a connection to a real BMC)
>   */
> @@ -180,15 +206,13 @@ OBJECT_DECLARE_TYPE(IPMIBmc, IPMIBmcClass,
>                      IPMI_BMC)
>  
>  struct IPMIBmc {
> -    DeviceState parent;
> +    IPMICore parent;
>  
>      uint8_t slave_addr;
> -
> -    IPMIInterface *intf;
>  };
>  
>  struct IPMIBmcClass {
> -    DeviceClass parent;
> +    IPMICoreClass parent;
>  
>      /* Called when the system resets to report to the bmc. */
>      void (*handle_reset)(struct IPMIBmc *s);
> -- 
> 2.33.0.309.g3052b89438-goog
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]