/*
 * S390 virtio-ccw network boot loading program
 *
 * Copyright 2017 Thomas Huth, Red Hat Inc.
 *
 * Based on the S390 virtio-ccw loading program (main.c)
 * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
 *
 * And based on the network loading code from SLOF (netload.c)
 * Copyright (c) 2004, 2008 IBM Corporation
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 */

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <tftp.h>
#include <ethernet.h>
#include <dhcp.h>
#include <dhcpv6.h>
#include <ipv4.h>
#include <ipv6.h>
#include <dns.h>
#include <time.h>
#include <pxelinux.h>

#include "s390-ccw.h"
#include "virtio.h"

#define DEFAULT_BOOT_RETRIES 10
#define DEFAULT_TFTP_RETRIES 20

extern char _start[];

#define KERNEL_ADDR             ((void *)0L)
#define KERNEL_MAX_SIZE         ((long)_start)
#define ARCH_COMMAND_LINE_SIZE  896              /* Taken from Linux kernel */

/* STSI 3.2.2 offset of first vmdb + offset of uuid inside vmdb */
#define STSI322_VMDB_UUID_OFFSET ((8 + 12) * 4)

char stack[PAGE_SIZE * 8] __attribute__((aligned(PAGE_SIZE)));
IplParameterBlock iplb __attribute__((aligned(PAGE_SIZE)));
static char cfgbuf[2048];

static SubChannelId net_schid = { .one = 1 };
static uint8_t mac[6];
static uint64_t dest_timer;

static uint64_t get_timer_ms(void)
{
    uint64_t clk;

    asm volatile(" stck %0 " : : "Q"(clk) : "memory");

    /* Bit 51 is incremented each microsecond */
    return (clk >> (63 - 51)) / 1000;
}

void set_timer(int val)
{
    dest_timer = get_timer_ms() + val;
}

int get_timer(void)
{
    return dest_timer - get_timer_ms();
}

int get_sec_ticks(void)
{
    return 1000;    /* number of ticks in 1 second */
}

/**
 * Obtain IP and configuration info from DHCP server (either IPv4 or IPv6).
 * @param  fn_ip     contains the following configuration information:
 *                   client MAC, client IP, TFTP-server MAC, TFTP-server IP,
 *                   boot file name
 * @param  retries   Number of DHCP attempts
 * @return           0 : IP and configuration info obtained;
 *                   non-0 : error condition occurred.
 */
static int dhcp(struct filename_ip *fn_ip, int retries)
{
    int i = retries + 1;
    int rc = -1;

    printf("  Requesting information via DHCP:     ");

    dhcpv4_generate_transaction_id();
    dhcpv6_generate_transaction_id();

    do {
        printf("\b\b\b%03d", i - 1);
        if (!--i) {
            printf("\nGiving up after %d DHCP requests\n", retries);
            return -1;
        }
        fn_ip->ip_version = 4;
        rc = dhcpv4(NULL, fn_ip);
        if (rc == -1) {
            fn_ip->ip_version = 6;
            set_ipv6_address(fn_ip->fd, 0);
            rc = dhcpv6(NULL, fn_ip);
            if (rc == 0) {
                memcpy(&fn_ip->own_ip6, get_ipv6_address(), 16);
                break;
            }
        }
        if (rc != -1) {    /* either success or non-dhcp failure */
            break;
        }
    } while (1);
    printf("\b\b\b\bdone\n");

    return rc;
}

/**
 * Seed the random number generator with our mac and current timestamp
 */
static void seed_rng(uint8_t mac[])
{
    uint64_t seed;

    asm volatile(" stck %0 " : : "Q"(seed) : "memory");
    seed ^= (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5];
    srand(seed);
}

static int tftp_load(filename_ip_t *fnip, void *buffer, int len)
{
    tftp_err_t tftp_err;
    int rc;

    rc = tftp(fnip, buffer, len, DEFAULT_TFTP_RETRIES, &tftp_err);

    if (rc < 0) {
        /* Make sure that error messages are put into a new line */
        printf("\n  ");
    }

    if (rc > 1024) {
        printf("  TFTP: Received %s (%d KBytes)\n", fnip->filename, rc / 1024);
    } else if (rc > 0) {
        printf("  TFTP: Received %s (%d Bytes)\n", fnip->filename, rc);
    } else {
        const char *errstr = NULL;
        int ecode;
        tftp_get_error_info(fnip, &tftp_err, rc, &errstr, &ecode);
        printf("TFTP error: %s\n", errstr ? errstr : "unknown error");
    }

    return rc;
}

static int net_init(filename_ip_t *fn_ip)
{
    int rc;

    memset(fn_ip, 0, sizeof(filename_ip_t));

    rc = virtio_net_init(mac);
    if (rc < 0) {
        puts("Could not initialize network device");
        return -101;
    }
    fn_ip->fd = rc;

    printf("  Using MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
           mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

    set_mac_address(mac);    /* init ethernet layer */
    seed_rng(mac);

    rc = dhcp(fn_ip, DEFAULT_BOOT_RETRIES);
    if (rc >= 0) {
        if (fn_ip->ip_version == 4) {
            set_ipv4_address(fn_ip->own_ip);
        }
    } else {
        puts("Could not get IP address");
        return -101;
    }

    if (fn_ip->ip_version == 4) {
        printf("  Using IPv4 address: %d.%d.%d.%d\n",
              (fn_ip->own_ip >> 24) & 0xFF, (fn_ip->own_ip >> 16) & 0xFF,
              (fn_ip->own_ip >>  8) & 0xFF, fn_ip->own_ip & 0xFF);
    } else if (fn_ip->ip_version == 6) {
        char ip6_str[40];
        ipv6_to_str(fn_ip->own_ip6.addr, ip6_str);
        printf("  Using IPv6 address: %s\n", ip6_str);
    }

    if (rc == -2) {
        printf("ARP request to TFTP server (%d.%d.%d.%d) failed\n",
               (fn_ip->server_ip >> 24) & 0xFF, (fn_ip->server_ip >> 16) & 0xFF,
               (fn_ip->server_ip >>  8) & 0xFF, fn_ip->server_ip & 0xFF);
        return -102;
    }
    if (rc == -4 || rc == -3) {
        puts("Can't obtain TFTP server IP address");
        return -107;
    }

    printf("  Using TFTP server: ");
    if (fn_ip->ip_version == 4) {
        printf("%d.%d.%d.%d\n",
               (fn_ip->server_ip >> 24) & 0xFF, (fn_ip->server_ip >> 16) & 0xFF,
               (fn_ip->server_ip >>  8) & 0xFF, fn_ip->server_ip & 0xFF);
    } else if (fn_ip->ip_version == 6) {
        char ip6_str[40];
        ipv6_to_str(fn_ip->server_ip6.addr, ip6_str);
        printf("%s\n", ip6_str);
    }

    if (strlen(fn_ip->filename) > 0) {
        printf("  Bootfile name: '%s'\n", fn_ip->filename);
    }

    return rc;
}

static void net_release(filename_ip_t *fn_ip)
{
    if (fn_ip->ip_version == 4) {
        dhcp_send_release(fn_ip->fd);
    }
}

/**
 * Retrieve the Universally Unique Identifier of the VM.
 * @return UUID string, or NULL in case of errors
 */
static const char *get_uuid(void)
{
    register int r0 asm("0");
    register int r1 asm("1");
    uint8_t *mem, *buf, uuid[16];
    int i, cc, chk = 0;
    static char uuid_str[37];

    mem = malloc(2 * PAGE_SIZE);
    if (!mem) {
        puts("Out of memory ... can not get UUID.");
        return NULL;
    }
    buf = (uint8_t *)(((uint64_t)mem + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
    memset(buf, 0, PAGE_SIZE);

    /* Get SYSIB 3.2.2 */
    r0 = (3 << 28) | 2;
    r1 = 2;
    asm volatile(" stsi 0(%[addr])\n"
                 " ipm  %[cc]\n"
                 " srl  %[cc],28\n"
                 : [cc] "=d" (cc)
                 : "d" (r0), "d" (r1), [addr] "a" (buf)
                 : "cc", "memory");
    if (cc) {
        return NULL;
    }

    for (i = 0; i < 16; i++) {
        uuid[i] = buf[STSI322_VMDB_UUID_OFFSET + i];
        chk |= uuid[i];
    }
    free(mem);
    if (!chk) {
        return NULL;
    }

    sprintf(uuid_str, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
            "%02x%02x%02x%02x%02x%02x", uuid[0], uuid[1], uuid[2], uuid[3],
            uuid[4], uuid[5], uuid[6], uuid[7], uuid[8], uuid[9], uuid[10],
            uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);

    return uuid_str;
}

/**
 * Load a kernel with initrd (i.e. with the information that we've got from
 * a pxelinux.cfg config file)
 */
static int load_kernel_with_initrd(filename_ip_t *fn_ip,
                                   struct pl_cfg_entry *entry)
{
    int rc;

    printf("Loading pxelinux.cfg entry '%s'\n", entry->label);

    if (!entry->kernel) {
        printf("Kernel entry is missing!\n");
        return -1;
    }

    strncpy(fn_ip->filename, entry->kernel, sizeof(fn_ip->filename));
    rc = tftp_load(fn_ip, KERNEL_ADDR, KERNEL_MAX_SIZE);
    if (rc < 0) {
        return rc;
    }

    if (entry->initrd) {
        uint64_t iaddr = (rc + 0xfff) & ~0xfffUL;

        strncpy(fn_ip->filename, entry->initrd, sizeof(fn_ip->filename));
        rc = tftp_load(fn_ip, (void *)iaddr, KERNEL_MAX_SIZE - iaddr);
        if (rc < 0) {
            return rc;
        }
        /* Patch location and size: */
        *(uint64_t *)0x10408 = iaddr;
        *(uint64_t *)0x10410 = rc;
        rc += iaddr;
    }

    if (entry->append) {
        strncpy((char *)0x10480, entry->append, ARCH_COMMAND_LINE_SIZE);
    }

    return rc;
}

#define MAX_PXELINUX_ENTRIES 16

static int net_try_pxelinux_cfg(filename_ip_t *fn_ip)
{
    struct pl_cfg_entry entries[MAX_PXELINUX_ENTRIES];
    int num_ent, def_ent = 0;

    num_ent = pxelinux_load_parse_cfg(fn_ip, mac, get_uuid(),
                                      DEFAULT_TFTP_RETRIES,
                                      cfgbuf, sizeof(cfgbuf),
                                      entries, MAX_PXELINUX_ENTRIES, &def_ent);
    if (num_ent > 0) {
        return load_kernel_with_initrd(fn_ip, &entries[def_ent]);
    }

    return -1;
}

/**
 * Load via information from a .INS file (which can be found on CD-ROMs
 * for example)
 */
static int handle_ins_cfg(filename_ip_t *fn_ip, char *cfg, int cfgsize)
{
    char *ptr;
    int rc = -1, llen;
    void *destaddr;
    char *insbuf = cfg;

    ptr = strchr(insbuf, '\n');
    if (!ptr) {
        puts("Does not seem to be a valid .INS file");
        return -1;
    }

    *ptr = 0;
    printf("\nParsing .INS file:\n %s\n", &insbuf[2]);

    insbuf = ptr + 1;
    while (*insbuf && insbuf < cfg + cfgsize) {
        ptr = strchr(insbuf, '\n');
        if (ptr) {
            *ptr = 0;
        }
        llen = strlen(insbuf);
        if (!llen) {
            insbuf = ptr + 1;
            continue;
        }
        ptr = strchr(insbuf, ' ');
        if (!ptr) {
            puts("Missing space separator in .INS file");
            return -1;
        }
        *ptr = 0;
        strncpy(fn_ip->filename, insbuf, sizeof(fn_ip->filename));
        destaddr = (char *)atol(ptr + 1);
        rc = tftp_load(fn_ip, destaddr, (long)_start - (long)destaddr);
        if (rc <= 0) {
            break;
        }
        insbuf += llen + 1;
    }

    return rc;
}

static int net_try_direct_tftp_load(filename_ip_t *fn_ip)
{
    int rc;
    void *loadaddr = (void *)0x2000;  /* Load right after the low-core */

    rc = tftp_load(fn_ip, loadaddr, KERNEL_MAX_SIZE - (long)loadaddr);
    if (rc < 0) {
        return rc;
    } else if (rc < 8) {
        printf("'%s' is too small (%i bytes only).\n", fn_ip->filename, rc);
        return -1;
    }

    /* Check whether it is a configuration file instead of a kernel */
    if (rc < sizeof(cfgbuf) - 1) {
        memcpy(cfgbuf, loadaddr, rc);
        cfgbuf[rc] = 0;    /* Make sure that it is NUL-terminated */
        if (!strncmp("* ", cfgbuf, 2)) {
            return handle_ins_cfg(fn_ip, cfgbuf, rc);
        }
        /*
         * pxelinux.cfg support via bootfile name is just here for developers'
         * convenience (it eases testing with the built-in DHCP server of QEMU
         * that does not support RFC 5071). The official way to configure a
         * pxelinux.cfg file name is to use DHCP options 209 and 210 instead.
         * So only use the pxelinux.cfg parser here for files that start with
         * a magic comment string.
         */
        if (!strncasecmp("# pxelinux", cfgbuf, 10)) {
            struct pl_cfg_entry entries[MAX_PXELINUX_ENTRIES];
            int num_ent, def_ent = 0;

            num_ent = pxelinux_parse_cfg(cfgbuf, sizeof(cfgbuf), entries,
                                         MAX_PXELINUX_ENTRIES, &def_ent);
            if (num_ent <= 0) {
                return -1;
            }
            return load_kernel_with_initrd(fn_ip, &entries[def_ent]);
        }
    }

    /* Move kernel to right location */
    memmove(KERNEL_ADDR, loadaddr, rc);

    return rc;
}

void panic(const char *string)
{
    sclp_print(string);
    for (;;) {
        disabled_wait();
    }
}

void write_subsystem_identification(void)
{
    SubChannelId *schid = (SubChannelId *) 184;
    uint32_t *zeroes = (uint32_t *) 188;

    *schid = net_schid;
    *zeroes = 0;
}

static bool find_net_dev(Schib *schib, int dev_no)
{
    int i, r;

    for (i = 0; i < 0x10000; i++) {
        net_schid.sch_no = i;
        r = stsch_err(net_schid, schib);
        if (r == 3 || r == -EIO) {
            break;
        }
        if (!schib->pmcw.dnv) {
            continue;
        }
        if (!virtio_is_supported(net_schid)) {
            continue;
        }
        if (virtio_get_device_type() != VIRTIO_ID_NET) {
            continue;
        }
        if (dev_no < 0 || schib->pmcw.dev == dev_no) {
            return true;
        }
    }

    return false;
}

static void virtio_setup(void)
{
    Schib schib;
    int ssid;
    bool found = false;
    uint16_t dev_no;

    /*
     * We unconditionally enable mss support. In every sane configuration,
     * this will succeed; and even if it doesn't, stsch_err() can deal
     * with the consequences.
     */
    enable_mss_facility();

    if (store_iplb(&iplb)) {
        IPL_assert(iplb.pbt == S390_IPL_TYPE_CCW, "IPL_TYPE_CCW expected");
        dev_no = iplb.ccw.devno;
        debug_print_int("device no. ", dev_no);
        net_schid.ssid = iplb.ccw.ssid & 0x3;
        debug_print_int("ssid ", net_schid.ssid);
        found = find_net_dev(&schib, dev_no);
    } else {
        for (ssid = 0; ssid < 0x3; ssid++) {
            net_schid.ssid = ssid;
            found = find_net_dev(&schib, -1);
            if (found) {
                break;
            }
        }
    }

    IPL_assert(found, "No virtio net device found");
}

void main(void)
{
    filename_ip_t fn_ip;
    int rc, fnlen;

    sclp_setup();
    sclp_print("Network boot starting...\n");

    virtio_setup();

    rc = net_init(&fn_ip);
    if (rc) {
        panic("Network initialization failed. Halting.\n");
    }

    fnlen = strlen(fn_ip.filename);
    if (fnlen > 0 && fn_ip.filename[fnlen - 1] != '/') {
        rc = net_try_direct_tftp_load(&fn_ip);
    }
    if (rc <= 0) {
        rc = net_try_pxelinux_cfg(&fn_ip);
    }

    net_release(&fn_ip);

    if (rc > 0) {
        sclp_print("Network loading done, starting kernel...\n");
        jump_to_low_kernel();
    }

    panic("Failed to load OS from network\n");
}
