// Copyright 2018 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 <fuchsia/hardware/pciroot/c/banjo.h>
#include <inttypes.h>
#include <lib/pci/pciroot.h>
#include <lib/pci/pio.h>
#include <lib/pci/root_host.h>
#include <lib/zx/resource.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <zircon/status.h>
#include <zircon/syscalls/resource.h>
#include <zircon/types.h>

#include <memory>

#include <acpica/acpi.h>
#include <acpica/actypes.h>
#include <acpica/acuuid.h>
#include <bits/limits.h>
#include <ddk/debug.h>
#include <fbl/alloc_checker.h>
#include <fbl/array.h>
#include <fbl/string_buffer.h>
#include <fbl/vector.h>
#include <region-alloc/region-alloc.h>

#include "acpi-private.h"
#include "methods.h"
#include "resources.h"

// This file contains the implementation for the code supporting the in-progress userland
// pci bus driver.
std::unique_ptr<PciRootHost> RootHost = {};

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

// ACPICA will call this function for each resource found while walking a device object's resource
// list.
static ACPI_STATUS resource_report_callback(ACPI_RESOURCE* res, void* _ctx) {
  auto* ctx = static_cast<ResourceContext*>(_ctx);
  zx_status_t status;

  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;
    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;
    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;
    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 < MB(1)) {
    // The PC platform defines many legacy regions below 1MB that we do not
    // want PCIe to try to map onto.
    zxlogf(INFO, "Skipping adding MMIO range due to being below 1MB");
    return AE_OK;
  }

  // Add/Subtract the [base, len] region we found through ACPI to the allocators
  // that PCI can use to allocate BARs.
  RegionAllocator* alloc;
  if (is_mmio) {
    if (base + len < UINT32_MAX) {
      alloc = &RootHost->Mmio32();
    } else {
      alloc = &RootHost->Mmio64();
    }
  } else {
    alloc = &RootHost->Io();
  }

  zxlogf(DEBUG, "ACPI range modification: %sing %s %016lx %016lx", add_range ? "add" : "subtract",
         is_mmio ? "MMIO" : "PIO", base, len);
  // Not all resources ACPI informs us are in use are provided to us as
  // resources in the first search, so we allow Incomplete ranges in both add
  // and subtract passes.
  if (add_range) {
    status = alloc->AddRegion({.base = base, .size = len}, RegionAllocator::AllowOverlap::Yes);
  } else {
    status =
        alloc->SubtractRegion({.base = base, .size = len}, RegionAllocator::AllowIncomplete::Yes);
  }

  if (status != ZX_OK) {
    if (add_range) {
      zxlogf(INFO, "Failed to add range: [%#lx - %#lx] (%#lx): %d", base, base + len, len, status);
    } else {
      // If we are subtracting a range and fail, abort.  This is bad.
      zxlogf(INFO, "Failed to subtract range [%#lx - %#lx] (%#lx): %d", base, base + len, len,
             status);
      return AE_ERROR;
    }
  }
  return AE_OK;
}

// ACPICA will call this function once per device object found while walking the device
// tree off of the PCI root.
static ACPI_STATUS walk_devices_callback(ACPI_HANDLE object, uint32_t /*nesting_level*/, void* _ctx,
                                         void** /*ret*/) {
  acpi::UniquePtr<ACPI_DEVICE_INFO> info;
  auto res = acpi::GetObjectInfo(object);
  if (res.is_error()) {
    zxlogf(DEBUG, "acpi::GetObjectInfo failed %d", res.error_value());
    return res.error_value();
  }
  info = std::move(res.value());

  auto* ctx = static_cast<ResourceContext*>(_ctx);
  ctx->device_is_root_bridge = (info->Flags & ACPI_PCI_ROOT_BRIDGE) != 0;

  ACPI_STATUS status =
      AcpiWalkResources(object, const_cast<char*>("_CRS"), resource_report_callback, 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 scan_acpi_tree_for_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.
  ResourceContext ctx = {
      .pci_handle = root_resource_handle,
      .device_is_root_bridge = false,
      .add_pass = true,
  };
  ACPI_STATUS status = AcpiGetDevices(nullptr, walk_devices_callback, &ctx, nullptr);
  if (status != AE_OK) {
    return ZX_ERR_INTERNAL;
  }

  // Removes resources we believe are in use by other parts of the platform
  ctx.add_pass = false;
  status = AcpiGetDevices(nullptr, walk_devices_callback, &ctx, nullptr);
  if (status != AE_OK) {
    return ZX_ERR_INTERNAL;
  }

  return ZX_OK;
}

// Reads the MCFG table from ACPI and caches it for later calls
// to pci_ger_segment_mcfg_alloc()
static zx_status_t read_mcfg_table(std::vector<McfgAllocation>* mcfg_table) {
  // Systems will have an MCFG table unless they only support legacy PCI.
  ACPI_TABLE_HEADER* raw_table = nullptr;
  ACPI_STATUS status = AcpiGetTable(const_cast<char*>(ACPI_SIG_MCFG), 1, &raw_table);
  if (status != AE_OK) {
    zxlogf(DEBUG, "no MCFG table found.");
    return ZX_ERR_NOT_FOUND;
  }

  // The MCFG table contains a variable number of Extended Config tables
  // hanging off of the end.  Typically there will be one, but more
  // complicated systems may have multiple per PCI Host Bridge. The length in
  // the header is the overall size, so that is used to calculate how many
  // ECAMs are included.
  auto* mcfg = reinterpret_cast<ACPI_TABLE_MCFG*>(raw_table);
  uintptr_t table_start = reinterpret_cast<uintptr_t>(mcfg) + sizeof(ACPI_TABLE_MCFG);
  uintptr_t table_end = reinterpret_cast<uintptr_t>(mcfg) + mcfg->Header.Length;
  size_t table_bytes = table_end - table_start;
  if (table_bytes % sizeof(McfgAllocation)) {
    zxlogf(ERROR, "MCFG table has invalid size %zu", table_bytes);
    return ZX_ERR_INTERNAL;
  }

  // Each allocation corresponds to a particular PCI Segment Group. We'll
  // store them so that the protocol can return them for bus driver instances
  // later.
  for (unsigned i = 0; i < table_bytes / sizeof(acpi_mcfg_allocation); i++) {
    auto entry = &(reinterpret_cast<acpi_mcfg_allocation*>(table_start))[i];
    zxlogf(DEBUG, "MCFG allocation %u (Addr = %#llx, Segment = %u, Start = %u, End = %u)", i,
           entry->Address, entry->PciSegment, entry->StartBusNumber, entry->EndBusNumber);
    mcfg_table->push_back(
        {entry->Address, entry->PciSegment, entry->StartBusNumber, entry->EndBusNumber});
  }
  return ZX_OK;
}

zx_status_t pci_init_interrupts(ACPI_HANDLE object, x64Pciroot::Context* dev_ctx) {
  zx::vmo routing_vmo{};
  if (acpi::GetPciRootIrqRouting(object, dev_ctx) != AE_OK) {
    zxlogf(ERROR, "Failed to obtain PCI IRQ routing information, legacy IRQs will not function");
  }

  fbl::Array<pci_legacy_irq> irq_list(new pci_legacy_irq[dev_ctx->irqs.size()]{},
                                      dev_ctx->irqs.size());
  size_t irq_cnt = 0;
  fbl::StringBuffer<ZX_MAX_NAME_LEN> name = {};
  name.Append(dev_ctx->name, sizeof(dev_ctx->name));
  name.Append(" legacy");

  for (const auto& e : dev_ctx->irqs) {
    const uint32_t& vector = e.first;
    const acpi_legacy_irq& irq_cfg = e.second;
    zx::resource resource;
    zx_status_t status = zx::resource::create(*zx::unowned_resource(get_root_resource()),
                                              ZX_RSRC_KIND_IRQ | ZX_RSRC_FLAG_EXCLUSIVE, vector, 1,
                                              name.data(), name.size(), &resource);

    if (status != ZX_OK) {
      zxlogf(ERROR, "Couldn't create resource for legacy vector %#x: %s, skipping it", vector,
             zx_status_get_string(status));
      continue;
    }

    status =
        zx_interrupt_create(resource.get(), vector, irq_cfg.options, &irq_list[irq_cnt].interrupt);
    if (status != ZX_OK) {
      zxlogf(ERROR, "Couldn't create irq for legacy vector %#x: %s, skipping it", vector,
             zx_status_get_string(status));
      continue;
    }

    dev_ctx->irq_resources.push_back(std::move(resource));
    irq_list[irq_cnt].vector = vector;
    irq_cnt++;
  }

  dev_ctx->info.legacy_irqs_list = irq_list.release();
  dev_ctx->info.legacy_irqs_count = irq_cnt;
  return ZX_OK;
}

zx_status_t pci_init_segment_and_ecam(ACPI_HANDLE object, x64Pciroot::Context* dev_ctx) {
  zx_status_t status = acpi_bbn_call(object, &dev_ctx->info.start_bus_num);
  if (status != ZX_OK && status != ZX_ERR_NOT_FOUND) {
    zxlogf(DEBUG, "Unable to read _BBN for '%s' (%d), assuming base bus of 0", dev_ctx->name,
           status);

    // Until we find an ecam we assume this potential legacy pci bus spans
    // bus 0 to bus 255 in its segment group.
    dev_ctx->info.end_bus_num = PCI_BUS_MAX;
  }
  bool found_bbn = (status == ZX_OK);

  status = acpi_seg_call(object, &dev_ctx->info.segment_group);
  if (status != ZX_OK) {
    dev_ctx->info.segment_group = 0;
    zxlogf(DEBUG, "Unable to read _SEG for '%s' (%d), assuming segment group 0.", dev_ctx->name,
           status);
  }

  // If an MCFG is found for the given segment group this root has then we'll
  // cache it for later pciroot operations and use its information to populate
  // any fields missing via _BBN / _SEG.
  auto& pinfo = dev_ctx->info;
  memcpy(pinfo.name, dev_ctx->name, sizeof(pinfo.name));
  McfgAllocation mcfg_alloc;
  status = RootHost->GetSegmentMcfgAllocation(dev_ctx->info.segment_group, &mcfg_alloc);
  if (status == ZX_OK) {
    // Print a warning if _BBN and MCFG bus numbers don't match. We'll use the
    // MCFG first if we have one, but a mismatch likely represents an error in
    // an ACPI table.
    if (found_bbn && mcfg_alloc.start_bus_number != pinfo.start_bus_num) {
      zxlogf(WARNING, "conflicting base bus num for '%s', _BBN reports %u and MCFG reports %u",
             dev_ctx->name, pinfo.start_bus_num, mcfg_alloc.start_bus_number);
    }

    // Same situation with Segment Group as with bus number above.
    if (pinfo.segment_group != 0 && pinfo.segment_group != mcfg_alloc.pci_segment) {
      zxlogf(WARNING, "conflicting segment group for '%s', _BBN reports %u and MCFG reports %u",
             dev_ctx->name, pinfo.segment_group, mcfg_alloc.pci_segment);
    }

    // Since we have an ecam its metadata will replace anything defined in the ACPI tables.
    pinfo.segment_group = mcfg_alloc.pci_segment;
    pinfo.start_bus_num = mcfg_alloc.start_bus_number;
    pinfo.end_bus_num = mcfg_alloc.end_bus_number;

    // The bus driver needs a VMO representing the entire ecam region so it can map it in.
    // The range from start_bus_num to end_bus_num is inclusive.
    size_t ecam_size = (pinfo.end_bus_num - pinfo.start_bus_num + 1) * PCIE_ECAM_BYTES_PER_BUS;
    zx_paddr_t vmo_base = mcfg_alloc.address + (pinfo.start_bus_num * PCIE_ECAM_BYTES_PER_BUS);
    // Please do not use get_root_resource() in new code. See fxbug.dev/31358.
    status = zx_vmo_create_physical(get_root_resource(), vmo_base, ecam_size, &pinfo.ecam_vmo);
    if (status != ZX_OK) {
      zxlogf(ERROR, "couldn't create VMO for ecam, mmio cfg will not work: %s!",
             zx_status_get_string(status));
      return status;
    }
  }

  if (zxlog_level_enabled(DEBUG)) {
    fbl::StringBuffer<128> log;
    log.AppendPrintf("%s { acpi_obj(%p), bus range: %u:%u, segment: %u", dev_ctx->name,
                     dev_ctx->acpi_object, pinfo.start_bus_num, pinfo.end_bus_num,
                     pinfo.segment_group);
    if (pinfo.ecam_vmo != ZX_HANDLE_INVALID) {
      log.AppendPrintf(", ecam base: %#" PRIxPTR, mcfg_alloc.address);
    }
    log.AppendPrintf(" }");
    zxlogf(DEBUG, "%s", log.c_str());
  }

  return ZX_OK;
}

// Parse the MCFG table and initialize the window allocators for the RootHost if this is the first
// root found.
zx_status_t pci_root_host_init() {
  static bool initialized = false;
  if (initialized) {
    return ZX_OK;
  }

  if (!RootHost) {
    RootHost = std::make_unique<PciRootHost>(zx::unowned_resource(get_root_resource()),
                                             /*io_type=*/PCI_ADDRESS_SPACE_IO);
  }

  zx_status_t st = read_mcfg_table(&RootHost->mcfgs());
  if (st != ZX_OK) {
    return st;
  }

  st = scan_acpi_tree_for_resources(get_root_resource());
  if (st != ZX_OK) {
    zxlogf(ERROR, "Scanning acpi resources failed: %s", zx_status_get_string(st));
    return st;
  }

  initialized = true;
  return ZX_OK;
}

zx_status_t pci_init(zx_device_t* sys_root, zx_device_t* parent, ACPI_HANDLE object,
                     ACPI_DEVICE_INFO* info) {
  zx_status_t status = pci_root_host_init();
  if (status != ZX_OK) {
    zxlogf(ERROR, "Error initializing PCI root host, attempting to boot regardless: %d", status);
  }

  // Build up a context structure for the PCI Root / Host Bridge we've found.
  // If we find _BBN / _SEG we will use those, but if we don't we can fall
  // back on having an ecam from mcfg allocations.
  x64Pciroot::Context dev_ctx = {};
  dev_ctx.platform_bus = parent;
  dev_ctx.acpi_object = object;
  dev_ctx.acpi_device_info = *info;
  // ACPI names are stored as 4 bytes in a u32
  memcpy(dev_ctx.name, &info->Name, 4);

  status = pci_init_segment_and_ecam(object, &dev_ctx);
  if (status != ZX_OK) {
    zxlogf(ERROR, "Initializing %.*s ecam and bus information failed: %s",
           static_cast<int>(sizeof(dev_ctx.name)), dev_ctx.name, zx_status_get_string(status));
    return status;
  }

  status = pci_init_interrupts(object, &dev_ctx);
  if (status != ZX_OK) {
    zxlogf(ERROR, "Initializing %.*s interrupt information failed: %s",
           static_cast<int>(sizeof(dev_ctx.name)), dev_ctx.name, zx_status_get_string(status));
    return status;
  }

  // These are cached here to work around dev_ctx potentially going out of scope
  // after device_add in the event that unbind/release are called from the DDK. See
  // the below TODO for more information.
  char name[ZX_DEVICE_NAME_MAX] = {0};
  memcpy(name, dev_ctx.name, ACPI_NAMESEG_SIZE);

  status = x64Pciroot::Create(&*RootHost, std::move(dev_ctx), parent, name);
  if (status != ZX_OK) {
    zxlogf(ERROR, "failed to add pciroot device for '%s': %d", name, status);
  } else {
    zxlogf(INFO, "published pciroot '%s'", name);
  }

  return status;
}
