// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <align.h>

#include <new>

#include <dev/iommu/dummy.h>
#include <fbl/ref_ptr.h>
#include <ktl/algorithm.h>
#include <ktl/move.h>
#include <vm/vm.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#define INVALID_PADDR UINT64_MAX

DummyIommu::DummyIommu() {}

zx_status_t DummyIommu::Create(ktl::unique_ptr<const uint8_t[]> desc, size_t desc_len,
                               fbl::RefPtr<Iommu>* out) {
  if (desc_len != sizeof(zx_iommu_desc_dummy_t)) {
    return ZX_ERR_INVALID_ARGS;
  }

  fbl::AllocChecker ac;
  auto instance = fbl::AdoptRef<DummyIommu>(new (&ac) DummyIommu());
  if (!ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }
  *out = ktl::move(instance);
  return ZX_OK;
}

DummyIommu::~DummyIommu() {}

bool DummyIommu::IsValidBusTxnId(uint64_t bus_txn_id) const { return true; }

zx_status_t DummyIommu::Map(uint64_t bus_txn_id, const fbl::RefPtr<VmObject>& vmo, uint64_t offset,
                            size_t size, uint32_t perms, dev_vaddr_t* vaddr, size_t* mapped_len) {
  DEBUG_ASSERT(vaddr);
  DEBUG_ASSERT(mapped_len);

  if (!IS_PAGE_ALIGNED(offset) || size == 0) {
    return ZX_ERR_INVALID_ARGS;
  }
  if (perms & ~(IOMMU_FLAG_PERM_READ | IOMMU_FLAG_PERM_WRITE | IOMMU_FLAG_PERM_EXECUTE)) {
    return ZX_ERR_INVALID_ARGS;
  }
  if (perms == 0) {
    return ZX_ERR_INVALID_ARGS;
  }

  paddr_t paddr = INVALID_PADDR;
  size = ROUNDUP(size, PAGE_SIZE);
  zx_status_t status = vmo->LookupContiguous(offset, size, &paddr);
  // If the range is fundamentally incorrect or out of range then we immediately error. Otherwise
  // even if we have some other error case we will fall back to attempting single pages at a time.
  if (status == ZX_ERR_INVALID_ARGS || status == ZX_ERR_OUT_OF_RANGE) {
    return status;
  }
  if (status == ZX_OK) {
    DEBUG_ASSERT(paddr != INVALID_PADDR);
    *vaddr = paddr;
    *mapped_len = size;
    return ZX_OK;
  }

  status = vmo->LookupContiguous(offset, PAGE_SIZE, &paddr);
  if (status != ZX_OK) {
    return status;
  }
  DEBUG_ASSERT(paddr != INVALID_PADDR);
  *vaddr = paddr;
  *mapped_len = PAGE_SIZE;
  return ZX_OK;
}

zx_status_t DummyIommu::MapContiguous(uint64_t bus_txn_id, const fbl::RefPtr<VmObject>& vmo,
                                      uint64_t offset, size_t size, uint32_t perms,
                                      dev_vaddr_t* vaddr, size_t* mapped_len) {
  DEBUG_ASSERT(vaddr);
  DEBUG_ASSERT(mapped_len);

  if (!IS_PAGE_ALIGNED(offset) || size == 0) {
    return ZX_ERR_INVALID_ARGS;
  }
  if (perms & ~(IOMMU_FLAG_PERM_READ | IOMMU_FLAG_PERM_WRITE | IOMMU_FLAG_PERM_EXECUTE)) {
    return ZX_ERR_INVALID_ARGS;
  }
  if (perms == 0) {
    return ZX_ERR_INVALID_ARGS;
  }

  paddr_t paddr = INVALID_PADDR;
  zx_status_t status = vmo->LookupContiguous(offset, size, &paddr);
  if (status != ZX_OK) {
    return status;
  }
  DEBUG_ASSERT(paddr != INVALID_PADDR);

  *vaddr = paddr;
  *mapped_len = size;
  return ZX_OK;
}

zx_status_t DummyIommu::Unmap(uint64_t bus_txn_id, dev_vaddr_t vaddr, size_t size) {
  if (!IS_PAGE_ALIGNED(vaddr) || !IS_PAGE_ALIGNED(size)) {
    return ZX_ERR_INVALID_ARGS;
  }
  return ZX_OK;
}

zx_status_t DummyIommu::ClearMappingsForBusTxnId(uint64_t bus_txn_id) { return ZX_OK; }

uint64_t DummyIommu::minimum_contiguity(uint64_t bus_txn_id) { return PAGE_SIZE; }

uint64_t DummyIommu::aspace_size(uint64_t bus_txn_id) { return UINT64_MAX; }
