// Paravirtualization support.
//
// Copyright (C) 2009 Red Hat Inc.
//
// Authors:
//  Gleb Natapov <gnatapov@redhat.com>
//
// This file may be distributed under the terms of the GNU LGPLv3 license.

#include "config.h" // CONFIG_COREBOOT
#include "util.h" // ntoh[ls]
#include "ioport.h" // outw
#include "paravirt.h" // qemu_cfg_port_probe
#include "smbios.h" // struct smbios_structure_header

int qemu_cfg_present;

static void
qemu_cfg_select(u16 f)
{
    outw(f, PORT_QEMU_CFG_CTL);
}

static void
qemu_cfg_read(u8 *buf, int len)
{
    while (len--)
        *(buf++) = inb(PORT_QEMU_CFG_DATA);
}

static void
qemu_cfg_skip(int len)
{
    while (len--)
        inb(PORT_QEMU_CFG_DATA);
}

static void
qemu_cfg_read_entry(void *buf, int e, int len)
{
    qemu_cfg_select(e);
    qemu_cfg_read(buf, len);
}

void qemu_cfg_port_probe(void)
{
    char *sig = "QEMU";
    int i;

    if (CONFIG_COREBOOT)
        return;

    qemu_cfg_present = 1;

    qemu_cfg_select(QEMU_CFG_SIGNATURE);

    for (i = 0; i < 4; i++)
        if (inb(PORT_QEMU_CFG_DATA) != sig[i]) {
            qemu_cfg_present = 0;
            break;
        }
    dprintf(4, "qemu_cfg_present=%d\n", qemu_cfg_present);
}

void qemu_cfg_get_uuid(u8 *uuid)
{
    if (!qemu_cfg_present)
        return;

    qemu_cfg_read_entry(uuid, QEMU_CFG_UUID, 16);
}

int qemu_cfg_show_boot_menu(void)
{
    u16 v;
    if (!qemu_cfg_present)
        return 1;

    qemu_cfg_read_entry(&v, QEMU_CFG_BOOT_MENU, sizeof(v));

    return v;
}

int qemu_cfg_irq0_override(void)
{
    u8 v;

    if (!qemu_cfg_present)
        return 0;

    qemu_cfg_read_entry(&v, QEMU_CFG_IRQ0_OVERRIDE, sizeof(v));

    return v;
}

u16 qemu_cfg_acpi_additional_tables(void)
{
    u16 cnt;

    if (!qemu_cfg_present)
        return 0;

    qemu_cfg_read_entry(&cnt, QEMU_CFG_ACPI_TABLES, sizeof(cnt));

    return cnt;
}

u16 qemu_cfg_next_acpi_table_len(void)
{
    u16 len;

    qemu_cfg_read((u8*)&len, sizeof(len));

    return len;
}

void* qemu_cfg_next_acpi_table_load(void *addr, u16 len)
{
    qemu_cfg_read(addr, len);
    return addr;
}

u16 qemu_cfg_smbios_entries(void)
{
    u16 cnt;

    if (!qemu_cfg_present)
        return 0;

    qemu_cfg_read_entry(&cnt, QEMU_CFG_SMBIOS_ENTRIES, sizeof(cnt));

    return cnt;
}

struct smbios_header {
    u16 length;
    u8 type;
} PACKED;

struct smbios_field {
    struct smbios_header header;
    u8 type;
    u16 offset;
    u8 data[];
} PACKED;

struct smbios_table {
    struct smbios_header header;
    u8 data[];
} PACKED;

#define SMBIOS_FIELD_ENTRY 0
#define SMBIOS_TABLE_ENTRY 1

size_t qemu_cfg_smbios_load_field(int type, size_t offset, void *addr)
{
    int i;

    for (i = qemu_cfg_smbios_entries(); i > 0; i--) {
        struct smbios_field field;

        qemu_cfg_read((u8 *)&field, sizeof(struct smbios_header));
        field.header.length -= sizeof(struct smbios_header);

        if (field.header.type != SMBIOS_FIELD_ENTRY) {
            qemu_cfg_skip(field.header.length);
            continue;
        }

        qemu_cfg_read((u8 *)&field.type,
                      sizeof(field) - sizeof(struct smbios_header));
        field.header.length -= sizeof(field) - sizeof(struct smbios_header);

        if (field.type != type || field.offset != offset) {
            qemu_cfg_skip(field.header.length);
            continue;
        }

        qemu_cfg_read(addr, field.header.length);
        return (size_t)field.header.length;
    }
    return 0;
}

int qemu_cfg_smbios_load_external(int type, char **p, unsigned *nr_structs,
                                  unsigned *max_struct_size, char *end)
{
    static u64 used_bitmap[4] = { 0 };
    char *start = *p;
    int i;

    /* Check if we've already reported these tables */
    if (used_bitmap[(type >> 6) & 0x3] & (1ULL << (type & 0x3f)))
        return 1;

    /* Don't introduce spurious end markers */
    if (type == 127)
        return 0;

    for (i = qemu_cfg_smbios_entries(); i > 0; i--) {
        struct smbios_table table;
        struct smbios_structure_header *header = (void *)*p;
        int string;

        qemu_cfg_read((u8 *)&table, sizeof(struct smbios_header));
        table.header.length -= sizeof(struct smbios_header);

        if (table.header.type != SMBIOS_TABLE_ENTRY) {
            qemu_cfg_skip(table.header.length);
            continue;
        }

        if (end - *p < sizeof(struct smbios_structure_header)) {
            dprintf(1, "No more memory for additional smbios tables\n");
            break;
        }

        qemu_cfg_read((u8 *)*p, sizeof(struct smbios_structure_header));
        table.header.length -= sizeof(struct smbios_structure_header);

        if (header->type != type) {
            qemu_cfg_skip(table.header.length);
            continue;
        }

        *p += sizeof(struct smbios_structure_header);

        /* Entries end with a double NULL char, if there's a string at
         * the end (length is greater than formatted length), the string
         * terminator provides the first NULL. */
        string = header->length < table.header.length +
                 sizeof(struct smbios_structure_header);

        /* Read the rest and terminate the entry */
        if (end - *p < table.header.length) {
            dprintf(1, "No memory for smbios table %d\n", header->type);
            *p -= sizeof(struct smbios_structure_header);
            continue;
        }
        qemu_cfg_read((u8 *)*p, table.header.length);
        *p += table.header.length;
        *((u8*)*p) = 0;
        (*p)++;
        if (!string) {
            *((u8*)*p) = 0;
            (*p)++;
        }

        (*nr_structs)++;
        if (*p - (char *)header > *max_struct_size)
            *max_struct_size = *p - (char *)header;
    }

    if (start != *p) {
        /* Mark that we've reported on this type */
        used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f));
        return 1;
    }

    return 0;
}

int qemu_cfg_get_numa_nodes(void)
{
    u64 cnt;

    qemu_cfg_read_entry(&cnt, QEMU_CFG_NUMA, sizeof(cnt));

    return (int)cnt;
}

void qemu_cfg_get_numa_data(u64 *data, int n)
{
    int i;

    for (i = 0; i < n; i++)
        qemu_cfg_read((u8*)(data + i), sizeof(u64));
}

u16 qemu_cfg_get_max_cpus(void)
{
    u16 cnt;

    if (!qemu_cfg_present)
        return 0;

    qemu_cfg_read_entry(&cnt, QEMU_CFG_MAX_CPUS, sizeof(cnt));

    return cnt;
}

u16 qemu_cfg_first_file(QemuCfgFile *entry)
{
    memset(entry, 0, sizeof(*entry));
    return qemu_cfg_next_file(entry);
}

u16 qemu_cfg_next_file(QemuCfgFile *entry)
{
    u16 last = ntohs(entry->select);
    u32 e,count;

    if (!qemu_cfg_present)
        return 0;

    qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count));
    for (e = 0; e < ntohl(count); e++) {
        qemu_cfg_read((void*)entry, sizeof(*entry));
        if (ntohs(entry->select) > last) {
            return 1;
        }
    }
    return 0;
}

u32 qemu_cfg_read_file(QemuCfgFile *entry, void *dst, u32 maxlen)
{
    int len = ntohl(entry->size);

    if (!qemu_cfg_present)
        return 0;
    if (len > maxlen)
        return 0;
    qemu_cfg_read_entry(dst, ntohs(entry->select), len);
    return len;
}
