/*
 * SCLP ASCII access driver
 *
 * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
 *
 * 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 "libc.h"
#include "s390-ccw.h"
#include "sclp.h"

long write(int fd, const void *str, size_t len);

static char _sccb[PAGE_SIZE] __attribute__((__aligned__(4096)));

const unsigned char ebc2asc[256] =
      /* 0123456789abcdef0123456789abcdef */
        "................................" /* 1F */
        "................................" /* 3F */
        " ...........<(+|&.........!$*);." /* 5F first.chr.here.is.real.space */
        "-/.........,%_>?.........`:#@'=\""/* 7F */
        ".abcdefghi.......jklmnopqr......" /* 9F */
        "..stuvwxyz......................" /* BF */
        ".ABCDEFGHI.......JKLMNOPQR......" /* DF */
        "..STUVWXYZ......0123456789......";/* FF */

/* Perform service call. Return 0 on success, non-zero otherwise. */
static int sclp_service_call(unsigned int command, void *sccb)
{
        int cc;

        asm volatile(
                "       .insn   rre,0xb2200000,%1,%2\n"  /* servc %1,%2 */
                "       ipm     %0\n"
                "       srl     %0,28"
                : "=&d" (cc) : "d" (command), "a" (__pa(sccb))
                : "cc", "memory");
        consume_sclp_int();
        if (cc == 3)
                return -EIO;
        if (cc == 2)
                return -EBUSY;
        return 0;
}

void sclp_set_write_mask(uint32_t receive_mask, uint32_t send_mask)
{
    WriteEventMask *sccb = (void *)_sccb;

    sccb->h.length = sizeof(WriteEventMask);
    sccb->mask_length = sizeof(unsigned int);
    sccb->cp_receive_mask = receive_mask;
    sccb->cp_send_mask = send_mask;

    sclp_service_call(SCLP_CMD_WRITE_EVENT_MASK, sccb);
}

void sclp_setup(void)
{
    sclp_set_write_mask(0, SCLP_EVENT_MASK_MSG_ASCII);
}

long write(int fd, const void *str, size_t len)
{
    WriteEventData *sccb = (void *)_sccb;
    const char *p = str;
    size_t data_len = 0;
    size_t i;

    if (fd != 1 && fd != 2) {
        return -EIO;
    }

    for (i = 0; i < len; i++) {
        if ((data_len + 1) >= SCCB_DATA_LEN) {
            /* We would overflow the sccb buffer, abort early */
            len = i;
            break;
        }

        if (*p == '\n') {
            /* Terminal emulators might need \r\n, so generate it */
            sccb->data[data_len++] = '\r';
        }

        sccb->data[data_len++] = *p;
        p++;
    }

    sccb->h.length = sizeof(WriteEventData) + data_len;
    sccb->h.function_code = SCLP_FC_NORMAL_WRITE;
    sccb->ebh.length = sizeof(EventBufferHeader) + data_len;
    sccb->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
    sccb->ebh.flags = 0;

    sclp_service_call(SCLP_CMD_WRITE_EVENT_DATA, sccb);

    return len;
}

void sclp_print(const char *str)
{
    write(1, str, strlen(str));
}

void sclp_get_loadparm_ascii(char *loadparm)
{

    ReadInfo *sccb = (void *)_sccb;

    memset((char *)_sccb, 0, sizeof(ReadInfo));
    sccb->h.length = SCCB_SIZE;
    if (!sclp_service_call(SCLP_CMDW_READ_SCP_INFO, sccb)) {
        ebcdic_to_ascii((char *) sccb->loadparm, loadparm, LOADPARM_LEN);
    }
}

int sclp_read(char *str, size_t count)
{
    ReadEventData *sccb = (void *)_sccb;
    char *buf = (char *)(&sccb->ebh) + 7;

    /* If count exceeds max buffer size, then restrict it to the max size */
    if (count > SCCB_SIZE - 8) {
        count = SCCB_SIZE - 8;
    }

    sccb->h.length = SCCB_SIZE;
    sccb->h.function_code = SCLP_UNCONDITIONAL_READ;

    sclp_service_call(SCLP_CMD_READ_EVENT_DATA, sccb);
    memcpy(str, buf, count);

    return sccb->ebh.length - 7;
}
