// Copyright 2019 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 "common.h"
#include "root.h"
#include "upstream_node.h"
#include <assert.h>
#include <err.h>
#include <fbl/algorithm.h>
#include <fbl/auto_call.h>
#include <inttypes.h>
#include <lib/zx/resource.h>
#include <lib/zx/vmo.h>
#include <string.h>
#include <zircon/rights.h>

namespace pci {

zx_status_t PciAllocation::CreateVmObject(fbl::unique_ptr<zx::vmo>* out_vmo) const {
    zx::vmo temp;
    zx_status_t status = zx::vmo::create_physical(resource_, base(), size(), &temp);
    if (status != ZX_OK) {
        return status;
    }

    *out_vmo = std::make_unique<zx::vmo>(std::move(temp));
    return status;
}

zx_status_t PciRootAllocator::GetRegion(zx_paddr_t in_base,
                                        size_t size,
                                        fbl::unique_ptr<PciAllocation>* alloc) {

    zx_paddr_t out_base;
    zx::resource res;
    zx_status_t status = pciroot_.GetAddressSpace(size, in_base, type_, low_, &out_base, &res);
    if (status != ZX_OK) {
        pci_errorf("failed to allocate [%#8lx, %#8lx, %s] from root: %d\n", in_base, size,
                   (type_ == PCI_ADDRESS_SPACE_MMIO) ? "mmio" : "io", status);
        return status;
    }

    auto cleanup = fbl::MakeAutoCall([&]() { pciroot_.FreeAddressSpace(out_base, size, type_); });

    fbl::AllocChecker ac;
    *alloc = fbl::unique_ptr<PciRootAllocation>(new (&ac) PciRootAllocation(pciroot_, type_,
                                                                            std::move(res),
                                                                            out_base, size));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }

    cleanup.cancel();
    return ZX_OK;
}

zx_status_t PciRootAllocator::AddAddressSpace(fbl::unique_ptr<PciAllocation> alloc) {
    // PciRootAllocations will free any space they hold when they are destroyed,
    // and nothing seeds a PciRootAllocator.
    return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t PciRegionAllocator::GetRegion(zx_paddr_t base,
                                          size_t size,
                                          fbl::unique_ptr<PciAllocation>* alloc) {
    RegionAllocator::Region::UPtr region_uptr;
    zx_status_t status;
    // Only use base if it is non-zero
    if (base) {
        ralloc_region_t request = {
            .base = base,
            .size = size,
        };
        status = allocator_.GetRegion(request, region_uptr);
    } else {
        status = allocator_.GetRegion(size, region_uptr);
    }

    if (status != ZX_OK) {
        return status;
    }

    zx::resource out_resource;
    status = backing_alloc_->resource().duplicate(ZX_DEFAULT_RESOURCE_RIGHTS, &out_resource);
    if (status != ZX_OK) {
        return status;
    }

    pci_tracef("bridge: assigned [ %#lx-%#lx ] to downstream\n", region_uptr->base,
               region_uptr->base + size);
    fbl::AllocChecker ac;
    *alloc =
        fbl::unique_ptr<PciRegionAllocation>(new (&ac) PciRegionAllocation(std::move(out_resource),
                                                                           std::move(region_uptr)));
    if (!ac.check()) {
        return ZX_ERR_NO_MEMORY;
    }

    return ZX_OK;
}

zx_status_t PciRegionAllocator::AddAddressSpace(fbl::unique_ptr<PciAllocation> alloc) {
    backing_alloc_ = std::move(alloc);
    auto base = backing_alloc_->base();
    auto size = backing_alloc_->size();
    return allocator_.AddRegion({.base = base, .size = size});
}

} // namespace pci
