// 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 <arch/mmu.h>
#include <assert.h>
#include <zircon/compiler.h>
#include <debug.h>
#include <dev/pcie_bridge.h>
#include <dev/pcie_bus_driver.h>
#include <dev/pcie_device.h>
#include <err.h>
#include <inttypes.h>
#include <kernel/spinlock.h>
#include <kernel/vm.h>
#include <vm/arch_vm_aspace.h>
#include <list.h>
#include <lk/init.h>
#include <fbl/algorithm.h>
#include <fbl/auto_lock.h>
#include <fbl/limits.h>
#include <dev/interrupt.h>
#include <string.h>
#include <trace.h>
#include <platform.h>

#include <fbl/alloc_checker.h>

using fbl::AutoLock;

#define LOCAL_TRACE 0

namespace {  // anon 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));
    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);
}

status_t PcieDevice::Init(PcieUpstreamNode& upstream) {
    AutoLock dev_lock(&dev_lock_);

    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;
}

status_t PcieDevice::InitLocked(PcieUpstreamNode& upstream) {
    status_t res;
    DEBUG_ASSERT(dev_lock_.IsHeld());
    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. */
    AutoLock dev_lock(&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);
}

status_t PcieDevice::DoFunctionLevelReset() {
    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.
    AutoLock dev_lock(&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);
        AutoSpinLockIrqSave cmd_reg_lock(&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"
    lk_time_t start = current_time();
    ret = ZX_ERR_TIMED_OUT;
    do {
        if (!check_trans_pending(this)) {
            ret = ZX_OK;
            break;
        }
        thread_sleep_relative(LK_MSEC(1));
    } while ((current_time() - start) < LK_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
        AutoSpinLockIrqSave cmd_reg_lock(&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_sleep_relative(LK_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_sleep_relative(LK_MSEC(1));
    } while ((current_time() - start) < LK_SEC(5));

    if (ret == ZX_OK) {
        // 6) Software reconfigures the function and enables it for normal operation
        AutoSpinLockIrqSave cmd_reg_lock(&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;
}

status_t PcieDevice::ModifyCmd(uint16_t clr_bits, uint16_t set_bits) {
    AutoLock dev_lock(&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_.IsHeld());

    {
        AutoSpinLockIrqSave cmd_reg_lock(&cmd_reg_lock_);
        cfg_->Write(PciConfig::kCommand,
                     static_cast<uint16_t>((cfg_->Read(PciConfig::kCommand) & ~clr_bits)
                                                                             |  set_bits));
    }
}

status_t PcieDevice::ProbeBarsLocked() {
    DEBUG_ASSERT(cfg_);
    DEBUG_ASSERT(dev_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_ <= fbl::count_of(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);

        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;
}

status_t PcieDevice::ProbeBarLocked(uint bar_id) {
    DEBUG_ASSERT(cfg_);
    DEBUG_ASSERT(bar_id < bar_count_);
    DEBUG_ASSERT(bar_id < fbl::count_of(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
     * acccess 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;
}


status_t PcieDevice::AllocateBars() {
    AutoLock dev_lock(&dev_lock_);
    return AllocateBarsLocked();
}

status_t PcieDevice::AllocateBarsLocked() {
    DEBUG_ASSERT(dev_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_ <= fbl::count_of(bars_));
    for (size_t i = 0; i < bar_count_; ++i) {
        if (bars_[i].size) {
            status_t ret = AllocateBarLocked(bars_[i]);
            if (ret != ZX_OK)
                return ret;
        }
    }

    return ZX_OK;
}

status_t PcieDevice::AllocateBarLocked(pcie_bar_info_t& info) {
    DEBUG_ASSERT(dev_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 (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 <= fbl::numeric_limits<uint32_t>::max()) {
                alloc = &upstream->mmio_lo_regions();
            } else
            if (info.bus_addr > fbl::numeric_limits<uint32_t>::max()) {
                alloc = &upstream->mmio_hi_regions();
            }
        } else {
            alloc = &upstream->pio_regions();
        }

        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 ? "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;
        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 ? "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_.IsHeld());
    AutoLock dev_lock(&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_.IsHeld());
    TRACEF("WARNING - Disabling device %02x:%02x.%01x due to unsatisfiable configuration\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;
}
