// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "pci.h"

#include <assert.h>
#include <fdio/debug.h>
#include <stdio.h>

#include <acpica/acpi.h>

#include "resources.h"

#define ZXDEBUG 0

#define PCIE_MAX_LEGACY_IRQ_PINS 4
#define PCIE_MAX_DEVICES_PER_BUS 32
#define PCIE_MAX_FUNCTIONS_PER_DEVICE 8
#define PCI_CONFIG_SIZE 256
#define PCIE_EXTENDED_CONFIG_SIZE 4096
#define PCI_HID  ((char*)"PNP0A03")
#define PCIE_HID ((char*)"PNP0A08")

#define PANIC_UNIMPLEMENTED __builtin_trap()

ACPI_STATUS pci_get_bbn(ACPI_HANDLE object, int* out_bbn) {
    ACPI_OBJECT out = {
        .Type = ACPI_TYPE_INTEGER,
    };
    ACPI_BUFFER buf = {
        .Length = sizeof(out),
        .Pointer = &out,
    };
    ACPI_STATUS acpi_status = AcpiEvaluateObject(object, (char*)"_BBN", NULL, &buf);
    if (acpi_status != AE_OK) {
        return acpi_status;
    }
    // Lower 8 bits of _BBN returned integer is the PCI base bus number.
    *out_bbn = out.Integer.Value & 0xFF;
    return ZX_OK;
}

/* Helper routine for translating IRQ routing tables into usable form
 *
 * @param port_dev_id The device ID on the root bus of this root port or
 * UINT8_MAX if this call is for the root bus, not a root port
 * @param port_func_id The function ID on the root bus of this root port or
 * UINT8_MAX if this call is for the root bus, not a root port
 */
static ACPI_STATUS handle_prt(
    ACPI_HANDLE object,
    zx_pci_init_arg_t* arg,
    uint8_t port_dev_id,
    uint8_t port_func_id) {
    assert((port_dev_id == UINT8_MAX && port_func_id == UINT8_MAX) ||
           (port_dev_id != UINT8_MAX && port_func_id != UINT8_MAX));

    ACPI_BUFFER buffer = {
        // Request that the ACPI subsystem allocate the buffer
        .Length = ACPI_ALLOCATE_BUFFER,
        .Pointer = NULL,
    };
    ACPI_BUFFER crs_buffer = {
        .Length = ACPI_ALLOCATE_BUFFER,
        .Pointer = NULL,
    };

    ACPI_STATUS status = AcpiGetIrqRoutingTable(object, &buffer);
    // IRQ routing tables are *required* to exist on the root hub
    if (status != AE_OK) {
        goto cleanup;
    }

    uintptr_t entry_addr = (uintptr_t)buffer.Pointer;
    ACPI_PCI_ROUTING_TABLE* entry;
    for (entry = (ACPI_PCI_ROUTING_TABLE*)entry_addr;
         entry->Length != 0;
         entry_addr += entry->Length, entry = (ACPI_PCI_ROUTING_TABLE*)entry_addr) {

        if (entry_addr > (uintptr_t)buffer.Pointer + buffer.Length) {
            return AE_ERROR;
        }
        if (entry->Pin >= PCIE_MAX_LEGACY_IRQ_PINS) {
            return AE_ERROR;
        }
        uint8_t dev_id = (entry->Address >> 16) & (PCIE_MAX_DEVICES_PER_BUS - 1);
        // Either we're handling the root complex (port_dev_id == UINT8_MAX), or
        // we're handling a root port, and if it's a root port, dev_id should
        // be 0.
        if (port_dev_id != UINT8_MAX && dev_id != 0) {
            // this is a weird entry, skip it
            continue;
        }

        uint32_t global_irq = ZX_PCI_NO_IRQ_MAPPING;
        bool level_triggered = true;
        bool active_high = false;
        if (entry->Source[0]) {
            // If the Source is not just a NULL byte, then it refers to a
            // PCI Interrupt Link Device
            ACPI_HANDLE ild;
            status = AcpiGetHandle(object, entry->Source, &ild);
            if (status != AE_OK) {
                goto cleanup;
            }
            status = AcpiGetCurrentResources(ild, &crs_buffer);
            if (status != AE_OK) {
                goto cleanup;
            }

            uintptr_t crs_entry_addr = (uintptr_t)crs_buffer.Pointer;
            ACPI_RESOURCE* res = (ACPI_RESOURCE*)crs_entry_addr;
            while (res->Type != ACPI_RESOURCE_TYPE_END_TAG) {
                if (res->Type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) {
                    ACPI_RESOURCE_EXTENDED_IRQ* irq = &res->Data.ExtendedIrq;
                    if (global_irq != ZX_PCI_NO_IRQ_MAPPING) {
                        // TODO: Handle finding two allocated IRQs.  Shouldn't
                        // happen?
                        PANIC_UNIMPLEMENTED;
                    }
                    if (irq->InterruptCount != 1) {
                        // TODO: Handle finding two allocated IRQs.  Shouldn't
                        // happen?
                        PANIC_UNIMPLEMENTED;
                    }
                    if (irq->Interrupts[0] != 0) {
                        active_high = (irq->Polarity == ACPI_ACTIVE_HIGH);
                        level_triggered = (irq->Triggering == ACPI_LEVEL_SENSITIVE);
                        global_irq = irq->Interrupts[0];
                    }
                } else {
                    // TODO: Handle non extended IRQs
                    PANIC_UNIMPLEMENTED;
                }
                crs_entry_addr += res->Length;
                res = (ACPI_RESOURCE*)crs_entry_addr;
            }
            if (global_irq == ZX_PCI_NO_IRQ_MAPPING) {
                // TODO: Invoke PRS to find what is allocatable and allocate it with SRS
                PANIC_UNIMPLEMENTED;
            }
            AcpiOsFree(crs_buffer.Pointer);
            crs_buffer.Length = ACPI_ALLOCATE_BUFFER;
            crs_buffer.Pointer = NULL;
        } else {
            // Otherwise, SourceIndex refers to a global IRQ number that the pin
            // is connected to
            global_irq = entry->SourceIndex;
        }

        // Check if we've seen this IRQ already, and if so, confirm the
        // IRQ signaling is the same.
        bool found_irq = false;
        for (unsigned int i = 0; i < arg->num_irqs; ++i) {
            if (global_irq != arg->irqs[i].global_irq) {
                continue;
            }
            if (active_high != arg->irqs[i].active_high ||
                level_triggered != arg->irqs[i].level_triggered) {

                // TODO: Handle mismatch here
                PANIC_UNIMPLEMENTED;
            }
            found_irq = true;
            break;
        }
        if (!found_irq) {
            assert(arg->num_irqs < countof(arg->irqs));
            arg->irqs[arg->num_irqs].global_irq = global_irq;
            arg->irqs[arg->num_irqs].active_high = active_high;
            arg->irqs[arg->num_irqs].level_triggered = level_triggered;
            arg->num_irqs++;
        }

        if (port_dev_id == UINT8_MAX) {
            for (unsigned int i = 0; i < PCIE_MAX_FUNCTIONS_PER_DEVICE; ++i) {
                arg->dev_pin_to_global_irq[dev_id][i][entry->Pin] =
                    global_irq;
            }
        } else {
            arg->dev_pin_to_global_irq[port_dev_id][port_func_id][entry->Pin] = global_irq;
        }
    }

cleanup:
    if (crs_buffer.Pointer) {
        AcpiOsFree(crs_buffer.Pointer);
    }
    if (buffer.Pointer) {
        AcpiOsFree(buffer.Pointer);
    }
    return status;
}

/* @brief Find the PCI config (returns the first one found)
 *
 * @param arg The structure to populate
 *
 * @return ZX_OK on success.
 */
static zx_status_t find_pcie_config(zx_pci_init_arg_t* arg) {
    ACPI_TABLE_HEADER* raw_table = NULL;
    ACPI_STATUS status = AcpiGetTable((char*)ACPI_SIG_MCFG, 1, &raw_table);
    if (status != AE_OK) {
        xprintf("could not find MCFG\n");
        return ZX_ERR_NOT_FOUND;
    }
    ACPI_TABLE_MCFG* mcfg = (ACPI_TABLE_MCFG*)raw_table;
    ACPI_MCFG_ALLOCATION* table_start = ((void*)mcfg) + sizeof(*mcfg);
    ACPI_MCFG_ALLOCATION* table_end = ((void*)mcfg) + mcfg->Header.Length;
    uintptr_t table_bytes = (uintptr_t)table_end - (uintptr_t)table_start;
    if (table_bytes % sizeof(*table_start) != 0) {
        xprintf("MCFG has unexpected size\n");
        return ZX_ERR_INTERNAL;
    }
    int num_entries = table_end - table_start;
    if (num_entries == 0) {
        xprintf("MCFG has no entries\n");
        return ZX_ERR_NOT_FOUND;
    }
    if (num_entries > 1) {
        xprintf("MCFG has more than one entry, just taking the first\n");
    }

    size_t size_per_bus = PCIE_EXTENDED_CONFIG_SIZE *
                          PCIE_MAX_DEVICES_PER_BUS * PCIE_MAX_FUNCTIONS_PER_DEVICE;
    int num_buses = table_start->EndBusNumber - table_start->StartBusNumber + 1;

    if (table_start->PciSegment != 0) {
        xprintf("Non-zero segment found\n");
        return ZX_ERR_NOT_SUPPORTED;
    }

    arg->addr_windows[0].is_mmio = true;
    arg->addr_windows[0].has_ecam = true;
    arg->addr_windows[0].bus_start = table_start->StartBusNumber;
    arg->addr_windows[0].bus_end = table_start->EndBusNumber;

    // We need to adjust the physical address we received to align to the proper
    // bus number.
    //
    // Citation from PCI Firmware Spec 3.0:
    // For PCI-X and PCI Express platforms utilizing the enhanced
    // configuration access method, the base address of the memory mapped
    // configuration space always corresponds to bus number 0 (regardless
    // of the start bus number decoded by the host bridge).
    arg->addr_windows[0].base = table_start->Address + size_per_bus * arg->addr_windows[0].bus_start;
    // The size of this mapping is defined in the PCI Firmware v3 spec to be
    // big enough for all of the buses in this config.
    arg->addr_windows[0].size = size_per_bus * num_buses;
    arg->addr_window_count = 1;
    return ZX_OK;
}


/* @brief Device enumerator for platform_configure_pcie_legacy_irqs */
static ACPI_STATUS get_pcie_devices_irq(
    ACPI_HANDLE object,
    UINT32 nesting_level,
    void* context,
    void** ret) {
    zx_pci_init_arg_t* arg = context;
    ACPI_STATUS status = handle_prt(
        object,
        arg,
        UINT8_MAX,
        UINT8_MAX);
    if (status != AE_OK) {
        return status;
    }

    // Enumerate root ports
    ACPI_HANDLE child = NULL;
    while (1) {
        status = AcpiGetNextObject(ACPI_TYPE_DEVICE, object, child, &child);
        if (status == AE_NOT_FOUND) {
            break;
        } else if (status != AE_OK) {
            return status;
        }

        ACPI_OBJECT object = {0};
        ACPI_BUFFER buffer = {
            .Length = sizeof(object),
            .Pointer = &object,
        };
        status = AcpiEvaluateObject(child, (char*)"_ADR", NULL, &buffer);
        if (status != AE_OK ||
            buffer.Length < sizeof(object) ||
            object.Type != ACPI_TYPE_INTEGER) {

            continue;
        }
        UINT64 data = object.Integer.Value;
        uint8_t port_dev_id = (data >> 16) & (PCIE_MAX_DEVICES_PER_BUS - 1);
        uint8_t port_func_id = data & (PCIE_MAX_FUNCTIONS_PER_DEVICE - 1);
        // Ignore the return value of this, since if child is not a
        // root port, it will fail and we don't care.
        handle_prt(
            child,
            arg,
            port_dev_id,
            port_func_id);
    }
    return AE_OK;
}

/* @brief Find the legacy IRQ swizzling for the PCIe root bus
 *
 * @param arg The structure to populate
 *
 * @return ZX_OK on success
 */
static zx_status_t find_pci_legacy_irq_mapping(zx_pci_init_arg_t* arg) {
    unsigned int map_len = sizeof(arg->dev_pin_to_global_irq) / sizeof(uint32_t);
    for (unsigned int i = 0; i < map_len; ++i) {
        uint32_t* flat_map = (uint32_t*)&arg->dev_pin_to_global_irq;
        flat_map[i] = ZX_PCI_NO_IRQ_MAPPING;
    }
    arg->num_irqs = 0;

    ACPI_STATUS status = AcpiGetDevices(
        (arg->addr_windows[0].has_ecam) ? PCIE_HID : PCI_HID,
        get_pcie_devices_irq,
        arg,
        NULL);
    if (status != AE_OK) {
        return ZX_ERR_INTERNAL;
    }
    return ZX_OK;
}

static ACPI_STATUS find_pci_configs_cb(
        ACPI_HANDLE object, uint32_t nesting_level, void* _ctx, void** ret) {
    ACPI_DEVICE_INFO* info;

    size_t size_per_bus = PCI_CONFIG_SIZE *
                          PCIE_MAX_DEVICES_PER_BUS * PCIE_MAX_FUNCTIONS_PER_DEVICE;
    zx_pci_init_arg_t* arg = (zx_pci_init_arg_t*)_ctx;

    // TODO(cja): This is essentially a hacky solution to deal with
    // legacy PCI on Virtualbox and GCE. When the ACPI bus driver
    // is enabled we'll be using proper binding and not need this
    // anymore.
    if (AcpiGetObjectInfo(object, &info) == AE_OK) {
        arg->addr_windows[0].is_mmio = false;
        arg->addr_windows[0].has_ecam = false;
        arg->addr_windows[0].base = 0;
        arg->addr_windows[0].bus_start = 0;
        arg->addr_windows[0].bus_end = 0;
        arg->addr_windows[0].size = size_per_bus;
        arg->addr_window_count = 1;

        return AE_OK;
    }

    return AE_ERROR;
}

/* @brief Find the PCI config (returns the first one found)
 *
 * @param arg The structure to populate
 *
 * @return ZX_OK on success.
 */
static zx_status_t find_pci_config(zx_pci_init_arg_t* arg) {
    // TODO: Although this will find every PCI legacy root, we're presently
    // hardcoding to just use the first at bus 0 dev 0 func 0 segment 0.
    return AcpiGetDevices(PCI_HID, find_pci_configs_cb, arg, NULL);
}

/* @brief Compute PCIe initialization information
 *
 * The computed initialization information can be released with free()
 *
 * @param arg Pointer to store the initialization information into
 *
 * @return ZX_OK on success
 */
zx_status_t get_pci_init_arg(zx_pci_init_arg_t** arg, uint32_t* size) {
    zx_pci_init_arg_t* res = NULL;

    // TODO(teisenbe): We assume only one ECAM window right now...
    size_t obj_size = sizeof(*res) + sizeof(res->addr_windows[0]) * 1;
    res = calloc(1, obj_size);
    if (!res) {
        return ZX_ERR_NO_MEMORY;
    }

    // First look for a PCIe root complex. If none is found, try legacy PCI.
    // This presently only cares about the first root found, multiple roots
    // will be handled when the PCI bus driver binds to roots via ACPI.
    zx_status_t status = find_pcie_config(res);
    if (status != ZX_OK) {
        status = find_pci_config(res);
        if (status != ZX_OK) {
            goto fail;
        }
    }

    status = find_pci_legacy_irq_mapping(res);
    if (status != ZX_OK) {
        goto fail;
    }

    *arg = res;
    *size = sizeof(*res) + sizeof(res->addr_windows[0]) * res->addr_window_count;
    return ZX_OK;
fail:
    free(res);
    return status;
}

struct report_current_resources_ctx {
    zx_handle_t pci_handle;
    bool device_is_root_bridge;
    bool add_pass;
};

static ACPI_STATUS report_current_resources_resource_cb(ACPI_RESOURCE* res, void* _ctx) {
    struct report_current_resources_ctx* ctx = _ctx;

    bool is_mmio = false;
    uint64_t base = 0;
    uint64_t len = 0;
    bool add_range = false;

    if (resource_is_memory(res)) {
        resource_memory_t mem;
        zx_status_t status = resource_parse_memory(res, &mem);
        if (status != ZX_OK || mem.minimum != mem.maximum) {
            return AE_ERROR;
        }

        is_mmio = true;
        base = mem.minimum;
        len = mem.address_length;
    } else if (resource_is_address(res)) {
        resource_address_t addr;
        zx_status_t status = resource_parse_address(res, &addr);
        if (status != ZX_OK) {
            return AE_ERROR;
        }

        if (addr.resource_type == RESOURCE_ADDRESS_MEMORY) {
            is_mmio = true;
        } else if (addr.resource_type == RESOURCE_ADDRESS_IO) {
            is_mmio = false;
        } else {
            return AE_OK;
        }

        if (!addr.min_address_fixed || !addr.max_address_fixed || addr.maximum < addr.minimum) {
            printf("WARNING: ACPI found bad _CRS address entry\n");
            return AE_OK;
        }

        // We compute len from maximum rather than address_length, since some
        // implementations don't set address_length...
        base = addr.minimum;
        len = addr.maximum - base + 1;

        // PCI root bridges report downstream resources via _CRS.  Since we're
        // gathering data on acceptable ranges for PCI to use for MMIO, consider
        // non-consume-only address resources to be valid for PCI MMIO.
        if (ctx->device_is_root_bridge && !addr.consumed_only) {
            add_range = true;
        }
    } else if (resource_is_io(res)) {
        resource_io_t io;
        zx_status_t status = resource_parse_io(res, &io);
        if (status != ZX_OK) {
            return AE_ERROR;
        }

        if (io.minimum != io.maximum) {
            printf("WARNING: ACPI found bad _CRS IO entry\n");
            return AE_OK;
        }

        is_mmio = false;
        base = io.minimum;
        len = io.address_length;
    } else {
        return AE_OK;
    }

    // Ignore empty regions that are reported, and skip any resources that
    // aren't for the pass we're doing.
    if (len == 0 || add_range != ctx->add_pass) {
        return AE_OK;
    }

    if (add_range && is_mmio && base < 1024 * 1024) {
        // The PC platform defines many legacy regions below 1MB that we do not
        // want PCIe to try to map onto.
        xprintf("Skipping adding MMIO range, due to being below 1MB\n");
        return AE_OK;
    }

    xprintf("ACPI range modification: %sing %s %016lx %016lx\n",
            add_range ? "add" : "subtract", is_mmio ? "MMIO" : "PIO", base, len);

    zx_status_t status = zx_pci_add_subtract_io_range(
            ctx->pci_handle, is_mmio, base, len, add_range);
    if (status != ZX_OK) {
        if (add_range) {
            xprintf("Failed to add range: %d\n", status);
        } else {
            // If we are subtracting a range and fail, abort.  This is bad.
            return AE_ERROR;
        }
    }
    return AE_OK;
}

static ACPI_STATUS report_current_resources_device_cb(
        ACPI_HANDLE object, uint32_t nesting_level, void* _ctx, void** ret) {

    ACPI_DEVICE_INFO* info = NULL;
    ACPI_STATUS status = AcpiGetObjectInfo(object, &info);
    if (status != AE_OK) {
        return status;
    }

    struct report_current_resources_ctx* ctx = _ctx;
    ctx->device_is_root_bridge = (info->Flags & ACPI_PCI_ROOT_BRIDGE) != 0;

    ACPI_FREE(info);

    status = AcpiWalkResources(object, (char*)"_CRS", report_current_resources_resource_cb, ctx);
    if (status == AE_NOT_FOUND || status == AE_OK) {
        return AE_OK;
    }
    return status;
}

/* @brief Report current resources to the kernel PCI driver
 *
 * Walks the ACPI namespace and use the reported current resources to inform
   the kernel PCI interface about what memory it shouldn't use.
 *
 * @param root_resource_handle The handle to pass to the kernel when talking
 * to the PCI driver.
 *
 * @return ZX_OK on success
 */
zx_status_t pci_report_current_resources(zx_handle_t root_resource_handle) {
    // First we search for resources to add, then we subtract out things that
    // are being consumed elsewhere.  This forces an ordering on the
    // operations so that it should be consistent, and should protect against
    // inconistencies in the _CRS methods.

    // Walk the device tree and add to the PCIe IO ranges any resources
    // "produced" by the PCI root in the ACPI namespace.
    struct report_current_resources_ctx ctx = {
        .pci_handle = root_resource_handle,
        .device_is_root_bridge = false,
        .add_pass = true,
    };
    ACPI_STATUS status = AcpiGetDevices(NULL, report_current_resources_device_cb, &ctx, NULL);
    if (status != AE_OK) {
        return ZX_ERR_INTERNAL;
    }

    // Removes resources we believe are in use by other parts of the platform
    ctx = (struct report_current_resources_ctx){
        .pci_handle = root_resource_handle,
        .device_is_root_bridge = false,
        .add_pass = false,
    };
    status = AcpiGetDevices(NULL, report_current_resources_device_cb, &ctx, NULL);
    if (status != AE_OK) {
        return ZX_ERR_INTERNAL;
    }


    return ZX_OK;
}
