// Copyright 2020 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 <lib/counters.h>
#include <lib/fit/defer.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <pow2.h>
#include <sys/types.h>
#include <trace.h>

#include <fbl/ref_counted.h>
#include <ktl/bit.h>
#include <ktl/move.h>
#include <object/msi_dispatcher.h>

#include <ktl/enforce.h>

KCOUNTER(msi_create_count, "msi.create")
KCOUNTER(msi_destroy_count, "msi.destroy")

#define LOCAL_TRACE 0

zx_status_t MsiAllocation::Create(uint32_t irq_cnt, fbl::RefPtr<MsiAllocation>* obj,
                                  MsiAllocFn msi_alloc_fn, MsiFreeFn msi_free_fn,
                                  MsiSupportedFn msi_support_fn) {
  if (!msi_support_fn()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  msi_block_t block = {};
  auto cleanup = fit::defer([&msi_free_fn, &block]() {
    if (block.allocated) {
      msi_free_fn(&block);
    }
  });

  // Ensure the requested IRQs fit within the mask of permitted IRQs in an
  // allocation. MSI allocations must be a power of two.
  // MSI supports up to 32, MSI-X supports up to 2048.
  if (irq_cnt == 0 || irq_cnt > kMsiAllocationCountMax || !ispow2(irq_cnt)) {
    return ZX_ERR_INVALID_ARGS;
  }

  zx_status_t st = msi_alloc_fn(irq_cnt, false /* can_target_64bit */, false /* is_msix */, &block);
  if (st != ZX_OK) {
    return st;
  }

  LTRACEF("MSI Allocation: { tgr_addr = 0x%lx, tgt_data = 0x%08x, base_irq_id = %u }\n",
          block.tgt_addr, block.tgt_data, block.base_irq_id);

  ktl::array<char, ZX_MAX_NAME_LEN> name;
  if (block.num_irq == 1) {
    snprintf(name.data(), name.max_size(), "MSI vector %u", block.base_irq_id);
  } else {
    snprintf(name.data(), name.max_size(), "MSI vectors %u-%u", block.base_irq_id,
             block.base_irq_id + block.num_irq - 1);
  }

  fbl::AllocChecker ac;
  auto msi = fbl::AdoptRef<MsiAllocation>(new (&ac) MsiAllocation(block, msi_free_fn));
  if (!ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }

  kcounter_add(msi_create_count, 1);
  cleanup.cancel();
  *obj = ktl::move(msi);
  return ZX_OK;
}

zx_status_t MsiAllocation::ReserveId(MsiId msi_id) {
  if (msi_id >= block_.num_irq) {
    return ZX_ERR_INVALID_ARGS;
  }

  Guard<SpinLock, IrqSave> guard{&lock_};
  auto id_mask = (1u << msi_id);
  if (ids_in_use_ & id_mask) {
    return ZX_ERR_ALREADY_BOUND;
  }

  ids_in_use_ |= id_mask;
  return ZX_OK;
}

zx_status_t MsiAllocation::ReleaseId(MsiId msi_id) {
  if (msi_id >= block_.num_irq) {
    return ZX_ERR_INVALID_ARGS;
  }

  Guard<SpinLock, IrqSave> guard{&lock_};
  auto id_mask = (1u << msi_id);
  if (!(ids_in_use_ & id_mask)) {
    return ZX_ERR_BAD_STATE;
  }

  ids_in_use_ &= ~id_mask;
  return ZX_OK;
}

MsiAllocation::~MsiAllocation() {
  Guard<SpinLock, IrqSave> guard{&lock_};
  DEBUG_ASSERT(ids_in_use_ == 0);

  msi_block_t block = block_;
  if (block_.allocated) {
    msi_free_fn_(&block);
  }
  DEBUG_ASSERT(!block.allocated);
  kcounter_add(msi_destroy_count, 1);
}

void MsiAllocation::GetInfo(zx_info_msi* info) const TA_EXCL(lock_) {
  DEBUG_ASSERT(info);
  Guard<SpinLock, IrqSave> guard{&lock_};
  info->target_addr = block_.tgt_addr;
  info->target_data = block_.tgt_data;
  info->base_irq_id = block_.base_irq_id;
  info->interrupt_count = ktl::popcount(ids_in_use_);
  info->num_irq = block_.num_irq;
}
