// Copyright 2020 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 <assert.h>
#include <fuchsia/hardware/pciroot/c/banjo.h>
#include <lib/fitx/result.h>
#include <lib/pci/pciroot.h>
#include <stdio.h>

#include <array>
#include <cstring>
#include <optional>

#include <acpica/acpi.h>

#include "acpi-buffer.h"
#include "acpi-private.h"
#include "pci.h"

// Legacy PCI device functions have a single interrupt that was traditionally
// wired directly into the interrupt controller. There are only four interrupt
// lines shared among devices, labeled A through D. When an interrupt is
// triggered on one of these lines it's the responsibility of system software to
// look at all devices using the line wired to that vector and check which
// device has their interrupt status bit flipped. To properly configure these
// legacy interrupts at the platform level we need to read the PCI Routing
// Tables (_PRT) for each root port found. PCI Routing Tables represent a
// mapping between a root device/function adddress and an Interrupt Link Device
// (ILD) or hardware vector. This ILD contains a resource that details how it is
// wired up, and how the interrupt needs to be configured. Using this we can
// build a routing table between a given BDF pin and a hard vector in the bus
// driver.

namespace {

struct PortInfo {
  uint8_t dev_id;
  uint8_t func_id;
};

constexpr const char* im_to_str(uint32_t irq_mode) {
  switch (irq_mode) {
    case ZX_INTERRUPT_MODE_EDGE_LOW:
      return "edge triggered, active low";
    case ZX_INTERRUPT_MODE_EDGE_HIGH:
      return "edge triggered, active high";
    case ZX_INTERRUPT_MODE_LEVEL_HIGH:
      return "level triggered, active high";
    case ZX_INTERRUPT_MODE_LEVEL_LOW:
      return "level triggered, active low";
    default:
      return "<unsupported irq mode>";
  }
}

// Find Extended IRQ information for a PRT's Interrupt Link Device.
fitx::result<ACPI_STATUS, ACPI_RESOURCE_EXTENDED_IRQ> FindExtendedIrqResource(ACPI_HANDLE parent,
                                                                              char source[4]) {
  // If this method is called then we're attempting to find the Interrupt Link Device referenced by
  // a given PRT entry.
  ACPI_HANDLE ild;
  ACPI_STATUS status = AcpiGetHandle(parent, source, &ild);
  if (status != AE_OK) {
    return fitx::error(status);
  }

  acpi::AcpiBuffer<ACPI_RESOURCE> crs_buffer;
  status = AcpiGetCurrentResources(ild, &crs_buffer);
  if (status != AE_OK) {
    return fitx::error(status);
  }

  for (auto& res : crs_buffer) {
    if (res.Type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) {
      return fitx::ok(res.Data.ExtendedIrq);
    }
  }
  return fitx::error(AE_NOT_FOUND);
}

// Take a PRT entry and return a usable acpi_legacy_irq based on the type of IRQ
// source information we were able to find in the ACPI table.
acpi_legacy_irq PrtEntryToIrq(ACPI_HANDLE object, ACPI_PCI_ROUTING_TABLE* entry) {
  // By default, SourceIndex refers to a global IRQ number that the pin is
  // connected to and we assume the legacy defaults of Level-triggered / Active Low.
  // PCI Local Bus Specification 3.0 section 2.2.6
  acpi_legacy_irq new_irq = {.vector = entry->SourceIndex, .options = ZX_INTERRUPT_MODE_LEVEL_LOW};
  // If the PRT contains a Source entry than we can attempt to find an Extended
  // IRQ Resource describing it.
  if (entry->Source[0]) {
    if (auto result = FindExtendedIrqResource(object, entry->Source); result.is_ok()) {
      new_irq.vector = result->Interrupts[0];
      if (result->Triggering == ACPI_LEVEL_SENSITIVE) {
        if (result->Polarity == ACPI_ACTIVE_HIGH) {
          new_irq.options = ZX_INTERRUPT_MODE_LEVEL_HIGH;
        } else {
          new_irq.options = ZX_INTERRUPT_MODE_LEVEL_LOW;
        }
      } else {
        if (result->Polarity == ACPI_ACTIVE_HIGH) {
          new_irq.options = ZX_INTERRUPT_MODE_EDGE_HIGH;
        } else {
          new_irq.options = ZX_INTERRUPT_MODE_EDGE_LOW;
        }
      }
    }
  }

  return new_irq;
}

void AddIrqToAccounting(acpi_legacy_irq irq, x64Pciroot::Context* context,
                        ACPI_PCI_ROUTING_TABLE* entry, std::optional<PortInfo> port,
                        uint8_t local_dev_id) {
  // The first time we find an irq in a PRT it should be stored in the root's
  // context so that later it can be passed to the PCI bus driver.
  auto vector_entry = context->irqs.find(irq.vector);
  if (vector_entry == context->irqs.end()) {
    context->irqs[irq.vector] = irq;
    zxlogf(DEBUG, "added vector %#x { %s } from PRT", irq.vector, im_to_str(irq.options));
  } else if (vector_entry->second.options != irq.options) {
    // This may not be fatal, but it would represent a misconfiguration that
    // would likely result in some devices wired to this pin to have
    // malfunctioning IRQs. It would most likely reflect an error in an ACPI
    // table, but we cannot do much about it without knowing which configuration
    // is correct. In lieu of that, go with the first.
    zxlogf(WARNING, "Multiple IRQ configurations found in PRT for vector %#x!", irq.vector);
  }

  auto& routing_vec = context->routing;
  auto find_fn = [local_dev_id, port](auto& e) -> bool {
    return ((port) ? port->dev_id : PCI_IRQ_ROUTING_NO_PARENT) == e.port_device_id &&
           ((port) ? port->func_id : PCI_IRQ_ROUTING_NO_PARENT) == e.port_function_id &&
           local_dev_id == e.device_id;
  };

  // Lastly, based on the device / function address provided we need to update the routing
  // table to reflect the new information we've found. If we have a valid device / function
  // address then we can update that entry, otherwise a new entry needs to be made for that
  // combination of port and child device. This would be easier in a map, but a vector allows us to
  // directly point to the backing storage in the pciroot protocol implementation.
  if (auto found_entry = std::find_if(routing_vec.begin(), routing_vec.end(), find_fn);
      found_entry != std::end(routing_vec)) {
    found_entry->pins[entry->Pin] = irq.vector;
  } else {
    pci_irq_routing_entry_t new_entry = {
        .port_device_id = (port) ? port->dev_id : static_cast<uint8_t>(PCI_IRQ_ROUTING_NO_PARENT),
        .port_function_id =
            (port) ? port->func_id : static_cast<uint8_t>(PCI_IRQ_ROUTING_NO_PARENT),
        .device_id = local_dev_id,
        .pins = {0},
    };
    new_entry.pins[entry->Pin] = irq.vector;
    routing_vec.push_back(new_entry);
  }
}

ACPI_STATUS ReadPciRoutingTable(ACPI_HANDLE object, x64Pciroot::Context* context,
                                std::optional<PortInfo> port) {
  acpi::AcpiBuffer<ACPI_PCI_ROUTING_TABLE> irt_buffer;
  ACPI_STATUS status = AcpiGetIrqRoutingTable(object, &irt_buffer);
  if (status != AE_OK) {
    return status;
  }

  for (auto& entry : irt_buffer) {
    if (entry.Pin >= PCI_MAX_LEGACY_IRQ_PINS) {
      zxlogf(ERROR, "PRT entry contains an invalid pin: %#x", entry.Pin);
      return AE_ERROR;
    }

    zxlogf(TRACE,
           "_PRT Entry RootPort %02x.%1x: .Address = 0x%05llx, .Pin = %u, .SourceIndex = %u, "
           ".Source = \"%s\"",
           (port) ? port->dev_id : 0, (port) ? port->func_id : 0, entry.Address, entry.Pin,
           entry.SourceIndex, entry.Source);

    // Per ACPI Spec 6.2.13, all _PRT entries must have a function address of
    // 0xFFFF representing all functions in the device. In effect, this means we
    // only care about the entry's dev id.
    uint8_t dev_id = (entry.Address >> 16) & (PCI_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 not, the entry is strange and we'll warn / skip it.
    if (port && dev_id != 0) {
      zxlogf(WARNING, "PRT entry for root %.*s unexpected contains device address: %#x",
             static_cast<int>(sizeof(context->name)), context->name, dev_id);
      continue;
    }

    acpi_legacy_irq new_irq = PrtEntryToIrq(object, &entry);
    AddIrqToAccounting(new_irq, context, &entry, port, dev_id);
  }

  return AE_OK;
}

}  // namespace

namespace acpi {

ACPI_STATUS GetPciRootIrqRouting(ACPI_HANDLE root_obj, x64Pciroot::Context* context) {
  // Start with the Root's _PRT. The spec requires that one exists.
  ACPI_STATUS status = ReadPciRoutingTable(root_obj, context, std::nullopt);
  if (status != AE_OK) {
    zxlogf(DEBUG, "Couldn't find an IRQ routing table for root %.*s",
           static_cast<int>(sizeof(context->name)), context->name);
    return status;
  }

  // If there are any host bridges / pcie-to-pci bridges or other ports under
  // the root then check them for PRTs as well. This is unncecessary in most
  // configurations.
  ACPI_HANDLE child = nullptr;
  while ((status = AcpiGetNextObject(ACPI_TYPE_DEVICE, root_obj, child, &child)) == AE_OK) {
    if (auto res = acpi::GetObjectInfo(child); res.is_ok()) {
      // If the object we're examining has a PCI address then use that as the
      // basis for the routing table we're inspecting.
      // Format: Acpi 6.1 section 6.1.1 "_ADR (Address)"
      PortInfo port{
          .dev_id = static_cast<uint8_t>((res->Address >> 16) & (PCI_MAX_DEVICES_PER_BUS - 1)),
          .func_id = static_cast<uint8_t>(res->Address & (PCI_MAX_FUNCTIONS_PER_DEVICE - 1)),
      };
      zxlogf(DEBUG, "Processing _PRT for %02x.%1x (%.*s)", port.dev_id, port.func_id, 4,
             reinterpret_cast<char*>(&res->Name));
      // Ignore the return value of this, since if child is not a root port, it
      // will fail and we don't care.
      ReadPciRoutingTable(child, context, port);
    }
  }

  return AE_OK;
}

}  // namespace acpi
