// 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 <lib/zx/bti.h>
#include <lib/zx/channel.h>
#include <lib/zx/interrupt.h>
#include <lib/zx/status.h>
#include <lib/zx/vmo.h>
#include <string.h>
#include <zircon/assert.h>
#include <zircon/errors.h>
#include <zircon/status.h>
// TODO(fxbug.dev/33713): Stop depending on the types in this file.
#include <fuchsia/hardware/pci/c/banjo.h>
#include <zircon/syscalls/pci.h>
#include <zircon/types.h>

#include "src/devices/bus/drivers/pci/common.h"
#include "src/devices/bus/drivers/pci/device.h"
#include "src/devices/bus/drivers/pci/proxy_rpc.h"

#define RPC_ENTRY zxlogf(DEBUG, "[%s] %s: entry", cfg_->addr(), __func__)

#define RPC_UNIMPLEMENTED \
  RPC_ENTRY;              \
  return RpcReply(ch, ZX_ERR_NOT_SUPPORTED)

namespace pci {

zx_status_t Device::DdkRxrpc(zx_handle_t channel) {
  if (channel == ZX_HANDLE_INVALID) {
    // A new connection has been made, there's nothing else to do.
    return ZX_OK;
  }

  // Clear the buffers. We only servce new requests after we've finished
  // previous messages, so we won't overwrite data here.
  memset(&request_, 0, sizeof(request_));
  memset(&response_, 0, sizeof(response_));

  uint32_t bytes_in;
  uint32_t handles_in;
  zx_handle_t handle;
  zx::unowned_channel ch(channel);
  zx_status_t st = ch->read(0, &request_, &handle, sizeof(request_), 1, &bytes_in, &handles_in);
  if (st != ZX_OK) {
    return ZX_ERR_INTERNAL;
  }

  if (bytes_in != sizeof(request_)) {
    return ZX_ERR_INTERNAL;
  }

  {
    fbl::AutoLock dev_lock(&dev_lock_);
    if (disabled_) {
      return RpcReply(ch, ZX_ERR_BAD_STATE);
    }
  }

  switch (request_.op) {
    case PCI_OP_CONFIG_READ:
      return RpcConfigRead(ch);
    case PCI_OP_CONFIG_WRITE:
      return RpcConfigWrite(ch);
    case PCI_OP_CONFIGURE_IRQ_MODE:
      return RpcConfigureIrqMode(ch);
    case PCI_OP_CONNECT_SYSMEM:
      return RpcConnectSysmem(ch, handle);
    case PCI_OP_ENABLE_BUS_MASTER:
      return RpcEnableBusMaster(ch);
    case PCI_OP_GET_BAR:
      return RpcGetBar(ch);
    case PCI_OP_GET_BTI:
      return RpcGetBti(ch);
    case PCI_OP_GET_DEVICE_INFO:
      return RpcGetDeviceInfo(ch);
    case PCI_OP_GET_NEXT_CAPABILITY:
      return RpcGetNextCapability(ch);
    case PCI_OP_MAP_INTERRUPT:
      return RpcMapInterrupt(ch);
    case PCI_OP_QUERY_IRQ_MODE:
      return RpcQueryIrqMode(ch);
    case PCI_OP_RESET_DEVICE:
      return RpcResetDevice(ch);
    case PCI_OP_SET_IRQ_MODE:
      return RpcSetIrqMode(ch);
    case PCI_OP_ACK_INTERRUPT:
      return RpcAckInterrupt(ch);
    default:
      return RpcReply(ch, ZX_ERR_INVALID_ARGS);
  };

  return ZX_OK;
}

// Utility method to handle setting up the payload to return to the proxy and common
// error situations.
zx_status_t Device::RpcReply(const zx::unowned_channel& ch, zx_status_t st, zx_handle_t* handles,
                             const uint32_t handle_cnt) {
  response_.op = request_.op;
  response_.txid = request_.txid;
  response_.ret = st;
  return ch->write(0, &response_, sizeof(response_), handles, handle_cnt);
}

zx_status_t Device::RpcConfigRead(const zx::unowned_channel& ch) {
  response_.cfg.width = request_.cfg.width;
  response_.cfg.offset = request_.cfg.offset;

  if (request_.cfg.offset >= PCI_EXT_CONFIG_SIZE) {
    return RpcReply(ch, ZX_ERR_OUT_OF_RANGE);
  }

  switch (request_.cfg.width) {
    case 1:
      response_.cfg.value = cfg_->Read(PciReg8(request_.cfg.offset));
      break;
    case 2:
      response_.cfg.value = cfg_->Read(PciReg16(request_.cfg.offset));
      break;
    case 4:
      response_.cfg.value = cfg_->Read(PciReg32(request_.cfg.offset));
      break;
    default:
      return RpcReply(ch, ZX_ERR_INVALID_ARGS);
  }

  zxlogf(TRACE, "[%s] Read%u[%#x] = %#x", cfg_->addr(), request_.cfg.width * 8, request_.cfg.offset,
         response_.cfg.value);
  return RpcReply(ch, ZX_OK);
}

zx_status_t Device::RpcConfigWrite(const zx::unowned_channel& ch) {
  response_.cfg.width = request_.cfg.width;
  response_.cfg.offset = request_.cfg.offset;
  response_.cfg.value = request_.cfg.value;

  // Don't permit writes inside the config header.
  if (request_.cfg.offset < PCI_CONFIG_HDR_SIZE) {
    return RpcReply(ch, ZX_ERR_ACCESS_DENIED);
  }

  if (request_.cfg.offset >= PCI_EXT_CONFIG_SIZE) {
    return RpcReply(ch, ZX_ERR_OUT_OF_RANGE);
  }

  switch (request_.cfg.width) {
    case 1:
      cfg_->Write(PciReg8(request_.cfg.offset), static_cast<uint8_t>(request_.cfg.value));
      break;
    case 2:
      cfg_->Write(PciReg16(request_.cfg.offset), static_cast<uint16_t>(request_.cfg.value));
      break;
    case 4:
      cfg_->Write(PciReg32(request_.cfg.offset), request_.cfg.value);
      break;
    default:
      return RpcReply(ch, ZX_ERR_INVALID_ARGS);
  }

  zxlogf(TRACE, "[%s] Write%u[%#x] <- %#x", cfg_->addr(), request_.cfg.width * 8,
         request_.cfg.offset, request_.cfg.value);
  return RpcReply(ch, ZX_OK);
}

zx_status_t Device::RpcEnableBusMaster(const zx::unowned_channel& ch) {
  fbl::AutoLock dev_lock(&dev_lock_);

  zx_status_t status = EnableBusMaster(request_.enable);
  zxlogf(DEBUG, "[%s] EnableBusMaster { enabled = %u, status = %s }", cfg_->addr(), request_.enable,
         zx_status_get_string(status));
  return RpcReply(ch, status);
}

zx_status_t Device::RpcGetBar(const zx::unowned_channel& ch) {
  fbl::AutoLock dev_lock(&dev_lock_);
  auto bar_id = request_.bar.id;
  if (bar_id >= bar_count_) {
    return RpcReply(ch, ZX_ERR_INVALID_ARGS);
  }

  // If this device supports MSIX then we need to deny access to the BARs it
  // uses.
  // TODO(fxbug.dev/32978): It is technically possible for a device to place the pba/mask
  // tables in the same bar as other data. In that case, we would need to ensure
  // that the bar size reflected the non-table portions, and only allow mapping
  // of that other space.
  auto& msix = caps_.msix;
  if (msix && (msix->table_bar() == bar_id || msix->pba_bar() == bar_id)) {
    return RpcReply(ch, ZX_ERR_ACCESS_DENIED);
  }

  // Both unused BARs and BARs that are the second half of a 64 bit
  // BAR have a size of zero.
  auto& bar = bars_[bar_id];
  if (bar.size == 0) {
    return RpcReply(ch, ZX_ERR_NOT_FOUND);
  }

  zx_handle_t handle = ZX_HANDLE_INVALID;
  uint32_t handle_cnt = 0;
  response_.bar.id = bar_id;
  // MMIO Bars have an associated VMO for the driver to map, whereas IO bars
  // have a Resource corresponding to an IO range for the driver to access.
  // These are mutually exclusive, so only one handle is ever needed.
  zx_status_t status = {};
  if (bar.is_mmio) {
    zx::vmo vmo = {};
    if ((status = bar.allocation->CreateVmObject(&vmo)) == ZX_OK) {
      response_.bar.is_mmio = true;
      response_.bar.size = bar.size;
      handle = vmo.release();
      handle_cnt++;
    }
  } else {  // Bar using IOports
    zx::resource res = {};
    if (bar.allocation->resource() &&
        (status = bar.allocation->resource().duplicate(ZX_RIGHT_SAME_RIGHTS, &res)) == ZX_OK) {
      response_.bar.is_mmio = false;
      response_.bar.io_addr = static_cast<uint16_t>(bar.address);
      response_.bar.size = static_cast<uint16_t>(bar.size);
      handle = res.release();
      handle_cnt++;
    } else {
      status = ZX_ERR_INTERNAL;
      zxlogf(ERROR, "[%s] Failed to create a resource for IO bar %u: %d", cfg_->addr(), bar_id,
             status);
    }
  }

  zxlogf(DEBUG, "[%s] GetBar { bar_id = %u, status = %s }", cfg_->addr(), bar_id,
         zx_status_get_string(status));
  return RpcReply(ch, status, &handle, handle_cnt);
}

zx_status_t Device::RpcConnectSysmem(const zx::unowned_channel& ch, zx_handle_t channel) {
  fbl::AutoLock dev_lock(&dev_lock_);

  zx_status_t st = bdi_->ConnectSysmem(zx::channel(channel));
  zxlogf(DEBUG, "[%s] ConnectSysmem { status = %s }", cfg_->addr(), zx_status_get_string(st));
  return RpcReply(ch, st);
}

zx_status_t Device::RpcGetBti(const zx::unowned_channel& ch) {
  fbl::AutoLock dev_lock(&dev_lock_);

  zx::bti bti;
  zx_handle_t handle = ZX_HANDLE_INVALID;
  uint32_t handle_cnt = 0;
  zx_status_t st = bdi_->GetBti(this, request_.bti_index, &bti);
  if (st == ZX_OK) {
    handle = bti.release();
    handle_cnt++;
  }

  zxlogf(DEBUG, "[%s] GetBti { index = %u, status = %s }", cfg_->addr(), request_.bti_index,
         zx_status_get_string(st));
  return RpcReply(ch, st, &handle, handle_cnt);
}

zx_status_t Device::RpcGetDeviceInfo(const zx::unowned_channel& ch) {
  response_.info.vendor_id = vendor_id();
  response_.info.device_id = device_id();
  response_.info.base_class = class_id();
  response_.info.sub_class = subclass();
  response_.info.program_interface = prog_if();
  response_.info.revision_id = rev_id();
  response_.info.bus_id = bus_id();
  response_.info.dev_id = dev_id();
  response_.info.func_id = func_id();

  return RpcReply(ch, ZX_OK);
}

namespace {
template <class T, class L>
zx_status_t GetNextCapability(PciRpcMsg* req, PciRpcMsg* resp, const L* list) {
  resp->cap.id = req->cap.id;
  resp->cap.is_extended = req->cap.is_extended;
  resp->cap.is_first = req->cap.is_first;
  // Scan for the capability type requested, returning the first capability
  // found after we've seen the capability owning the previous offset.  We
  // can't scan entirely based on offset being >= than a given base because
  // capabilities pointers can point backwards in config space as long as the
  // structures are valid.
  zx_status_t st = ZX_ERR_NOT_FOUND;
  bool found_prev = (req->cap.is_first) ? true : false;
  T scan_offset = static_cast<T>(req->cap.offset);

  for (auto& cap : *list) {
    if (found_prev) {
      if (cap.id() == req->cap.id) {
        resp->cap.offset = cap.base();
        st = ZX_OK;
        break;
      }
    } else {
      if (cap.base() == scan_offset) {
        found_prev = true;
      }
    }
  }
  return st;
}

}  // namespace
zx_status_t Device::RpcGetNextCapability(const zx::unowned_channel& ch) {
  // Capabilities and Extended Capabilities only differ by what list they're in along with the
  // size of their entries. We can offload most of the work into a templated work function.
  zx_status_t st = ZX_ERR_NOT_FOUND;
  if (request_.cap.is_extended) {
    st = GetNextCapability<uint16_t, ExtCapabilityList>(&request_, &response_,
                                                        &capabilities().ext_list);
  } else {
    st = GetNextCapability<uint8_t, CapabilityList>(&request_, &response_, &capabilities().list);
  }
  return RpcReply(ch, st);
}

zx_status_t Device::RpcConfigureIrqMode(const zx::unowned_channel& ch) {
  uint32_t irq_cnt = request_.irq.requested_irqs;
  std::array<pci_irq_mode_t, 3> modes{PCI_IRQ_MODE_MSI_X, PCI_IRQ_MODE_MSI, PCI_IRQ_MODE_LEGACY};
  for (auto& mode : modes) {
    if (auto result = QueryIrqMode(mode); result.is_ok() && result.value() >= irq_cnt) {
      zx_status_t st = SetIrqMode(mode, irq_cnt);
      zxlogf(DEBUG, "[%s] ConfigureIrqMode { mode = %u, requested_irqs = %u, status = %s }",
             cfg_->addr(), mode, irq_cnt, zx_status_get_string(st));
      if (st == ZX_OK) {
        response_.irq.mode = mode;
      }
      return RpcReply(ch, st);
    }
  }

  zxlogf(DEBUG, "[%s] ConfigureIrqMode { no valid modes found }", cfg_->addr());
  return RpcReply(ch, ZX_ERR_NOT_SUPPORTED);
}

zx_status_t Device::RpcQueryIrqMode(const zx::unowned_channel& ch) {
  response_.irq.max_irqs = 0;
  auto result = QueryIrqMode(request_.irq.mode);
  if (result.is_ok()) {
    response_.irq.max_irqs = result.value();
  }

  zxlogf(DEBUG, "[%s] QueryIrqMode { mode = %u, max_irqs = %u, status = %s }", cfg_->addr(),
         request_.irq.mode, response_.irq.max_irqs, result.status_string());
  return RpcReply(ch, result.status_value());
}

zx_status_t Device::RpcSetIrqMode(const zx::unowned_channel& ch) {
  zx_status_t st = SetIrqMode(request_.irq.mode, request_.irq.requested_irqs);
  zxlogf(DEBUG, "[%s] SetIrqMode { mode = %u, requested_irqs = %u, status = %s }", cfg_->addr(),
         request_.irq.mode, request_.irq.requested_irqs, zx_status_get_string(st));
  return RpcReply(ch, st);
}

zx_status_t Device::RpcMapInterrupt(const zx::unowned_channel& ch) {
  zx_handle_t handle = ZX_HANDLE_INVALID;
  size_t handle_cnt = 0;
  zx::status<zx::interrupt> result = MapInterrupt(request_.irq.which_irq);
  if (result.is_ok()) {
    handle_cnt++;
    handle = result.value().release();
  }

  zxlogf(DEBUG, "[%s] MapInterrupt { irq = %u, status = %s }", cfg_->addr(), request_.irq.which_irq,
         zx_status_get_string(result.status_value()));
  return RpcReply(ch, result.status_value(), &handle, handle_cnt);
}

zx_status_t Device::RpcAckInterrupt(const zx::unowned_channel& ch) {
  fbl::AutoLock dev_lock(&dev_lock_);

  zx_status_t status = AckLegacyIrq();
  return RpcReply(ch, status, nullptr, 0);
}

zx_status_t Device::RpcResetDevice(const zx::unowned_channel& ch) { RPC_UNIMPLEMENTED; }

}  // namespace pci
