// 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 <assert.h>
#include <inttypes.h>
#include <lib/virtio/backends/pci.h>
#include <lib/virtio/device.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <zircon/status.h>

#include <memory>
#include <utility>

#include <ddk/debug.h>
#include <hw/inout.h>
#include <pretty/hexdump.h>

namespace virtio {

Device::Device(zx_device_t* bus_device, zx::bti bti, std::unique_ptr<Backend> backend)
    : bti_(std::move(bti)), backend_(std::move(backend)), bus_device_(bus_device) {
  zxlogf(TRACE, "%s: entry", __func__);
  device_ops_.version = DEVICE_OPS_VERSION;
}

Device::~Device() { zxlogf(TRACE, "%s: exit", __func__); }

void Device::Unbind(ddk::UnbindTxn txn) { txn.Reply(); }

void Device::Release() {
  irq_thread_should_exit_.store(true, std::memory_order_release);
  thrd_join(irq_thread_, nullptr);
  backend_.reset();
}

void Device::IrqWorker() {
  const auto irq_mode = backend_->InterruptMode();
  ZX_DEBUG_ASSERT(irq_mode == PCI_IRQ_MODE_LEGACY || irq_mode == PCI_IRQ_MODE_MSI_X);
  zxlogf(DEBUG, "%s: starting %s irq worker", tag(),
         (irq_mode == PCI_IRQ_MODE_LEGACY) ? "legacy" : "msi-x");

  while (backend_->InterruptValid() == ZX_OK) {
    auto result = backend_->WaitForInterrupt();
    if (!result.is_ok()) {
      // Timeouts are fine, but need to continue because there's nothing to ack.
      if (result.status_value() == ZX_ERR_TIMED_OUT) {
        continue;
      }

      zxlogf(DEBUG, "%s: error while waiting for interrupt: %s", tag(), result.status_string());
      break;
    }

    // Ack the interrupt we saw based on the key returned from the port. For legacy interrupts
    // this will always be 0, but MSI-X will depend on the number of vectors configured.
    auto key = result.value();
    backend_->InterruptAck(key);

    // Read the status before completing the interrupt in case
    // another interrupt fires and changes the status.
    if (irq_mode == PCI_IRQ_MODE_LEGACY) {
      uint32_t irq_status = IsrStatus();
      zxlogf(TRACE, "%s: irq_status: %#x\n", __func__, irq_status);

      // Since we handle both interrupt types here it's possible for a
      // spurious interrupt if they come in sequence and we check IsrStatus
      // after both have been triggered.
      if (irq_status) {
        if (irq_status & VIRTIO_ISR_QUEUE_INT) { /* used ring update */
          IrqRingUpdate();
        }
        if (irq_status & VIRTIO_ISR_DEV_CFG_INT) { /* config change */
          IrqConfigChange();
        }
      }
    } else {
      // MSI-X
      zxlogf(TRACE, "%s: irq key: %u\n", __func__, key);
      switch (key) {
        case PciBackend::kMsiConfigVector:
          IrqConfigChange();
          break;
        case PciBackend::kMsiQueueVector:
          IrqRingUpdate();
          break;
      }
    }

    if (irq_thread_should_exit_.load(std::memory_order_relaxed)) {
      break;
    }
  }
}

int Device::IrqThreadEntry(void* arg) {
  Device* d = static_cast<Device*>(arg);
  d->IrqWorker();
  return 0;
}

void Device::StartIrqThread() {
  thrd_create_with_name(&irq_thread_, IrqThreadEntry, this, "virtio-irq-thread");
}

zx_status_t Device::CopyDeviceConfig(void* _buf, size_t len) const {
  assert(_buf);

  for (uint16_t i = 0; i < len; i++) {
    backend_->ReadDeviceConfig(i, static_cast<uint8_t*>(_buf) + i);
  }

  return ZX_OK;
}

}  // namespace virtio
