/* 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 "system/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);
    /* Flags. bit 0: PCAT_COMPAT */
    build_append_int_noprefix(table_data,
                              x86ms->pic != ON_OFF_AUTO_OFF ? 1 : 0 , 4);

    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);
}

