/* Support for generating ACPI tables and passing them to Guests
 *
 * Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
 * Copyright (C) 2006 Fabrice Bellard
 * Copyright (C) 2013 Red Hat Inc
 *
 * Author: Michael S. Tsirkin <mst@redhat.com>
 *
 * This program 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.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"

#include "exec/memory.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/aml-build.h"
#include "hw/acpi/utils.h"
#include "target/i386/cpu.h"

#include "acpi-build.h"
#include "acpi-common.h"

void pc_madt_cpu_entry(int uid, const CPUArchIdList *apic_ids,
                       GArray *entry, bool force_enabled)
{
    uint32_t apic_id = apic_ids->cpus[uid].arch_id;
    /* Flags – Local APIC Flags */
    uint32_t flags = apic_ids->cpus[uid].cpu != NULL || force_enabled ?
                     1 /* Enabled */ : 0;

    /* ACPI spec says that LAPIC entry for non present
     * CPU may be omitted from MADT or it must be marked
     * as disabled. However omitting non present CPU from
     * MADT breaks hotplug on linux. So possible CPUs
     * should be put in MADT but kept disabled.
     */
    if (apic_id < 255) {
        /* Rev 1.0b, Table 5-13 Processor Local APIC Structure */
        build_append_int_noprefix(entry, 0, 1);       /* Type */
        build_append_int_noprefix(entry, 8, 1);       /* Length */
        build_append_int_noprefix(entry, uid, 1);     /* ACPI Processor ID */
        build_append_int_noprefix(entry, apic_id, 1); /* APIC ID */
        build_append_int_noprefix(entry, flags, 4); /* Flags */
    } else {
        /* Rev 4.0, 5.2.12.12 Processor Local x2APIC Structure */
        build_append_int_noprefix(entry, 9, 1);       /* Type */
        build_append_int_noprefix(entry, 16, 1);      /* Length */
        build_append_int_noprefix(entry, 0, 2);       /* Reserved */
        build_append_int_noprefix(entry, apic_id, 4); /* X2APIC ID */
        build_append_int_noprefix(entry, flags, 4);   /* Flags */
        build_append_int_noprefix(entry, uid, 4);     /* ACPI Processor UID */
    }
}

static void build_ioapic(GArray *entry, uint8_t id, uint32_t addr, uint32_t irq)
{
    /* Rev 1.0b, 5.2.8.2 IO APIC */
    build_append_int_noprefix(entry, 1, 1);    /* Type */
    build_append_int_noprefix(entry, 12, 1);   /* Length */
    build_append_int_noprefix(entry, id, 1);   /* IO APIC ID */
    build_append_int_noprefix(entry, 0, 1);    /* Reserved */
    build_append_int_noprefix(entry, addr, 4); /* IO APIC Address */
    build_append_int_noprefix(entry, irq, 4);  /* System Vector Base */
}

static void
build_xrupt_override(GArray *entry, uint8_t src, uint32_t gsi, uint16_t flags)
{
    /* Rev 1.0b, 5.2.8.3.1 Interrupt Source Overrides */
    build_append_int_noprefix(entry, 2, 1);  /* Type */
    build_append_int_noprefix(entry, 10, 1); /* Length */
    build_append_int_noprefix(entry, 0, 1);  /* Bus */
    build_append_int_noprefix(entry, src, 1);  /* Source */
    /* Global System Interrupt Vector */
    build_append_int_noprefix(entry, gsi, 4);
    build_append_int_noprefix(entry, flags, 2);  /* Flags */
}

/*
 * ACPI spec, Revision 1.0b
 * 5.2.8 Multiple APIC Description Table
 */
void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
                     X86MachineState *x86ms,
                     const char *oem_id, const char *oem_table_id)
{
    int i;
    bool x2apic_mode = false;
    MachineClass *mc = MACHINE_GET_CLASS(x86ms);
    X86MachineClass *x86mc = X86_MACHINE_GET_CLASS(x86ms);
    const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(x86ms));
    AcpiTable table = { .sig = "APIC", .rev = 3, .oem_id = oem_id,
                        .oem_table_id = oem_table_id };

    acpi_table_begin(&table, table_data);
    /* Local APIC Address */
    build_append_int_noprefix(table_data, APIC_DEFAULT_ADDRESS, 4);
    build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */

    for (i = 0; i < apic_ids->len; i++) {
        pc_madt_cpu_entry(i, apic_ids, table_data, false);
        if (apic_ids->cpus[i].arch_id > 254) {
            x2apic_mode = true;
        }
    }

    build_ioapic(table_data, ACPI_BUILD_IOAPIC_ID, IO_APIC_DEFAULT_ADDRESS, 0);
    if (x86ms->ioapic2) {
        build_ioapic(table_data, ACPI_BUILD_IOAPIC_ID + 1,
                     IO_APIC_SECONDARY_ADDRESS, IO_APIC_SECONDARY_IRQBASE);
    }

    if (x86mc->apic_xrupt_override) {
        build_xrupt_override(table_data, 0, 2,
            0 /* Flags: Conforms to the specifications of the bus */);
    }

    for (i = 1; i < 16; i++) {
        if (!(x86ms->pci_irq_mask & (1 << i))) {
            /* No need for a INT source override structure. */
            continue;
        }
        build_xrupt_override(table_data, i, i,
            0xd /* Flags: Active high, Level Triggered */);
    }

    if (x2apic_mode) {
        /* Rev 4.0, 5.2.12.13 Local x2APIC NMI Structure*/
        build_append_int_noprefix(table_data, 0xA, 1); /* Type */
        build_append_int_noprefix(table_data, 12, 1);  /* Length */
        build_append_int_noprefix(table_data, 0, 2);   /* Flags */
        /* ACPI Processor UID */
        build_append_int_noprefix(table_data, 0xFFFFFFFF /* all processors */,
                                  4);
        /* Local x2APIC LINT# */
        build_append_int_noprefix(table_data, 1 /* ACPI_LINT1 */, 1);
        build_append_int_noprefix(table_data, 0, 3); /* Reserved */
    } else {
        /* Rev 1.0b, 5.2.8.3.3 Local APIC NMI */
        build_append_int_noprefix(table_data, 4, 1);  /* Type */
        build_append_int_noprefix(table_data, 6, 1);  /* Length */
        /* ACPI Processor ID */
        build_append_int_noprefix(table_data, 0xFF /* all processors */, 1);
        build_append_int_noprefix(table_data, 0, 2);  /* Flags */
        /* Local APIC INTI# */
        build_append_int_noprefix(table_data, 1 /* ACPI_LINT1 */, 1);
    }

    acpi_table_end(linker, &table);
}

