// 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 "device_proxy.h"

#include <lib/zx/bti.h>
#include <zircon/types.h>

#include <cstring>

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/protocol/pci.h>
#include <ddk/protocol/sysmem.h>

#include "common.h"

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

#define DEVICE_PROXY_UNIMPLEMENTED                   \
  zxlogf(INFO, "[DeviceProxy] called %s", __func__); \
  return ZX_ERR_NOT_SUPPORTED

// This file contains the PciProtocol implementation that is proxied over
// a channel to the specific pci::Device objects in the PCI Bus Driver.
namespace pci {

zx_status_t DeviceProxy::Create(zx_device_t* parent, zx_handle_t rpcch, const char* name) {
  DeviceProxy* dp = new DeviceProxy(parent, rpcch);
  return dp->DdkAdd(name);
}

zx_status_t DeviceProxy::RpcRequest(PciRpcOp op, zx_handle_t* rd_handle, zx_handle_t* wr_handle,
                                    PciRpcMsg* req, PciRpcMsg* resp) {
  if (rpcch_ == ZX_HANDLE_INVALID) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  uint32_t rd_handle_cnt = 0;
  if (rd_handle) {
    // Since only the caller knows if they expected a valid handle back, make
    // sure the handle is invalid if we didn't get one.
    *rd_handle = ZX_HANDLE_INVALID;
    rd_handle_cnt = 1;
  }

  uint32_t wr_handle_cnt = 0;
  if (wr_handle) {
    wr_handle_cnt = 1;
  }

  req->op = op;
  zx_channel_call_args_t cc_args = {};
  cc_args.wr_bytes = req;
  cc_args.wr_num_bytes = sizeof(*req);
  cc_args.rd_bytes = resp;
  cc_args.rd_num_bytes = sizeof(*resp);
  cc_args.rd_handles = rd_handle;
  cc_args.rd_num_handles = rd_handle_cnt;
  cc_args.wr_handles = wr_handle;
  cc_args.wr_num_handles = wr_handle_cnt;

  uint32_t actual_bytes;
  uint32_t actual_handles;
  zx_status_t st =
      rpcch_.call(0, zx::time(ZX_TIME_INFINITE), &cc_args, &actual_bytes, &actual_handles);
  if (st != ZX_OK) {
    return st;
  }

  if (actual_bytes != sizeof(*resp)) {
    return ZX_ERR_INTERNAL;
  }

  return resp->ret;
}

zx_status_t DeviceProxy::DdkGetProtocol(uint32_t proto_id, void* out) {
  switch (proto_id) {
    case ZX_PROTOCOL_PCI: {
      auto proto = static_cast<pci_protocol_t*>(out);
      proto->ctx = this;
      proto->ops = &pci_protocol_ops_;
      return ZX_OK;
    }
    case ZX_PROTOCOL_SYSMEM: {
      auto proto = static_cast<sysmem_protocol_t*>(out);
      proto->ctx = this;
      proto->ops = &sysmem_protocol_ops_;
      return ZX_OK;
    }
  }

  return ZX_ERR_NOT_SUPPORTED;
}

// TODO(fxbug.dev/33713): Convert this to using a better wire format when we no longer
// have to support the kernel driver.
zx_status_t DeviceProxy::PciGetBar(uint32_t bar_id, zx_pci_bar_t* out_bar) {
  PciRpcMsg req = {};
  PciRpcMsg resp = {};
  zx_handle_t handle;

  req.bar.id = bar_id;
  zx_status_t st =
      RpcRequest(PCI_OP_GET_BAR, /*rd_handle=*/&handle, /*wr_handle=*/nullptr, &req, &resp);
  // |st| is the channel operation status, |resp.ret| is the RPC status.
  if (st != ZX_OK) {
    return st;
  }

  if (resp.ret != ZX_OK) {
    return resp.ret;
  }

  out_bar->id = resp.bar.id;
  if (!resp.bar.is_mmio) {
    out_bar->type = ZX_PCI_BAR_TYPE_PIO;
    // TODO(cja): Figure out once and for all what the story is with IO on ARM.
#if __x86_64__
    out_bar->addr = resp.bar.io_addr;
    out_bar->size = resp.bar.io_size;
    // x86 PIO space access requires permission in the I/O bitmap. If an IO BAR
    // is used then the handle returned corresponds to a resource with access to
    // this range of IO space.
    //
    // In a test environment we are not passed a handle back. We can still verify
    // the I/O address and size.
    if (handle != ZX_HANDLE_INVALID) {
      st = zx_ioports_request(handle, static_cast<uint16_t>(out_bar->addr),
                              static_cast<uint32_t>(out_bar->size));
      if (st != ZX_OK) {
        zxlogf(ERROR, "Failed to map IO window for bar into process: %d", st);
        return st;
      }
    }
#else
    zxlogf(INFO,
           "%s: PIO bars may not be supported correctly on this arch. "
           "Please have someone check this!\n",
           __func__);
    return ZX_ERR_NOT_SUPPORTED;
#endif
  } else {
    out_bar->type = ZX_PCI_BAR_TYPE_MMIO;
    out_bar->handle = handle;
  }

  return ZX_OK;
}

zx_status_t DeviceProxy::PciEnableBusMaster(bool enable) {
  PciRpcMsg req = {};
  PciRpcMsg resp = {};

  req.enable = enable;
  return RpcRequest(PCI_OP_ENABLE_BUS_MASTER, /*rd_handle=*/nullptr, /*wr_handle=*/nullptr, &req,
                    &resp);
}

zx_status_t DeviceProxy::PciResetDevice() { DEVICE_PROXY_UNIMPLEMENTED; }

zx_status_t DeviceProxy::PciMapInterrupt(uint32_t which_irq, zx::interrupt* out_handle) {
  PciRpcMsg req = {};
  PciRpcMsg resp = {};

  req.irq.which_irq = which_irq;
  zx_handle_t irq_handle;
  zx_status_t st = RpcRequest(PCI_OP_MAP_INTERRUPT, /*rd_handle=*/&irq_handle,
                              /*wr_handle=*/nullptr, &req, &resp);
  if (st == ZX_OK) {
    out_handle->reset(irq_handle);
  }

  return st;
}

zx_status_t DeviceProxy::PciConfigureIrqMode(uint32_t requested_irq_count) {
  PciRpcMsg req = {};
  PciRpcMsg resp = {};

  req.irq.requested_irqs = requested_irq_count;
  return RpcRequest(PCI_OP_CONFIGURE_IRQ_MODE, /*rd_handle=*/nullptr, /*wr_handle=*/nullptr, &req,
                    &resp);
}

zx_status_t DeviceProxy::PciQueryIrqMode(zx_pci_irq_mode_t mode, uint32_t* out_max_irqs) {
  PciRpcMsg req = {};
  PciRpcMsg resp = {};

  req.irq.mode = mode;
  resp.irq.mode = mode;
  zx_status_t st =
      RpcRequest(PCI_OP_QUERY_IRQ_MODE, /*rd_handle=*/nullptr, /*wr_handle=*/nullptr, &req, &resp);
  if (st == ZX_OK) {
    *out_max_irqs = resp.irq.max_irqs;
  }
  return st;
}

zx_status_t DeviceProxy::PciSetIrqMode(zx_pci_irq_mode_t mode, uint32_t requested_irq_count) {
  PciRpcMsg req = {};
  PciRpcMsg resp = {};

  req.irq.mode = mode;
  req.irq.requested_irqs = requested_irq_count;
  return RpcRequest(PCI_OP_SET_IRQ_MODE, /*rd_handle=*/nullptr, /*wr_handle=*/nullptr, &req, &resp);
}

zx_status_t DeviceProxy::PciGetDeviceInfo(zx_pcie_device_info_t* out_info) {
  PciRpcMsg req = {};
  PciRpcMsg resp = {};

  zx_status_t st =
      RpcRequest(PCI_OP_GET_DEVICE_INFO, /*rd_handle=*/nullptr, /*wr_handle=*/nullptr, &req, &resp);
  if (st == ZX_OK) {
    *out_info = resp.info;
  }
  return st;
}

template <typename T>
zx_status_t DeviceProxy::PciConfigRead(uint16_t offset, T* out_value) {
  PciRpcMsg req = {};
  PciRpcMsg resp = {};

  req.cfg.offset = offset;
  req.cfg.width = static_cast<uint16_t>(sizeof(T));
  zx_status_t st =
      RpcRequest(PCI_OP_CONFIG_READ, /*rd_handle=*/nullptr, /*wr_handle=*/nullptr, &req, &resp);
  if (st == ZX_OK) {
    *out_value = static_cast<T>(resp.cfg.value);
  }
  return st;
}

zx_status_t DeviceProxy::PciConfigRead8(uint16_t offset, uint8_t* out_value) {
  return PciConfigRead(offset, out_value);
}

zx_status_t DeviceProxy::PciConfigRead16(uint16_t offset, uint16_t* out_value) {
  return PciConfigRead(offset, out_value);
}

zx_status_t DeviceProxy::PciConfigRead32(uint16_t offset, uint32_t* out_value) {
  return PciConfigRead(offset, out_value);
}

template <typename T>
zx_status_t DeviceProxy::PciConfigWrite(uint16_t offset, T value) {
  PciRpcMsg req = {};
  PciRpcMsg resp = {};

  req.cfg.offset = offset;
  req.cfg.width = static_cast<uint16_t>(sizeof(T));
  req.cfg.value = value;
  return RpcRequest(PCI_OP_CONFIG_WRITE, /*rd_handle=*/nullptr, /*wr_handle=*/nullptr, &req, &resp);
}

zx_status_t DeviceProxy::PciConfigWrite8(uint16_t offset, uint8_t value) {
  return PciConfigWrite(offset, value);
}

zx_status_t DeviceProxy::PciConfigWrite16(uint16_t offset, uint16_t value) {
  return PciConfigWrite(offset, value);
}

zx_status_t DeviceProxy::PciConfigWrite32(uint16_t offset, uint32_t value) {
  return PciConfigWrite(offset, value);
}

zx_status_t DeviceProxy::PciGetFirstCapability(uint8_t cap_id, uint8_t* out_offset) {
  return PciGetNextCapability(cap_id, kPciCapOffsetFirst, out_offset);
}

zx_status_t DeviceProxy::PciGetNextCapability(uint8_t cap_id, uint8_t offset, uint8_t* out_offset) {
  if (!out_offset) {
    return ZX_ERR_INVALID_ARGS;
  }

  PciRpcMsg req;
  memset(&req, 0, sizeof(req));
  req.cap.id = cap_id;
  if (offset == kPciCapOffsetFirst) {
    req.cap.is_first = true;
    req.cap.offset = 0;
  } else {
    req.cap.offset = offset;
  }

  PciRpcMsg resp;
  memset(&resp, 0, sizeof(resp));
  zx_status_t st = RpcRequest(PCI_OP_GET_NEXT_CAPABILITY, /*rd_handle=*/nullptr,
                              /*wr_handle=*/nullptr, &req, &resp);
  if (st == ZX_OK) {
    *out_offset = static_cast<uint8_t>(resp.cap.offset);
  }
  return st;
}

zx_status_t DeviceProxy::PciGetFirstExtendedCapability(uint16_t cap_id, uint16_t* out_offset) {
  return PciGetNextExtendedCapability(cap_id, kPciExtCapOffsetFirst, out_offset);
}

zx_status_t DeviceProxy::PciGetNextExtendedCapability(uint16_t cap_id, uint16_t offset,
                                                      uint16_t* out_offset) {
  if (!out_offset) {
    return ZX_ERR_INVALID_ARGS;
  }

  PciRpcMsg req;
  memset(&req, 0, sizeof(req));
  req.cap.id = cap_id;
  if (offset == kPciExtCapOffsetFirst) {
    req.cap.is_first = true;
    req.cap.offset = 0;
  } else {
    req.cap.offset = offset;
  }
  req.cap.is_extended = true;

  PciRpcMsg resp;
  memset(&resp, 0, sizeof(resp));
  zx_status_t st = RpcRequest(PCI_OP_GET_NEXT_CAPABILITY, /*rd_handle=*/nullptr,
                              /*wr_handle=*/nullptr, &req, &resp);
  if (st == ZX_OK) {
    *out_offset = resp.cap.offset;
  }
  return st;
}

zx_status_t DeviceProxy::PciGetBti(uint32_t index, zx::bti* out_bti) {
  PciRpcMsg req = {};
  PciRpcMsg resp = {};
  req.bti_index = index;
  zx_handle_t handle;
  zx_status_t st =
      RpcRequest(PCI_OP_GET_BTI, /*rd_handle=*/&handle, /*wr_handle=*/nullptr, &req, &resp);
  if (st == ZX_OK) {
    out_bti->reset(handle);
  }
  return st;
}

zx_status_t DeviceProxy::SysmemConnect(zx::channel allocator_request) {
  PciRpcMsg req = {};
  PciRpcMsg resp = {};
  zx_handle_t handle = allocator_request.release();
  return RpcRequest(PCI_OP_CONNECT_SYSMEM, /*rd_handle=*/nullptr, /*wr_handle=*/&handle, &req,
                    &resp);
}

}  // namespace pci

static zx_status_t pci_device_proxy_create(void* ctx, zx_device_t* parent, const char* name,
                                           const char* args, zx_handle_t rpcch) {
  return pci::DeviceProxy::Create(parent, rpcch, name);
}

static constexpr zx_driver_ops_t pci_device_proxy_driver_ops = []() {
  zx_driver_ops_t ops = {};
  ops.version = DRIVER_OPS_VERSION;
  ops.create = pci_device_proxy_create;
  return ops;
}();

// clang-format off
ZIRCON_DRIVER_BEGIN(pci_device_proxy, pci_device_proxy_driver_ops, "zircon", "0.1", 1)
    BI_ABORT_IF_AUTOBIND,
ZIRCON_DRIVER_END(pci_device_proxy)
