// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2016, Google, Inc. All rights reserved
//
// 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 <assert.h>
#include <debug.h>
#include <inttypes.h>
#include <platform.h>
#include <string.h>
#include <trace.h>
#include <zircon/compiler.h>
#include <zircon/errors.h>
#include <zircon/time.h>
#include <zircon/types.h>

#include <dev/interrupt.h>
#include <dev/pcie_bridge.h>
#include <dev/pcie_bus_driver.h>
#include <dev/pcie_device.h>
#include <fbl/algorithm.h>
#include <fbl/alloc_checker.h>
#include <kernel/spinlock.h>
#include <ktl/iterator.h>
#include <ktl/limits.h>
#include <vm/arch_vm_aspace.h>
#include <vm/vm.h>

#include <ktl/enforce.h>

#define LOCAL_TRACE 0

namespace {  // namespace.  Externals do not need to know about PcieDeviceImpl
class PcieDeviceImpl : public PcieDevice {
 public:
  static fbl::RefPtr<PcieDevice> Create(PcieUpstreamNode& upstream, uint dev_id, uint func_id);

  // Disallow copying, assigning and moving.
  DISALLOW_COPY_ASSIGN_AND_MOVE(PcieDeviceImpl);

  // Implement ref counting, do not let derived classes override.
  PCIE_IMPLEMENT_REFCOUNTED;

 protected:
  PcieDeviceImpl(PcieBusDriver& bus_drv, uint bus_id, uint dev_id, uint func_id)
      : PcieDevice(bus_drv, bus_id, dev_id, func_id, false) {}
};

fbl::RefPtr<PcieDevice> PcieDeviceImpl::Create(PcieUpstreamNode& upstream, uint dev_id,
                                               uint func_id) {
  fbl::AllocChecker ac;
  auto raw_dev =
      new (&ac) PcieDeviceImpl(upstream.driver(), upstream.managed_bus_id(), dev_id, func_id);
  if (!ac.check()) {
    TRACEF("Out of memory attemping to create PCIe device %02x:%02x.%01x.\n",
           upstream.managed_bus_id(), dev_id, func_id);
    return nullptr;
  }

  auto dev = fbl::AdoptRef(static_cast<PcieDevice*>(raw_dev));
  zx_status_t res = raw_dev->Init(upstream);
  if (res != ZX_OK) {
    TRACEF("Failed to initialize PCIe device %02x:%02x.%01x. (res %d)\n", upstream.managed_bus_id(),
           dev_id, func_id, res);
    return nullptr;
  }

  return dev;
}
}  // namespace

PcieDevice::PcieDevice(PcieBusDriver& bus_drv, uint bus_id, uint dev_id, uint func_id,
                       bool is_bridge)
    : bus_drv_(bus_drv),
      is_bridge_(is_bridge),
      bus_id_(bus_id),
      dev_id_(dev_id),
      func_id_(func_id),
      bar_count_(is_bridge ? PCIE_BAR_REGS_PER_BRIDGE : PCIE_BAR_REGS_PER_DEVICE) {}

PcieDevice::~PcieDevice() {
  /* We should already be unlinked from the bus's device tree. */
  DEBUG_ASSERT(!upstream_);
  DEBUG_ASSERT(!plugged_in_);

  /* TODO(johngro) : ASSERT that this device no longer participating in any of
   * the bus driver's shared IRQ dispatching. */

  /* Make certain that all bus access (MMIO, PIO, Bus mastering) has been
   * disabled.  Also, explicitly disable legacy IRQs */
  if (cfg_)
    cfg_->Write(PciConfig::kCommand, PCIE_CFG_COMMAND_INT_DISABLE);
}

fbl::RefPtr<PcieDevice> PcieDevice::Create(PcieUpstreamNode& upstream, uint dev_id, uint func_id) {
  return PcieDeviceImpl::Create(upstream, dev_id, func_id);
}

zx_status_t PcieDevice::Init(PcieUpstreamNode& upstream) {
  Guard<Mutex> guard{&dev_lock_};

  zx_status_t res = InitLocked(upstream);
  if (res == ZX_OK) {
    // Things went well, flag the device as plugged in and link ourselves up to
    // the graph.
    plugged_in_ = true;
    bus_drv_.LinkDeviceToUpstream(*this, upstream);
  }

  return res;
}

zx_status_t PcieDevice::InitLocked(PcieUpstreamNode& upstream) {
  zx_status_t res;
  DEBUG_ASSERT(cfg_ == nullptr);

  cfg_ = bus_drv_.GetConfig(bus_id_, dev_id_, func_id_, &cfg_phys_);
  if (cfg_ == nullptr) {
    TRACEF("Failed to fetch config for device %02x:%02x.%01x.\n", bus_id_, dev_id_, func_id_);
    return ZX_ERR_BAD_STATE;
  }

  // Cache basic device info
  vendor_id_ = cfg_->Read(PciConfig::kVendorId);
  device_id_ = cfg_->Read(PciConfig::kDeviceId);
  class_id_ = cfg_->Read(PciConfig::kBaseClass);
  subclass_ = cfg_->Read(PciConfig::kSubClass);
  prog_if_ = cfg_->Read(PciConfig::kProgramInterface);
  rev_id_ = cfg_->Read(PciConfig::kRevisionId);

  // Determine the details of each of the BARs, but do not actually allocate
  // space on the bus for them yet.
  res = ProbeBarsLocked();
  if (res != ZX_OK)
    return res;

  // Parse and sanity check the capabilities and extended capabilities lists
  // if they exist
  res = ProbeCapabilitiesLocked();
  if (res != ZX_OK)
    return res;

  // Now that we know what our capabilities are, initialize our internal IRQ
  // bookkeeping
  res = InitLegacyIrqStateLocked(upstream);
  if (res != ZX_OK)
    return res;

  return ZX_OK;
}

fbl::RefPtr<PcieUpstreamNode> PcieDevice::GetUpstream() { return bus_drv_.GetUpstream(*this); }

void PcieDevice::Unplug() {
  /* Begin by completely nerfing this device, and preventing an new API
   * operations on it.  We need to be inside the dev lock to do this.  Note:
   * it is assumed that we will not disappear during any of this function,
   * because our caller is holding a reference to us. */
  Guard<Mutex> guard{&dev_lock_};

  if (plugged_in_) {
    /* Remove all access this device has to the PCI bus */
    cfg_->Write(PciConfig::kCommand, PCIE_CFG_COMMAND_INT_DISABLE);

    /* TODO(johngro) : Make sure that our interrupt mode has been set to
     * completely disabled.  Do not return allocated BARs to the central
     * pool yet.  These regions of the physical bus need to remain
     * "allocated" until all drivers/users in the system release their last
     * reference to the device.  This way, if the device gets plugged in
     * again immediately, the new version of the device will not end up
     * getting mapped underneath any stale driver instances. */

    plugged_in_ = false;
  } else {
    /* TODO(johngro) : Assert that the device has been completely disabled. */
  }

  /* Unlink ourselves from our upstream parent (if we still have one). */
  bus_drv_.UnlinkDeviceFromUpstream(*this);
}

zx_status_t PcieDevice::DoFunctionLevelReset() {
  zx_status_t ret;

  // TODO(johngro) : Function level reset is an operation which can take quite
  // a long time (more than a second).  We should not hold the device lock for
  // the entire duration of the operation.  This should be re-done so that the
  // device can be placed into a "resetting" state (and other API calls can
  // fail with ZX_ERR_BAD_STATE, or some-such) and the lock can be released while the
  // reset timeouts run.  This way, a spontaneous unplug event can occur and
  // not block the whole world because the device unplugged was in the process
  // of a FLR.
  Guard<Mutex> dev_guard{&dev_lock_};

  // Make certain to check to see if the device is still plugged in.
  if (!plugged_in_)
    return ZX_ERR_UNAVAILABLE;

  // Disallow reset if we currently have an active IRQ mode.
  //
  // Note: the only possible reason for get_irq_mode to fail would be for the
  // device to be unplugged.  Since we have already checked for that, we
  // assert that the call should succeed.
  pcie_irq_mode_info_t irq_mode_info;
  ret = GetIrqModeLocked(&irq_mode_info);
  DEBUG_ASSERT(ZX_OK == ret);

  if (irq_mode_info.mode != PCIE_IRQ_MODE_DISABLED)
    return ZX_ERR_BAD_STATE;

  DEBUG_ASSERT(!irq_mode_info.registered_handlers);
  DEBUG_ASSERT(!irq_mode_info.max_handlers);

  // If cannot reset via the PCIe capability, or the PCI advanced capability,
  // then this device simply does not support function level reset.
  if (!(pcie_ && pcie_->has_flr()) && !(pci_af_ && pci_af_->has_flr()))
    return ZX_ERR_NOT_SUPPORTED;

  // Pick the functions we need for testing whether or not transactions are
  // pending for this device, and for initiating the FLR
  bool (*check_trans_pending)(void* ctx);
  void (*initiate_flr)(void* ctx);

  if (pcie_ && pcie_->has_flr()) {
    check_trans_pending = [](void* ctx) -> bool {
      auto thiz = reinterpret_cast<PcieDevice*>(ctx);
      return thiz->cfg_->Read(thiz->pcie_->device.status()) & PCS_DEV_STS_TRANSACTIONS_PENDING;
    };
    initiate_flr = [](void* ctx) {
      auto thiz = reinterpret_cast<PcieDevice*>(ctx);
      auto val = static_cast<uint16_t>(thiz->cfg_->Read(thiz->pcie_->device.ctrl()) |
                                       PCS_DEV_CTRL_INITIATE_FLR);
      thiz->cfg_->Write(thiz->pcie_->device.ctrl(), val);
    };
  } else {
    check_trans_pending = [](void* ctx) -> bool {
      auto thiz = reinterpret_cast<PcieDevice*>(ctx);
      return thiz->cfg_->Read(thiz->pci_af_->af_status()) & PCS_ADVCAPS_STATUS_TRANS_PENDING;
    };
    initiate_flr = [](void* ctx) {
      auto thiz = reinterpret_cast<PcieDevice*>(ctx);
      thiz->cfg_->Write(thiz->pci_af_->af_ctrl(), PCS_ADVCAPS_CTRL_INITIATE_FLR);
    };
  }

  // Following the procedure outlined in the Implementation notes
  uint32_t bar_backup[PCIE_MAX_BAR_REGS];
  uint16_t cmd_backup;

  // 1) Make sure driver code is not creating new transactions (not much I
  //    can do about this, just have to hope).
  // 2) Clear out the command register so that no new transactions may be
  //    initiated.  Also back up the BARs in the process.
  {
    DEBUG_ASSERT(irq_.legacy.shared_handler != nullptr);
    Guard<SpinLock, IrqSave> cmd_reg_guard{&cmd_reg_lock_};

    cmd_backup = cfg_->Read(PciConfig::kCommand);
    cfg_->Write(PciConfig::kCommand, PCIE_CFG_COMMAND_INT_DISABLE);
    for (uint i = 0; i < bar_count_; ++i)
      bar_backup[i] = cfg_->Read(PciConfig::kBAR(i));
  }

  // 3) Poll the transaction pending bit until it clears.  This may take
  //    "several seconds"
  zx_time_t start = current_time();
  ret = ZX_ERR_TIMED_OUT;
  do {
    if (!check_trans_pending(this)) {
      ret = ZX_OK;
      break;
    }
    Thread::Current::SleepRelative(ZX_MSEC(1));
  } while (zx_time_sub_time(current_time(), start) < ZX_SEC(5));

  if (ret != ZX_OK) {
    TRACEF(
        "Timeout waiting for pending transactions to clear the bus "
        "for %02x:%02x.%01x\n",
        bus_id_, dev_id_, func_id_);

    // Restore the command register
    Guard<SpinLock, IrqSave> guard{&cmd_reg_lock_};
    cfg_->Write(PciConfig::kCommand, cmd_backup);

    return ret;
  } else {
    // 4) Software initiates the FLR
    initiate_flr(this);

    // 5) Software waits 100mSec
    Thread::Current::SleepRelative(ZX_MSEC(100));
  }

  // NOTE: Even though the spec says that the reset operation is supposed
  // to always take less than 100mSec, no one really follows this rule.
  // Generally speaking, when a device resets, config read cycles will
  // return all 0xFFs until the device finally resets and comes back.
  // Poll the Vendor ID field until the device finally completes it's
  // reset.
  start = current_time();
  ret = ZX_ERR_TIMED_OUT;
  do {
    if (cfg_->Read(PciConfig::kVendorId) != PCIE_INVALID_VENDOR_ID) {
      ret = ZX_OK;
      break;
    }
    Thread::Current::SleepRelative(ZX_MSEC(1));
  } while (zx_time_sub_time(current_time(), start) < ZX_SEC(5));

  if (ret == ZX_OK) {
    // 6) Software reconfigures the function and enables it for normal operation
    Guard<SpinLock, IrqSave> guard{&cmd_reg_lock_};

    for (uint i = 0; i < bar_count_; ++i)
      cfg_->Write(PciConfig::kBAR(i), bar_backup[i]);
    cfg_->Write(PciConfig::kCommand, cmd_backup);
  } else {
    // TODO(johngro) : What do we do if this fails?  If we trigger a
    // device reset, and the device fails to re-appear after 5 seconds,
    // it is probably gone for good.  We probably need to force unload
    // any device drivers which had previously owned the device.
    TRACEF(
        "Timeout waiting for %02x:%02x.%01x to complete function "
        "level reset.  This is Very Bad.\n",
        bus_id_, dev_id_, func_id_);
  }

  return ret;
}

zx_status_t PcieDevice::ModifyCmd(uint16_t clr_bits, uint16_t set_bits) {
  Guard<Mutex> guard{&dev_lock_};

  /* In order to keep internal bookkeeping coherent, and interactions between
   * MSI/MSI-X and Legacy IRQ mode safe, API users may not directly manipulate
   * the legacy IRQ enable/disable bit.  Just ignore them if they try to
   * manipulate the bit via the modify cmd API. */
  clr_bits = static_cast<uint16_t>(clr_bits & ~PCIE_CFG_COMMAND_INT_DISABLE);
  set_bits = static_cast<uint16_t>(set_bits & ~PCIE_CFG_COMMAND_INT_DISABLE);

  if (plugged_in_) {
    ModifyCmdLocked(clr_bits, set_bits);
    return ZX_OK;
  }

  return ZX_ERR_UNAVAILABLE;
}

void PcieDevice::ModifyCmdLocked(uint16_t clr_bits, uint16_t set_bits) {
  DEBUG_ASSERT(dev_lock_.lock().IsHeld());

  {
    Guard<SpinLock, IrqSave> guard{&cmd_reg_lock_};
    cfg_->Write(PciConfig::kCommand,
                static_cast<uint16_t>((cfg_->Read(PciConfig::kCommand) & ~clr_bits) | set_bits));
  }
}

zx_status_t PcieDevice::EnableBusMaster(bool enabled) {
  {
    Guard<Mutex> guard{&dev_lock_};

    if (enabled && disabled_) {
      return ZX_ERR_BAD_STATE;
    }

    ModifyCmdLocked(enabled ? 0 : PCI_COMMAND_BUS_MASTER_EN,
                    enabled ? PCI_COMMAND_BUS_MASTER_EN : 0);
  }
  return upstream_->EnableBusMasterUpstream(enabled);
}

zx_status_t PcieDevice::ProbeBarsLocked() {
  DEBUG_ASSERT(cfg_);
  DEBUG_ASSERT(dev_lock_.lock().IsHeld());

  static_assert(PCIE_MAX_BAR_REGS >= PCIE_BAR_REGS_PER_DEVICE, "");
  static_assert(PCIE_MAX_BAR_REGS >= PCIE_BAR_REGS_PER_BRIDGE, "");

  __UNUSED uint8_t header_type = cfg_->Read(PciConfig::kHeaderType) & PCI_HEADER_TYPE_MASK;

  DEBUG_ASSERT((header_type == PCI_HEADER_TYPE_STANDARD) ||
               (header_type == PCI_HEADER_TYPE_PCI_BRIDGE));
  DEBUG_ASSERT(bar_count_ <= ktl::size(bars_));

  for (uint i = 0; i < bar_count_; ++i) {
    /* If this is a re-scan of the bus, We should not be re-enumerating BARs. */
    DEBUG_ASSERT(bars_[i].size == 0);
    DEBUG_ASSERT(bars_[i].allocation == nullptr);

    zx_status_t probe_res = ProbeBarLocked(i);
    if (probe_res != ZX_OK)
      return probe_res;

    if (bars_[i].size > 0) {
      /* If this was a 64 bit bar, it took two registers to store.  Make
       * sure to skip the next register */
      if (bars_[i].is_64bit) {
        i++;

        if (i >= bar_count_) {
          TRACEF("Device %02x:%02x:%01x claims to have 64-bit BAR in position %u/%u!\n", bus_id_,
                 dev_id_, func_id_, i, bar_count_);
          return ZX_ERR_BAD_STATE;
        }
      }
    }
  }

  return ZX_OK;
}

zx_status_t PcieDevice::ProbeBarLocked(uint bar_id) {
  DEBUG_ASSERT(cfg_);
  DEBUG_ASSERT(bar_id < bar_count_);
  DEBUG_ASSERT(bar_id < ktl::size(bars_));

  /* Determine the type of BAR this is.  Make sure that it is one of the types we understand */
  pcie_bar_info_t& bar_info = bars_[bar_id];
  uint32_t bar_val = cfg_->Read(PciConfig::kBAR(bar_id));
  bar_info.is_mmio = (bar_val & PCI_BAR_IO_TYPE_MASK) == PCI_BAR_IO_TYPE_MMIO;
  bar_info.is_64bit =
      bar_info.is_mmio && ((bar_val & PCI_BAR_MMIO_TYPE_MASK) == PCI_BAR_MMIO_TYPE_64BIT);
  bar_info.is_prefetchable = bar_info.is_mmio && (bar_val & PCI_BAR_MMIO_PREFETCH_MASK);
  bar_info.first_bar_reg = bar_id;

  if (bar_info.is_64bit) {
    if ((bar_id + 1) >= bar_count_) {
      TRACEF(
          "Illegal 64-bit MMIO BAR position (%u/%u) while fetching BAR info "
          "for device config @%p\n",
          bar_id, bar_count_, cfg_);
      return ZX_ERR_BAD_STATE;
    }
  } else {
    if (bar_info.is_mmio && ((bar_val & PCI_BAR_MMIO_TYPE_MASK) != PCI_BAR_MMIO_TYPE_32BIT)) {
      TRACEF(
          "Unrecognized MMIO BAR type (BAR[%u] == 0x%08x) while fetching BAR info "
          "for device config @%p\n",
          bar_id, bar_val, cfg_);
      return ZX_ERR_BAD_STATE;
    }
  }

  /* Disable either MMIO or PIO (depending on the BAR type) access while we
   * perform the probe.  We don't want the addresses written during probing to
   * conflict with anything else on the bus.  Note:  No drivers should have
   * access to this device's registers during the probe process as the device
   * should not have been published yet.  That said, there could be other
   * (special case) parts of the system accessing a devices registers at this
   * point in time, like an early init debug console or serial port.  Don't
   * make any attempt to print or log until the probe operation has been
   * completed.  Hopefully these special systems are quiescent at this point
   * in time, otherwise they might see some minor glitching while access is
   * disabled.
   */
  uint16_t backup = cfg_->Read(PciConfig::kCommand);
  if (bar_info.is_mmio)
    cfg_->Write(PciConfig::kCommand, static_cast<uint16_t>(backup & ~PCI_COMMAND_MEM_EN));
  else
    cfg_->Write(PciConfig::kCommand, static_cast<uint16_t>(backup & ~PCI_COMMAND_IO_EN));

  /* Figure out the size of this BAR region by writing 1's to the
   * address bits, then reading back to see which bits the device
   * considers un-configurable. */
  uint32_t addr_mask = bar_info.is_mmio ? PCI_BAR_MMIO_ADDR_MASK : PCI_BAR_PIO_ADDR_MASK;
  uint32_t addr_lo = bar_val & addr_mask;
  uint64_t size_mask;

  cfg_->Write(PciConfig::kBAR(bar_id), bar_val | addr_mask);
  size_mask = ~(cfg_->Read(PciConfig::kBAR(bar_id)) & addr_mask);
  cfg_->Write(PciConfig::kBAR(bar_id), bar_val);

  if (bar_info.is_mmio) {
    if (bar_info.is_64bit) {
      /* 64bit MMIO? Probe the upper bits as well */
      bar_id++;
      bar_val = cfg_->Read(PciConfig::kBAR(bar_id));
      cfg_->Write(PciConfig::kBAR(bar_id), 0xFFFFFFFF);
      size_mask |= ((uint64_t)~cfg_->Read(PciConfig::kBAR(bar_id))) << 32;
      cfg_->Write(PciConfig::kBAR(bar_id), bar_val);
      bar_info.size = size_mask + 1;
      bar_info.bus_addr = (static_cast<uint64_t>(bar_val) << 32) | addr_lo;
    } else {
      bar_info.size = (uint32_t)(size_mask + 1);
      bar_info.bus_addr = addr_lo;
    }
  } else {
    /* PIO BAR */
    bar_info.size = ((uint32_t)(size_mask + 1)) & PCIE_PIO_ADDR_SPACE_MASK;
    bar_info.bus_addr = addr_lo;
  }

  /* Restore the command register to its previous value */
  cfg_->Write(PciConfig::kCommand, backup);

  /* Success */
  return ZX_OK;
}

zx_status_t PcieDevice::AllocateBars() {
  Guard<Mutex> guard{&dev_lock_};
  return AllocateBarsLocked();
}

zx_status_t PcieDevice::AllocateBarsLocked() {
  DEBUG_ASSERT(dev_lock_.lock().IsHeld());
  DEBUG_ASSERT(plugged_in_);

  // Have we become unplugged?
  if (!plugged_in_)
    return ZX_ERR_UNAVAILABLE;

  /* Allocate BARs for the device */
  DEBUG_ASSERT(bar_count_ <= ktl::size(bars_));
  for (size_t i = 0; i < bar_count_; ++i) {
    if (bars_[i].size) {
      zx_status_t ret = AllocateBarLocked(bars_[i]);
      if (ret != ZX_OK)
        return ret;
    }
  }

  return ZX_OK;
}

zx_status_t PcieDevice::AllocateBarLocked(pcie_bar_info_t& info) {
  DEBUG_ASSERT(dev_lock_.lock().IsHeld());
  DEBUG_ASSERT(plugged_in_);

  // Do not attempt to remap if we are rescanning the bus and this BAR is
  // already allocated, or if it does not exist (size is zero)
  if ((info.size == 0) || (info.allocation != nullptr))
    return ZX_OK;

  // Hold a reference to our upstream node while we do this.  If we cannot
  // obtain a reference, then our upstream node has become unplugged and we
  // should just fail out now.
  auto upstream = GetUpstream();
  if (upstream == nullptr)
    return ZX_ERR_UNAVAILABLE;

  /* Does this BAR already have an assigned address?  If so, try to preserve
   * it, if possible. */
  if (info.bus_addr != 0) {
    RegionAllocator* alloc = nullptr;
    if (upstream->type() == PcieUpstreamNode::Type::BRIDGE && info.is_prefetchable) {
      alloc = &upstream->pf_mmio_regions();
    } else if (info.is_mmio) {
      /* We currently do not support preserving an MMIO region which spans
       * the 4GB mark.  If we encounter such a thing, clear out the
       * allocation and attempt to re-allocate. */
      uint64_t inclusive_end = info.bus_addr + info.size - 1;
      if (inclusive_end <= ktl::numeric_limits<uint32_t>::max()) {
        alloc = &upstream->mmio_lo_regions();
      } else if (info.bus_addr > ktl::numeric_limits<uint32_t>::max()) {
        alloc = &upstream->mmio_hi_regions();
      }
    } else {
      alloc = &upstream->pio_regions();
    }

    zx_status_t res = ZX_ERR_NOT_FOUND;
    if (alloc != nullptr) {
      res = alloc->GetRegion({.base = info.bus_addr, .size = info.size}, info.allocation);
    }

    if (res == ZX_OK)
      return ZX_OK;

    TRACEF(
        "Failed to preserve device %02x:%02x.%01x's %s window "
        "[%#" PRIx64 ", %#" PRIx64 "] Attempting to re-allocate.\n",
        bus_id_, dev_id_, func_id_,
        info.is_mmio ? (info.is_prefetchable ? "PFMMIO" : "MMIO") : "PIO", info.bus_addr,
        info.bus_addr + info.size - 1);
    info.bus_addr = 0;
  }

  /* We failed to preserve the allocation and need to attempt to
   * dynamically allocate a new region.  Close the device MMIO/PIO
   * windows, disable interrupts and shut of bus mastering (which will
   * also disable MSI interrupts) before we attempt dynamic allocation.
   */
  AssignCmdLocked(PCIE_CFG_COMMAND_INT_DISABLE);

  /* Choose which region allocator we will attempt to allocate from, then
   * check to see if we have the space. */
  RegionAllocator* alloc =
      !info.is_mmio ? &upstream->pio_regions()
                    : (info.is_64bit ? &upstream->mmio_hi_regions() : &upstream->mmio_lo_regions());
  uint32_t addr_mask = info.is_mmio ? PCI_BAR_MMIO_ADDR_MASK : PCI_BAR_PIO_ADDR_MASK;

  /* If check to see if we have the space to allocate within the chosen
   * range.  In the case of a 64 bit MMIO BAR, if we run out of space in
   * the high-memory MMIO range, try the low memory range as well.
   */
  while (true) {
    /* MMIO windows and I/O windows on systems where I/O space is actually
     * memory mapped must be aligned to a page boundary, at least. */
    bool is_io_space = PCIE_HAS_IO_ADDR_SPACE && !info.is_mmio;
    uint64_t align_size = ((info.size >= PAGE_SIZE) || is_io_space) ? info.size : PAGE_SIZE;
    zx_status_t res = alloc->GetRegion(align_size, align_size, info.allocation);

    if (res != ZX_OK) {
      if ((res == ZX_ERR_NOT_FOUND) && (alloc == &upstream->mmio_hi_regions())) {
        LTRACEF(
            "Insufficient space to map 64-bit MMIO BAR in high region while "
            "configuring BARs for device at %02x:%02x.%01x (cfg vaddr = %p).  "
            "Falling back on low memory region.\n",
            bus_id_, dev_id_, func_id_, cfg_);
        alloc = &upstream->mmio_lo_regions();
        continue;
      }

      TRACEF("Failed to dynamically allocate %s BAR region (size %#" PRIx64
             ") "
             "while configuring BARs for device at %02x:%02x.%01x (res = %d)\n",
             info.is_mmio ? (info.is_prefetchable ? "PFMMIO" : "MMIO") : "PIO", info.size, bus_id_,
             dev_id_, func_id_, res);

      // Looks like we are out of luck.  Propagate the error up the stack
      // so that our upstream node knows to disable us.
      return res;
    }

    break;
  }

  /* Allocation succeeded.  Record our allocated and aligned physical address
   * in our BAR(s) */
  DEBUG_ASSERT(info.allocation != nullptr);
  uint bar_reg = info.first_bar_reg;
  info.bus_addr = info.allocation->base;

  cfg_->Write(PciConfig::kBAR(bar_reg),
              static_cast<uint32_t>((info.bus_addr & 0xFFFFFFFF) |
                                    (cfg_->Read(PciConfig::kBAR(bar_reg)) & ~addr_mask)));
  if (info.is_64bit)
    cfg_->Write(PciConfig::kBAR(bar_reg + 1), static_cast<uint32_t>(info.bus_addr >> 32));

  return ZX_OK;
}

void PcieDevice::Disable() {
  DEBUG_ASSERT(!dev_lock_.lock().IsHeld());
  Guard<Mutex> guard{&dev_lock_};
  DisableLocked();
}

void PcieDevice::DisableLocked() {
  // Disable a device because we cannot allocate space for all of its BARs (or
  // forwarding windows, in the case of a bridge).  Flag the device as
  // disabled from here on out.
  DEBUG_ASSERT(dev_lock_.lock().IsHeld());
  printf("PCI: Disabling device %02x:%02x.%01x\n", bus_id_, dev_id_, func_id_);

  // Flag the device as disabled.  Close the device's MMIO/PIO windows, shut
  // off device initiated accesses to the bus, disable legacy interrupts.
  // Basically, prevent the device from doing anything from here on out.
  disabled_ = true;
  AssignCmdLocked(PCIE_CFG_COMMAND_INT_DISABLE);

  // Release all BAR allocations back into the pool they came from.
  for (auto& bar : bars_)
    bar.allocation = nullptr;
}

void PcieDevice::Dump() const {
  printf("PCI: device at %02x:%02x:%02x vid:did %04x:%04x\n", bus_id(), dev_id(), func_id(),
         vendor_id(), device_id());
}
