// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <zircon/compiler.h>

#include <acpica/acpi.h>

#include <assert.h>
#include <err.h>
#include <trace.h>

#include <lk/init.h>

#include <arch/x86/apic.h>
#include <platform/pc/acpi.h>

#define LOCAL_TRACE 0

#define ACPI_MAX_INIT_TABLES 32
static ACPI_TABLE_DESC acpi_tables[ACPI_MAX_INIT_TABLES];
static bool acpi_initialized = false;

static ACPI_STATUS acpi_set_apic_irq_mode(void);

/**
 * @brief  Initialize early-access ACPI tables
 *
 * This function enables *only* the ACPICA Table Manager subsystem.
 * The rest of the ACPI subsystem will remain uninitialized.
 */
void platform_init_acpi_tables(uint level)
{
    DEBUG_ASSERT(!acpi_initialized);

    ACPI_STATUS status;
    status = AcpiInitializeTables(acpi_tables, ACPI_MAX_INIT_TABLES, FALSE);

    if (status == AE_NOT_FOUND) {
        TRACEF("WARNING: could not find ACPI tables\n");
        return;
    } else if (status == AE_NO_MEMORY) {
        TRACEF("WARNING: could not initialize ACPI tables\n");
        return;
    } else if (status != AE_OK) {
        TRACEF("WARNING: could not initialize ACPI tables for unknown reason\n");
        return;
    }

    acpi_initialized = true;
    LTRACEF("ACPI tables initialized\n");
}

/* initialize ACPI tables as soon as we have a working VM */
LK_INIT_HOOK(acpi_tables, &platform_init_acpi_tables, LK_INIT_LEVEL_VM + 1);

static status_t acpi_get_madt_record_limits(uintptr_t *start, uintptr_t *end)
{
    ACPI_TABLE_HEADER *table = NULL;
    ACPI_STATUS status = AcpiGetTable((char *)ACPI_SIG_MADT, 1, &table);
    if (status != AE_OK) {
        TRACEF("could not find MADT\n");
        return ZX_ERR_NOT_FOUND;
    }
    ACPI_TABLE_MADT *madt = (ACPI_TABLE_MADT *)table;
    uintptr_t records_start = ((uintptr_t)madt) + sizeof(*madt);
    uintptr_t records_end = ((uintptr_t)madt) + madt->Header.Length;
    if (records_start >= records_end) {
        TRACEF("MADT wraps around address space\n");
        return ZX_ERR_INTERNAL;
    }
    // Shouldn't be too many records
    if (madt->Header.Length > 4096) {
        TRACEF("MADT suspiciously long: %u\n", madt->Header.Length);
        return ZX_ERR_INTERNAL;
    }
    *start = records_start;
    *end = records_end;
    return ZX_OK;
}

/* @brief Enumerate all functioning CPUs and their APIC IDs
 *
 * If apic_ids is NULL, just returns the number of logical processors
 * via num_cpus.
 *
 * @param apic_ids Array to write found APIC ids into.
 * @param len Length of apic_ids.
 * @param num_cpus Output for the number of logical processors detected.
 *
 * @return ZX_OK on success. Note that if len < *num_cpus, not all
 *         logical apic_ids will be returned.
 */
status_t platform_enumerate_cpus(
        uint32_t *apic_ids,
        uint32_t len,
        uint32_t *num_cpus)
{
    if (num_cpus == NULL) {
        return ZX_ERR_INVALID_ARGS;
    }

    uintptr_t records_start, records_end;
    status_t status = acpi_get_madt_record_limits(&records_start, &records_end);
    if (status != AE_OK) {
        return status;
    }
    uint32_t count = 0;
    uintptr_t addr;
    ACPI_SUBTABLE_HEADER *record_hdr;
    for (addr = records_start; addr < records_end; addr += record_hdr->Length) {
        record_hdr = (ACPI_SUBTABLE_HEADER *)addr;
        switch (record_hdr->Type) {
            case ACPI_MADT_TYPE_LOCAL_APIC: {
                ACPI_MADT_LOCAL_APIC *lapic = (ACPI_MADT_LOCAL_APIC *)record_hdr;
                if (!(lapic->LapicFlags & ACPI_MADT_ENABLED)) {
                    TRACEF("Skipping disabled processor %02x\n", lapic->Id);
                    continue;
                }
                if (apic_ids != NULL && count < len) {
                    apic_ids[count] = lapic->Id;
                }
                count++;
                break;
            }
        }
    }
    if (addr != records_end) {
      TRACEF("malformed MADT\n");
      return ZX_ERR_INTERNAL;
    }
    *num_cpus = count;
    return ZX_OK;
}

/* @brief Enumerate all IO APICs
 *
 * If io_apics is NULL, just returns the number of IO APICs
 * via num_io_apics.
 *
 * @param io_apics Array to populate descriptors into.
 * @param len Length of io_apics.
 * @param num_io_apics Number of IO apics found
 *
 * @return ZX_OK on success. Note that if len < *num_io_apics, not all
 *         IO APICs will be returned.
 */
status_t platform_enumerate_io_apics(
        struct io_apic_descriptor *io_apics,
        uint32_t len,
        uint32_t *num_io_apics)
{
    if (num_io_apics == NULL) {
        return ZX_ERR_INVALID_ARGS;
    }

    uintptr_t records_start, records_end;
    status_t status = acpi_get_madt_record_limits(&records_start, &records_end);
    if (status != AE_OK) {
        return status;
    }

    uint32_t count = 0;
    uintptr_t addr;
    for (addr = records_start; addr < records_end;) {
        ACPI_SUBTABLE_HEADER *record_hdr = (ACPI_SUBTABLE_HEADER *)addr;
        switch (record_hdr->Type) {
            case ACPI_MADT_TYPE_IO_APIC: {
                ACPI_MADT_IO_APIC *io_apic = (ACPI_MADT_IO_APIC *)record_hdr;
                if (io_apics != NULL && count < len) {
                    io_apics[count].apic_id = io_apic->Id;
                    io_apics[count].paddr = io_apic->Address;
                    io_apics[count].global_irq_base = io_apic->GlobalIrqBase;
                }
                count++;
                break;
            }
        }

        addr += record_hdr->Length;
    }
    if (addr != records_end) {
      TRACEF("malformed MADT\n");
      return ZX_ERR_INVALID_ARGS;
    }
    *num_io_apics = count;
    return ZX_OK;
}

/* @brief Enumerate all interrupt source overrides
 *
 * If isos is NULL, just returns the number of ISOs via num_isos.
 *
 * @param isos Array to populate overrides into.
 * @param len Length of isos.
 * @param num_isos Number of ISOs found
 *
 * @return ZX_OK on success. Note that if len < *num_isos, not all
 *         ISOs will be returned.
 */
status_t platform_enumerate_interrupt_source_overrides(
        struct io_apic_isa_override *isos,
        uint32_t len,
        uint32_t *num_isos)
{
    if (num_isos == NULL) {
        return ZX_ERR_INVALID_ARGS;
    }

    uintptr_t records_start, records_end;
    status_t status = acpi_get_madt_record_limits(&records_start, &records_end);
    if (status != AE_OK) {
        return status;
    }

    uint32_t count = 0;
    uintptr_t addr;
    for (addr = records_start; addr < records_end;) {
        ACPI_SUBTABLE_HEADER *record_hdr = (ACPI_SUBTABLE_HEADER *)addr;
        switch (record_hdr->Type) {
            case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE: {
                ACPI_MADT_INTERRUPT_OVERRIDE *iso =
                        (ACPI_MADT_INTERRUPT_OVERRIDE *)record_hdr;
                if (isos != NULL && count < len) {
                    ASSERT(iso->Bus == 0); // 0 means ISA, ISOs are only ever for ISA IRQs
                    isos[count].isa_irq = iso->SourceIrq;
                    isos[count].remapped = true;
                    isos[count].global_irq = iso->GlobalIrq;

                    uint32_t flags = iso->IntiFlags;
                    uint32_t polarity = flags & ACPI_MADT_POLARITY_MASK;
                    uint32_t trigger = flags & ACPI_MADT_TRIGGER_MASK;

                    // Conforms below means conforms to the bus spec.  ISA is
                    // edge triggered and active high.
                    switch (polarity) {
                        case ACPI_MADT_POLARITY_CONFORMS:
                        case ACPI_MADT_POLARITY_ACTIVE_HIGH:
                            isos[count].pol = IRQ_POLARITY_ACTIVE_HIGH;
                            break;
                        case ACPI_MADT_POLARITY_ACTIVE_LOW:
                            isos[count].pol = IRQ_POLARITY_ACTIVE_LOW;
                            break;
                        default:
                            panic("Unknown IRQ polarity in override: %u\n",
                                  polarity);
                    }

                    switch (trigger) {
                        case ACPI_MADT_TRIGGER_CONFORMS:
                        case ACPI_MADT_TRIGGER_EDGE:
                            isos[count].tm = IRQ_TRIGGER_MODE_EDGE;
                            break;
                        case ACPI_MADT_TRIGGER_LEVEL:
                            isos[count].tm = IRQ_TRIGGER_MODE_LEVEL;
                            break;
                        default:
                            panic("Unknown IRQ trigger in override: %u\n",
                                  trigger);
                    }
                }
                count++;
                break;
            }
        }

        addr += record_hdr->Length;
    }
    if (addr != records_end) {
      TRACEF("malformed MADT\n");
      return ZX_ERR_INVALID_ARGS;
    }
    *num_isos = count;
    return ZX_OK;
}

/* @brief Return information about the High Precision Event Timer, if present.
 *
 * @param hpet Descriptor to populate
 *
 * @return ZX_OK on success.
 */
status_t platform_find_hpet(struct acpi_hpet_descriptor *hpet)
{
    ACPI_TABLE_HEADER *table = NULL;
    ACPI_STATUS status = AcpiGetTable((char *)ACPI_SIG_HPET, 1, &table);
    if (status != AE_OK) {
        TRACEF("could not find HPET\n");
        return ZX_ERR_NOT_FOUND;
    }
    ACPI_TABLE_HPET *hpet_tbl = (ACPI_TABLE_HPET *)table;
    if (hpet_tbl->Header.Length != sizeof(ACPI_TABLE_HPET)) {
        TRACEF("Unexpected HPET table length\n");
        return ZX_ERR_NOT_FOUND;
    }

    hpet->minimum_tick = hpet_tbl->MinimumTick;
    hpet->sequence = hpet_tbl->Sequence;
    hpet->address = hpet_tbl->Address.Address;
    switch (hpet_tbl->Address.SpaceId) {
        case ACPI_ADR_SPACE_SYSTEM_IO: hpet->port_io = true; break;
        case ACPI_ADR_SPACE_SYSTEM_MEMORY: hpet->port_io = false; break;
        default: return ZX_ERR_NOT_SUPPORTED;
    }

    return ZX_OK;
}
