/*
 * SCLP event types
 *    Operations Command - Line Mode input
 *    Message            - Line Mode output
 *
 * Copyright IBM, Corp. 2013
 *
 * Authors:
 *  Heinz Graalfs <graalfs@linux.vnet.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or (at your
 * option) any later version.  See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "hw/qdev.h"
#include "qemu/thread.h"
#include "qemu/error-report.h"
#include "sysemu/char.h"

#include "hw/s390x/sclp.h"
#include "hw/s390x/event-facility.h"
#include "hw/s390x/ebcdic.h"

#define SIZE_BUFFER 4096
#define NEWLINE     "\n"

typedef struct OprtnsCommand {
    EventBufferHeader header;
    MDMSU message_unit;
    char data[0];
} QEMU_PACKED OprtnsCommand;

/* max size for line-mode data in 4K SCCB page */
#define SIZE_CONSOLE_BUFFER (SCCB_DATA_LEN - sizeof(OprtnsCommand))

typedef struct SCLPConsoleLM {
    SCLPEvent event;
    CharBackend chr;
    bool echo;                  /* immediate echo of input if true        */
    uint32_t write_errors;      /* errors writing to char layer           */
    uint32_t length;            /* length of byte stream in buffer        */
    uint8_t buf[SIZE_CONSOLE_BUFFER];
} SCLPConsoleLM;

#define TYPE_SCLPLM_CONSOLE "sclplmconsole"
#define SCLPLM_CONSOLE(obj) \
    OBJECT_CHECK(SCLPConsoleLM, (obj), TYPE_SCLPLM_CONSOLE)

/*
*  Character layer call-back functions
 *
 * Allow 1 character at a time
 *
 * Accumulate bytes from character layer in console buffer,
 * event_pending is set when a newline character is encountered
 *
 * The maximum command line length is limited by the maximum
 * space available in an SCCB. Line mode console input is sent
 * truncated to the guest in case it doesn't fit into the SCCB.
 */

static int chr_can_read(void *opaque)
{
    SCLPConsoleLM *scon = opaque;

    if (scon->event.event_pending) {
        return 0;
    }
    return 1;
}

static void chr_read(void *opaque, const uint8_t *buf, int size)
{
    SCLPConsoleLM *scon = opaque;

    assert(size == 1);

    if (*buf == '\r' || *buf == '\n') {
        scon->event.event_pending = true;
        sclp_service_interrupt(0);
        return;
    }
    if (scon->length == SIZE_CONSOLE_BUFFER) {
        /* Eat the character, but still process CR and LF.  */
        return;
    }
    scon->buf[scon->length] = *buf;
    scon->length += 1;
    if (scon->echo) {
        /* XXX this blocks entire thread. Rewrite to use
         * qemu_chr_fe_write and background I/O callbacks */
        qemu_chr_fe_write_all(&scon->chr, buf, size);
    }
}

/* functions to be called by event facility */

static bool can_handle_event(uint8_t type)
{
    return type == SCLP_EVENT_MESSAGE || type == SCLP_EVENT_PMSGCMD;
}

static unsigned int send_mask(void)
{
    return SCLP_EVENT_MASK_OP_CMD | SCLP_EVENT_MASK_PMSGCMD;
}

static unsigned int receive_mask(void)
{
    return SCLP_EVENT_MASK_MSG | SCLP_EVENT_MASK_PMSGCMD;
}

/*
 * Triggered by SCLP's read_event_data
 * - convert ASCII byte stream to EBCDIC and
 * - copy converted data into provided (SCLP) buffer
 */
static int get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size,
                            int avail)
{
    int len;

    SCLPConsoleLM *cons = SCLPLM_CONSOLE(event);

    len = cons->length;
    /* data need to fit into provided SCLP buffer */
    if (len > avail) {
        return 1;
    }

    ebcdic_put(buf, (char *)&cons->buf, len);
    *size = len;
    cons->length = 0;
    /* data provided and no more data pending */
    event->event_pending = false;
    qemu_notify_event();
    return 0;
}

static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
                           int *slen)
{
    int avail, rc;
    size_t src_len;
    uint8_t *to;
    OprtnsCommand *oc = (OprtnsCommand *) evt_buf_hdr;

    if (!event->event_pending) {
        /* no data pending */
        return 0;
    }

    to = (uint8_t *)&oc->data;
    avail = *slen - sizeof(OprtnsCommand);
    rc = get_console_data(event, to, &src_len, avail);
    if (rc) {
        /* data didn't fit, try next SCCB */
        return 1;
    }

    oc->message_unit.mdmsu.gds_id = GDS_ID_MDSMU;
    oc->message_unit.mdmsu.length = cpu_to_be16(sizeof(struct MDMSU));

    oc->message_unit.cpmsu.gds_id = GDS_ID_CPMSU;
    oc->message_unit.cpmsu.length =
        cpu_to_be16(sizeof(struct MDMSU) - sizeof(GdsVector));

    oc->message_unit.text_command.gds_id = GDS_ID_TEXTCMD;
    oc->message_unit.text_command.length =
        cpu_to_be16(sizeof(struct MDMSU) - (2 * sizeof(GdsVector)));

    oc->message_unit.self_def_text_message.key = GDS_KEY_SELFDEFTEXTMSG;
    oc->message_unit.self_def_text_message.length =
        cpu_to_be16(sizeof(struct MDMSU) - (3 * sizeof(GdsVector)));

    oc->message_unit.text_message.key = GDS_KEY_TEXTMSG;
    oc->message_unit.text_message.length =
        cpu_to_be16(sizeof(GdsSubvector) + src_len);

    oc->header.length = cpu_to_be16(sizeof(OprtnsCommand) + src_len);
    oc->header.type = SCLP_EVENT_OPRTNS_COMMAND;
    *slen = avail - src_len;

    return 1;
}

/*
 * Triggered by SCLP's write_event_data
 *  - write console data to character layer
 *  returns < 0 if an error occurred
 */
static int write_console_data(SCLPEvent *event, const uint8_t *buf, int len)
{
    SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);

    if (!qemu_chr_fe_get_driver(&scon->chr)) {
        /* If there's no backend, we can just say we consumed all data. */
        return len;
    }

    /* XXX this blocks entire thread. Rewrite to use
     * qemu_chr_fe_write and background I/O callbacks */
    return qemu_chr_fe_write_all(&scon->chr, buf, len);
}

static int process_mdb(SCLPEvent *event, MDBO *mdbo)
{
    int rc;
    int len;
    uint8_t buffer[SIZE_BUFFER];

    len = be16_to_cpu(mdbo->length);
    len -= sizeof(mdbo->length) + sizeof(mdbo->type)
            + sizeof(mdbo->mto.line_type_flags)
            + sizeof(mdbo->mto.alarm_control)
            + sizeof(mdbo->mto._reserved);

    assert(len <= SIZE_BUFFER);

    /* convert EBCDIC SCLP contents to ASCII console message */
    ascii_put(buffer, mdbo->mto.message, len);
    rc = write_console_data(event, (uint8_t *)NEWLINE, 1);
    if (rc < 0) {
        return rc;
    }
    return write_console_data(event, buffer, len);
}

static int write_event_data(SCLPEvent *event, EventBufferHeader *ebh)
{
    int len;
    int written;
    int errors = 0;
    MDBO *mdbo;
    SclpMsg *data = (SclpMsg *) ebh;
    SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);

    len = be16_to_cpu(data->mdb.header.length);
    if (len < sizeof(data->mdb.header)) {
        return SCLP_RC_INCONSISTENT_LENGTHS;
    }
    len -= sizeof(data->mdb.header);

    /* first check message buffers */
    mdbo = data->mdb.mdbo;
    while (len > 0) {
        if (be16_to_cpu(mdbo->length) > len
                || be16_to_cpu(mdbo->length) == 0) {
            return SCLP_RC_INCONSISTENT_LENGTHS;
        }
        len -= be16_to_cpu(mdbo->length);
        mdbo = (void *) mdbo + be16_to_cpu(mdbo->length);
    }

    /* then execute */
    len = be16_to_cpu(data->mdb.header.length) - sizeof(data->mdb.header);
    mdbo = data->mdb.mdbo;
    while (len > 0) {
        switch (be16_to_cpu(mdbo->type)) {
        case MESSAGE_TEXT:
            /* message text object */
            written = process_mdb(event, mdbo);
            if (written < 0) {
                /* character layer error */
                errors++;
            }
            break;
        default: /* ignore */
            break;
        }
        len -= be16_to_cpu(mdbo->length);
        mdbo = (void *) mdbo + be16_to_cpu(mdbo->length);
    }
    if (errors) {
        scon->write_errors += errors;
    }
    data->header.flags = SCLP_EVENT_BUFFER_ACCEPTED;

    return SCLP_RC_NORMAL_COMPLETION;
}

/* functions for live migration */

static const VMStateDescription vmstate_sclplmconsole = {
    .name = "sclplmconsole",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_BOOL(event.event_pending, SCLPConsoleLM),
        VMSTATE_UINT32(write_errors, SCLPConsoleLM),
        VMSTATE_UINT32(length, SCLPConsoleLM),
        VMSTATE_UINT8_ARRAY(buf, SCLPConsoleLM, SIZE_CONSOLE_BUFFER),
        VMSTATE_END_OF_LIST()
     }
};

/* qemu object creation and initialization functions */

/* tell character layer our call-back functions */

static int console_init(SCLPEvent *event)
{
    static bool console_available;

    SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);

    if (console_available) {
        error_report("Multiple line-mode operator consoles are not supported");
        return -1;
    }
    console_available = true;

    qemu_chr_fe_set_handlers(&scon->chr, chr_can_read,
                             chr_read, NULL, scon, NULL, true);

    return 0;
}

static int console_exit(SCLPEvent *event)
{
    return 0;
}

static void console_reset(DeviceState *dev)
{
   SCLPEvent *event = SCLP_EVENT(dev);
   SCLPConsoleLM *scon = SCLPLM_CONSOLE(event);

   event->event_pending = false;
   scon->length = 0;
   scon->write_errors = 0;
}

static Property console_properties[] = {
    DEFINE_PROP_CHR("chardev", SCLPConsoleLM, chr),
    DEFINE_PROP_UINT32("write_errors", SCLPConsoleLM, write_errors, 0),
    DEFINE_PROP_BOOL("echo", SCLPConsoleLM, echo, true),
    DEFINE_PROP_END_OF_LIST(),
};

static void console_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SCLPEventClass *ec = SCLP_EVENT_CLASS(klass);

    dc->props = console_properties;
    dc->reset = console_reset;
    dc->vmsd = &vmstate_sclplmconsole;
    ec->init = console_init;
    ec->exit = console_exit;
    ec->get_send_mask = send_mask;
    ec->get_receive_mask = receive_mask;
    ec->can_handle_event = can_handle_event;
    ec->read_event_data = read_event_data;
    ec->write_event_data = write_event_data;
    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}

static const TypeInfo sclp_console_info = {
    .name          = "sclplmconsole",
    .parent        = TYPE_SCLP_EVENT,
    .instance_size = sizeof(SCLPConsoleLM),
    .class_init    = console_class_init,
    .class_size    = sizeof(SCLPEventClass),
};

static void register_types(void)
{
    type_register_static(&sclp_console_info);
}

type_init(register_types)
