// Copyright 2019 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 "pci-bus.h"

#include <lib/ddk/debug.h>
#include <lib/device-protocol/pci.h>
#include <lib/pci/hw.h>

#include "fuchsia/hardware/pci/c/banjo.h"

namespace ahci {

PciBus::~PciBus() {}

zx_status_t PciBus::RegRead(size_t offset, uint32_t* val_out) {
  *val_out = le32toh(mmio_->Read32(offset));
  return ZX_OK;
}

zx_status_t PciBus::RegWrite(size_t offset, uint32_t val) {
  mmio_->Write32(htole32(val), offset);
  return ZX_OK;
}

zx_status_t PciBus::Configure(zx_device_t* parent) {
  zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PCI, &pci_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "ahci: error getting pci config information");
    return status;
  }

  // Map register window.
  mmio_buffer_t buf;
  status = pci_map_bar_buffer(&pci_, 5u, ZX_CACHE_POLICY_UNCACHED_DEVICE, &buf);
  if (status != ZX_OK) {
    zxlogf(ERROR, "ahci: error %d mapping pci register window", status);
    return status;
  }
  mmio_ = ddk::MmioBuffer(buf);

  pcie_device_info_t config;
  status = pci_get_device_info(&pci_, &config);
  if (status != ZX_OK) {
    zxlogf(ERROR, "ahci: error getting pci config information");
    return status;
  }

  // TODO: move this to SATA.
  if (config.sub_class != 0x06 && config.base_class == 0x01) {  // SATA
    zxlogf(ERROR, "ahci: device class 0x%x unsupported", config.sub_class);
    return ZX_ERR_NOT_SUPPORTED;
  }

  // FIXME intel devices need to set SATA port enable at config + 0x92
  // ahci controller is bus master
  status = pci_enable_bus_master(&pci_, true);
  if (status != ZX_OK) {
    zxlogf(ERROR, "ahci: error %d enabling bus master", status);
    return status;
  }

  // Request 1 interrupt of any mode.
  status = pci_configure_irq_mode(&pci_, 1, &irq_mode_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "ahci: no interrupts available %d", status);
    return ZX_ERR_NO_RESOURCES;
  }

  // Get bti handle.
  status = pci_get_bti(&pci_, 0, bti_.reset_and_get_address());
  if (status != ZX_OK) {
    zxlogf(ERROR, "ahci: error %d getting bti handle", status);
    return status;
  }

  // Get irq handle.
  status = pci_map_interrupt(&pci_, 0, irq_.reset_and_get_address());
  if (status != ZX_OK) {
    zxlogf(ERROR, "ahci: error %d getting irq handle", status);
    return status;
  }
  return ZX_OK;
}

zx_status_t PciBus::IoBufferInit(io_buffer_t* buffer_, size_t size, uint32_t flags,
                                 zx_paddr_t* phys_out, void** virt_out) {
  // Allocate memory for the command list, FIS receive area, command table and PRDT.
  zx_status_t status = io_buffer_init(buffer_, bti_.get(), size, flags);
  if (status != ZX_OK) {
    return status;
  }
  *phys_out = io_buffer_phys(buffer_);
  *virt_out = io_buffer_virt(buffer_);
  return ZX_OK;
}

zx_status_t PciBus::BtiPin(uint32_t options, const zx::unowned_vmo& vmo, uint64_t offset,
                           uint64_t size, zx_paddr_t* addrs, size_t addrs_count, zx::pmt* pmt_out) {
  zx_handle_t pmt;
  zx_status_t status =
      zx_bti_pin(bti_.get(), options, vmo->get(), offset, size, addrs, addrs_count, &pmt);
  if (status == ZX_OK) {
    *pmt_out = zx::pmt(pmt);
  }
  return status;
}

zx_status_t PciBus::InterruptWait() {
  if (irq_mode_ == PCI_IRQ_MODE_LEGACY) {
    pci_ack_interrupt(&pci_);
  }

  return irq_.wait(nullptr);
}

void PciBus::InterruptCancel() { irq_.destroy(); }

}  // namespace ahci
