/*
 * Copyright 2014, NICTA
 *
 * This software may be distributed and modified according to the terms of
 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
 * See "LICENSE_GPLv2.txt" for details.
 *
 * @TAG(NICTA_GPL)
 */

/* Routines for generating guest ACPI tables.
Author: W.A. */

#include <stdlib.h>
#include <string.h>

#include "vmm/debug.h"
#include "vmm/platform/acpi.h"
#include "vmm/platform/guest_memory.h"
#include "vmm/platform/guest_vspace.h"
#include "vmm/processor/apicdef.h"

#include "platsupport/plat/acpi/acpi.h"

#define APIC_FLAGS_ENABLED (1)


uint8_t acpi_calc_checksum(const char* table, int length)
{
    uint32_t sum = 0;

    for (int i = 0; i < length; i++) {
        sum += *table++;
    }

    return 0x100 - (sum & 0xFF);
}


static void acpi_fill_table_head(acpi_header_t *head, const char *signature, uint8_t rev) {
    const char *oem = "NICTA ";
    const char *padd = "    ";
    memcpy(head->signature, signature, sizeof(head->signature));
    memcpy(head->oem_id, oem, sizeof(head->oem_id));
    memcpy(head->creator_id, oem, sizeof(head->creator_id));
    memcpy(head->oem_table_id, signature, sizeof(head->signature));
    memcpy(head->oem_table_id + sizeof(head->signature), padd, 4);

    head->revision = rev;
    head->checksum = 0;
    head->length = sizeof(*head);
    head->oem_revision = rev;
    head->creator_revision = 1;
}

static int make_guest_acpi_tables_continued(uintptr_t paddr, void *vaddr,
        size_t size, size_t offset, void *cookie) {
    (void)offset;
    memcpy((char *)vaddr, (char *)cookie, size);
    return 0;
}

// Give some ACPI tables to the guest
int make_guest_acpi_tables(vmm_t *vmm) {
    DPRINTF(2, "Making ACPI tables\n");

    int cpus = vmm->num_vcpus;

    int err;

    // XSDT and other tables
    void *tables[MAX_ACPI_TABLES];
    size_t table_sizes[MAX_ACPI_TABLES];
    int num_tables = 1;

    // MADT
    int madt_size = sizeof(acpi_madt_t)
        /* + sizeof(acpi_madt_ioapic_t)*/
        + sizeof(acpi_madt_local_apic_t) * cpus;
    acpi_madt_t *madt = malloc(madt_size);
    acpi_fill_table_head(&madt->header, "APIC", 3);
    madt->local_int_crt_address = APIC_DEFAULT_PHYS_BASE;
    madt->flags = 1;

    char *madt_entry = (char *)madt + sizeof(acpi_madt_t);

#if 0
    acpi_madt_ioapic_t ioapic = { // MADT IOAPIC entry
        .header = {
            .type = ACPI_APIC_IOAPIC,
            .length = sizeof(acpi_madt_ioapic_t)
        },
        .ioapic_id = 0,
        .address = IOAPIC_DEFAULT_PHYS_BASE,
        .gs_interrupt_base = 0 // TODO set this up?
    };
    memcpy(madt_entry, &ioapic, sizeof(ioapic));
    madt_entry += sizeof(ioapic);
#endif

    for (int i = 0; i < cpus; i++) { // MADT APIC entries
        acpi_madt_local_apic_t apic = {
            .header = {
                .type = ACPI_APIC_LOCAL,
                .length = sizeof(acpi_madt_local_apic_t)
            },
            .processor_id = i + 1,
            .apic_id = i,
            .flags = APIC_FLAGS_ENABLED
        };
        memcpy(madt_entry, &apic, sizeof(apic));
        madt_entry += sizeof(apic);
    }

    madt->header.length = madt_size;
    madt->header.checksum = acpi_calc_checksum((char *)madt, madt_size);

    tables[num_tables] = madt;
    table_sizes[num_tables] = madt_size;
    num_tables++;

    // Could set up other tables here...

    // XSDT
    size_t xsdt_size = sizeof(acpi_xsdt_t) + sizeof(uint64_t) * (num_tables - 1);

    // How much space will all the tables take up?
    size_t acpi_size = xsdt_size;
    for (int i = 1; i < num_tables; i++) {
        acpi_size += table_sizes[i];
    }

    // Allocate some frames for this
    uintptr_t xsdt_addr = 0xe1000; // TODO actually allocate frames, can be anywhere

    acpi_xsdt_t *xsdt = malloc(xsdt_size);
    acpi_fill_table_head(&xsdt->header, "XSDT", 1);
    
    // Add previous tables to XSDT pointer list
    uintptr_t table_paddr = xsdt_addr + xsdt_size;
    uint64_t *entry = (uint64_t *)((char *)xsdt + sizeof(acpi_xsdt_t));
    for (int i = 1; i < num_tables; i++) {
        *entry++ = (uint64_t)table_paddr;
        table_paddr += table_sizes[i];
    }
    
    xsdt->header.length = xsdt_size;
    xsdt->header.checksum = acpi_calc_checksum((char *)xsdt, xsdt_size);
    
    tables[0] = xsdt;
    table_sizes[0] = xsdt_size;

    // Copy all the tables to guest
    table_paddr = xsdt_addr;
    for (int i = 0; i < num_tables; i++) {
        DPRINTF(2, "ACPI table \"%.4s\", addr = %08x, size = %d bytes\n",
                (char *)tables[i], table_paddr, table_sizes[i]);
        err = vmm_guest_vspace_touch(&vmm->guest_mem.vspace, table_paddr,
                table_sizes[i], make_guest_acpi_tables_continued, tables[i]);
        if (err) {
            return err;
        }
        table_paddr += table_sizes[i];
    }

    // RSDP
    uintptr_t rsdp_addr = ACPI_START;
    err = vmm_alloc_guest_device_at(vmm, ACPI_START, sizeof(acpi_rsdp_t));
    if (err) {
        return err;
    }
    
    acpi_rsdp_t rsdp = {
        .signature = "RSD PTR ",
        .oem_id = "NICTA ",
        .revision = 2, /* ACPI v3*/
        .checksum = 0,
        .rsdt_address = xsdt_addr,
        /* rsdt_addrss will not be inspected as the xsdt is present.
           This is not ACPI 1 compliant */
        .length = sizeof(acpi_rsdp_t),
        .xsdt_address = xsdt_addr,
        .extended_checksum = 0,
        .reserved = {0}
    };

    rsdp.checksum = acpi_calc_checksum((char *)&rsdp, 20);  
    rsdp.extended_checksum = acpi_calc_checksum((char *)&rsdp, sizeof(rsdp));

    DPRINTF(2, "ACPI RSDP addr = %08x\n", rsdp_addr);

    return vmm_guest_vspace_touch(&vmm->guest_mem.vspace, rsdp_addr, sizeof(rsdp),
            make_guest_acpi_tables_continued, &rsdp);
}

