/*
 * 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 "system/system.h"
#include "qemu/timer.h"
#include "hw/ipmi/ipmi.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "hw/loader.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "migration/vmstate.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_PLATFORM_EVENT_MSG       0x02
#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_CMD_SET_SENSOR_READING       0x30

/* #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_CMD_GET_CHANNEL_INFO         0x42

#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_FRU_AREA_INFO        0x10
#define IPMI_CMD_READ_FRU_DATA            0x11
#define IPMI_CMD_WRITE_FRU_DATA           0x12
#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 IPMIFru {
    char *filename;
    unsigned int nentries;
    uint16_t areasize;
    uint8_t *data;
} IPMIFru;

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

#define MAX_NETFNS 64

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

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 */
    uint8_t  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;
    uint32_t mfg_id;
    uint16_t product_id;

    uint8_t restart_cause;

    uint8_t acpi_power_state[2];
    QemuUUID uuid;

    IPMISel sel;
    IPMISdr sdr;
    IPMIFru fru;
    IPMISensor sensors[MAX_SENSORS];
    char *sdr_filename;

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

    /* 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_GLOBAL_ENABLES_SUPPORTED 0x0f
#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

#define RSP_BUFFER_INITIALIZER { }

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;
}

int ipmi_bmc_sdr_find(IPMIBmc *b, uint16_t recid,
                      const struct ipmi_sdr_compact **sdr, uint16_t *nextrec)

{
    IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
    unsigned int pos;

    pos = 0;
    if (sdr_find_entry(&ibs->sdr, recid, &pos, nextrec)) {
        return -1;
    }

    *sdr = (const struct ipmi_sdr_compact *) &ibs->sdr.sdr[pos];
    return 0;
}

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)
{
    uint8_t ts[4];

    event[0] = 0xff;
    event[1] = 0xff;
    set_timestamp(ibs, ts);
    if (event[2] < 0xe0) { /* Don't set timestamps for type 0xe0-0xff. */
        memcpy(event + 3, ts, 4);
    }
    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, ts, 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_MSG_FLAG_WATCHDOG_TIMEOUT_MASK_SET(ibs)))
        || (IPMI_BMC_EVBUF_FULL_INT_ENABLED(ibs) &&
            IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(ibs));
}

void ipmi_bmc_gen_event(IPMIBmc *b, uint8_t *evt, bool log)
{
    IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
    IPMIInterface *s = ibs->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);

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

    if (log && 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 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,
                                    bool do_log)
{
    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 (do_log && (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 (do_log && (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;
    }
}

int ipmi_sim_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);
    bool do_log = !IPMI_BMC_WATCHDOG_GET_DONT_LOG(ibs);

    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,
                                    do_log);
            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,
                                    do_log);
            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,
                                do_log);
        break;

    case IPMI_BMC_WATCHDOG_ACTION_RESET:
        sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 1, 1,
                                0xc1, ibs->watchdog_use & 0xf, 0xff,
                                do_log);
        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,
                                do_log);
        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,
                                do_log);
        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 & 0xff);
    rsp_buffer_push(rsp, (ibs->mfg_id >> 8) & 0xff);
    rsp_buffer_push(rsp, (ibs->mfg_id >> 16) & 0xff);
    rsp_buffer_push(rsp, ibs->product_id & 0xff);
    rsp_buffer_push(rsp, (ibs->product_id >> 8) & 0xff);
}

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;

    /* An uninitialized uuid is all zeros, use that to know if it is set. */
    for (i = 0; i < 16; i++) {
        if (ibs->uuid.data[i]) {
            goto uuid_set;
        }
    }
    /* No uuid is set, return an error. */
    rsp_buffer_set_error(rsp, IPMI_CC_INVALID_CMD);
    return;

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

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

    if (val & ~IPMI_BMC_GLOBAL_ENABLES_SUPPORTED) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }

    set_global_enables(ibs, val);
}

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;

    if (QTAILQ_EMPTY(&ibs->rcvbufs)) {
        rsp_buffer_set_error(rsp, 0x80); /* Queue empty */
        return;
    }
    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));
    }
}

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] != IPMI_CHANNEL_IPMB) {
        /* We only handle channel 0h (IPMB) 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++;
    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));
}

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);
    rsp_buffer_push(rsp, ibs->watchdog_timeout & 0xff);
    rsp_buffer_push(rsp, (ibs->watchdog_timeout >> 8) & 0xff);
    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_channel_info(IPMIBmcSim *ibs,
                             uint8_t *cmd, unsigned int cmd_len,
                             RspBuffer *rsp)
{
    IPMIInterface *s = ibs->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
    IPMIFwInfo info = {};
    uint8_t ch = cmd[2] & 0x0f;

    /* Only define channel 0h (IPMB) and Fh (system interface) */

    if (ch == 0x0e) { /* "This channel" */
        ch = IPMI_CHANNEL_SYSTEM;
    }
    rsp_buffer_push(rsp, ch);

    if (ch != IPMI_CHANNEL_IPMB && ch != IPMI_CHANNEL_SYSTEM) {
        /* Not a supported channel */
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }

    if (k->get_fwinfo) {
        k->get_fwinfo(s, &info);
    }

    if (ch == IPMI_CHANNEL_IPMB) {
        rsp_buffer_push(rsp, IPMI_CHANNEL_MEDIUM_IPMB);
        rsp_buffer_push(rsp, IPMI_CHANNEL_PROTOCOL_IPMB);
    } else { /* IPMI_CHANNEL_SYSTEM */
        rsp_buffer_push(rsp, IPMI_CHANNEL_MEDIUM_SYSTEM);
        rsp_buffer_push(rsp, info.ipmi_channel_protocol);
    }

    rsp_buffer_push(rsp, 0x00); /* Session-less */

    /* IPMI Enterprise Number for Vendor ID */
    rsp_buffer_push(rsp, 0xf2);
    rsp_buffer_push(rsp, 0x1b);
    rsp_buffer_push(rsp, 0x00);

    if (ch == IPMI_CHANNEL_SYSTEM) {
        uint8_t irq;

        if (info.irq_source == IPMI_ISA_IRQ) {
            irq = info.interrupt_number;
        } else if (info.irq_source == IPMI_PCI_IRQ) {
            irq = 0x10 + info.interrupt_number;
        } else {
            irq = 0xff; /* no interrupt / unspecified */
        }

        /* Both interrupts use the same irq number */
        rsp_buffer_push(rsp, irq);
        rsp_buffer_push(rsp, irq);
    } else {
        /* Reserved */
        rsp_buffer_push(rsp, 0x00);
        rsp_buffer_push(rsp, 0x00);
    }
}

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 get_fru_area_info(IPMIBmcSim *ibs,
                         uint8_t *cmd, unsigned int cmd_len,
                         RspBuffer *rsp)
{
    uint8_t fruid;
    uint16_t fru_entry_size;

    fruid = cmd[2];

    if (fruid >= ibs->fru.nentries) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }

    fru_entry_size = ibs->fru.areasize;

    rsp_buffer_push(rsp, fru_entry_size & 0xff);
    rsp_buffer_push(rsp, fru_entry_size >> 8 & 0xff);
    rsp_buffer_push(rsp, 0x0);
}

static void read_fru_data(IPMIBmcSim *ibs,
                         uint8_t *cmd, unsigned int cmd_len,
                         RspBuffer *rsp)
{
    uint8_t fruid;
    uint16_t offset;
    int i;
    uint8_t *fru_entry;
    unsigned int count;

    fruid = cmd[2];
    offset = (cmd[3] | cmd[4] << 8);

    if (fruid >= ibs->fru.nentries) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }

    if (offset >= ibs->fru.areasize - 1) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }

    fru_entry = &ibs->fru.data[fruid * ibs->fru.areasize];

    count = MIN(cmd[5], ibs->fru.areasize - offset);

    rsp_buffer_push(rsp, count & 0xff);
    for (i = 0; i < count; i++) {
        rsp_buffer_push(rsp, fru_entry[offset + i]);
    }
}

static void write_fru_data(IPMIBmcSim *ibs,
                         uint8_t *cmd, unsigned int cmd_len,
                         RspBuffer *rsp)
{
    uint8_t fruid;
    uint16_t offset;
    uint8_t *fru_entry;
    unsigned int count;

    fruid = cmd[2];
    offset = (cmd[3] | cmd[4] << 8);

    if (fruid >= ibs->fru.nentries) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }

    if (offset >= ibs->fru.areasize - 1) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }

    fru_entry = &ibs->fru.data[fruid * ibs->fru.areasize];

    count = MIN(cmd_len - 5, ibs->fru.areasize - offset);

    memcpy(fru_entry + offset, cmd + 5, count);

    rsp_buffer_push(rsp, count & 0xff);
}

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 platform_event_msg(IPMIBmcSim *ibs,
                               uint8_t *cmd, unsigned int cmd_len,
                               RspBuffer *rsp)
{
    uint8_t event[16];

    event[2] = 2; /* System event record */
    event[7] = cmd[2]; /* Generator ID */
    event[8] = 0;
    event[9] = cmd[3]; /* EvMRev */
    event[10] = cmd[4]; /* Sensor type */
    event[11] = cmd[5]; /* Sensor number */
    event[12] = cmd[6]; /* Event dir / Event type */
    event[13] = cmd[7]; /* Event data 1 */
    event[14] = cmd[8]; /* Event data 2 */
    event[15] = cmd[9]; /* Event data 3 */

    if (sel_add_event(ibs, event)) {
        rsp_buffer_set_error(rsp, IPMI_CC_OUT_OF_SPACE);
    }
}

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);
}

/*
 * bytes   parameter
 *    1    sensor number
 *    2    operation (see below for bits meaning)
 *    3    sensor reading
 *  4:5    assertion states (optional)
 *  6:7    deassertion states (optional)
 *  8:10   event data 1,2,3 (optional)
 */
static void set_sensor_reading(IPMIBmcSim *ibs,
                               uint8_t *cmd, unsigned int cmd_len,
                               RspBuffer *rsp)
{
    IPMISensor *sens;
    uint8_t evd1 = 0;
    uint8_t evd2 = 0;
    uint8_t evd3 = 0;
    uint8_t new_reading = 0;
    uint16_t new_assert_states = 0;
    uint16_t new_deassert_states = 0;
    bool change_reading = false;
    bool change_assert = false;
    bool change_deassert = false;
    enum {
        SENSOR_GEN_EVENT_NONE,
        SENSOR_GEN_EVENT_DATA,
        SENSOR_GEN_EVENT_BMC,
    } do_gen_event = SENSOR_GEN_EVENT_NONE;

    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];

    /* [1:0] Sensor Reading operation */
    switch ((cmd[3]) & 0x3) {
    case 0: /* Do not change */
        break;
    case 1: /* write given value to sensor reading byte */
        new_reading = cmd[4];
        if (sens->reading != new_reading) {
            change_reading = true;
        }
        break;
    case 2:
    case 3:
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }

    /* [3:2] Deassertion bits operation */
    switch ((cmd[3] >> 2) & 0x3) {
    case 0: /* Do not change */
        break;
    case 1: /* write given value */
        if (cmd_len > 7) {
            new_deassert_states = cmd[7];
            change_deassert = true;
        }
        if (cmd_len > 8) {
            new_deassert_states |= (cmd[8] << 8);
        }
        break;

    case 2: /* mask on */
        if (cmd_len > 7) {
            new_deassert_states = (sens->deassert_states | cmd[7]);
            change_deassert = true;
        }
        if (cmd_len > 8) {
            new_deassert_states |= (sens->deassert_states | (cmd[8] << 8));
        }
        break;

    case 3: /* mask off */
        if (cmd_len > 7) {
            new_deassert_states = (sens->deassert_states & cmd[7]);
            change_deassert = true;
        }
        if (cmd_len > 8) {
            new_deassert_states |= (sens->deassert_states & (cmd[8] << 8));
        }
        break;
    }

    if (change_deassert && (new_deassert_states == sens->deassert_states)) {
        change_deassert = false;
    }

    /* [5:4] Assertion bits operation */
    switch ((cmd[3] >> 4) & 0x3) {
    case 0: /* Do not change */
        break;
    case 1: /* write given value */
        if (cmd_len > 5) {
            new_assert_states = cmd[5];
            change_assert = true;
        }
        if (cmd_len > 6) {
            new_assert_states |= (cmd[6] << 8);
        }
        break;

    case 2: /* mask on */
        if (cmd_len > 5) {
            new_assert_states = (sens->assert_states | cmd[5]);
            change_assert = true;
        }
        if (cmd_len > 6) {
            new_assert_states |= (sens->assert_states | (cmd[6] << 8));
        }
        break;

    case 3: /* mask off */
        if (cmd_len > 5) {
            new_assert_states = (sens->assert_states & cmd[5]);
            change_assert = true;
        }
        if (cmd_len > 6) {
            new_assert_states |= (sens->assert_states & (cmd[6] << 8));
        }
        break;
    }

    if (change_assert && (new_assert_states == sens->assert_states)) {
        change_assert = false;
    }

    if (cmd_len > 9) {
        evd1 = cmd[9];
    }
    if (cmd_len > 10) {
        evd2 = cmd[10];
    }
    if (cmd_len > 11) {
        evd3 = cmd[11];
    }

    /* [7:6] Event Data Bytes operation */
    switch ((cmd[3] >> 6) & 0x3) {
    case 0: /*
             * Don’t use Event Data bytes from this command. BMC will
             * generate it's own Event Data bytes based on its sensor
             * implementation.
             */
        evd1 = evd2 = evd3 = 0x0;
        do_gen_event = SENSOR_GEN_EVENT_BMC;
        break;
    case 1: /*
             * Write given values to event data bytes including bits
             * [3:0] Event Data 1.
             */
        do_gen_event = SENSOR_GEN_EVENT_DATA;
        break;
    case 2: /*
             * Write given values to event data bytes excluding bits
             * [3:0] Event Data 1.
             */
        evd1 &= 0xf0;
        do_gen_event = SENSOR_GEN_EVENT_DATA;
        break;
    case 3:
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }

    /*
     * Event Data Bytes operation and parameter are inconsistent. The
     * Specs are not clear on that topic but generating an error seems
     * correct.
     */
    if (do_gen_event == SENSOR_GEN_EVENT_DATA && cmd_len < 10) {
        rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
        return;
    }

    /* commit values */
    if (change_reading) {
        sens->reading = new_reading;
    }

    if (change_assert) {
        sens->assert_states = new_assert_states;
    }

    if (change_deassert) {
        sens->deassert_states = new_deassert_states;
    }

    /* TODO: handle threshold sensor */
    if (!IPMI_SENSOR_IS_DISCRETE(sens)) {
        return;
    }

    switch (do_gen_event) {
    case SENSOR_GEN_EVENT_DATA: {
        unsigned int bit = evd1 & 0xf;
        uint16_t mask = (1 << bit);

        if (sens->assert_states & mask & sens->assert_enable) {
            gen_event(ibs, cmd[2], 0, evd1, evd2, evd3);
        }

        if (sens->deassert_states & mask & sens->deassert_enable) {
            gen_event(ibs, cmd[2], 1, evd1, evd2, evd3);
        }
        break;
    }
    case SENSOR_GEN_EVENT_BMC:
        /*
         * TODO: generate event and event data bytes depending on the
         * sensor
         */
        break;
    case SENSOR_GEN_EVENT_NONE:
        break;
    }
}

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_PLATFORM_EVENT_MSG] = { platform_event_msg, 10 },
    [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 },
    [IPMI_CMD_SET_SENSOR_READING] = { set_sensor_reading, 5 },
};
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 },
    [IPMI_CMD_GET_CHANNEL_INFO] = { get_channel_info, 3 },
};
static const IPMINetfn app_netfn = {
    .cmd_nums = ARRAY_SIZE(app_cmds),
    .cmd_handlers = app_cmds
};

static const IPMICmdHandler storage_cmds[] = {
    [IPMI_CMD_GET_FRU_AREA_INFO] = { get_fru_area_info, 3 },
    [IPMI_CMD_READ_FRU_DATA] = { read_fru_data, 5 },
    [IPMI_CMD_WRITE_FRU_DATA] = { write_fru_data, 5 },
    [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 },
    [IPMI_CMD_SET_SEL_TIME] = { set_sel_time, 6 },
};

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

static void register_cmds(IPMIBmcSim *s)
{
    ipmi_sim_register_netfn(s, IPMI_NETFN_CHASSIS, &chassis_netfn);
    ipmi_sim_register_netfn(s, IPMI_NETFN_SENSOR_EVENT, &sensor_event_netfn);
    ipmi_sim_register_netfn(s, IPMI_NETFN_APP, &app_netfn);
    ipmi_sim_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;
    if (ibs->sdr_filename &&
        !g_file_get_contents(ibs->sdr_filename, (gchar **) &sdrs, &sdrs_size,
                             NULL)) {
        error_report("failed to load sdr file '%s'", ibs->sdr_filename);
        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);
            break;
        }
        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);
            break;
        }
        sdr_add_entry(ibs, sdrh, len, NULL);
    }

    if (sdrs != init_sdrs) {
        g_free(sdrs);
    }
}

static const VMStateDescription vmstate_ipmi_sim = {
    .name = TYPE_IPMI_BMC_SIMULATOR,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (const 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_UINT8(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_fru_init(IPMIFru *fru)
{
    int fsize;
    int size = 0;

    if (!fru->filename) {
        goto out;
    }

    fsize = get_image_size(fru->filename);
    if (fsize > 0) {
        size = QEMU_ALIGN_UP(fsize, fru->areasize);
        fru->data = g_malloc0(size);
        if (load_image_size(fru->filename, fru->data, fsize) != fsize) {
            error_report("Could not load file '%s'", fru->filename);
            g_free(fru->data);
            fru->data = NULL;
        }
    }

out:
    if (!fru->data) {
        /* give one default FRU */
        size = fru->areasize;
        fru->data = g_malloc0(size);
    }

    fru->nentries = size / fru->areasize;
}

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

    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);

    ipmi_fru_init(&ibs->fru);

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

    ipmi_init_sensors_from_sdrs(ibs);
    register_cmds(ibs);

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

static const Property ipmi_sim_properties[] = {
    DEFINE_PROP_UINT16("fruareasize", IPMIBmcSim, fru.areasize, 1024),
    DEFINE_PROP_STRING("frudatafile", IPMIBmcSim, fru.filename),
    DEFINE_PROP_STRING("sdrfile", IPMIBmcSim, sdr_filename),
    DEFINE_PROP_UINT8("device_id", IPMIBmcSim, device_id, 0x20),
    DEFINE_PROP_UINT8("ipmi_version", IPMIBmcSim, ipmi_version, 0x02),
    DEFINE_PROP_UINT8("device_rev", IPMIBmcSim, device_rev, 0),
    DEFINE_PROP_UINT8("fwrev1", IPMIBmcSim, fwrev1, 0),
    DEFINE_PROP_UINT8("fwrev2", IPMIBmcSim, fwrev2, 0),
    DEFINE_PROP_UINT32("mfg_id", IPMIBmcSim, mfg_id, 0),
    DEFINE_PROP_UINT16("product_id", IPMIBmcSim, product_id, 0),
    DEFINE_PROP_UUID_NODEFAULT("guid", IPMIBmcSim, uuid),
};

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

    dc->hotpluggable = false;
    dc->realize = ipmi_sim_realize;
    dc->vmsd = &vmstate_ipmi_sim;
    device_class_set_props(dc, ipmi_sim_properties);
    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)
