/*
 * Support for generating PCI related ACPI tables and passing them to Guests
 *
 * Copyright (C) 2006 Fabrice Bellard
 * Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
 * Copyright (C) 2013-2019 Red Hat Inc
 * Copyright (C) 2019 Intel Corporation
 *
 * Author: Wei Yang <richardw.yang@linux.intel.com>
 * 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 "qemu/error-report.h"
#include "qom/object_interfaces.h"
#include "qapi/error.h"
#include "hw/boards.h"
#include "hw/acpi/aml-build.h"
#include "hw/acpi/pci.h"
#include "hw/pci/pci_bridge.h"
#include "hw/pci/pci_device.h"
#include "hw/pci/pcie_host.h"

/*
 * PCI Firmware Specification, Revision 3.0
 * 4.1.2 MCFG Table Description.
 */
void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info,
                const char *oem_id, const char *oem_table_id)
{
    AcpiTable table = { .sig = "MCFG", .rev = 1,
                        .oem_id = oem_id, .oem_table_id = oem_table_id };

    acpi_table_begin(&table, table_data);

    /* Reserved */
    build_append_int_noprefix(table_data, 0, 8);
    /*
     * Memory Mapped Enhanced Configuration Space Base Address Allocation
     * Structure
     */
    /* Base address, processor-relative */
    build_append_int_noprefix(table_data, info->base, 8);
    /* PCI segment group number */
    build_append_int_noprefix(table_data, 0, 2);
    /* Starting PCI Bus number */
    build_append_int_noprefix(table_data, 0, 1);
    /* Final PCI Bus number */
    build_append_int_noprefix(table_data, PCIE_MMCFG_BUS(info->size - 1), 1);
    /* Reserved */
    build_append_int_noprefix(table_data, 0, 4);

    acpi_table_end(linker, &table);
}

typedef struct AcpiGenericInitiator {
    /* private */
    Object parent;

    /* public */
    char *pci_dev;
    uint32_t node;
} AcpiGenericInitiator;

typedef struct AcpiGenericInitiatorClass {
    ObjectClass parent_class;
} AcpiGenericInitiatorClass;

#define TYPE_ACPI_GENERIC_INITIATOR "acpi-generic-initiator"

OBJECT_DEFINE_TYPE_WITH_INTERFACES(AcpiGenericInitiator, acpi_generic_initiator,
                   ACPI_GENERIC_INITIATOR, OBJECT,
                   { TYPE_USER_CREATABLE },
                   { NULL })

OBJECT_DECLARE_SIMPLE_TYPE(AcpiGenericInitiator, ACPI_GENERIC_INITIATOR)

static void acpi_generic_initiator_init(Object *obj)
{
    AcpiGenericInitiator *gi = ACPI_GENERIC_INITIATOR(obj);

    gi->node = MAX_NODES;
    gi->pci_dev = NULL;
}

static void acpi_generic_initiator_finalize(Object *obj)
{
    AcpiGenericInitiator *gi = ACPI_GENERIC_INITIATOR(obj);

    g_free(gi->pci_dev);
}

static void acpi_generic_initiator_set_pci_device(Object *obj, const char *val,
                                                  Error **errp)
{
    AcpiGenericInitiator *gi = ACPI_GENERIC_INITIATOR(obj);

    gi->pci_dev = g_strdup(val);
}

static void acpi_generic_initiator_set_node(Object *obj, Visitor *v,
                                            const char *name, void *opaque,
                                            Error **errp)
{
    AcpiGenericInitiator *gi = ACPI_GENERIC_INITIATOR(obj);
    MachineState *ms = MACHINE(qdev_get_machine());
    uint32_t value;

    if (!visit_type_uint32(v, name, &value, errp)) {
        return;
    }

    if (value >= MAX_NODES) {
        error_printf("%s: Invalid NUMA node specified\n",
                     TYPE_ACPI_GENERIC_INITIATOR);
        exit(1);
    }

    gi->node = value;
    ms->numa_state->nodes[gi->node].has_gi = true;
}

static void acpi_generic_initiator_class_init(ObjectClass *oc, const void *data)
{
    object_class_property_add_str(oc, "pci-dev", NULL,
        acpi_generic_initiator_set_pci_device);
    object_class_property_set_description(oc, "pci-dev",
        "PCI device to associate with the node");
    object_class_property_add(oc, "node", "int", NULL,
        acpi_generic_initiator_set_node, NULL, NULL);
    object_class_property_set_description(oc, "node",
        "NUMA node associated with the PCI device");
}

static int build_acpi_generic_initiator(Object *obj, void *opaque)
{
    MachineState *ms = MACHINE(qdev_get_machine());
    AcpiGenericInitiator *gi;
    GArray *table_data = opaque;
    int32_t devfn;
    uint8_t bus;
    Object *o;

    if (!object_dynamic_cast(obj, TYPE_ACPI_GENERIC_INITIATOR)) {
        return 0;
    }

    gi = ACPI_GENERIC_INITIATOR(obj);
    if (gi->node >= ms->numa_state->num_nodes) {
        error_printf("%s: Specified node %d is invalid.\n",
                     TYPE_ACPI_GENERIC_INITIATOR, gi->node);
        exit(1);
    }

    o = object_resolve_path_type(gi->pci_dev, TYPE_PCI_DEVICE, NULL);
    if (!o) {
        error_printf("%s: Specified device must be a PCI device.\n",
                     TYPE_ACPI_GENERIC_INITIATOR);
        exit(1);
    }

    bus = object_property_get_uint(o, "busnr", &error_fatal);
    devfn = object_property_get_uint(o, "addr", &error_fatal);
    /* devfn is constrained in PCI to be 8 bit but storage is an int32_t */
    assert(devfn >= 0 && devfn < PCI_DEVFN_MAX);

    build_srat_pci_generic_initiator(table_data, gi->node, 0, bus, devfn);

    return 0;
}

typedef struct AcpiGenericPort {
    /* private */
    Object parent;

    /* public */
    char *pci_bus;
    uint32_t node;
} AcpiGenericPort;

typedef struct AcpiGenericPortClass {
    ObjectClass parent_class;
} AcpiGenericPortClass;

#define TYPE_ACPI_GENERIC_PORT "acpi-generic-port"

OBJECT_DEFINE_TYPE_WITH_INTERFACES(AcpiGenericPort, acpi_generic_port,
                   ACPI_GENERIC_PORT, OBJECT,
                   { TYPE_USER_CREATABLE },
                   { NULL })

OBJECT_DECLARE_SIMPLE_TYPE(AcpiGenericPort, ACPI_GENERIC_PORT)

static void acpi_generic_port_init(Object *obj)
{
    AcpiGenericPort *gp = ACPI_GENERIC_PORT(obj);

    gp->node = MAX_NODES;
    gp->pci_bus = NULL;
}

static void acpi_generic_port_finalize(Object *obj)
{
    AcpiGenericPort *gp = ACPI_GENERIC_PORT(obj);

    g_free(gp->pci_bus);
}

static void acpi_generic_port_set_pci_bus(Object *obj, const char *val,
                                          Error **errp)
{
    AcpiGenericPort *gp = ACPI_GENERIC_PORT(obj);

    gp->pci_bus = g_strdup(val);
}

static void acpi_generic_port_set_node(Object *obj, Visitor *v,
                                       const char *name, void *opaque,
                                       Error **errp)
{
    AcpiGenericPort *gp = ACPI_GENERIC_PORT(obj);
    uint32_t value;

    if (!visit_type_uint32(v, name, &value, errp)) {
        return;
    }

    if (value >= MAX_NODES) {
        error_printf("%s: Invalid NUMA node specified\n",
                     TYPE_ACPI_GENERIC_INITIATOR);
        exit(1);
    }

    gp->node = value;
}

static void acpi_generic_port_class_init(ObjectClass *oc, const void *data)
{
    object_class_property_add_str(oc, "pci-bus", NULL,
        acpi_generic_port_set_pci_bus);
    object_class_property_set_description(oc, "pci-bus",
       "PCI Bus of the host bridge associated with this GP affinity structure");
    object_class_property_add(oc, "node", "int", NULL,
        acpi_generic_port_set_node, NULL, NULL);
    object_class_property_set_description(oc, "node",
       "The NUMA node like ID to index HMAT/SLIT NUMA properties involving GP");
}

static int build_acpi_generic_port(Object *obj, void *opaque)
{
    MachineState *ms = MACHINE(qdev_get_machine());
    const char *hid = "ACPI0016";
    GArray *table_data = opaque;
    AcpiGenericPort *gp;
    uint32_t uid;
    Object *o;

    if (!object_dynamic_cast(obj, TYPE_ACPI_GENERIC_PORT)) {
        return 0;
    }

    gp = ACPI_GENERIC_PORT(obj);

    if (gp->node >= ms->numa_state->num_nodes) {
        error_printf("%s: node %d is invalid.\n",
                     TYPE_ACPI_GENERIC_PORT, gp->node);
        exit(1);
    }

    o = object_resolve_path_type(gp->pci_bus, TYPE_PXB_CXL_BUS, NULL);
    if (!o) {
        error_printf("%s: device must be a CXL host bridge.\n",
                     TYPE_ACPI_GENERIC_PORT);
       exit(1);
    }

    uid = object_property_get_uint(o, "acpi_uid", &error_fatal);
    build_srat_acpi_generic_port(table_data, gp->node, hid, uid);

    return 0;
}

void build_srat_generic_affinity_structures(GArray *table_data)
{
    object_child_foreach_recursive(object_get_root(),
                                   build_acpi_generic_initiator,
                                   table_data);
    object_child_foreach_recursive(object_get_root(), build_acpi_generic_port,
                                   table_data);
}

Aml *build_pci_host_bridge_osc_method(bool enable_native_pcie_hotplug)
{
    Aml *if_ctx;
    Aml *if_ctx2;
    Aml *else_ctx;
    Aml *method;
    Aml *a_cwd1 = aml_name("CDW1");
    Aml *a_ctrl = aml_local(0);

    method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
    aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));

    if_ctx = aml_if(aml_equal(
        aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766")));
    aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
    aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));

    aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl));

    /*
     * Always allow native PME, AER (no dependencies)
     * Allow SHPC (PCI bridges can have SHPC controller)
     * Disable PCIe Native Hot-plug if ACPI PCI Hot-plug is enabled.
     */
    aml_append(if_ctx, aml_and(a_ctrl,
        aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 : 0x0)), a_ctrl));

    if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1))));
    /* Unknown revision */
    aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x08), a_cwd1));
    aml_append(if_ctx, if_ctx2);

    if_ctx2 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl)));
    /* Capabilities bits were masked */
    aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x10), a_cwd1));
    aml_append(if_ctx, if_ctx2);

    /* Update DWORD3 in the buffer */
    aml_append(if_ctx, aml_store(a_ctrl, aml_name("CDW3")));
    aml_append(method, if_ctx);

    else_ctx = aml_else();
    /* Unrecognized UUID */
    aml_append(else_ctx, aml_or(a_cwd1, aml_int(4), a_cwd1));
    aml_append(method, else_ctx);

    aml_append(method, aml_return(aml_arg(3)));
    return method;
}
