/*
 * IPMI BMC 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 "qemu/osdep.h"
#include "sysemu/sysemu.h"
#include "qemu/timer.h"
#include "hw/ipmi/ipmi.h"
#include "qemu/error-report.h"

#define IPMI_NETFN_CHASSIS            0x00

#define IPMI_CMD_GET_CHASSIS_CAPABILITIES 0x00
#define IPMI_CMD_GET_CHASSIS_STATUS       0x01
#define IPMI_CMD_CHASSIS_CONTROL          0x02
#define IPMI_CMD_GET_SYS_RESTART_CAUSE    0x09

#define IPMI_NETFN_SENSOR_EVENT       0x04

#define IPMI_CMD_SET_SENSOR_EVT_ENABLE    0x28
#define IPMI_CMD_GET_SENSOR_EVT_ENABLE    0x29
#define IPMI_CMD_REARM_SENSOR_EVTS        0x2a
#define IPMI_CMD_GET_SENSOR_EVT_STATUS    0x2b
#define IPMI_CMD_GET_SENSOR_READING       0x2d
#define IPMI_CMD_SET_SENSOR_TYPE          0x2e
#define IPMI_CMD_GET_SENSOR_TYPE          0x2f

/* #define IPMI_NETFN_APP             0x06 In ipmi.h */

#define IPMI_CMD_GET_DEVICE_ID            0x01
#define IPMI_CMD_COLD_RESET               0x02
#define IPMI_CMD_WARM_RESET               0x03
#define IPMI_CMD_SET_ACPI_POWER_STATE     0x06
#define IPMI_CMD_GET_ACPI_POWER_STATE     0x07
#define IPMI_CMD_GET_DEVICE_GUID          0x08
#define IPMI_CMD_RESET_WATCHDOG_TIMER     0x22
#define IPMI_CMD_SET_WATCHDOG_TIMER       0x24
#define IPMI_CMD_GET_WATCHDOG_TIMER       0x25
#define IPMI_CMD_SET_BMC_GLOBAL_ENABLES   0x2e
#define IPMI_CMD_GET_BMC_GLOBAL_ENABLES   0x2f
#define IPMI_CMD_CLR_MSG_FLAGS            0x30
#define IPMI_CMD_GET_MSG_FLAGS            0x31
#define IPMI_CMD_GET_MSG                  0x33
#define IPMI_CMD_SEND_MSG                 0x34
#define IPMI_CMD_READ_EVT_MSG_BUF         0x35

#define IPMI_NETFN_STORAGE            0x0a

#define IPMI_CMD_GET_SDR_REP_INFO         0x20
#define IPMI_CMD_GET_SDR_REP_ALLOC_INFO   0x21
#define IPMI_CMD_RESERVE_SDR_REP          0x22
#define IPMI_CMD_GET_SDR                  0x23
#define IPMI_CMD_ADD_SDR                  0x24
#define IPMI_CMD_PARTIAL_ADD_SDR          0x25
#define IPMI_CMD_DELETE_SDR               0x26
#define IPMI_CMD_CLEAR_SDR_REP            0x27
#define IPMI_CMD_GET_SDR_REP_TIME         0x28
#define IPMI_CMD_SET_SDR_REP_TIME         0x29
#define IPMI_CMD_ENTER_SDR_REP_UPD_MODE   0x2A
#define IPMI_CMD_EXIT_SDR_REP_UPD_MODE    0x2B
#define IPMI_CMD_RUN_INIT_AGENT           0x2C
#define IPMI_CMD_GET_SEL_INFO             0x40
#define IPMI_CMD_GET_SEL_ALLOC_INFO       0x41
#define IPMI_CMD_RESERVE_SEL              0x42
#define IPMI_CMD_GET_SEL_ENTRY            0x43
#define IPMI_CMD_ADD_SEL_ENTRY            0x44
#define IPMI_CMD_PARTIAL_ADD_SEL_ENTRY    0x45
#define IPMI_CMD_DELETE_SEL_ENTRY         0x46
#define IPMI_CMD_CLEAR_SEL                0x47
#define IPMI_CMD_GET_SEL_TIME             0x48
#define IPMI_CMD_SET_SEL_TIME             0x49


/* Same as a timespec struct. */
struct ipmi_time {
    long tv_sec;
    long tv_nsec;
};

#define MAX_SEL_SIZE 128

typedef struct IPMISel {
    uint8_t sel[MAX_SEL_SIZE][16];
    unsigned int next_free;
    long time_offset;
    uint16_t reservation;
    uint8_t last_addition[4];
    uint8_t last_clear[4];
    uint8_t overflow;
} IPMISel;

#define MAX_SDR_SIZE 16384

typedef struct IPMISdr {
    uint8_t sdr[MAX_SDR_SIZE];
    unsigned int next_free;
    uint16_t next_rec_id;
    uint16_t reservation;
    uint8_t last_addition[4];
    uint8_t last_clear[4];
    uint8_t overflow;
} IPMISdr;

typedef struct IPMISensor {
    uint8_t status;
    uint8_t reading;
    uint16_t states_suppt;
    uint16_t assert_suppt;
    uint16_t deassert_suppt;
    uint16_t states;
    uint16_t assert_states;
    uint16_t deassert_states;
    uint16_t assert_enable;
    uint16_t deassert_enable;
    uint8_t  sensor_type;
    uint8_t  evt_reading_type_code;
} IPMISensor;
#define IPMI_SENSOR_GET_PRESENT(s)       ((s)->status & 0x01)
#define IPMI_SENSOR_SET_PRESENT(s, v)    ((s)->status = (s->status & ~0x01) | \
                                             !!(v))
#define IPMI_SENSOR_GET_SCAN_ON(s)       ((s)->status & 0x40)
#define IPMI_SENSOR_SET_SCAN_ON(s, v)    ((s)->status = (s->status & ~0x40) | \
                                             ((!!(v)) << 6))
#define IPMI_SENSOR_GET_EVENTS_ON(s)     ((s)->status & 0x80)
#define IPMI_SENSOR_SET_EVENTS_ON(s, v)  ((s)->status = (s->status & ~0x80) | \
                                             ((!!(v)) << 7))
#define IPMI_SENSOR_GET_RET_STATUS(s)    ((s)->status & 0xc0)
#define IPMI_SENSOR_SET_RET_STATUS(s, v) ((s)->status = (s->status & ~0xc0) | \
                                             (v & 0xc0))
#define IPMI_SENSOR_IS_DISCRETE(s) ((s)->evt_reading_type_code != 1)

#define MAX_SENSORS 20
#define IPMI_WATCHDOG_SENSOR 0

typedef struct IPMIBmcSim IPMIBmcSim;
typedef struct RspBuffer RspBuffer;

#define MAX_NETFNS 64

typedef struct IPMICmdHandler {
    void (*cmd_handler)(IPMIBmcSim *s,
                        uint8_t *cmd, unsigned int cmd_len,
                        RspBuffer *rsp);
    unsigned int cmd_len_min;
} IPMICmdHandler;

typedef struct IPMINetfn {
    unsigned int cmd_nums;
    const IPMICmdHandler *cmd_handlers;
} IPMINetfn;

typedef struct IPMIRcvBufEntry {
    QTAILQ_ENTRY(IPMIRcvBufEntry) entry;
    uint8_t len;
    uint8_t buf[MAX_IPMI_MSG_SIZE];
} IPMIRcvBufEntry;

#define TYPE_IPMI_BMC_SIMULATOR "ipmi-bmc-sim"
#define IPMI_BMC_SIMULATOR(obj) OBJECT_CHECK(IPMIBmcSim, (obj), \
                                        TYPE_IPMI_BMC_SIMULATOR)
struct IPMIBmcSim {
    IPMIBmc parent;

    QEMUTimer *timer;

    uint8_t bmc_global_enables;
    uint8_t msg_flags;

    bool     watchdog_initialized;
    uint8_t  watchdog_use;
    uint8_t  watchdog_action;
    uint8_t  watchdog_pretimeout; /* In seconds */
    bool     watchdog_expired;
    uint16_t watchdog_timeout; /* in 100's of milliseconds */

    bool     watchdog_running;
    bool     watchdog_preaction_ran;
    int64_t  watchdog_expiry;

    uint8_t device_id;
    uint8_t ipmi_version;
    uint8_t device_rev;
    uint8_t fwrev1;
    uint8_t fwrev2;
    uint8_t mfg_id[3];
    uint8_t product_id[2];

    uint8_t restart_cause;

    uint8_t acpi_power_state[2];
    uint8_t uuid[16];

    IPMISel sel;
    IPMISdr sdr;
    IPMISensor sensors[MAX_SENSORS];

    /* Odd netfns are for responses, so we only need the even ones. */
    const IPMINetfn *netfns[MAX_NETFNS / 2];

    QemuMutex lock;
    /* We allow one event in the buffer */
    uint8_t evtbuf[16];

    QTAILQ_HEAD(, IPMIRcvBufEntry) rcvbufs;
};

#define IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK        (1 << 3)
#define IPMI_BMC_MSG_FLAG_EVT_BUF_FULL                 (1 << 1)
#define IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE                (1 << 0)
#define IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK_SET(s) \
    (IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK & (s)->msg_flags)
#define IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(s) \
    (IPMI_BMC_MSG_FLAG_EVT_BUF_FULL & (s)->msg_flags)
#define IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(s) \
    (IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE & (s)->msg_flags)

#define IPMI_BMC_RCV_MSG_QUEUE_INT_BIT    0
#define IPMI_BMC_EVBUF_FULL_INT_BIT       1
#define IPMI_BMC_EVENT_MSG_BUF_BIT        2
#define IPMI_BMC_EVENT_LOG_BIT            3
#define IPMI_BMC_MSG_INTS_ON(s) ((s)->bmc_global_enables & \
                                 (1 << IPMI_BMC_RCV_MSG_QUEUE_INT_BIT))
#define IPMI_BMC_EVBUF_FULL_INT_ENABLED(s) ((s)->bmc_global_enables & \
                                        (1 << IPMI_BMC_EVBUF_FULL_INT_BIT))
#define IPMI_BMC_EVENT_LOG_ENABLED(s) ((s)->bmc_global_enables & \
                                       (1 << IPMI_BMC_EVENT_LOG_BIT))
#define IPMI_BMC_EVENT_MSG_BUF_ENABLED(s) ((s)->bmc_global_enables & \
                                           (1 << IPMI_BMC_EVENT_MSG_BUF_BIT))

#define IPMI_BMC_WATCHDOG_USE_MASK 0xc7
#define IPMI_BMC_WATCHDOG_ACTION_MASK 0x77
#define IPMI_BMC_WATCHDOG_GET_USE(s) ((s)->watchdog_use & 0x7)
#define IPMI_BMC_WATCHDOG_GET_DONT_LOG(s) (((s)->watchdog_use >> 7) & 0x1)
#define IPMI_BMC_WATCHDOG_GET_DONT_STOP(s) (((s)->watchdog_use >> 6) & 0x1)
#define IPMI_BMC_WATCHDOG_GET_PRE_ACTION(s) (((s)->watchdog_action >> 4) & 0x7)
#define IPMI_BMC_WATCHDOG_PRE_NONE               0
#define IPMI_BMC_WATCHDOG_PRE_SMI                1
#define IPMI_BMC_WATCHDOG_PRE_NMI                2
#define IPMI_BMC_WATCHDOG_PRE_MSG_INT            3
#define IPMI_BMC_WATCHDOG_GET_ACTION(s) ((s)->watchdog_action & 0x7)
#define IPMI_BMC_WATCHDOG_ACTION_NONE            0
#define IPMI_BMC_WATCHDOG_ACTION_RESET           1
#define IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN      2
#define IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE     3

struct RspBuffer {
    uint8_t buffer[MAX_IPMI_MSG_SIZE];
    unsigned int len;
};

#define RSP_BUFFER_INITIALIZER { }

static inline void rsp_buffer_set_error(RspBuffer *rsp, uint8_t byte)
{
    rsp->buffer[2] = byte;
}

/* Add a byte to the response. */
static inline void rsp_buffer_push(RspBuffer *rsp, uint8_t byte)
{
    if (rsp->len >= sizeof(rsp->buffer)) {
        rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_TRUNCATED);
        return;
    }
    rsp->buffer[rsp->len++] = byte;
}

static inline void rsp_buffer_pushmore(RspBuffer *rsp, uint8_t *bytes,
                                       unsigned int n)
{
    if (rsp->len + n >= sizeof(rsp->buffer)) {
        rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_TRUNCATED);
        return;
    }

    memcpy(&rsp->buffer[rsp->len], bytes, n);
    rsp->len += n;
}

static void ipmi_sim_handle_timeout(IPMIBmcSim *ibs);

static void ipmi_gettime(struct ipmi_time *time)
{
    int64_t stime;

    stime = qemu_clock_get_ns(QEMU_CLOCK_HOST);
    time->tv_sec = stime / 1000000000LL;
    time->tv_nsec = stime % 1000000000LL;
}

static int64_t ipmi_getmonotime(void)
{
    return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}

static void ipmi_timeout(void *opaque)
{
    IPMIBmcSim *ibs = opaque;

    ipmi_sim_handle_timeout(ibs);
}

static void set_timestamp(IPMIBmcSim *ibs, uint8_t *ts)
{
    unsigned int val;
    struct ipmi_time now;

    ipmi_gettime(&now);
    val = now.tv_sec + ibs->sel.time_offset;
    ts[0] = val & 0xff;
    ts[1] = (val >> 8) & 0xff;
    ts[2] = (val >> 16) & 0xff;
    ts[3] = (val >> 24) & 0xff;
}

static void sdr_inc_reservation(IPMISdr *sdr)
{
    sdr->reservation++;
    if (sdr->reservation == 0) {
        sdr->reservation = 1;
    }
}

static int sdr_add_entry(IPMIBmcSim *ibs,
                         const struct ipmi_sdr_header *sdrh_entry,
                         unsigned int len, uint16_t *recid)
{
    struct ipmi_sdr_header *sdrh =
        (struct ipmi_sdr_header *) &ibs->sdr.sdr[ibs->sdr.next_free];

    if ((len < IPMI_SDR_HEADER_SIZE) || (len > 255)) {
        return 1;
    }

    if (ipmi_sdr_length(sdrh_entry) != len) {
        return 1;
    }

    if (ibs->sdr.next_free + len > MAX_SDR_SIZE) {
        ibs->sdr.overflow = 1;
        return 1;
    }

    memcpy(sdrh, sdrh_entry, len);
    sdrh->rec_id[0] = ibs->sdr.next_rec_id & 0xff;
    sdrh->rec_id[1] = (ibs->sdr.next_rec_id >> 8) & 0xff;
    sdrh->sdr_version = 0x51; /* Conform to IPMI 1.5 spec */

    if (recid) {
        *recid = ibs->sdr.next_rec_id;
    }
    ibs->sdr.next_rec_id++;
    set_timestamp(ibs, ibs->sdr.last_addition);
    ibs->sdr.next_free += len;
    sdr_inc_reservation(&ibs->sdr);
    return 0;
}

static int sdr_find_entry(IPMISdr *sdr, uint16_t recid,
                          unsigned int *retpos, uint16_t *nextrec)
{
    unsigned int pos = *retpos;

    while (pos < sdr->next_free) {
        struct ipmi_sdr_header *sdrh =
            (struct ipmi_sdr_header *) &sdr->sdr[pos];
        uint16_t trec = ipmi_sdr_recid(sdrh);
        unsigned int nextpos = pos + ipmi_sdr_length(sdrh);

        if (trec == recid) {
            if (nextrec) {
                if (nextpos >= sdr->next_free) {
                    *nextrec = 0xffff;
                } else {
                    *nextrec = (sdr->sdr[nextpos] |
                                (sdr->sdr[nextpos + 1] << 8));
                }
            }
            *retpos = pos;
            return 0;
        }
        pos = nextpos;
    }
    return 1;
}

static void sel_inc_reservation(IPMISel *sel)
{
    sel->reservation++;
    if (sel->reservation == 0) {
        sel->reservation = 1;
    }
}

/* Returns 1 if the SEL is full and can't hold the event. */
static int sel_add_event(IPMIBmcSim *ibs, uint8_t *event)
{
    event[0] = 0xff;
    event[1] = 0xff;
    set_timestamp(ibs, event + 3);
    if (ibs->sel.next_free == MAX_SEL_SIZE) {
        ibs->sel.overflow = 1;
        return 1;
    }
    event[0] = ibs->sel.next_free & 0xff;
    event[1] = (ibs->sel.next_free >> 8) & 0xff;
    memcpy(ibs->sel.last_addition, event + 3, 4);
    memcpy(ibs->sel.sel[ibs->sel.next_free], event, 16);
    ibs->sel.next_free++;
    sel_inc_reservation(&ibs->sel);
    return 0;
}

static int attn_set(IPMIBmcSim *ibs)
{
    return IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(ibs)
        || IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(ibs)
        || IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK_SET(ibs);
}

static int attn_irq_enabled(IPMIBmcSim *ibs)
{
    return (IPMI_BMC_MSG_INTS_ON(ibs) && IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(ibs))
        || (IPMI_BMC_EVBUF_FULL_INT_ENABLED(ibs) &&
            IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(ibs));
}

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;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
    uint8_t evt[16];
    IPMISensor *sens = ibs->sensors + sens_num;

    if (!IPMI_BMC_EVENT_MSG_BUF_ENABLED(ibs)) {
        return;
    }
    if (!IPMI_SENSOR_GET_EVENTS_ON(sens)) {
        return;
    }

    evt[2] = 0x2; /* System event record */
    evt[7] = ibs->parent.slave_addr;
    evt[8] = 0;
    evt[9] = 0x04; /* Format version */
    evt[10] = sens->sensor_type;
    evt[11] = sens_num;
    evt[12] = sens->evt_reading_type_code | (!!deassert << 7);
    evt[13] = evd1;
    evt[14] = evd2;
    evt[15] = evd3;

    if (IPMI_BMC_EVENT_LOG_ENABLED(ibs)) {
        sel_add_event(ibs, evt);
    }

    if (ibs->msg_flags & IPMI_BMC_MSG_FLAG_EVT_BUF_FULL) {
        return;
    }

    memcpy(ibs->evtbuf, evt, 16);
    ibs->msg_flags |= IPMI_BMC_MSG_FLAG_EVT_BUF_FULL;
    k->set_atn(s, 1, attn_irq_enabled(ibs));
}

static void sensor_set_discrete_bit(IPMIBmcSim *ibs, unsigned int sensor,
                                    unsigned int bit, unsigned int val,
                                    uint8_t evd1, uint8_t evd2, uint8_t evd3)
{
    IPMISensor *sens;
    uint16_t mask;

    if (sensor >= MAX_SENSORS) {
        return;
    }
    if (bit >= 16) {
        return;
    }

    mask = (1 << bit);
    sens = ibs->sensors + sensor;
    if (val) {
        sens->states |= mask & sens->states_suppt;
        if (sens->assert_states & mask) {
            return; /* Already asserted */
        }
        sens->assert_states |= mask & sens->assert_suppt;
        if (sens->assert_enable & mask & sens->assert_states) {
            /* Send an event on assert */
            gen_event(ibs, sensor, 0, evd1, evd2, evd3);
        }
    } else {
        sens->states &= ~(mask & sens->states_suppt);
        if (sens->deassert_states & mask) {
            return; /* Already deasserted */
        }
        sens->deassert_states |= mask & sens->deassert_suppt;
        if (sens->deassert_enable & mask & sens->deassert_states) {
            /* Send an event on deassert */
            gen_event(ibs, sensor, 1, evd1, evd2, evd3);
        }
    }
}

static void ipmi_init_sensors_from_sdrs(IPMIBmcSim *s)
{
    unsigned int i, pos;
    IPMISensor *sens;

    for (i = 0; i < MAX_SENSORS; i++) {
        memset(s->sensors + i, 0, sizeof(*sens));
    }

    pos = 0;
    for (i = 0; !sdr_find_entry(&s->sdr, i, &pos, NULL); i++) {
        struct ipmi_sdr_compact *sdr =
            (struct ipmi_sdr_compact *) &s->sdr.sdr[pos];
        unsigned int len = sdr->header.rec_length;

        if (len < 20) {
            continue;
        }
        if (sdr->header.rec_type != IPMI_SDR_COMPACT_TYPE) {
            continue; /* Not a sensor SDR we set from */
        }

        if (sdr->sensor_owner_number >= MAX_SENSORS) {
            continue;
        }
        sens = s->sensors + sdr->sensor_owner_number;

        IPMI_SENSOR_SET_PRESENT(sens, 1);
        IPMI_SENSOR_SET_SCAN_ON(sens, (sdr->sensor_init >> 6) & 1);
        IPMI_SENSOR_SET_EVENTS_ON(sens, (sdr->sensor_init >> 5) & 1);
        sens->assert_suppt = sdr->assert_mask[0] | (sdr->assert_mask[1] << 8);
        sens->deassert_suppt =
            sdr->deassert_mask[0] | (sdr->deassert_mask[1] << 8);
        sens->states_suppt =
            sdr->discrete_mask[0] | (sdr->discrete_mask[1] << 8);
        sens->sensor_type = sdr->sensor_type;
        sens->evt_reading_type_code = sdr->reading_type & 0x7f;

        /* Enable all the events that are supported. */
        sens->assert_enable = sens->assert_suppt;
        sens->deassert_enable = sens->deassert_suppt;
    }
}

static int ipmi_register_netfn(IPMIBmcSim *s, unsigned int netfn,
                               const IPMINetfn *netfnd)
{
    if ((netfn & 1) || (netfn >= MAX_NETFNS) || (s->netfns[netfn / 2])) {
        return -1;
    }
    s->netfns[netfn / 2] = netfnd;
    return 0;
}

static const IPMICmdHandler *ipmi_get_handler(IPMIBmcSim *ibs,
                                              unsigned int netfn,
                                              unsigned int cmd)
{
    const IPMICmdHandler *hdl;

    if (netfn & 1 || netfn >= MAX_NETFNS || !ibs->netfns[netfn / 2]) {
        return NULL;
    }

    if (cmd >= ibs->netfns[netfn / 2]->cmd_nums) {
        return NULL;
    }

    hdl = &ibs->netfns[netfn / 2]->cmd_handlers[cmd];
    if (!hdl->cmd_handler) {
        return NULL;
    }

    return hdl;
}

static void next_timeout(IPMIBmcSim *ibs)
{
    int64_t next;
    if (ibs->watchdog_running) {
        next = ibs->watchdog_expiry;
    } else {
        /* Wait a minute */
        next = ipmi_getmonotime() + 60 * 1000000000LL;
    }
    timer_mod_ns(ibs->timer, next);
}

static void ipmi_sim_handle_command(IPMIBmc *b,
                                    uint8_t *cmd, unsigned int cmd_len,
                                    unsigned int max_cmd_len,
                                    uint8_t msg_id)
{
    IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
    IPMIInterface *s = ibs->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
    const IPMICmdHandler *hdl;
    RspBuffer rsp = RSP_BUFFER_INITIALIZER;

    /* Set up the response, set the low bit of NETFN. */
    /* Note that max_rsp_len must be at least 3 */
    if (sizeof(rsp.buffer) < 3) {
        rsp_buffer_set_error(&rsp, IPMI_CC_REQUEST_DATA_TRUNCATED);
        goto out;
    }

    rsp_buffer_push(&rsp, cmd[0] | 0x04);
    rsp_buffer_push(&rsp, cmd[1]);
    rsp_buffer_push(&rsp, 0); /* Assume success */

    /* If it's too short or it was truncated, return an error. */
    if (cmd_len < 2) {
        rsp_buffer_set_error(&rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
        goto out;
    }
    if (cmd_len > max_cmd_len) {
        rsp_buffer_set_error(&rsp, IPMI_CC_REQUEST_DATA_TRUNCATED);
        goto out;
    }

    if ((cmd[0] & 0x03) != 0) {
        /* Only have stuff on LUN 0 */
        rsp_buffer_set_error(&rsp, IPMI_CC_COMMAND_INVALID_FOR_LUN);
        goto out;
    }

    hdl = ipmi_get_handler(ibs, cmd[0] >> 2, cmd[1]);
    if (!hdl) {
        rsp_buffer_set_error(&rsp, IPMI_CC_INVALID_CMD);
        goto out;
    }

    if (cmd_len < hdl->cmd_len_min) {
        rsp_buffer_set_error(&rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
        goto out;
    }

    hdl->cmd_handler(ibs, cmd, cmd_len, &rsp);

 out:
    k->handle_rsp(s, msg_id, rsp.buffer, rsp.len);

    next_timeout(ibs);
}

static void ipmi_sim_handle_timeout(IPMIBmcSim *ibs)
{
    IPMIInterface *s = ibs->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);

    if (!ibs->watchdog_running) {
        goto out;
    }

    if (!ibs->watchdog_preaction_ran) {
        switch (IPMI_BMC_WATCHDOG_GET_PRE_ACTION(ibs)) {
        case IPMI_BMC_WATCHDOG_PRE_NMI:
            ibs->msg_flags |= IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK;
            k->do_hw_op(s, IPMI_SEND_NMI, 0);
            sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 8, 1,
                                    0xc8, (2 << 4) | 0xf, 0xff);
            break;

        case IPMI_BMC_WATCHDOG_PRE_MSG_INT:
            ibs->msg_flags |= IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK;
            k->set_atn(s, 1, attn_irq_enabled(ibs));
            sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 8, 1,
                                    0xc8, (3 << 4) | 0xf, 0xff);
            break;

        default:
            goto do_full_expiry;
        }

        ibs->watchdog_preaction_ran = 1;
        /* Issued the pretimeout, do the rest of the timeout now. */
        ibs->watchdog_expiry = ipmi_getmonotime();
        ibs->watchdog_expiry += ibs->watchdog_pretimeout * 1000000000LL;
        goto out;
    }

 do_full_expiry:
    ibs->watchdog_running = 0; /* Stop the watchdog on a timeout */
    ibs->watchdog_expired |= (1 << IPMI_BMC_WATCHDOG_GET_USE(ibs));
    switch (IPMI_BMC_WATCHDOG_GET_ACTION(ibs)) {
    case IPMI_BMC_WATCHDOG_ACTION_NONE:
        sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 0, 1,
                                0xc0, ibs->watchdog_use & 0xf, 0xff);
        break;

    case IPMI_BMC_WATCHDOG_ACTION_RESET:
        sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 1, 1,
                                0xc1, ibs->watchdog_use & 0xf, 0xff);
        k->do_hw_op(s, IPMI_RESET_CHASSIS, 0);
        break;

    case IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN:
        sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 2, 1,
                                0xc2, ibs->watchdog_use & 0xf, 0xff);
        k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 0);
        break;

    case IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE:
        sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 2, 1,
                                0xc3, ibs->watchdog_use & 0xf, 0xff);
        k->do_hw_op(s, IPMI_POWERCYCLE_CHASSIS, 0);
        break;
    }

 out:
    next_timeout(ibs);
}

static void chassis_capabilities(IPMIBmcSim *ibs,
                                 uint8_t *cmd, unsigned int cmd_len,
                                 RspBuffer *rsp)
{
    rsp_buffer_push(rsp, 0);
    rsp_buffer_push(rsp, ibs->parent.slave_addr);
    rsp_buffer_push(rsp, ibs->parent.slave_addr);
    rsp_buffer_push(rsp, ibs->parent.slave_addr);
    rsp_buffer_push(rsp, ibs->parent.slave_addr);
}

static void chassis_status(IPMIBmcSim *ibs,
                           uint8_t *cmd, unsigned int cmd_len,
                           RspBuffer *rsp)
{
    rsp_buffer_push(rsp, 0x61); /* Unknown power restore, power is on */
    rsp_buffer_push(rsp, 0);
    rsp_buffer_push(rsp, 0);
    rsp_buffer_push(rsp, 0);
}

static void chassis_control(IPMIBmcSim *ibs,
                            uint8_t *cmd, unsigned int cmd_len,
                            RspBuffer *rsp)
{
    IPMIInterface *s = ibs->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);

    switch (cmd[2] & 0xf) {
    case 0: /* power down */
        rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 0));
        break;
    case 1: /* power up */
        rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWERON_CHASSIS, 0));
        break;
    case 2: /* power cycle */
        rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWERCYCLE_CHASSIS, 0));
        break;
    case 3: /* hard reset */
        rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_RESET_CHASSIS, 0));
        break;
    case 4: /* pulse diagnostic interrupt */
        rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_PULSE_DIAG_IRQ, 0));
        break;
    case 5: /* soft shutdown via ACPI by overtemp emulation */
        rsp_buffer_set_error(rsp, k->do_hw_op(s,
                                          IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP, 0));
        break;
    default:
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }
}

static void chassis_get_sys_restart_cause(IPMIBmcSim *ibs,
                           uint8_t *cmd, unsigned int cmd_len,
                           RspBuffer *rsp)

{
    rsp_buffer_push(rsp, ibs->restart_cause & 0xf); /* Restart Cause */
    rsp_buffer_push(rsp, 0);  /* Channel 0 */
}

static void get_device_id(IPMIBmcSim *ibs,
                          uint8_t *cmd, unsigned int cmd_len,
                          RspBuffer *rsp)
{
    rsp_buffer_push(rsp, ibs->device_id);
    rsp_buffer_push(rsp, ibs->device_rev & 0xf);
    rsp_buffer_push(rsp, ibs->fwrev1 & 0x7f);
    rsp_buffer_push(rsp, ibs->fwrev2);
    rsp_buffer_push(rsp, ibs->ipmi_version);
    rsp_buffer_push(rsp, 0x07); /* sensor, SDR, and SEL. */
    rsp_buffer_push(rsp, ibs->mfg_id[0]);
    rsp_buffer_push(rsp, ibs->mfg_id[1]);
    rsp_buffer_push(rsp, ibs->mfg_id[2]);
    rsp_buffer_push(rsp, ibs->product_id[0]);
    rsp_buffer_push(rsp, ibs->product_id[1]);
}

static void set_global_enables(IPMIBmcSim *ibs, uint8_t val)
{
    IPMIInterface *s = ibs->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
    bool irqs_on;

    ibs->bmc_global_enables = val;

    irqs_on = val & (IPMI_BMC_EVBUF_FULL_INT_BIT |
                     IPMI_BMC_RCV_MSG_QUEUE_INT_BIT);

    k->set_irq_enable(s, irqs_on);
}

static void cold_reset(IPMIBmcSim *ibs,
                       uint8_t *cmd, unsigned int cmd_len,
                       RspBuffer *rsp)
{
    IPMIInterface *s = ibs->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);

    /* Disable all interrupts */
    set_global_enables(ibs, 1 << IPMI_BMC_EVENT_LOG_BIT);

    if (k->reset) {
        k->reset(s, true);
    }
}

static void warm_reset(IPMIBmcSim *ibs,
                       uint8_t *cmd, unsigned int cmd_len,
                       RspBuffer *rsp)
{
    IPMIInterface *s = ibs->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);

    if (k->reset) {
        k->reset(s, false);
    }
}
static void set_acpi_power_state(IPMIBmcSim *ibs,
                                 uint8_t *cmd, unsigned int cmd_len,
                                 RspBuffer *rsp)
{
    ibs->acpi_power_state[0] = cmd[2];
    ibs->acpi_power_state[1] = cmd[3];
}

static void get_acpi_power_state(IPMIBmcSim *ibs,
                                 uint8_t *cmd, unsigned int cmd_len,
                                 RspBuffer *rsp)
{
    rsp_buffer_push(rsp, ibs->acpi_power_state[0]);
    rsp_buffer_push(rsp, ibs->acpi_power_state[1]);
}

static void get_device_guid(IPMIBmcSim *ibs,
                            uint8_t *cmd, unsigned int cmd_len,
                            RspBuffer *rsp)
{
    unsigned int i;

    for (i = 0; i < 16; i++) {
        rsp_buffer_push(rsp, ibs->uuid[i]);
    }
}

static void set_bmc_global_enables(IPMIBmcSim *ibs,
                                   uint8_t *cmd, unsigned int cmd_len,
                                   RspBuffer *rsp)
{
    set_global_enables(ibs, cmd[2]);
}

static void get_bmc_global_enables(IPMIBmcSim *ibs,
                                   uint8_t *cmd, unsigned int cmd_len,
                                   RspBuffer *rsp)
{
    rsp_buffer_push(rsp, ibs->bmc_global_enables);
}

static void clr_msg_flags(IPMIBmcSim *ibs,
                          uint8_t *cmd, unsigned int cmd_len,
                          RspBuffer *rsp)
{
    IPMIInterface *s = ibs->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);

    ibs->msg_flags &= ~cmd[2];
    k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
}

static void get_msg_flags(IPMIBmcSim *ibs,
                          uint8_t *cmd, unsigned int cmd_len,
                          RspBuffer *rsp)
{
    rsp_buffer_push(rsp, ibs->msg_flags);
}

static void read_evt_msg_buf(IPMIBmcSim *ibs,
                             uint8_t *cmd, unsigned int cmd_len,
                             RspBuffer *rsp)
{
    IPMIInterface *s = ibs->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
    unsigned int i;

    if (!(ibs->msg_flags & IPMI_BMC_MSG_FLAG_EVT_BUF_FULL)) {
        rsp_buffer_set_error(rsp, 0x80);
        return;
    }
    for (i = 0; i < 16; i++) {
        rsp_buffer_push(rsp, ibs->evtbuf[i]);
    }
    ibs->msg_flags &= ~IPMI_BMC_MSG_FLAG_EVT_BUF_FULL;
    k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
}

static void get_msg(IPMIBmcSim *ibs,
                    uint8_t *cmd, unsigned int cmd_len,
                    RspBuffer *rsp)
{
    IPMIRcvBufEntry *msg;

    qemu_mutex_lock(&ibs->lock);
    if (QTAILQ_EMPTY(&ibs->rcvbufs)) {
        rsp_buffer_set_error(rsp, 0x80); /* Queue empty */
        goto out;
    }
    rsp_buffer_push(rsp, 0); /* Channel 0 */
    msg = QTAILQ_FIRST(&ibs->rcvbufs);
    rsp_buffer_pushmore(rsp, msg->buf, msg->len);
    QTAILQ_REMOVE(&ibs->rcvbufs, msg, entry);
    g_free(msg);

    if (QTAILQ_EMPTY(&ibs->rcvbufs)) {
        IPMIInterface *s = ibs->parent.intf;
        IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);

        ibs->msg_flags &= ~IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE;
        k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
    }

out:
    qemu_mutex_unlock(&ibs->lock);
    return;
}

static unsigned char
ipmb_checksum(unsigned char *data, int size, unsigned char csum)
{
    for (; size > 0; size--, data++) {
            csum += *data;
    }

    return -csum;
}

static void send_msg(IPMIBmcSim *ibs,
                     uint8_t *cmd, unsigned int cmd_len,
                     RspBuffer *rsp)
{
    IPMIInterface *s = ibs->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
    IPMIRcvBufEntry *msg;
    uint8_t *buf;
    uint8_t netfn, rqLun, rsLun, rqSeq;

    if (cmd[2] != 0) {
        /* We only handle channel 0 with no options */
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }

    if (cmd_len < 10) {
        rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
        return;
    }

    if (cmd[3] != 0x40) {
        /* We only emulate a MC at address 0x40. */
        rsp_buffer_set_error(rsp, 0x83); /* NAK on write */
        return;
    }

    cmd += 3; /* Skip the header. */
    cmd_len -= 3;

    /*
     * At this point we "send" the message successfully.  Any error will
     * be returned in the response.
     */
    if (ipmb_checksum(cmd, cmd_len, 0) != 0 ||
        cmd[3] != 0x20) { /* Improper response address */
        return; /* No response */
    }

    netfn = cmd[1] >> 2;
    rqLun = cmd[4] & 0x3;
    rsLun = cmd[1] & 0x3;
    rqSeq = cmd[4] >> 2;

    if (rqLun != 2) {
        /* We only support LUN 2 coming back to us. */
        return;
    }

    msg = g_malloc(sizeof(*msg));
    msg->buf[0] = ((netfn | 1) << 2) | rqLun; /* NetFN, and make a response */
    msg->buf[1] = ipmb_checksum(msg->buf, 1, 0);
    msg->buf[2] = cmd[0]; /* rsSA */
    msg->buf[3] = (rqSeq << 2) | rsLun;
    msg->buf[4] = cmd[5]; /* Cmd */
    msg->buf[5] = 0; /* Completion Code */
    msg->len = 6;

    if ((cmd[1] >> 2) != IPMI_NETFN_APP || cmd[5] != IPMI_CMD_GET_DEVICE_ID) {
        /* Not a command we handle. */
        msg->buf[5] = IPMI_CC_INVALID_CMD;
        goto end_msg;
    }

    buf = msg->buf + msg->len; /* After the CC */
    buf[0] = 0;
    buf[1] = 0;
    buf[2] = 0;
    buf[3] = 0;
    buf[4] = 0x51;
    buf[5] = 0;
    buf[6] = 0;
    buf[7] = 0;
    buf[8] = 0;
    buf[9] = 0;
    buf[10] = 0;
    msg->len += 11;

 end_msg:
    msg->buf[msg->len] = ipmb_checksum(msg->buf, msg->len, 0);
    msg->len++;
    qemu_mutex_lock(&ibs->lock);
    QTAILQ_INSERT_TAIL(&ibs->rcvbufs, msg, entry);
    ibs->msg_flags |= IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE;
    k->set_atn(s, 1, attn_irq_enabled(ibs));
    qemu_mutex_unlock(&ibs->lock);
}

static void do_watchdog_reset(IPMIBmcSim *ibs)
{
    if (IPMI_BMC_WATCHDOG_GET_ACTION(ibs) ==
        IPMI_BMC_WATCHDOG_ACTION_NONE) {
        ibs->watchdog_running = 0;
        return;
    }
    ibs->watchdog_preaction_ran = 0;


    /* Timeout is in tenths of a second, offset is in seconds */
    ibs->watchdog_expiry = ipmi_getmonotime();
    ibs->watchdog_expiry += ibs->watchdog_timeout * 100000000LL;
    if (IPMI_BMC_WATCHDOG_GET_PRE_ACTION(ibs) != IPMI_BMC_WATCHDOG_PRE_NONE) {
        ibs->watchdog_expiry -= ibs->watchdog_pretimeout * 1000000000LL;
    }
    ibs->watchdog_running = 1;
}

static void reset_watchdog_timer(IPMIBmcSim *ibs,
                                 uint8_t *cmd, unsigned int cmd_len,
                                 RspBuffer *rsp)
{
    if (!ibs->watchdog_initialized) {
        rsp_buffer_set_error(rsp, 0x80);
        return;
    }
    do_watchdog_reset(ibs);
}

static void set_watchdog_timer(IPMIBmcSim *ibs,
                               uint8_t *cmd, unsigned int cmd_len,
                               RspBuffer *rsp)
{
    IPMIInterface *s = ibs->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
    unsigned int val;

    val = cmd[2] & 0x7; /* Validate use */
    if (val == 0 || val > 5) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }
    val = cmd[3] & 0x7; /* Validate action */
    switch (val) {
    case IPMI_BMC_WATCHDOG_ACTION_NONE:
        break;

    case IPMI_BMC_WATCHDOG_ACTION_RESET:
        rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_RESET_CHASSIS, 1));
        break;

    case IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN:
        rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 1));
        break;

    case IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE:
        rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWERCYCLE_CHASSIS, 1));
        break;

    default:
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
    }
    if (rsp->buffer[2]) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }

    val = (cmd[3] >> 4) & 0x7; /* Validate preaction */
    switch (val) {
    case IPMI_BMC_WATCHDOG_PRE_MSG_INT:
    case IPMI_BMC_WATCHDOG_PRE_NONE:
        break;

    case IPMI_BMC_WATCHDOG_PRE_NMI:
        if (!k->do_hw_op(s, IPMI_SEND_NMI, 1)) {
            /* NMI not supported. */
            rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
            return;
        }
        break;

    default:
        /* We don't support PRE_SMI */
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }

    ibs->watchdog_initialized = 1;
    ibs->watchdog_use = cmd[2] & IPMI_BMC_WATCHDOG_USE_MASK;
    ibs->watchdog_action = cmd[3] & IPMI_BMC_WATCHDOG_ACTION_MASK;
    ibs->watchdog_pretimeout = cmd[4];
    ibs->watchdog_expired &= ~cmd[5];
    ibs->watchdog_timeout = cmd[6] | (((uint16_t) cmd[7]) << 8);
    if (ibs->watchdog_running & IPMI_BMC_WATCHDOG_GET_DONT_STOP(ibs)) {
        do_watchdog_reset(ibs);
    } else {
        ibs->watchdog_running = 0;
    }
}

static void get_watchdog_timer(IPMIBmcSim *ibs,
                               uint8_t *cmd, unsigned int cmd_len,
                               RspBuffer *rsp)
{
    rsp_buffer_push(rsp, ibs->watchdog_use);
    rsp_buffer_push(rsp, ibs->watchdog_action);
    rsp_buffer_push(rsp, ibs->watchdog_pretimeout);
    rsp_buffer_push(rsp, ibs->watchdog_expired);
    if (ibs->watchdog_running) {
        long timeout;
        timeout = ((ibs->watchdog_expiry - ipmi_getmonotime() + 50000000)
                   / 100000000);
        rsp_buffer_push(rsp, timeout & 0xff);
        rsp_buffer_push(rsp, (timeout >> 8) & 0xff);
    } else {
        rsp_buffer_push(rsp, 0);
        rsp_buffer_push(rsp, 0);
    }
}

static void get_sdr_rep_info(IPMIBmcSim *ibs,
                             uint8_t *cmd, unsigned int cmd_len,
                             RspBuffer *rsp)
{
    unsigned int i;

    rsp_buffer_push(rsp, 0x51); /* Conform to IPMI 1.5 spec */
    rsp_buffer_push(rsp, ibs->sdr.next_rec_id & 0xff);
    rsp_buffer_push(rsp, (ibs->sdr.next_rec_id >> 8) & 0xff);
    rsp_buffer_push(rsp, (MAX_SDR_SIZE - ibs->sdr.next_free) & 0xff);
    rsp_buffer_push(rsp, ((MAX_SDR_SIZE - ibs->sdr.next_free) >> 8) & 0xff);
    for (i = 0; i < 4; i++) {
        rsp_buffer_push(rsp, ibs->sdr.last_addition[i]);
    }
    for (i = 0; i < 4; i++) {
        rsp_buffer_push(rsp, ibs->sdr.last_clear[i]);
    }
    /* Only modal support, reserve supported */
    rsp_buffer_push(rsp, (ibs->sdr.overflow << 7) | 0x22);
}

static void reserve_sdr_rep(IPMIBmcSim *ibs,
                            uint8_t *cmd, unsigned int cmd_len,
                            RspBuffer *rsp)
{
    rsp_buffer_push(rsp, ibs->sdr.reservation & 0xff);
    rsp_buffer_push(rsp, (ibs->sdr.reservation >> 8) & 0xff);
}

static void get_sdr(IPMIBmcSim *ibs,
                    uint8_t *cmd, unsigned int cmd_len,
                    RspBuffer *rsp)
{
    unsigned int pos;
    uint16_t nextrec;
    struct ipmi_sdr_header *sdrh;

    if (cmd[6]) {
        if ((cmd[2] | (cmd[3] << 8)) != ibs->sdr.reservation) {
            rsp_buffer_set_error(rsp, IPMI_CC_INVALID_RESERVATION);
            return;
        }
    }

    pos = 0;
    if (sdr_find_entry(&ibs->sdr, cmd[4] | (cmd[5] << 8),
                       &pos, &nextrec)) {
        rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
        return;
    }

    sdrh = (struct ipmi_sdr_header *) &ibs->sdr.sdr[pos];

    if (cmd[6] > ipmi_sdr_length(sdrh)) {
        rsp_buffer_set_error(rsp, IPMI_CC_PARM_OUT_OF_RANGE);
        return;
    }

    rsp_buffer_push(rsp, nextrec & 0xff);
    rsp_buffer_push(rsp, (nextrec >> 8) & 0xff);

    if (cmd[7] == 0xff) {
        cmd[7] = ipmi_sdr_length(sdrh) - cmd[6];
    }

    if ((cmd[7] + rsp->len) > sizeof(rsp->buffer)) {
        rsp_buffer_set_error(rsp, IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES);
        return;
    }

    rsp_buffer_pushmore(rsp, ibs->sdr.sdr + pos + cmd[6], cmd[7]);
}

static void add_sdr(IPMIBmcSim *ibs,
                    uint8_t *cmd, unsigned int cmd_len,
                    RspBuffer *rsp)
{
    uint16_t recid;
    struct ipmi_sdr_header *sdrh = (struct ipmi_sdr_header *) cmd + 2;

    if (sdr_add_entry(ibs, sdrh, cmd_len - 2, &recid)) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }
    rsp_buffer_push(rsp, recid & 0xff);
    rsp_buffer_push(rsp, (recid >> 8) & 0xff);
}

static void clear_sdr_rep(IPMIBmcSim *ibs,
                          uint8_t *cmd, unsigned int cmd_len,
                          RspBuffer *rsp)
{
    if ((cmd[2] | (cmd[3] << 8)) != ibs->sdr.reservation) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_RESERVATION);
        return;
    }

    if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }
    if (cmd[7] == 0xaa) {
        ibs->sdr.next_free = 0;
        ibs->sdr.overflow = 0;
        set_timestamp(ibs, ibs->sdr.last_clear);
        rsp_buffer_push(rsp, 1); /* Erasure complete */
        sdr_inc_reservation(&ibs->sdr);
    } else if (cmd[7] == 0) {
        rsp_buffer_push(rsp, 1); /* Erasure complete */
    } else {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }
}

static void get_sel_info(IPMIBmcSim *ibs,
                         uint8_t *cmd, unsigned int cmd_len,
                         RspBuffer *rsp)
{
    unsigned int i, val;

    rsp_buffer_push(rsp, 0x51); /* Conform to IPMI 1.5 */
    rsp_buffer_push(rsp, ibs->sel.next_free & 0xff);
    rsp_buffer_push(rsp, (ibs->sel.next_free >> 8) & 0xff);
    val = (MAX_SEL_SIZE - ibs->sel.next_free) * 16;
    rsp_buffer_push(rsp, val & 0xff);
    rsp_buffer_push(rsp, (val >> 8) & 0xff);
    for (i = 0; i < 4; i++) {
        rsp_buffer_push(rsp, ibs->sel.last_addition[i]);
    }
    for (i = 0; i < 4; i++) {
        rsp_buffer_push(rsp, ibs->sel.last_clear[i]);
    }
    /* Only support Reserve SEL */
    rsp_buffer_push(rsp, (ibs->sel.overflow << 7) | 0x02);
}

static void reserve_sel(IPMIBmcSim *ibs,
                        uint8_t *cmd, unsigned int cmd_len,
                        RspBuffer *rsp)
{
    rsp_buffer_push(rsp, ibs->sel.reservation & 0xff);
    rsp_buffer_push(rsp, (ibs->sel.reservation >> 8) & 0xff);
}

static void get_sel_entry(IPMIBmcSim *ibs,
                          uint8_t *cmd, unsigned int cmd_len,
                          RspBuffer *rsp)
{
    unsigned int val;

    if (cmd[6]) {
        if ((cmd[2] | (cmd[3] << 8)) != ibs->sel.reservation) {
            rsp_buffer_set_error(rsp, IPMI_CC_INVALID_RESERVATION);
            return;
        }
    }
    if (ibs->sel.next_free == 0) {
        rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
        return;
    }
    if (cmd[6] > 15) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }
    if (cmd[7] == 0xff) {
        cmd[7] = 16;
    } else if ((cmd[7] + cmd[6]) > 16) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    } else {
        cmd[7] += cmd[6];
    }

    val = cmd[4] | (cmd[5] << 8);
    if (val == 0xffff) {
        val = ibs->sel.next_free - 1;
    } else if (val >= ibs->sel.next_free) {
        rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
        return;
    }
    if ((val + 1) == ibs->sel.next_free) {
        rsp_buffer_push(rsp, 0xff);
        rsp_buffer_push(rsp, 0xff);
    } else {
        rsp_buffer_push(rsp, (val + 1) & 0xff);
        rsp_buffer_push(rsp, ((val + 1) >> 8) & 0xff);
    }
    for (; cmd[6] < cmd[7]; cmd[6]++) {
        rsp_buffer_push(rsp, ibs->sel.sel[val][cmd[6]]);
    }
}

static void add_sel_entry(IPMIBmcSim *ibs,
                          uint8_t *cmd, unsigned int cmd_len,
                          RspBuffer *rsp)
{
    if (sel_add_event(ibs, cmd + 2)) {
        rsp_buffer_set_error(rsp, IPMI_CC_OUT_OF_SPACE);
        return;
    }
    /* sel_add_event fills in the record number. */
    rsp_buffer_push(rsp, cmd[2]);
    rsp_buffer_push(rsp, cmd[3]);
}

static void clear_sel(IPMIBmcSim *ibs,
                      uint8_t *cmd, unsigned int cmd_len,
                      RspBuffer *rsp)
{
    if ((cmd[2] | (cmd[3] << 8)) != ibs->sel.reservation) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_RESERVATION);
        return;
    }

    if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }
    if (cmd[7] == 0xaa) {
        ibs->sel.next_free = 0;
        ibs->sel.overflow = 0;
        set_timestamp(ibs, ibs->sdr.last_clear);
        rsp_buffer_push(rsp, 1); /* Erasure complete */
        sel_inc_reservation(&ibs->sel);
    } else if (cmd[7] == 0) {
        rsp_buffer_push(rsp, 1); /* Erasure complete */
    } else {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }
}

static void get_sel_time(IPMIBmcSim *ibs,
                         uint8_t *cmd, unsigned int cmd_len,
                         RspBuffer *rsp)
{
    uint32_t val;
    struct ipmi_time now;

    ipmi_gettime(&now);
    val = now.tv_sec + ibs->sel.time_offset;
    rsp_buffer_push(rsp, val & 0xff);
    rsp_buffer_push(rsp, (val >> 8) & 0xff);
    rsp_buffer_push(rsp, (val >> 16) & 0xff);
    rsp_buffer_push(rsp, (val >> 24) & 0xff);
}

static void set_sel_time(IPMIBmcSim *ibs,
                         uint8_t *cmd, unsigned int cmd_len,
                         RspBuffer *rsp)
{
    uint32_t val;
    struct ipmi_time now;

    val = cmd[2] | (cmd[3] << 8) | (cmd[4] << 16) | (cmd[5] << 24);
    ipmi_gettime(&now);
    ibs->sel.time_offset = now.tv_sec - ((long) val);
}

static void set_sensor_evt_enable(IPMIBmcSim *ibs,
                                  uint8_t *cmd, unsigned int cmd_len,
                                  RspBuffer *rsp)
{
    IPMISensor *sens;

    if ((cmd[2] >= MAX_SENSORS) ||
            !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
        rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
        return;
    }
    sens = ibs->sensors + cmd[2];
    switch ((cmd[3] >> 4) & 0x3) {
    case 0: /* Do not change */
        break;
    case 1: /* Enable bits */
        if (cmd_len > 4) {
            sens->assert_enable |= cmd[4];
        }
        if (cmd_len > 5) {
            sens->assert_enable |= cmd[5] << 8;
        }
        if (cmd_len > 6) {
            sens->deassert_enable |= cmd[6];
        }
        if (cmd_len > 7) {
            sens->deassert_enable |= cmd[7] << 8;
        }
        break;
    case 2: /* Disable bits */
        if (cmd_len > 4) {
            sens->assert_enable &= ~cmd[4];
        }
        if (cmd_len > 5) {
            sens->assert_enable &= ~(cmd[5] << 8);
        }
        if (cmd_len > 6) {
            sens->deassert_enable &= ~cmd[6];
        }
        if (cmd_len > 7) {
            sens->deassert_enable &= ~(cmd[7] << 8);
        }
        break;
    case 3:
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }
    IPMI_SENSOR_SET_RET_STATUS(sens, cmd[3]);
}

static void get_sensor_evt_enable(IPMIBmcSim *ibs,
                                  uint8_t *cmd, unsigned int cmd_len,
                                  RspBuffer *rsp)
{
    IPMISensor *sens;

    if ((cmd[2] >= MAX_SENSORS) ||
        !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
        rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
        return;
    }
    sens = ibs->sensors + cmd[2];
    rsp_buffer_push(rsp, IPMI_SENSOR_GET_RET_STATUS(sens));
    rsp_buffer_push(rsp, sens->assert_enable & 0xff);
    rsp_buffer_push(rsp, (sens->assert_enable >> 8) & 0xff);
    rsp_buffer_push(rsp, sens->deassert_enable & 0xff);
    rsp_buffer_push(rsp, (sens->deassert_enable >> 8) & 0xff);
}

static void rearm_sensor_evts(IPMIBmcSim *ibs,
                              uint8_t *cmd, unsigned int cmd_len,
                              RspBuffer *rsp)
{
    IPMISensor *sens;

    if ((cmd[2] >= MAX_SENSORS) ||
        !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
        rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
        return;
    }
    sens = ibs->sensors + cmd[2];

    if ((cmd[3] & 0x80) == 0) {
        /* Just clear everything */
        sens->states = 0;
        return;
    }
}

static void get_sensor_evt_status(IPMIBmcSim *ibs,
                                  uint8_t *cmd, unsigned int cmd_len,
                                  RspBuffer *rsp)
{
    IPMISensor *sens;

    if ((cmd[2] >= MAX_SENSORS) ||
        !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
        rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
        return;
    }
    sens = ibs->sensors + cmd[2];
    rsp_buffer_push(rsp, sens->reading);
    rsp_buffer_push(rsp, IPMI_SENSOR_GET_RET_STATUS(sens));
    rsp_buffer_push(rsp, sens->assert_states & 0xff);
    rsp_buffer_push(rsp, (sens->assert_states >> 8) & 0xff);
    rsp_buffer_push(rsp, sens->deassert_states & 0xff);
    rsp_buffer_push(rsp, (sens->deassert_states >> 8) & 0xff);
}

static void get_sensor_reading(IPMIBmcSim *ibs,
                               uint8_t *cmd, unsigned int cmd_len,
                               RspBuffer *rsp)
{
    IPMISensor *sens;

    if ((cmd[2] >= MAX_SENSORS) ||
            !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
        rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
        return;
    }
    sens = ibs->sensors + cmd[2];
    rsp_buffer_push(rsp, sens->reading);
    rsp_buffer_push(rsp, IPMI_SENSOR_GET_RET_STATUS(sens));
    rsp_buffer_push(rsp, sens->states & 0xff);
    if (IPMI_SENSOR_IS_DISCRETE(sens)) {
        rsp_buffer_push(rsp, (sens->states >> 8) & 0xff);
    }
}

static void set_sensor_type(IPMIBmcSim *ibs,
                            uint8_t *cmd, unsigned int cmd_len,
                            RspBuffer *rsp)
{
    IPMISensor *sens;


    if ((cmd[2] >= MAX_SENSORS) ||
            !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
        rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
        return;
    }
    sens = ibs->sensors + cmd[2];
    sens->sensor_type = cmd[3];
    sens->evt_reading_type_code = cmd[4] & 0x7f;
}

static void get_sensor_type(IPMIBmcSim *ibs,
                            uint8_t *cmd, unsigned int cmd_len,
                            RspBuffer *rsp)
{
    IPMISensor *sens;


    if ((cmd[2] >= MAX_SENSORS) ||
            !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
        rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
        return;
    }
    sens = ibs->sensors + cmd[2];
    rsp_buffer_push(rsp, sens->sensor_type);
    rsp_buffer_push(rsp, sens->evt_reading_type_code);
}


static const IPMICmdHandler chassis_cmds[] = {
    [IPMI_CMD_GET_CHASSIS_CAPABILITIES] = { chassis_capabilities },
    [IPMI_CMD_GET_CHASSIS_STATUS] = { chassis_status },
    [IPMI_CMD_CHASSIS_CONTROL] = { chassis_control, 3 },
    [IPMI_CMD_GET_SYS_RESTART_CAUSE] = { chassis_get_sys_restart_cause }
};
static const IPMINetfn chassis_netfn = {
    .cmd_nums = ARRAY_SIZE(chassis_cmds),
    .cmd_handlers = chassis_cmds
};

static const IPMICmdHandler sensor_event_cmds[] = {
    [IPMI_CMD_SET_SENSOR_EVT_ENABLE] = { set_sensor_evt_enable, 4 },
    [IPMI_CMD_GET_SENSOR_EVT_ENABLE] = { get_sensor_evt_enable, 3 },
    [IPMI_CMD_REARM_SENSOR_EVTS] = { rearm_sensor_evts, 4 },
    [IPMI_CMD_GET_SENSOR_EVT_STATUS] = { get_sensor_evt_status, 3 },
    [IPMI_CMD_GET_SENSOR_READING] = { get_sensor_reading, 3 },
    [IPMI_CMD_SET_SENSOR_TYPE] = { set_sensor_type, 5 },
    [IPMI_CMD_GET_SENSOR_TYPE] = { get_sensor_type, 3 },
};
static const IPMINetfn sensor_event_netfn = {
    .cmd_nums = ARRAY_SIZE(sensor_event_cmds),
    .cmd_handlers = sensor_event_cmds
};

static const IPMICmdHandler app_cmds[] = {
    [IPMI_CMD_GET_DEVICE_ID] = { get_device_id },
    [IPMI_CMD_COLD_RESET] = { cold_reset },
    [IPMI_CMD_WARM_RESET] = { warm_reset },
    [IPMI_CMD_SET_ACPI_POWER_STATE] = { set_acpi_power_state, 4 },
    [IPMI_CMD_GET_ACPI_POWER_STATE] = { get_acpi_power_state },
    [IPMI_CMD_GET_DEVICE_GUID] = { get_device_guid },
    [IPMI_CMD_SET_BMC_GLOBAL_ENABLES] = { set_bmc_global_enables, 3 },
    [IPMI_CMD_GET_BMC_GLOBAL_ENABLES] = { get_bmc_global_enables },
    [IPMI_CMD_CLR_MSG_FLAGS] = { clr_msg_flags, 3 },
    [IPMI_CMD_GET_MSG_FLAGS] = { get_msg_flags },
    [IPMI_CMD_GET_MSG] = { get_msg },
    [IPMI_CMD_SEND_MSG] = { send_msg, 3 },
    [IPMI_CMD_READ_EVT_MSG_BUF] = { read_evt_msg_buf },
    [IPMI_CMD_RESET_WATCHDOG_TIMER] = { reset_watchdog_timer },
    [IPMI_CMD_SET_WATCHDOG_TIMER] = { set_watchdog_timer, 8 },
    [IPMI_CMD_GET_WATCHDOG_TIMER] = { get_watchdog_timer },
};
static const IPMINetfn app_netfn = {
    .cmd_nums = ARRAY_SIZE(app_cmds),
    .cmd_handlers = app_cmds
};

static const IPMICmdHandler storage_cmds[] = {
    [IPMI_CMD_GET_SDR_REP_INFO] = { get_sdr_rep_info },
    [IPMI_CMD_RESERVE_SDR_REP] = { reserve_sdr_rep },
    [IPMI_CMD_GET_SDR] = { get_sdr, 8 },
    [IPMI_CMD_ADD_SDR] = { add_sdr },
    [IPMI_CMD_CLEAR_SDR_REP] = { clear_sdr_rep, 8 },
    [IPMI_CMD_GET_SEL_INFO] = { get_sel_info },
    [IPMI_CMD_RESERVE_SEL] = { reserve_sel },
    [IPMI_CMD_GET_SEL_ENTRY] = { get_sel_entry, 8 },
    [IPMI_CMD_ADD_SEL_ENTRY] = { add_sel_entry, 18 },
    [IPMI_CMD_CLEAR_SEL] = { clear_sel, 8 },
    [IPMI_CMD_GET_SEL_TIME] = { get_sel_time, 6 },
    [IPMI_CMD_SET_SEL_TIME] = { set_sel_time },
};

static const IPMINetfn storage_netfn = {
    .cmd_nums = ARRAY_SIZE(storage_cmds),
    .cmd_handlers = storage_cmds
};

static void register_cmds(IPMIBmcSim *s)
{
    ipmi_register_netfn(s, IPMI_NETFN_CHASSIS, &chassis_netfn);
    ipmi_register_netfn(s, IPMI_NETFN_SENSOR_EVENT, &sensor_event_netfn);
    ipmi_register_netfn(s, IPMI_NETFN_APP, &app_netfn);
    ipmi_register_netfn(s, IPMI_NETFN_STORAGE, &storage_netfn);
}

static uint8_t init_sdrs[] = {
    /* Watchdog device */
    0x00, 0x00, 0x51, 0x02,   35, 0x20, 0x00, 0x00,
    0x23, 0x01, 0x63, 0x00, 0x23, 0x6f, 0x0f, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
    'W',  'a',  't',  'c',  'h',  'd',  'o',  'g',
};

static void ipmi_sdr_init(IPMIBmcSim *ibs)
{
    unsigned int i;
    int len;
    size_t sdrs_size;
    uint8_t *sdrs;

    sdrs_size = sizeof(init_sdrs);
    sdrs = init_sdrs;

    for (i = 0; i < sdrs_size; i += len) {
        struct ipmi_sdr_header *sdrh;

        if (i + IPMI_SDR_HEADER_SIZE > sdrs_size) {
            error_report("Problem with recid 0x%4.4x", i);
            return;
        }
        sdrh = (struct ipmi_sdr_header *) &sdrs[i];
        len = ipmi_sdr_length(sdrh);
        if (i + len > sdrs_size) {
            error_report("Problem with recid 0x%4.4x", i);
            return;
        }
        sdr_add_entry(ibs, sdrh, len, NULL);
    }
}

static const VMStateDescription vmstate_ipmi_sim = {
    .name = TYPE_IPMI_BMC_SIMULATOR,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields      = (VMStateField[]) {
        VMSTATE_UINT8(bmc_global_enables, IPMIBmcSim),
        VMSTATE_UINT8(msg_flags, IPMIBmcSim),
        VMSTATE_BOOL(watchdog_initialized, IPMIBmcSim),
        VMSTATE_UINT8(watchdog_use, IPMIBmcSim),
        VMSTATE_UINT8(watchdog_action, IPMIBmcSim),
        VMSTATE_UINT8(watchdog_pretimeout, IPMIBmcSim),
        VMSTATE_BOOL(watchdog_expired, IPMIBmcSim),
        VMSTATE_UINT16(watchdog_timeout, IPMIBmcSim),
        VMSTATE_BOOL(watchdog_running, IPMIBmcSim),
        VMSTATE_BOOL(watchdog_preaction_ran, IPMIBmcSim),
        VMSTATE_INT64(watchdog_expiry, IPMIBmcSim),
        VMSTATE_UINT8_ARRAY(evtbuf, IPMIBmcSim, 16),
        VMSTATE_UINT8(sensors[IPMI_WATCHDOG_SENSOR].status, IPMIBmcSim),
        VMSTATE_UINT8(sensors[IPMI_WATCHDOG_SENSOR].reading, IPMIBmcSim),
        VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].states, IPMIBmcSim),
        VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].assert_states, IPMIBmcSim),
        VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].deassert_states,
                       IPMIBmcSim),
        VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].assert_enable, IPMIBmcSim),
        VMSTATE_END_OF_LIST()
    }
};

static void ipmi_sim_realize(DeviceState *dev, Error **errp)
{
    IPMIBmc *b = IPMI_BMC(dev);
    unsigned int i;
    IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);

    qemu_mutex_init(&ibs->lock);
    QTAILQ_INIT(&ibs->rcvbufs);

    ibs->bmc_global_enables = (1 << IPMI_BMC_EVENT_LOG_BIT);
    ibs->device_id = 0x20;
    ibs->ipmi_version = 0x02; /* IPMI 2.0 */
    ibs->restart_cause = 0;
    for (i = 0; i < 4; i++) {
        ibs->sel.last_addition[i] = 0xff;
        ibs->sel.last_clear[i] = 0xff;
        ibs->sdr.last_addition[i] = 0xff;
        ibs->sdr.last_clear[i] = 0xff;
    }

    ipmi_sdr_init(ibs);

    ibs->acpi_power_state[0] = 0;
    ibs->acpi_power_state[1] = 0;

    if (qemu_uuid_set) {
        memcpy(&ibs->uuid, qemu_uuid, 16);
    } else {
        memset(&ibs->uuid, 0, 16);
    }

    ipmi_init_sensors_from_sdrs(ibs);
    register_cmds(ibs);

    ibs->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ipmi_timeout, ibs);

    vmstate_register(NULL, 0, &vmstate_ipmi_sim, ibs);
}

static void ipmi_sim_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    IPMIBmcClass *bk = IPMI_BMC_CLASS(oc);

    dc->realize = ipmi_sim_realize;
    bk->handle_command = ipmi_sim_handle_command;
}

static const TypeInfo ipmi_sim_type = {
    .name          = TYPE_IPMI_BMC_SIMULATOR,
    .parent        = TYPE_IPMI_BMC,
    .instance_size = sizeof(IPMIBmcSim),
    .class_init    = ipmi_sim_class_init,
};

static void ipmi_sim_register_types(void)
{
    type_register_static(&ipmi_sim_type);
}

type_init(ipmi_sim_register_types)
