/*
 * SCLP event type
 *    Ascii Console Data (VT220 Console)
 *
 * Copyright IBM, Corp. 2012
 *
 * Authors:
 *  Heinz Graalfs <graalfs@de.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 "hw/s390x/sclp.h"
#include "hw/s390x/event-facility.h"
#include "sysemu/char.h"

typedef struct ASCIIConsoleData {
    EventBufferHeader ebh;
    char data[0];
} QEMU_PACKED ASCIIConsoleData;

/* max size for ASCII data in 4K SCCB page */
#define SIZE_BUFFER_VT220 4080

typedef struct SCLPConsole {
    SCLPEvent event;
    CharDriverState *chr;
    uint8_t iov[SIZE_BUFFER_VT220];
    uint32_t iov_sclp;      /* offset in buf for SCLP read operation       */
    uint32_t iov_bs;        /* offset in buf for char layer read operation */
    uint32_t iov_data_len;  /* length of byte stream in buffer             */
    uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP     */
    bool notify;            /* qemu_notify_event() req'd if true           */
} SCLPConsole;

#define TYPE_SCLP_CONSOLE "sclpconsole"
#define SCLP_CONSOLE(obj) \
    OBJECT_CHECK(SCLPConsole, (obj), TYPE_SCLP_CONSOLE)

/* character layer call-back functions */

/* Return number of bytes that fit into iov buffer */
static int chr_can_read(void *opaque)
{
    SCLPConsole *scon = opaque;
    int avail = SIZE_BUFFER_VT220 - scon->iov_data_len;

    if (avail == 0) {
        scon->notify = true;
    }
    return avail;
}

/* Send data from a char device over to the guest */
static void chr_read(void *opaque, const uint8_t *buf, int size)
{
    SCLPConsole *scon = opaque;

    assert(scon);
    /* read data must fit into current buffer */
    assert(size <= SIZE_BUFFER_VT220 - scon->iov_data_len);

    /* put byte-stream from character layer into buffer */
    memcpy(&scon->iov[scon->iov_bs], buf, size);
    scon->iov_data_len += size;
    scon->iov_sclp_rest += size;
    scon->iov_bs += size;
    scon->event.event_pending = true;
    sclp_service_interrupt(0);
}

/* functions to be called by event facility */

static bool can_handle_event(uint8_t type)
{
    return type == SCLP_EVENT_ASCII_CONSOLE_DATA;
}

static unsigned int send_mask(void)
{
    return SCLP_EVENT_MASK_MSG_ASCII;
}

static unsigned int receive_mask(void)
{
    return SCLP_EVENT_MASK_MSG_ASCII;
}

/* triggered by SCLP's read_event_data -
 * copy console data byte-stream into provided (SCLP) buffer
 */
static void get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size,
                             int avail)
{
    SCLPConsole *cons = SCLP_CONSOLE(event);

    /* first byte is hex 0 saying an ascii string follows */
    *buf++ = '\0';
    avail--;
    /* if all data fit into provided SCLP buffer */
    if (avail >= cons->iov_sclp_rest) {
        /* copy character byte-stream to SCLP buffer */
        memcpy(buf, &cons->iov[cons->iov_sclp], cons->iov_sclp_rest);
        *size = cons->iov_sclp_rest + 1;
        cons->iov_sclp = 0;
        cons->iov_bs = 0;
        cons->iov_data_len = 0;
        cons->iov_sclp_rest = 0;
        event->event_pending = false;
        /* data provided and no more data pending */
    } else {
        /* if provided buffer is too small, just copy part */
        memcpy(buf, &cons->iov[cons->iov_sclp], avail);
        *size = avail + 1;
        cons->iov_sclp_rest -= avail;
        cons->iov_sclp += avail;
        /* more data pending */
    }
    if (cons->notify) {
        cons->notify = false;
        qemu_notify_event();
    }
}

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

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

    to = (uint8_t *)&acd->data;
    avail = *slen - sizeof(ASCIIConsoleData);
    get_console_data(event, to, &src_len, avail);

    acd->ebh.length = cpu_to_be16(sizeof(ASCIIConsoleData) + src_len);
    acd->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
    acd->ebh.flags |= SCLP_EVENT_BUFFER_ACCEPTED;
    *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 ssize_t write_console_data(SCLPEvent *event, const uint8_t *buf,
                                  size_t len)
{
    SCLPConsole *scon = SCLP_CONSOLE(event);

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

    return qemu_chr_fe_write_all(scon->chr, buf, len);
}

static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
{
    int rc;
    int length;
    ssize_t written;
    ASCIIConsoleData *acd = (ASCIIConsoleData *) evt_buf_hdr;

    length = be16_to_cpu(evt_buf_hdr->length) - sizeof(EventBufferHeader);
    written = write_console_data(event, (uint8_t *)acd->data, length);

    rc = SCLP_RC_NORMAL_COMPLETION;
    /* set event buffer accepted flag */
    evt_buf_hdr->flags |= SCLP_EVENT_BUFFER_ACCEPTED;

    /* written will be zero if a pty is not connected - don't treat as error */
    if (written < 0) {
        /* event buffer not accepted due to error in character layer */
        evt_buf_hdr->flags &= ~(SCLP_EVENT_BUFFER_ACCEPTED);
        rc = SCLP_RC_CONTAINED_EQUIPMENT_CHECK;
    }

    return rc;
}

static const VMStateDescription vmstate_sclpconsole = {
    .name = "sclpconsole",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_BOOL(event.event_pending, SCLPConsole),
        VMSTATE_UINT8_ARRAY(iov, SCLPConsole, SIZE_BUFFER_VT220),
        VMSTATE_UINT32(iov_sclp, SCLPConsole),
        VMSTATE_UINT32(iov_bs, SCLPConsole),
        VMSTATE_UINT32(iov_data_len, SCLPConsole),
        VMSTATE_UINT32(iov_sclp_rest, SCLPConsole),
        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;

    SCLPConsole *scon = SCLP_CONSOLE(event);

    if (console_available) {
        error_report("Multiple VT220 operator consoles are not supported");
        return -1;
    }
    console_available = true;
    if (scon->chr) {
        qemu_chr_add_handlers(scon->chr, chr_can_read,
                              chr_read, NULL, scon);
    }

    return 0;
}

static void console_reset(DeviceState *dev)
{
   SCLPEvent *event = SCLP_EVENT(dev);
   SCLPConsole *scon = SCLP_CONSOLE(event);

   event->event_pending = false;
   scon->iov_sclp = 0;
   scon->iov_bs = 0;
   scon->iov_data_len = 0;
   scon->iov_sclp_rest = 0;
   scon->notify = false;
}

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

static Property console_properties[] = {
    DEFINE_PROP_CHR("chardev", SCLPConsole, chr),
    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_sclpconsole;
    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          = "sclpconsole",
    .parent        = TYPE_SCLP_EVENT,
    .instance_size = sizeof(SCLPConsole),
    .class_init    = console_class_init,
    .class_size    = sizeof(SCLPEventClass),
};

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

type_init(register_types)
