/*
 * IPMI BMC external connection
 *
 * 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.
 */

/*
 * This is designed to connect with OpenIPMI's lanserv serial interface
 * using the "VM" connection type.  See that for details.
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "qemu/timer.h"
#include "chardev/char-fe.h"
#include "hw/ipmi/ipmi.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"

#define VM_MSG_CHAR        0xA0 /* Marks end of message */
#define VM_CMD_CHAR        0xA1 /* Marks end of a command */
#define VM_ESCAPE_CHAR     0xAA /* Set bit 4 from the next byte to 0 */

#define VM_PROTOCOL_VERSION        1
#define VM_CMD_VERSION             0xff /* A version number byte follows */
#define VM_CMD_NOATTN              0x00
#define VM_CMD_ATTN                0x01
#define VM_CMD_ATTN_IRQ            0x02
#define VM_CMD_POWEROFF            0x03
#define VM_CMD_RESET               0x04
#define VM_CMD_ENABLE_IRQ          0x05 /* Enable/disable the messaging irq */
#define VM_CMD_DISABLE_IRQ         0x06
#define VM_CMD_SEND_NMI            0x07
#define VM_CMD_CAPABILITIES        0x08
#define   VM_CAPABILITIES_POWER    0x01
#define   VM_CAPABILITIES_RESET    0x02
#define   VM_CAPABILITIES_IRQ      0x04
#define   VM_CAPABILITIES_NMI      0x08
#define   VM_CAPABILITIES_ATTN     0x10
#define   VM_CAPABILITIES_GRACEFUL_SHUTDOWN 0x20
#define VM_CMD_GRACEFUL_SHUTDOWN   0x09

#define TYPE_IPMI_BMC_EXTERN "ipmi-bmc-extern"
#define IPMI_BMC_EXTERN(obj) OBJECT_CHECK(IPMIBmcExtern, (obj), \
                                        TYPE_IPMI_BMC_EXTERN)
typedef struct IPMIBmcExtern {
    IPMIBmc parent;

    CharBackend chr;

    bool connected;

    unsigned char inbuf[MAX_IPMI_MSG_SIZE + 2];
    unsigned int inpos;
    bool in_escape;
    bool in_too_many;
    bool waiting_rsp;
    bool sending_cmd;

    unsigned char outbuf[(MAX_IPMI_MSG_SIZE + 2) * 2 + 1];
    unsigned int outpos;
    unsigned int outlen;

    struct QEMUTimer *extern_timer;

    /* A reset event is pending to be sent upstream. */
    bool send_reset;
} IPMIBmcExtern;

static unsigned char
ipmb_checksum(const unsigned char *data, int size, unsigned char start)
{
        unsigned char csum = start;

        for (; size > 0; size--, data++) {
                csum += *data;
        }
        return csum;
}

static void continue_send(IPMIBmcExtern *ibe)
{
    int ret;
    if (ibe->outlen == 0) {
        goto check_reset;
    }
 send:
    ret = qemu_chr_fe_write(&ibe->chr, ibe->outbuf + ibe->outpos,
                            ibe->outlen - ibe->outpos);
    if (ret > 0) {
        ibe->outpos += ret;
    }
    if (ibe->outpos < ibe->outlen) {
        /* Not fully transmitted, try again in a 10ms */
        timer_mod_ns(ibe->extern_timer,
                     qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 10000000);
    } else {
        /* Sent */
        ibe->outlen = 0;
        ibe->outpos = 0;
        if (!ibe->sending_cmd) {
            ibe->waiting_rsp = true;
        } else {
            ibe->sending_cmd = false;
        }
    check_reset:
        if (ibe->connected && ibe->send_reset) {
            /* Send the reset */
            ibe->outbuf[0] = VM_CMD_RESET;
            ibe->outbuf[1] = VM_CMD_CHAR;
            ibe->outlen = 2;
            ibe->outpos = 0;
            ibe->send_reset = false;
            ibe->sending_cmd = true;
            goto send;
        }

        if (ibe->waiting_rsp) {
            /* Make sure we get a response within 4 seconds. */
            timer_mod_ns(ibe->extern_timer,
                         qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 4000000000ULL);
        }
    }
    return;
}

static void extern_timeout(void *opaque)
{
    IPMIBmcExtern *ibe = opaque;
    IPMIInterface *s = ibe->parent.intf;

    if (ibe->connected) {
        if (ibe->waiting_rsp && (ibe->outlen == 0)) {
            IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
            /* The message response timed out, return an error. */
            ibe->waiting_rsp = false;
            ibe->inbuf[1] = ibe->outbuf[1] | 0x04;
            ibe->inbuf[2] = ibe->outbuf[2];
            ibe->inbuf[3] = IPMI_CC_TIMEOUT;
            k->handle_rsp(s, ibe->outbuf[0], ibe->inbuf + 1, 3);
        } else {
            continue_send(ibe);
        }
    }
}

static void addchar(IPMIBmcExtern *ibe, unsigned char ch)
{
    switch (ch) {
    case VM_MSG_CHAR:
    case VM_CMD_CHAR:
    case VM_ESCAPE_CHAR:
        ibe->outbuf[ibe->outlen] = VM_ESCAPE_CHAR;
        ibe->outlen++;
        ch |= 0x10;
        /* fall through */
    default:
        ibe->outbuf[ibe->outlen] = ch;
        ibe->outlen++;
    }
}

static void ipmi_bmc_extern_handle_command(IPMIBmc *b,
                                       uint8_t *cmd, unsigned int cmd_len,
                                       unsigned int max_cmd_len,
                                       uint8_t msg_id)
{
    IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(b);
    IPMIInterface *s = ibe->parent.intf;
    uint8_t err = 0, csum;
    unsigned int i;

    if (ibe->outlen) {
        /* We already have a command queued.  Shouldn't ever happen. */
        error_report("IPMI KCS: Got command when not finished with the"
                     " previous command");
        abort();
    }

    /* If it's too short or it was truncated, return an error. */
    if (cmd_len < 2) {
        err = IPMI_CC_REQUEST_DATA_LENGTH_INVALID;
    } else if ((cmd_len > max_cmd_len) || (cmd_len > MAX_IPMI_MSG_SIZE)) {
        err = IPMI_CC_REQUEST_DATA_TRUNCATED;
    } else if (!ibe->connected) {
        err = IPMI_CC_BMC_INIT_IN_PROGRESS;
    }
    if (err) {
        IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
        unsigned char rsp[3];
        rsp[0] = cmd[0] | 0x04;
        rsp[1] = cmd[1];
        rsp[2] = err;
        ibe->waiting_rsp = false;
        k->handle_rsp(s, msg_id, rsp, 3);
        goto out;
    }

    addchar(ibe, msg_id);
    for (i = 0; i < cmd_len; i++) {
        addchar(ibe, cmd[i]);
    }
    csum = ipmb_checksum(&msg_id, 1, 0);
    addchar(ibe, -ipmb_checksum(cmd, cmd_len, csum));

    ibe->outbuf[ibe->outlen] = VM_MSG_CHAR;
    ibe->outlen++;

    /* Start the transmit */
    continue_send(ibe);

 out:
    return;
}

static void handle_hw_op(IPMIBmcExtern *ibe, unsigned char hw_op)
{
    IPMIInterface *s = ibe->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);

    switch (hw_op) {
    case VM_CMD_VERSION:
        /* We only support one version at this time. */
        break;

    case VM_CMD_NOATTN:
        k->set_atn(s, 0, 0);
        break;

    case VM_CMD_ATTN:
        k->set_atn(s, 1, 0);
        break;

    case VM_CMD_ATTN_IRQ:
        k->set_atn(s, 1, 1);
        break;

    case VM_CMD_POWEROFF:
        k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 0);
        break;

    case VM_CMD_RESET:
        k->do_hw_op(s, IPMI_RESET_CHASSIS, 0);
        break;

    case VM_CMD_ENABLE_IRQ:
        k->set_irq_enable(s, 1);
        break;

    case VM_CMD_DISABLE_IRQ:
        k->set_irq_enable(s, 0);
        break;

    case VM_CMD_SEND_NMI:
        k->do_hw_op(s, IPMI_SEND_NMI, 0);
        break;

    case VM_CMD_GRACEFUL_SHUTDOWN:
        k->do_hw_op(s, IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP, 0);
        break;
    }
}

static void handle_msg(IPMIBmcExtern *ibe)
{
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(ibe->parent.intf);

    if (ibe->in_escape) {
        ipmi_debug("msg escape not ended\n");
        return;
    }
    if (ibe->inpos < 5) {
        ipmi_debug("msg too short\n");
        return;
    }
    if (ibe->in_too_many) {
        ibe->inbuf[3] = IPMI_CC_REQUEST_DATA_TRUNCATED;
        ibe->inpos = 4;
    } else if (ipmb_checksum(ibe->inbuf, ibe->inpos, 0) != 0) {
        ipmi_debug("msg checksum failure\n");
        return;
    } else {
        ibe->inpos--; /* Remove checkum */
    }

    timer_del(ibe->extern_timer);
    ibe->waiting_rsp = false;
    k->handle_rsp(ibe->parent.intf, ibe->inbuf[0], ibe->inbuf + 1, ibe->inpos - 1);
}

static int can_receive(void *opaque)
{
    return 1;
}

static void receive(void *opaque, const uint8_t *buf, int size)
{
    IPMIBmcExtern *ibe = opaque;
    int i;
    unsigned char hw_op;

    for (i = 0; i < size; i++) {
        unsigned char ch = buf[i];

        switch (ch) {
        case VM_MSG_CHAR:
            handle_msg(ibe);
            ibe->in_too_many = false;
            ibe->inpos = 0;
            break;

        case VM_CMD_CHAR:
            if (ibe->in_too_many) {
                ipmi_debug("cmd in too many\n");
                ibe->in_too_many = false;
                ibe->inpos = 0;
                break;
            }
            if (ibe->in_escape) {
                ipmi_debug("cmd in escape\n");
                ibe->in_too_many = false;
                ibe->inpos = 0;
                ibe->in_escape = false;
                break;
            }
            ibe->in_too_many = false;
            if (ibe->inpos < 1) {
                break;
            }
            hw_op = ibe->inbuf[0];
            ibe->inpos = 0;
            goto out_hw_op;
            break;

        case VM_ESCAPE_CHAR:
            ibe->in_escape = true;
            break;

        default:
            if (ibe->in_escape) {
                ch &= ~0x10;
                ibe->in_escape = false;
            }
            if (ibe->in_too_many) {
                break;
            }
            if (ibe->inpos >= sizeof(ibe->inbuf)) {
                ibe->in_too_many = true;
                break;
            }
            ibe->inbuf[ibe->inpos] = ch;
            ibe->inpos++;
            break;
        }
    }
    return;

 out_hw_op:
    handle_hw_op(ibe, hw_op);
}

static void chr_event(void *opaque, QEMUChrEvent event)
{
    IPMIBmcExtern *ibe = opaque;
    IPMIInterface *s = ibe->parent.intf;
    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
    unsigned char v;

    switch (event) {
    case CHR_EVENT_OPENED:
        ibe->connected = true;
        ibe->outpos = 0;
        ibe->outlen = 0;
        addchar(ibe, VM_CMD_VERSION);
        addchar(ibe, VM_PROTOCOL_VERSION);
        ibe->outbuf[ibe->outlen] = VM_CMD_CHAR;
        ibe->outlen++;
        addchar(ibe, VM_CMD_CAPABILITIES);
        v = VM_CAPABILITIES_IRQ | VM_CAPABILITIES_ATTN;
        if (k->do_hw_op(ibe->parent.intf, IPMI_POWEROFF_CHASSIS, 1) == 0) {
            v |= VM_CAPABILITIES_POWER;
        }
        if (k->do_hw_op(ibe->parent.intf, IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP, 1)
            == 0) {
            v |= VM_CAPABILITIES_GRACEFUL_SHUTDOWN;
        }
        if (k->do_hw_op(ibe->parent.intf, IPMI_RESET_CHASSIS, 1) == 0) {
            v |= VM_CAPABILITIES_RESET;
        }
        if (k->do_hw_op(ibe->parent.intf, IPMI_SEND_NMI, 1) == 0) {
            v |= VM_CAPABILITIES_NMI;
        }
        addchar(ibe, v);
        ibe->outbuf[ibe->outlen] = VM_CMD_CHAR;
        ibe->outlen++;
        ibe->sending_cmd = false;
        continue_send(ibe);
        break;

    case CHR_EVENT_CLOSED:
        if (!ibe->connected) {
            return;
        }
        ibe->connected = false;
        /*
         * Don't hang the OS trying to handle the ATN bit, other end will
         * resend on a reconnect.
         */
        k->set_atn(s, 0, 0);
        if (ibe->waiting_rsp) {
            ibe->waiting_rsp = false;
            ibe->inbuf[1] = ibe->outbuf[1] | 0x04;
            ibe->inbuf[2] = ibe->outbuf[2];
            ibe->inbuf[3] = IPMI_CC_BMC_INIT_IN_PROGRESS;
            k->handle_rsp(s, ibe->outbuf[0], ibe->inbuf + 1, 3);
        }
        break;

    case CHR_EVENT_BREAK:
    case CHR_EVENT_MUX_IN:
    case CHR_EVENT_MUX_OUT:
        /* Ignore */
        break;
    }
}

static void ipmi_bmc_extern_handle_reset(IPMIBmc *b)
{
    IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(b);

    ibe->send_reset = true;
    continue_send(ibe);
}

static void ipmi_bmc_extern_realize(DeviceState *dev, Error **errp)
{
    IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(dev);

    if (!qemu_chr_fe_backend_connected(&ibe->chr)) {
        error_setg(errp, "IPMI external bmc requires chardev attribute");
        return;
    }

    qemu_chr_fe_set_handlers(&ibe->chr, can_receive, receive,
                             chr_event, NULL, ibe, NULL, true);
}

static int ipmi_bmc_extern_post_migrate(void *opaque, int version_id)
{
    IPMIBmcExtern *ibe = opaque;

    /*
     * We don't directly restore waiting_rsp, Instead, we return an
     * error on the interface if a response was being waited for.
     */
    if (ibe->waiting_rsp) {
        IPMIInterface *ii = ibe->parent.intf;
        IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii);

        ibe->waiting_rsp = false;
        ibe->inbuf[1] = ibe->outbuf[1] | 0x04;
        ibe->inbuf[2] = ibe->outbuf[2];
        ibe->inbuf[3] = IPMI_CC_BMC_INIT_IN_PROGRESS;
        iic->handle_rsp(ii, ibe->outbuf[0], ibe->inbuf + 1, 3);
    }
    return 0;
}

static const VMStateDescription vmstate_ipmi_bmc_extern = {
    .name = TYPE_IPMI_BMC_EXTERN,
    .version_id = 1,
    .minimum_version_id = 1,
    .post_load = ipmi_bmc_extern_post_migrate,
    .fields      = (VMStateField[]) {
        VMSTATE_BOOL(send_reset, IPMIBmcExtern),
        VMSTATE_BOOL(waiting_rsp, IPMIBmcExtern),
        VMSTATE_END_OF_LIST()
    }
};

static void ipmi_bmc_extern_init(Object *obj)
{
    IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(obj);

    ibe->extern_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, extern_timeout, ibe);
    vmstate_register(NULL, 0, &vmstate_ipmi_bmc_extern, ibe);
}

static void ipmi_bmc_extern_finalize(Object *obj)
{
    IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(obj);

    timer_del(ibe->extern_timer);
    timer_free(ibe->extern_timer);
}

static Property ipmi_bmc_extern_properties[] = {
    DEFINE_PROP_CHR("chardev", IPMIBmcExtern, chr),
    DEFINE_PROP_END_OF_LIST(),
};

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

    bk->handle_command = ipmi_bmc_extern_handle_command;
    bk->handle_reset = ipmi_bmc_extern_handle_reset;
    dc->hotpluggable = false;
    dc->realize = ipmi_bmc_extern_realize;
    device_class_set_props(dc, ipmi_bmc_extern_properties);
}

static const TypeInfo ipmi_bmc_extern_type = {
    .name          = TYPE_IPMI_BMC_EXTERN,
    .parent        = TYPE_IPMI_BMC,
    .instance_size = sizeof(IPMIBmcExtern),
    .instance_init = ipmi_bmc_extern_init,
    .instance_finalize = ipmi_bmc_extern_finalize,
    .class_init    = ipmi_bmc_extern_class_init,
 };

static void ipmi_bmc_extern_register_types(void)
{
    type_register_static(&ipmi_bmc_extern_type);
}

type_init(ipmi_bmc_extern_register_types)
