// 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 <fidl/fuchsia.hardware.pci/cpp/wire_types.h>
#include <lib/device-protocol/pci.h>
#include <lib/mmio/mmio.h>

namespace ddk {

namespace fpci = fuchsia_hardware_pci;

zx_status_t Pci::GetDeviceInfo(fpci::wire::DeviceInfo* out_info) const {
  auto result = client_->GetDeviceInfo();
  if (!result.ok()) {
    return result.status();
  }
  *out_info = result.value().info;
  return ZX_OK;
}

zx_status_t Pci::GetBar(fidl::AnyArena& arena, uint32_t bar_id, fpci::wire::Bar* out_result) const {
  auto result = client_.buffer(arena)->GetBar(bar_id);
  if (!result.ok()) {
    return result.status();
  }
  if (result->is_error()) {
    return result->error_value();
  }
  *out_result = std::move(result->value()->result);
  if (out_result->result.is_io()) {
    zx_status_t status = zx_ioports_request(out_result->result.io().resource.get(),
                                            static_cast<uint16_t>(out_result->result.io().address),
                                            static_cast<uint32_t>(out_result->size));
    return status;
  } else {
    return ZX_OK;
  }
}

zx_status_t Pci::SetBusMastering(bool enabled) const {
  auto result = client_->SetBusMastering(enabled);
  if (!result.ok()) {
    return result.status();
  }
  if (result->is_error()) {
    return result->error_value();
  }
  return ZX_OK;
}

zx_status_t Pci::ResetDevice() const {
  auto result = client_->ResetDevice();
  if (!result.ok()) {
    return result.status();
  }
  if (result->is_error()) {
    return result->error_value();
  }
  return ZX_OK;
}

zx_status_t Pci::AckInterrupt() const {
  auto result = client_->AckInterrupt();
  if (!result.ok()) {
    return result.status();
  }
  if (result->is_error()) {
    return result->error_value();
  }
  return ZX_OK;
}

zx_status_t Pci::MapInterrupt(uint32_t which_irq, zx::interrupt* out_interrupt) const {
  auto result = client_->MapInterrupt(which_irq);
  if (!result.ok()) {
    return result.status();
  }
  if (result->is_error()) {
    return result->error_value();
  }
  *out_interrupt = std::move(result->value()->interrupt);
  return ZX_OK;
}

void Pci::GetInterruptModes(fpci::wire::InterruptModes* out_modes) const {
  auto result = client_->GetInterruptModes();
  if (!result.ok()) {
    return;
  }
  *out_modes = result.value().modes;
}

zx_status_t Pci::SetInterruptMode(fpci::InterruptMode mode, uint32_t requested_irq_count) const {
  auto result = client_->SetInterruptMode(mode, requested_irq_count);
  if (!result.ok()) {
    return result.status();
  }
  if (result->is_error()) {
    return result->error_value();
  }
  return ZX_OK;
}

zx_status_t Pci::ReadConfig8(uint16_t offset, uint8_t* out_value) const {
  auto result = client_->ReadConfig8(offset);
  if (!result.ok()) {
    return result.status();
  }
  if (result->is_error()) {
    return result->error_value();
  }
  *out_value = result->value()->value;
  return ZX_OK;
}

zx_status_t Pci::ReadConfig8(fpci::Config offset, uint8_t* out_value) const {
  return ReadConfig8(static_cast<uint16_t>(offset), out_value);
}

zx_status_t Pci::ReadConfig16(uint16_t offset, uint16_t* out_value) const {
  auto result = client_->ReadConfig16(offset);
  if (!result.ok()) {
    return result.status();
  }
  if (result->is_error()) {
    return result->error_value();
  }
  *out_value = result->value()->value;
  return ZX_OK;
}

zx_status_t Pci::ReadConfig16(fpci::Config offset, uint16_t* out_value) const {
  return ReadConfig16(static_cast<uint16_t>(offset), out_value);
}

zx_status_t Pci::ReadConfig32(uint16_t offset, uint32_t* out_value) const {
  auto result = client_->ReadConfig32(offset);
  if (!result.ok()) {
    return result.status();
  }
  if (result->is_error()) {
    return result->error_value();
  }
  *out_value = result->value()->value;
  return ZX_OK;
}

zx_status_t Pci::ReadConfig32(fpci::Config offset, uint32_t* out_value) const {
  return ReadConfig32(static_cast<uint16_t>(offset), out_value);
}

zx_status_t Pci::WriteConfig8(uint16_t offset, uint8_t value) const {
  auto result = client_->WriteConfig8(offset, value);
  if (!result.ok()) {
    return result.status();
  }
  if (result->is_error()) {
    return result->error_value();
  }
  return ZX_OK;
}

zx_status_t Pci::WriteConfig16(uint16_t offset, uint16_t value) const {
  auto result = client_->WriteConfig16(offset, value);
  if (!result.ok()) {
    return result.status();
  }
  if (result->is_error()) {
    return result->error_value();
  }
  return ZX_OK;
}

zx_status_t Pci::WriteConfig32(uint16_t offset, uint32_t value) const {
  auto result = client_->WriteConfig32(offset, value);
  if (!result.ok()) {
    return result.status();
  }
  if (result->is_error()) {
    return result->error_value();
  }
  return ZX_OK;
}

zx_status_t Pci::GetFirstCapability(fpci::CapabilityId id, uint8_t* out_offset) const {
  auto result = client_->GetCapabilities(id);
  if (!result.ok()) {
    return result.status();
  }

  if (result.value().offsets.count() == 0) {
    return ZX_ERR_NOT_FOUND;
  }

  *out_offset = result.value().offsets[0];
  return ZX_OK;
}

zx_status_t Pci::GetNextCapability(fpci::CapabilityId id, uint8_t start_offset,
                                   uint8_t* out_offset) const {
  auto result = client_->GetCapabilities(id);
  if (!result.ok()) {
    return result.status();
  }
  fidl::VectorView<uint8_t> offsets = result.value().offsets;
  for (uint64_t i = 0; i < offsets.count() - 1; i++) {
    if (offsets[i] == start_offset) {
      *out_offset = offsets[i + 1];
      return ZX_OK;
    }
  }
  return ZX_ERR_NOT_FOUND;
}

zx_status_t Pci::GetFirstExtendedCapability(fpci::ExtendedCapabilityId id,
                                            uint16_t* out_offset) const {
  auto result = client_->GetExtendedCapabilities(id);
  if (!result.ok()) {
    return result.status();
  }

  if (result.value().offsets.count() == 0) {
    return ZX_ERR_NOT_FOUND;
  }

  *out_offset = result.value().offsets[0];
  return ZX_OK;
}

zx_status_t Pci::GetNextExtendedCapability(fpci::ExtendedCapabilityId id, uint16_t start_offset,
                                           uint16_t* out_offset) const {
  auto result = client_->GetExtendedCapabilities(id);
  if (!result.ok()) {
    return result.status();
  }
  auto offsets = result.value().offsets;
  for (uint64_t i = 0; i < offsets.count() - 1; i++) {
    if (offsets[i] == start_offset) {
      *out_offset = offsets[i + 1];
      return ZX_OK;
    }
  }
  return ZX_ERR_NOT_FOUND;
}

zx_status_t Pci::GetBti(uint32_t index, zx::bti* out_bti) const {
  auto result = client_->GetBti(index);
  if (!result.ok()) {
    return result.status();
  }
  if (result->is_error()) {
    return result->error_value();
  }
  *out_bti = std::move(result->value()->bti);
  return ZX_OK;
}

zx_status_t Pci::MapMmio(uint32_t index, uint32_t cache_policy,
                         std::optional<fdf::MmioBuffer>* mmio) const {
  fidl::Arena arena;
  fpci::wire::Bar bar;
  zx_status_t status = GetBar(arena, index, &bar);
  if (status != ZX_OK) {
    return status;
  }

  if (!bar.result.is_vmo()) {
    return ZX_ERR_WRONG_TYPE;
  }
  size_t vmo_size;
  status = bar.result.vmo().get_size(&vmo_size);
  if (status != ZX_OK) {
    return status;
  }

  zx::result<fdf::MmioBuffer> result =
      fdf::MmioBuffer::Create(0, vmo_size, std::move(bar.result.vmo()), cache_policy);
  if (result.is_ok()) {
    *mmio = std::move(result.value());
  }
  return result.status_value();
}

zx_status_t Pci::ConfigureInterruptMode(uint32_t requested_irq_count,
                                        fpci::InterruptMode* out_mode) const {
  // NOTE: Any changes to this method should likely also be reflected in the C
  // version, pci_configure_interrupt_mode. These two implementations are
  // temporarily coexisting while we migrate PCI from Banjo to FIDL. Eventually
  // the C version will go away.
  //
  // TODO(https://fxbug.dev/42182407): Remove this notice once PCI over Banjo is removed.
  if (requested_irq_count == 0) {
    return ZX_ERR_INVALID_ARGS;
  }

  fpci::wire::InterruptModes modes;
  GetInterruptModes(&modes);
  std::pair<fpci::InterruptMode, uint32_t> pairs[] = {
      {fpci::InterruptMode::kMsiX, modes.msix_count},
      {fpci::InterruptMode::kMsi, modes.msi_count},
      {fpci::InterruptMode::kLegacy, modes.has_legacy}};
  for (auto& [mode, irq_cnt] : pairs) {
    if (irq_cnt >= requested_irq_count) {
      zx_status_t status = SetInterruptMode(mode, requested_irq_count);
      if (status == ZX_OK) {
        if (out_mode) {
          *out_mode = fpci::InterruptMode{mode};
        }
        return status;
      }
    }
  }
  return ZX_ERR_NOT_SUPPORTED;
}

pci_device_info_t convert_device_info_to_banjo(const fuchsia_hardware_pci::wire::DeviceInfo& info) {
  pci_device_info_t out_info{};
  out_info.vendor_id = info.vendor_id;
  out_info.device_id = info.device_id;
  out_info.base_class = info.base_class;
  out_info.sub_class = info.sub_class;
  out_info.program_interface = info.program_interface;
  out_info.revision_id = info.revision_id;
  out_info.bus_id = info.bus_id;
  out_info.dev_id = info.dev_id;
  out_info.func_id = info.func_id;
  return out_info;
}

pci_interrupt_modes_t convert_interrupt_modes_to_banjo(
    const fuchsia_hardware_pci::wire::InterruptModes& modes) {
  pci_interrupt_modes_t out_modes{};
  out_modes.has_legacy = modes.has_legacy;
  out_modes.msi_count = modes.msi_count;
  out_modes.msix_count = modes.msix_count;
  return out_modes;
}

pci_bar_t convert_bar_to_banjo(fuchsia_hardware_pci::wire::Bar bar) {
  pci_bar_t out_bar{};
  out_bar.bar_id = bar.bar_id;
  out_bar.size = bar.size;
  if (bar.result.is_io()) {
    out_bar.type = PCI_BAR_TYPE_IO;
    out_bar.result.io.address = bar.result.io().address;
    out_bar.result.io.resource = bar.result.io().resource.release();
  } else {
    out_bar.type = PCI_BAR_TYPE_MMIO;
    out_bar.result.vmo = bar.result.vmo().release();
  }
  return out_bar;
}

}  // namespace ddk
