// 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 <align.h>
#include <lib/page/size.h>
#include <lib/pci/kpci.h>
#include <lib/pci/pio.h>
#include <lib/syscalls/forward.h>
#include <lib/user_copy/user_ptr.h>
#include <platform.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <trace.h>
#include <zircon/errors.h>
#include <zircon/syscalls/pci.h>
#include <zircon/types.h>

#include <dev/address_provider/ecam_region.h>
#include <dev/interrupt.h>
#include <dev/pcie_bus_driver.h>
#include <dev/pcie_root.h>
#include <fbl/algorithm.h>
#include <fbl/alloc_checker.h>
#include <fbl/ref_ptr.h>
#include <ktl/algorithm.h>
#include <ktl/iterator.h>
#include <ktl/limits.h>
#include <ktl/unique_ptr.h>
#include <object/handle.h>
#include <object/pci_device_dispatcher.h>
#include <object/process_dispatcher.h>
#include <object/resource.h>
#include <object/vm_object_dispatcher.h>
#include <vm/vm_object_physical.h>

#include <ktl/enforce.h>

#define LOCAL_TRACE 0

// Implementation of a PcieRoot with a look-up table based legacy IRQ swizzler
// suitable for use with ACPI style swizzle definitions.
class PcieRootLUTSwizzle : public PcieRoot {
 public:
  static fbl::RefPtr<PcieRoot> Create(PcieBusDriver& bus_drv, uint managed_bus_id,
                                      const zx_pci_irq_swizzle_lut_t& lut) {
    fbl::AllocChecker ac;
    auto root = fbl::AdoptRef(new (&ac) PcieRootLUTSwizzle(bus_drv, managed_bus_id, lut));
    if (!ac.check()) {
      TRACEF("Out of memory attemping to create PCIe root to manage bus ID 0x%02x\n",
             managed_bus_id);
      return nullptr;
    }

    return root;
  }

  zx_status_t Swizzle(uint dev_id, uint func_id, uint pin, uint* irq) override {
    if ((irq == nullptr) || (dev_id >= ktl::size(lut_)) || (func_id >= ktl::size(lut_[dev_id])) ||
        (pin >= ktl::size(lut_[dev_id][func_id])))
      return ZX_ERR_INVALID_ARGS;

    *irq = lut_[dev_id][func_id][pin];
    return (*irq == ZX_PCI_NO_IRQ_MAPPING) ? ZX_ERR_NOT_FOUND : ZX_OK;
  }

 private:
  PcieRootLUTSwizzle(PcieBusDriver& bus_drv, uint managed_bus_id,
                     const zx_pci_irq_swizzle_lut_t& lut)
      : PcieRoot(bus_drv, managed_bus_id) {
    ::memcpy(&lut_, &lut, sizeof(lut_));
  }

  zx_pci_irq_swizzle_lut_t lut_;
};

// Scan |lut| for entries mapping to |irq|, and replace them with
// ZX_PCI_NO_IRQ_MAPPING.
static void pci_irq_swizzle_lut_remove_irq(zx_pci_irq_swizzle_lut_t* lut, uint32_t irq) {
  for (size_t dev = 0; dev < ktl::size(*lut); ++dev) {
    for (size_t func = 0; func < ktl::size((*lut)[dev]); ++func) {
      for (size_t pin = 0; pin < ktl::size((*lut)[dev][func]); ++pin) {
        uint32_t* assigned_irq = &(*lut)[dev][func][pin];
        if (*assigned_irq == irq) {
          *assigned_irq = ZX_PCI_NO_IRQ_MAPPING;
        }
      }
    }
  }
}

// zx_status_t zx_pci_add_subtract_io_range
zx_status_t sys_pci_add_subtract_io_range(zx_handle_t handle, uint32_t mmio, uint64_t base,
                                          uint64_t len, uint32_t add) {
  if (!Pci::KernelPciEnabled()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  bool is_add = (add > 0);
  bool is_mmio = (mmio > 0);
  LTRACEF("handle %x mmio %d base %#" PRIx64 " len %#" PRIx64 " add %d\n", handle, is_mmio, base,
          len, is_add);

  zx_status_t status = validate_resource_mmio(handle, base, len);

  if (status < 0) {
    return status;
  }

  auto pcie = PcieBusDriver::GetDriver();
  if (pcie == nullptr) {
    return ZX_ERR_BAD_STATE;
  }

  PciAddrSpace addr_space = is_mmio ? PciAddrSpace::MMIO : PciAddrSpace::PIO;

  if (is_add) {
    return pcie->AddBusRegion(base, len, addr_space);
  } else {
    return pcie->SubtractBusRegion(base, len, addr_space);
  }
}

static inline PciEcamRegion addr_window_to_pci_ecam_region(zx_pci_init_arg_t* arg, size_t index) {
  ASSERT(index < arg->addr_window_count);

  const PciEcamRegion result = {
      .phys_base = static_cast<paddr_t>(arg->addr_windows[index].base),
      .size = arg->addr_windows[index].size,
      .bus_start = arg->addr_windows[index].bus_start,
      .bus_end = arg->addr_windows[index].bus_end,
  };

  return result;
}

static inline bool is_designware(const zx_pci_init_arg_t* arg) {
  for (size_t i = 0; i < arg->addr_window_count; i++) {
    if ((arg->addr_windows[i].cfg_space_type == PCI_CFG_SPACE_TYPE_DW_ROOT) ||
        (arg->addr_windows[i].cfg_space_type == PCI_CFG_SPACE_TYPE_DW_DS)) {
      return true;
    }
  }

  return false;
}

// zx_status_t zx_pci_init
zx_status_t sys_pci_init(zx_handle_t handle, user_in_ptr<const zx_pci_init_arg_t> init_buf,
                         uint32_t len) {
  if (!Pci::KernelPciEnabled()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  // This can't use plain `new` because it's a variable-sized struct, really a
  // struct plus an array, but not just a proper array.
  struct OperatorArrayDeleter {
    void operator()(void* ptr) const {
      operator delete[](ptr, ktl::align_val_t{alignof(zx_pci_init_arg_t)});
    }
  };
  using ArgPtr = ktl::unique_ptr<zx_pci_init_arg_t, OperatorArrayDeleter>;
  auto NewArray = [len](fbl::AllocChecker& ac) {
    return ArgPtr{static_cast<zx_pci_init_arg_t*>(operator new[](
        len, ktl::align_val_t{alignof(zx_pci_init_arg_t)}, ac))};
  };

  zx_status_t status;
  if ((status = validate_resource(handle, ZX_RSRC_KIND_MMIO)) < 0) {
    return status;
  }

  ArgPtr arg;
  if (len < sizeof(*arg) || len > ZX_PCI_INIT_ARG_MAX_SIZE) {
    return ZX_ERR_INVALID_ARGS;
  }

  auto pcie = PcieBusDriver::GetDriver();
  if (pcie == nullptr)
    return ZX_ERR_BAD_STATE;

  if (fbl::AllocChecker ac; arg = NewArray(ac), !ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }

  // Copy in the base struct.
  status = init_buf.copy_from_user(arg.get());
  if (status != ZX_OK) {
    return status;
  }

  const uint32_t win_count = arg->addr_window_count;
  if (win_count > 0) {
    auto addr_windows = init_buf.flex_array<&zx_pci_init_arg_t::addr_windows>(win_count, len);
    if (addr_windows.is_error()) {
      return addr_windows.error_value();
    }

    status = addr_windows->copy_array_from_user(arg->addr_windows, win_count);
    if (status != ZX_OK) {
      return status;
    }
  }

  if (arg->num_irqs > ktl::size(arg->irqs)) {
    return ZX_ERR_INVALID_ARGS;
  }

  if (LOCAL_TRACE) {
    const char* kAddrWindowTypes[] = {"PIO", "MMIO", "DW Root Bridge (MMIO)",
                                      "DW Downstream (MMIO)", "Unknown"};
    TRACEF("%u address window%s found in init arg\n", arg->addr_window_count,
           (arg->addr_window_count == 1) ? "" : "s");
    for (uint32_t i = 0; i < arg->addr_window_count; i++) {
      const size_t window_type_idx =
          ktl::min(ktl::size(kAddrWindowTypes) - 1,
                   static_cast<size_t>(arg->addr_windows[i].cfg_space_type));
      const char* window_type_name = kAddrWindowTypes[window_type_idx];

      printf("[%u]\n\tcfg_space_type: %s\n\thas_ecam: %d\n\tbase: %#" PRIxPTR
             "\n"
             "\tsize: %zu\n\tbus_start: %u\n\tbus_end: %u\n",
             i, window_type_name, arg->addr_windows[i].has_ecam, arg->addr_windows[i].base,
             arg->addr_windows[i].size, arg->addr_windows[i].bus_start,
             arg->addr_windows[i].bus_end);
    }
  }

  // Configure interrupts
  for (unsigned int i = 0; i < arg->num_irqs; ++i) {
    uint32_t irq = arg->irqs[i].global_irq;
    if (!is_valid_interrupt(irq, 0)) {
      // If the interrupt isn't valid, mask it out of the IRQ swizzle table
      // and don't activate it.  Attempts to use legacy IRQs for the device
      // will fail later.
      arg->irqs[i].global_irq = ZX_PCI_NO_IRQ_MAPPING;
      pci_irq_swizzle_lut_remove_irq(&arg->dev_pin_to_global_irq, irq);
      continue;
    }

    interrupt_trigger_mode tm = interrupt_trigger_mode::EDGE;
    if (arg->irqs[i].level_triggered) {
      tm = interrupt_trigger_mode::LEVEL;
    }
    enum interrupt_polarity pol = interrupt_polarity::LOW;
    if (arg->irqs[i].active_high) {
      pol = interrupt_polarity::HIGH;
    }

    zx_status_t configure_status = configure_interrupt(irq, tm, pol);
    if (configure_status != ZX_OK) {
      return configure_status;
    }
  }
  // TODO(teisenbe): For now assume there is only one ECAM, unless it's a
  // DesignWare Controller.
  // The DesignWare controller needs exactly two windows: One specifying where
  // the root bridge is and the other specifying where the downstream devices
  // are.
  if (is_designware(arg.get())) {
    if (win_count != 2) {
      return ZX_ERR_INVALID_ARGS;
    }
  } else {
    if (win_count != 1) {
      return ZX_ERR_INVALID_ARGS;
    }
  }

  if (arg->addr_windows[0].bus_start != 0) {
    return ZX_ERR_INVALID_ARGS;
  }

  if (arg->addr_windows[0].bus_start > arg->addr_windows[0].bus_end) {
    return ZX_ERR_INVALID_ARGS;
  }

#if ARCH_X86
  // Check for a quirk that we've seen.  Some systems will report overly large
  // PCIe config regions that collide with architectural registers.
  unsigned int num_buses = arg->addr_windows[0].bus_end - arg->addr_windows[0].bus_start + 1;
  paddr_t end = arg->addr_windows[0].base + num_buses * PCIE_ECAM_BYTE_PER_BUS;
  const paddr_t high_limit = 0xfec00000ULL;
  if (end > high_limit) {
    TRACEF("PCIe config space collides with arch devices, truncating\n");
    end = high_limit;
    if (end < arg->addr_windows[0].base) {
      return ZX_ERR_INVALID_ARGS;
    }
    arg->addr_windows[0].size = ROUNDDOWN(end - arg->addr_windows[0].base, PCIE_ECAM_BYTE_PER_BUS);
    uint64_t new_bus_end =
        (arg->addr_windows[0].size / PCIE_ECAM_BYTE_PER_BUS) + arg->addr_windows[0].bus_start - 1;
    if (new_bus_end >= PCIE_MAX_BUSSES) {
      return ZX_ERR_INVALID_ARGS;
    }
    arg->addr_windows[0].bus_end = static_cast<uint8_t>(new_bus_end);
  }
#endif

  if (arg->addr_windows[0].cfg_space_type == PCI_CFG_SPACE_TYPE_MMIO) {
    if (arg->addr_windows[0].size < PCIE_ECAM_BYTE_PER_BUS) {
      return ZX_ERR_INVALID_ARGS;
    }
    if (arg->addr_windows[0].size / PCIE_ECAM_BYTE_PER_BUS >
        PCIE_MAX_BUSSES - arg->addr_windows[0].bus_start) {
      return ZX_ERR_INVALID_ARGS;
    }

    // TODO(johngro): Update the syscall to pass a paddr_t for base instead of a uint64_t
    ASSERT(arg->addr_windows[0].base < ktl::numeric_limits<paddr_t>::max());

    fbl::AllocChecker ac;
    auto addr_provider = ktl::make_unique<MmioPcieAddressProvider>(&ac);
    if (!ac.check()) {
      TRACEF("Failed to allocate PCIe Address Provider\n");
      return ZX_ERR_NO_MEMORY;
    }

    // TODO(johngro): Do not limit this to a single range.  Instead, fetch all
    // of the ECAM ranges from ACPI, as well as the appropriate bus start/end
    // ranges.
    const PciEcamRegion ecam = {
        .phys_base = static_cast<paddr_t>(arg->addr_windows[0].base),
        .size = arg->addr_windows[0].size,
        .bus_start = 0x00,
        .bus_end = static_cast<uint8_t>((arg->addr_windows[0].size / PCIE_ECAM_BYTE_PER_BUS) - 1),
    };

    zx_status_t ret = addr_provider->AddEcamRegion(ecam);
    if (ret != ZX_OK) {
      TRACEF("Failed to add ECAM region to PCIe bus driver! (ret %d)\n", ret);
      return ret;
    }

    ret = pcie->SetAddressTranslationProvider(ktl::move(addr_provider));
    if (ret != ZX_OK) {
      TRACEF("Failed to set Address Translation Provider, st = %d\n", ret);
      return ret;
    }
  } else if (arg->addr_windows[0].cfg_space_type == PCI_CFG_SPACE_TYPE_PIO) {
    // Create a PIO address provider.
    fbl::AllocChecker ac;

    auto addr_provider = ktl::make_unique<PioPcieAddressProvider>(&ac);
    if (!ac.check()) {
      TRACEF("Failed to allocate PCIe address provider\n");
      return ZX_ERR_NO_MEMORY;
    }

    zx_status_t ret = pcie->SetAddressTranslationProvider(ktl::move(addr_provider));
    if (ret != ZX_OK) {
      TRACEF("Failed to set Address Translation Provider, st = %d\n", ret);
      return ret;
    }
  } else if (is_designware(arg.get())) {
    fbl::AllocChecker ac;

    if (win_count < 2) {
      TRACEF("DesignWare Config Space requires at least 2 windows\n");
      return ZX_ERR_INVALID_ARGS;
    }

    auto addr_provider = ktl::make_unique<DesignWarePcieAddressProvider>(&ac);
    if (!ac.check()) {
      TRACEF("Failed to allocate PCIe address provider\n");
      return ZX_ERR_NO_MEMORY;
    }

    PciEcamRegion dw_root_bridge{};
    PciEcamRegion dw_downstream{};
    for (size_t i = 0; i < win_count; i++) {
      switch (arg->addr_windows[i].cfg_space_type) {
        case PCI_CFG_SPACE_TYPE_DW_ROOT:
          dw_root_bridge = addr_window_to_pci_ecam_region(arg.get(), i);
          break;
        case PCI_CFG_SPACE_TYPE_DW_DS:
          dw_downstream = addr_window_to_pci_ecam_region(arg.get(), i);
          break;
      }
    }

    if (dw_root_bridge.size == 0 || dw_downstream.size == 0) {
      TRACEF("Did not find DesignWare root and downstream device in init arg\n");
      return ZX_ERR_INVALID_ARGS;
    }

    zx_status_t ret = addr_provider->Init(dw_root_bridge, dw_downstream);
    if (ret != ZX_OK) {
      TRACEF("Failed to initialize DesignWare PCIe Address Provider, error = %d\n", ret);
      return ret;
    }

    ret = pcie->SetAddressTranslationProvider(ktl::move(addr_provider));
    if (ret != ZX_OK) {
      TRACEF("Failed to set Address Translation Provider, st = %d\n", ret);
      return ret;
    }

  } else {
    TRACEF("Unknown config space type!\n");
    return ZX_ERR_INVALID_ARGS;
  }
  // TODO(johngro): Change the user-mode and devmgr behavior to add all of the
  // roots in the system.  Do not assume that there is a single root, nor that
  // it manages bus ID 0.
  auto root = PcieRootLUTSwizzle::Create(*pcie, 0, arg->dev_pin_to_global_irq);
  if (root == nullptr)
    return ZX_ERR_NO_MEMORY;

  zx_status_t ret = pcie->AddRoot(ktl::move(root));
  if (ret != ZX_OK) {
    TRACEF("Failed to add root complex to PCIe bus driver! (ret %d)\n", ret);
    return ret;
  }

  ret = pcie->StartBusDriver();
  if (ret != ZX_OK) {
    TRACEF("Failed to start PCIe bus driver! (ret %d)\n", ret);
    return ret;
  }

  return ZX_OK;
}

// zx_status_t zx_pci_get_nth_device
zx_status_t sys_pci_get_nth_device(zx_handle_t hrsrc, uint32_t index,
                                   user_out_ptr<zx_pcie_device_info_t> out_info,
                                   zx_handle_t* out_handle) {
  if (!Pci::KernelPciEnabled()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  /**
   * Returns the pci config of a device.
   * @param index Device index
   * @param out_info Device info (BDF address, vendor id, etc...)
   */
  LTRACEF("handle %x index %u\n", hrsrc, index);

  zx_status_t status;
  if ((status = validate_resource_irq(hrsrc, index)) < 0) {
    return status;
  }

  if (!out_info) {
    return ZX_ERR_INVALID_ARGS;
  }

  KernelHandle<PciDeviceDispatcher> handle;
  zx_rights_t rights;
  zx_pcie_device_info_t info{};
  status = PciDeviceDispatcher::Create(index, &info, &handle, &rights);
  if (status != ZX_OK) {
    return status;
  }

  // If everything is successful add the handle to the process
  status = out_info.copy_to_user(info);
  if (status != ZX_OK)
    return status;

  return ProcessDispatcher::GetCurrent()->MakeAndAddHandle(ktl::move(handle), rights, out_handle);
}

// zx_status_t zx_pci_config_read
zx_status_t sys_pci_config_read(zx_handle_t handle, uint16_t offset, size_t width,
                                user_out_ptr<uint32_t> out_val) {
  if (!Pci::KernelPciEnabled()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  fbl::RefPtr<PciDeviceDispatcher> pci_device;
  fbl::RefPtr<Dispatcher> dispatcher;

  // Get the PciDeviceDispatcher from the handle passed in via the pci protocol
  auto up = ProcessDispatcher::GetCurrent();
  zx_status_t status = up->handle_table().GetDispatcherWithRights(
      *up, handle, ZX_RIGHT_READ | ZX_RIGHT_WRITE, &pci_device);
  if (status != ZX_OK) {
    return status;
  }

  auto device = pci_device->device();
  auto cfg_size = device->is_pcie() ? PCIE_EXTENDED_CONFIG_SIZE : PCIE_BASE_CONFIG_SIZE;
  if (out_val.get() == nullptr || offset + width > cfg_size) {
    return ZX_ERR_INVALID_ARGS;
  }

  // Based on the width passed in we can use the type safety of the PciConfig layer
  // to ensure we're getting correctly sized data back and return errors in the PIO
  // cases.
  auto config = device->config();
  switch (width) {
    case 1u:
      return out_val.copy_to_user(static_cast<uint32_t>(config->Read(PciReg8(offset))));
    case 2u:
      return out_val.copy_to_user(static_cast<uint32_t>(config->Read(PciReg16(offset))));
    case 4u:
      return out_val.copy_to_user(config->Read(PciReg32(offset)));
  }

  // If we reached this point then the width was invalid.
  return ZX_ERR_INVALID_ARGS;
}

// zx_status_t zx_pci_config_write
zx_status_t sys_pci_config_write(zx_handle_t handle, uint16_t offset, size_t width, uint32_t val) {
  if (!Pci::KernelPciEnabled()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  fbl::RefPtr<PciDeviceDispatcher> pci_device;
  fbl::RefPtr<Dispatcher> dispatcher;

  // Get the PciDeviceDispatcher from the handle passed in via the pci protocol
  auto up = ProcessDispatcher::GetCurrent();
  zx_status_t status = up->handle_table().GetDispatcherWithRights(
      *up, handle, ZX_RIGHT_READ | ZX_RIGHT_WRITE, &pci_device);
  if (status != ZX_OK) {
    return status;
  }

  // Writes to the PCI header or outside of the device's config space are not allowed.
  auto device = pci_device->device();
  auto cfg_size = device->is_pcie() ? PCIE_EXTENDED_CONFIG_SIZE : PCIE_BASE_CONFIG_SIZE;
  if (offset < ZX_PCI_STANDARD_CONFIG_HDR_SIZE || offset + width > cfg_size) {
    return ZX_ERR_INVALID_ARGS;
  }

  auto config = device->config();
  switch (width) {
    case 1u:
      config->Write(PciReg8(offset), static_cast<uint8_t>(val & UINT8_MAX));
      break;
    case 2u:
      config->Write(PciReg16(offset), static_cast<uint16_t>(val & UINT16_MAX));
      break;
    case 4u:
      config->Write(PciReg32(offset), val);
      break;
    default:
      return ZX_ERR_INVALID_ARGS;
  }

  return ZX_OK;
}
/* This is a transitional method to bootstrap legacy PIO access before
 * PCI moves to userspace.
 */
// zx_status_t zx_pci_cfg_pio_rw
zx_status_t sys_pci_cfg_pio_rw(zx_handle_t handle, uint8_t bus, uint8_t dev, uint8_t func,
                               uint8_t offset, user_inout_ptr<uint32_t> val, size_t width,
                               uint32_t write) {
  return ZX_ERR_NOT_SUPPORTED;
}

// zx_status_t zx_pci_enable_bus_master
zx_status_t sys_pci_enable_bus_master(zx_handle_t dev_handle, uint32_t enable) {
  if (!Pci::KernelPciEnabled()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  /**
   * Enables or disables bus mastering for the PCI device associated with the handle.
   * @param handle Handle associated with a PCI device
   * @param enable true if bus mastering should be enabled.
   */
  LTRACEF("handle %x\n", dev_handle);

  auto up = ProcessDispatcher::GetCurrent();

  fbl::RefPtr<PciDeviceDispatcher> pci_device;
  zx_status_t status =
      up->handle_table().GetDispatcherWithRights(*up, dev_handle, ZX_RIGHT_WRITE, &pci_device);
  if (status != ZX_OK)
    return status;

  return pci_device->EnableBusMaster(enable > 0);
}

// zx_status_t zx_pci_reset_device
zx_status_t sys_pci_reset_device(zx_handle_t dev_handle) {
  if (!Pci::KernelPciEnabled()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  /**
   * Resets the PCI device associated with the handle.
   * @param handle Handle associated with a PCI device
   */
  LTRACEF("handle %x\n", dev_handle);

  auto up = ProcessDispatcher::GetCurrent();

  fbl::RefPtr<PciDeviceDispatcher> pci_device;
  zx_status_t status =
      up->handle_table().GetDispatcherWithRights(*up, dev_handle, ZX_RIGHT_WRITE, &pci_device);
  if (status != ZX_OK)
    return status;

  return pci_device->ResetDevice();
}

// zx_status_t zx_pci_get_bar
zx_status_t sys_pci_get_bar(zx_handle_t dev_handle, uint32_t bar_num,
                            user_out_ptr<zx_pci_bar_t> out_bar, zx_handle_t* out_handle) {
  if (!Pci::KernelPciEnabled()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  if (dev_handle == ZX_HANDLE_INVALID || !out_bar || bar_num >= PCIE_MAX_BAR_REGS) {
    return ZX_ERR_INVALID_ARGS;
  }

  // Grab the PCI device object
  auto up = ProcessDispatcher::GetCurrent();
  fbl::RefPtr<PciDeviceDispatcher> pci_device;
  zx_status_t status = up->handle_table().GetDispatcherWithRights(
      *up, dev_handle, ZX_RIGHT_READ | ZX_RIGHT_WRITE, &pci_device);
  if (status != ZX_OK) {
    return status;
  }

  // Get bar info from the device via the dispatcher and make sure it makes sense
  const pcie_bar_info_t* info = pci_device->GetBar(bar_num);
  if (info == nullptr || info->size == 0) {
    return ZX_ERR_NOT_FOUND;
  }

  // A bar can be MMIO, PIO, or unused. In the MMIO case it can be passed
  // back to the caller as a VMO.
  zx_pci_bar_t bar = {};
  bar.size = info->size;
  bar.type = (info->is_mmio) ? ZX_PCI_BAR_TYPE_MMIO : ZX_PCI_BAR_TYPE_PIO;

  // MMIO based bars are passed back using a VMO. If we end up creating one here
  // without errors then later a handle will be passed back to the caller.
  KernelHandle<VmObjectDispatcher> kernel_handle;
  fbl::RefPtr<VmObjectPhysical> vmo;
  zx_rights_t rights;
  if (info->is_mmio) {
    // Create a VMO mapping to the address / size of the mmio region this bar
    // was allocated at
    status =
        VmObjectPhysical::Create(info->bus_addr, ktl::max<uint64_t>(info->size, kPageSize), &vmo);
    if (status != ZX_OK) {
      return status;
    }

    // Set the name of the vmo for tracking
    char name[32];
    auto dev = pci_device->device();
    snprintf(name, sizeof(name), "pci-%02x:%02x.%1x-bar%u", dev->bus_id(), dev->dev_id(),
             dev->func_id(), bar_num);
    vmo->set_name(name, sizeof(name));

    // Now that the vmo has been created for the bar, create a handle to
    // the appropriate dispatcher for the caller
    status = VmObjectDispatcher::Create(
        vmo, info->size, VmObjectDispatcher::InitialMutability::kMutable, &kernel_handle, &rights);
    if (status != ZX_OK) {
      return status;
    }

    pci_device->EnableMmio(true);
  } else {
    DEBUG_ASSERT(info->bus_addr != 0);
    bar.addr = info->bus_addr;
    pci_device->EnablePio(true);
  }

  // Metadata has been sorted out, so copy back the structure to userspace
  // and then account for the vmo handle if one was created.
  status = out_bar.copy_to_user(bar);
  if (status != ZX_OK) {
    return status;
  }

  if (vmo) {
    return up->MakeAndAddHandle(ktl::move(kernel_handle), rights, out_handle);
  }

  return ZX_OK;
}

// zx_status_t zx_pci_map_interrupt
zx_status_t sys_pci_map_interrupt(zx_handle_t dev_handle, int32_t which_irq,
                                  zx_handle_t* out_handle) {
  if (!Pci::KernelPciEnabled()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  /**
   * Returns a handle that can be waited on.
   * @param handle Handle associated with a PCI device
   * @param which_irq Identifier for an IRQ, returned in sys_pci_get_nth_device
   * @param out_handle pointer to a handle to associate with the interrupt mapping
   */
  LTRACEF("handle %x\n", dev_handle);

  auto up = ProcessDispatcher::GetCurrent();

  fbl::RefPtr<PciDeviceDispatcher> pci_device;
  zx_status_t status =
      up->handle_table().GetDispatcherWithRights(*up, dev_handle, ZX_RIGHT_READ, &pci_device);
  if (status != ZX_OK)
    return status;

  KernelHandle<InterruptDispatcher> interrupt_handle;
  zx_rights_t rights;
  zx_status_t result = pci_device->MapInterrupt(which_irq, &interrupt_handle, &rights);
  if (result != ZX_OK)
    return result;

  return up->MakeAndAddHandle(ktl::move(interrupt_handle), rights, out_handle);
}

/**
 * Gets info about the capabilities of a PCI device's IRQ modes.
 * @param handle Handle associated with a PCI device.
 * @param mode The IRQ mode whose capabilities are to be queried.
 * @param out_len Out param which will hold the maximum number of IRQs supported by the mode.
 */
// zx_status_t zx_pci_query_irq_mode
zx_status_t sys_pci_query_irq_mode(zx_handle_t dev_handle, uint32_t mode,
                                   user_out_ptr<uint32_t> out_max_irqs) {
  if (!Pci::KernelPciEnabled()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  LTRACEF("handle %x\n", dev_handle);

  auto up = ProcessDispatcher::GetCurrent();

  fbl::RefPtr<PciDeviceDispatcher> pci_device;
  zx_status_t status =
      up->handle_table().GetDispatcherWithRights(*up, dev_handle, ZX_RIGHT_READ, &pci_device);
  if (status != ZX_OK)
    return status;

  uint32_t max_irqs;
  zx_status_t result = pci_device->QueryIrqModeCaps((zx_pci_irq_mode_t)mode, &max_irqs);
  if (result != ZX_OK)
    return result;

  status = out_max_irqs.copy_to_user(max_irqs);
  if (status != ZX_OK)
    return status;

  return result;
}

/**
 * Selects an IRQ mode for a PCI device.
 * @param handle Handle associated with a PCI device.
 * @param mode The IRQ mode to select.
 * @param requested_irq_count The number of IRQs to select request for the given mode.
 */
// zx_status_t zx_pci_set_irq_mode
zx_status_t sys_pci_set_irq_mode(zx_handle_t dev_handle, uint32_t mode,
                                 uint32_t requested_irq_count) {
  if (!Pci::KernelPciEnabled()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  LTRACEF("handle %x\n", dev_handle);

  auto up = ProcessDispatcher::GetCurrent();

  fbl::RefPtr<PciDeviceDispatcher> pci_device;
  zx_status_t status =
      up->handle_table().GetDispatcherWithRights(*up, dev_handle, ZX_RIGHT_WRITE, &pci_device);
  if (status != ZX_OK)
    return status;

  return pci_device->SetIrqMode((zx_pci_irq_mode_t)mode, requested_irq_count);
}
