// Copyright 2016 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 "zircon_platform_pci_device.h"

#include "magma_util/dlog.h"
#include "magma_util/macros.h"
#include "platform_mmio.h"
#include "zircon_platform_bus_mapper.h"
#include "zircon_platform_interrupt.h"
#include "zircon_platform_mmio.h"

#include <ddk/device.h>
#include <ddk/driver.h>

namespace magma {

std::unique_ptr<PlatformMmio>
ZirconPlatformPciDevice::CpuMapPciMmio(unsigned int pci_bar, PlatformMmio::CachePolicy cache_policy)
{
    DLOG("CpuMapPciMmio bar %d", pci_bar);

    zx_pci_bar_t bar;
    zx_status_t status = pci_get_bar(&pci(), pci_bar, &bar);
    if (status != ZX_OK)
        return DRETP(nullptr, "map_resource failed");

    DASSERT(bar.type == ZX_PCI_BAR_TYPE_MMIO);
    mmio_buffer_t mmio_buffer;
    mmio_buffer_init(&mmio_buffer, 0, bar.size, bar.handle, cache_policy);

    std::unique_ptr<ZirconPlatformMmio> mmio(new ZirconPlatformMmio(mmio_buffer));

    DLOG("map_mmio bar %d cache_policy %d returned: 0x%x", pci_bar, static_cast<int>(cache_policy),
         mmio_buffer.vmo);

    return mmio;
}

bool ZirconPlatformPciDevice::ReadPciConfig16(uint64_t addr, uint16_t* value)
{
    if (!value)
        return DRETF(false, "bad value");

    zx_status_t status = pci_config_read16(&pci(), addr, value);
    if (status != ZX_OK)
        return DRETF(false, "failed to read config: %d\n", status);

    return true;
}

std::unique_ptr<PlatformHandle> ZirconPlatformPciDevice::GetBusTransactionInitiator()
{
    zx_handle_t bti_handle;
    zx_status_t status = pci_get_bti(&pci(), 0, &bti_handle);
    if (status != ZX_OK)
        return DRETP(nullptr, "failed to get bus transaction initiator");

    return std::make_unique<ZirconPlatformHandle>(zx::handle(bti_handle));
}

std::unique_ptr<PlatformInterrupt> ZirconPlatformPciDevice::RegisterInterrupt()
{
    uint32_t max_irqs;
    zx_status_t status = pci_query_irq_mode(&pci(), ZX_PCIE_IRQ_MODE_LEGACY, &max_irqs);
    if (status != ZX_OK)
        return DRETP(nullptr, "query_irq_mode_caps failed (%d)", status);

    if (max_irqs == 0)
        return DRETP(nullptr, "max_irqs is zero");

    // Mode must be Disabled before we can request Legacy
    status = pci_set_irq_mode(&pci(), ZX_PCIE_IRQ_MODE_DISABLED, 0);
    if (status != ZX_OK)
        return DRETP(nullptr, "set_irq_mode(DISABLED) failed (%d)", status);

    status = pci_set_irq_mode(&pci(), ZX_PCIE_IRQ_MODE_LEGACY, 1);
    if (status != ZX_OK)
        return DRETP(nullptr, "set_irq_mode(LEGACY) failed (%d)", status);

    zx_handle_t interrupt_handle;
    status = pci_map_interrupt(&pci(), 0, &interrupt_handle);
    if (status < 0)
        return DRETP(nullptr, "map_interrupt failed (%d)", status);

    return std::make_unique<ZirconPlatformInterrupt>(zx::handle(interrupt_handle));
}

ZirconPlatformPciDevice::~ZirconPlatformPciDevice() {}

std::unique_ptr<PlatformPciDevice> PlatformPciDevice::Create(void* device_handle)
{
    if (!device_handle)
        return DRETP(nullptr, "device_handle is null, cannot create PlatformPciDevice");

    pci_protocol_t pci;
    zx_device_t* zx_device = reinterpret_cast<zx_device_t*>(device_handle);
    zx_status_t status = device_get_protocol(zx_device, ZX_PROTOCOL_PCI, &pci);
    if (status != ZX_OK)
        return DRETP(nullptr, "pci protocol is null, cannot create PlatformPciDevice");

    return std::unique_ptr<PlatformPciDevice>(new ZirconPlatformPciDevice(zx_device, pci));
}

} // namespace magma
