/*
 * QEMU S390 Interactive Boot Menu
 *
 * Copyright 2018 IBM Corp.
 * Author: Collin L. Walling <walling@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 <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "s390-ccw.h"
#include "sclp.h"
#include "s390-time.h"

#define KEYCODE_NO_INP '\0'
#define KEYCODE_ESCAPE '\033'
#define KEYCODE_BACKSP '\177'
#define KEYCODE_ENTER  '\r'

/* Offsets from zipl fields to zipl banner start */
#define ZIPL_TIMEOUT_OFFSET 138
#define ZIPL_FLAG_OFFSET    140

#define TOD_CLOCK_MILLISECOND   0x3e8000

#define LOW_CORE_EXTERNAL_INT_ADDR   0x86
#define CLOCK_COMPARATOR_INT         0X1004

static uint8_t flag;
static uint64_t timeout;

static inline void enable_clock_int(void)
{
    uint64_t tmp = 0;

    asm volatile(
        "stctg      %%c0,%%c0,%0\n"
        "oi         6+%0, 0x8\n"
        "lctlg      %%c0,%%c0,%0"
        : : "Q" (tmp) : "memory"
    );
}

static inline void disable_clock_int(void)
{
    uint64_t tmp = 0;

    asm volatile(
        "stctg      %%c0,%%c0,%0\n"
        "ni         6+%0, 0xf7\n"
        "lctlg      %%c0,%%c0,%0"
        : : "Q" (tmp) : "memory"
    );
}

static inline void set_clock_comparator(uint64_t time)
{
    asm volatile("sckc %0" : : "Q" (time));
}

static inline bool check_clock_int(void)
{
    uint16_t *code = (uint16_t *)LOW_CORE_EXTERNAL_INT_ADDR;

    consume_sclp_int();

    return *code == CLOCK_COMPARATOR_INT;
}

static int read_prompt(char *buf, size_t len)
{
    char inp[2] = {};
    uint8_t idx = 0;
    uint64_t time;

    if (timeout) {
        time = get_clock() + timeout * TOD_CLOCK_MILLISECOND;
        set_clock_comparator(time);
        enable_clock_int();
        timeout = 0;
    }

    while (!check_clock_int()) {

        sclp_read(inp, 1); /* Process only one character at a time */

        switch (inp[0]) {
        case KEYCODE_NO_INP:
        case KEYCODE_ESCAPE:
            continue;
        case KEYCODE_BACKSP:
            if (idx > 0) {
                buf[--idx] = 0;
                printf("\b \b");
            }
            continue;
        case KEYCODE_ENTER:
            disable_clock_int();
            return idx;
        default:
            /* Echo input and add to buffer */
            if (idx < len) {
                buf[idx++] = inp[0];
                printf("%s", inp);
            }
        }
    }

    disable_clock_int();
    *buf = 0;

    return 0;
}

static int get_index(void)
{
    char buf[11];
    int len;
    int i;

    memset(buf, 0, sizeof(buf));

    sclp_set_write_mask(SCLP_EVENT_MASK_MSG_ASCII, SCLP_EVENT_MASK_MSG_ASCII);

    len = read_prompt(buf, sizeof(buf) - 1);

    sclp_set_write_mask(0, SCLP_EVENT_MASK_MSG_ASCII);

    /* If no input, boot default */
    if (len == 0) {
        return 0;
    }

    /* Check for erroneous input */
    for (i = 0; i < len; i++) {
        if (!isdigit((unsigned char)buf[i])) {
            return -1;
        }
    }

    return atoi(buf);
}

static void boot_menu_prompt(bool retry)
{
    if (retry) {
        printf("\nError: undefined configuration"
                   "\nPlease choose:\n");
    } else if (timeout > 0) {
        printf("Please choose (default will boot in %d seconds):\n",
               (int)(timeout / 1000));
    } else {
        puts("Please choose:");
    }
}

static int get_boot_index(bool *valid_entries)
{
    int boot_index;
    bool retry = false;

    do {
        boot_menu_prompt(retry);
        boot_index = get_index();
        retry = true;
    } while (boot_index < 0 || boot_index >= MAX_BOOT_ENTRIES ||
             !valid_entries[boot_index]);

    printf("\nBooting entry #%d", boot_index);

    return boot_index;
}

/* Returns the entry number that was printed */
static int zipl_print_entry(const char *data, size_t len)
{
    char buf[len + 2];

    ebcdic_to_ascii(data, buf, len);
    buf[len] = '\n';
    buf[len + 1] = '\0';

    printf("%s", buf);

    return buf[0] == ' ' ? atoi(buf + 1) : atoi(buf);
}

int menu_get_zipl_boot_index(const char *menu_data)
{
    size_t len;
    int entry;
    bool valid_entries[MAX_BOOT_ENTRIES] = {false};
    uint16_t zipl_flag = *(uint16_t *)(menu_data - ZIPL_FLAG_OFFSET);
    uint16_t zipl_timeout = *(uint16_t *)(menu_data - ZIPL_TIMEOUT_OFFSET);

    if (flag == QIPL_FLAG_BM_OPTS_ZIPL) {
        if (!zipl_flag) {
            return 0; /* Boot default */
        }
        /* zipl stores timeout as seconds */
        timeout = zipl_timeout * 1000;
    }

    /* Print banner */
    puts("s390-ccw zIPL Boot Menu\n");
    menu_data += strlen(menu_data) + 1;

    /* Print entries */
    while (*menu_data) {
        len = strlen(menu_data);
        entry = zipl_print_entry(menu_data, len);
        menu_data += len + 1;

        valid_entries[entry] = true;

        if (entry == 0) {
            printf("\n");
        }
    }

    printf("\n");
    return get_boot_index(valid_entries);
}

int menu_get_enum_boot_index(bool *valid_entries)
{
    int i;

    puts("s390-ccw Enumerated Boot Menu.\n");

    for (i = 0; i < MAX_BOOT_ENTRIES; i++) {
        if (valid_entries[i]) {
            if (i < 10) {
                printf(" ");
            }
            printf("[%d]", i);
            if (i == 0) {
                printf(" default\n");
            }
            printf("\n");
        }
    }

    printf("\n");
    return get_boot_index(valid_entries);
}

void menu_set_parms(uint8_t boot_menu_flag, uint32_t boot_menu_timeout)
{
    flag = boot_menu_flag;
    timeout = boot_menu_timeout;
}

bool menu_is_enabled_zipl(void)
{
    return flag & (QIPL_FLAG_BM_OPTS_CMD | QIPL_FLAG_BM_OPTS_ZIPL);
}

bool menu_is_enabled_enum(void)
{
    return flag & QIPL_FLAG_BM_OPTS_CMD;
}
