// 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 <debug.h>
#include <lib/unittest/unittest.h>
#include <platform.h>
#include <pow2.h>
#include <zircon/errors.h>
#include <zircon/time.h>

#include <utility>

#include <fbl/ref_ptr.h>
#include <kernel/thread.h>
#include <object/handle.h>
#include <object/msi_allocation.h>
#include <object/msi_dispatcher.h>
#include <vm/pmm.h>
#include <vm/vm_address_region.h>
#include <vm/vm_object.h>
#include <vm/vm_object_paged.h>

namespace {
bool MsiIsSupportedTrue() { return true; }
zx_status_t MsiAllocate(uint requested_irqs, bool /*unused*/, bool /*unused*/,
                        msi_block_t* out_block) {
  out_block->allocated = true;
  out_block->base_irq_id = 128;
  out_block->num_irq = requested_irqs;
  out_block->tgt_addr = 0x1234u;
  out_block->tgt_addr = 0x4321u;
  out_block->platform_ctx = nullptr;
  return ZX_OK;
}

// These functions are used to verify we properly bail out if MSI isn't supported.
void MsiFree(msi_block_t* block) { block->allocated = false; }
bool MsiIsSupportedFalse() { return false; }
zx_status_t MsiAllocateAssert(uint32_t /* unused */, bool /* unused */, bool /* unused */,
                              msi_block_t* /* unused */) {
  assert(false);
  return ZX_ERR_NOT_SUPPORTED;
}

void MsiFreeAssert(msi_block_t* /* unused */) { assert(false); }
}  // namespace
const uint32_t kVectorMax = 256u;

zx_status_t create_resource_storage_and_allocation(
    ResourceDispatcher::ResourceStorage* rsrc_storage, fbl::RefPtr<MsiAllocation>* alloc,
    uint32_t cnt) {
  zx_status_t status;
  if ((status = ResourceDispatcher::InitializeAllocator(ZX_RSRC_KIND_IRQ, 0, kVectorMax,
                                                        rsrc_storage)) != ZX_OK) {
    return status;
  }

  if ((status = MsiAllocation::Create(cnt, alloc, MsiAllocate, MsiFree, MsiIsSupportedTrue,
                                      rsrc_storage) != ZX_OK)) {
    return status;
  }

  if (rsrc_storage->resource_list.size_slow() != 1u) {
    return ZX_ERR_NO_MEMORY;
  }

  return ZX_OK;
}

// Helper function to create a valid vmo / mapping / capability tuple to cut down
// on the duplication within tests.
zx_status_t create_valid_msi_vmo(fbl::RefPtr<VmObject>* out_vmo,
                                 fbl::RefPtr<VmMapping>* out_mapping,
                                 volatile MsiCapability** out_cap) {
  zx_status_t status;
  size_t vmo_size = sizeof(MsiCapability);
  fbl::RefPtr<VmObjectPaged> vmo;
  if ((status = VmObjectPaged::CreateContiguous(PMM_ALLOC_FLAG_ANY, vmo_size, 0 /* options */,
                                                &vmo)) != ZX_OK) {
    return status;
  }

  if ((status = vmo->SetMappingCachePolicy(ZX_CACHE_POLICY_UNCACHED_DEVICE)) != ZX_OK) {
    return status;
  }

  fbl::RefPtr<VmMapping> mapping;
  status = VmAspace::kernel_aspace()->RootVmar()->CreateVmMapping(
      /*mapping_offset=*/0, /*size=*/vmo_size, /*align_pow2=*/0, /*vmar_flags=*/0, vmo,
      /*vmo_offset=*/0, ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE,
      /*name=*/nullptr, &mapping);
  if (status == ZX_OK) {
    // Prepopulate the mapping so no page faults are needed in kernel mode.
    status = mapping->MapRange(/*offset=*/0, vmo_size, /*commit=*/true);
  }
  if (status != ZX_OK) {
    return status;
  }

  *out_vmo = ktl::move(vmo);
  *out_mapping = ktl::move(mapping);
  *out_cap = reinterpret_cast<MsiCapability*>(out_mapping->get()->base());
  (*out_cap)->id = kMsiCapabilityId;

  return ZX_OK;
}

static bool allocation_creation_and_info_test() {
  BEGIN_TEST;

  const uint32_t test_irq_cnt = 8;
  ResourceDispatcher::ResourceStorage rsrc_storage;
  fbl::RefPtr<MsiAllocation> alloc;
  ASSERT_EQ(ZX_OK, create_resource_storage_and_allocation(&rsrc_storage, &alloc, test_irq_cnt));

  zx_info_msi_t info = {};
  alloc->GetInfo(&info);

  // Grab the lock and compare the block values and info values to both our test
  // data and info data.
  Guard<SpinLock, IrqSave> guard{&alloc->lock()};
  ASSERT_EQ(test_irq_cnt, alloc->block().num_irq);
  ASSERT_EQ(true, alloc->block().allocated);
  ASSERT_EQ(info.base_irq_id, alloc->block().base_irq_id);
  ASSERT_EQ(info.num_irq, alloc->block().num_irq);
  ASSERT_EQ(info.target_addr, alloc->block().tgt_addr);
  ASSERT_EQ(info.target_data, alloc->block().tgt_data);
  END_TEST;
}

static bool allocation_irq_count_test() {
  BEGIN_TEST;

  ResourceDispatcher::ResourceStorage rsrc_storage;
  ASSERT_EQ(ZX_OK, ResourceDispatcher::InitializeAllocator(ZX_RSRC_KIND_IRQ, 0, kVectorMax,
                                                           &rsrc_storage));
  // Check that the valid range of allocation sizes work. Verifies that only
  // powers of two are valid.
  for (uint32_t cnt = 1; cnt < MsiAllocation::kMsiAllocationCountMax; cnt++) {
    fbl::RefPtr<MsiAllocation> alloc;
    zx_status_t expected = ispow2(cnt) ? ZX_OK : ZX_ERR_INVALID_ARGS;
    ASSERT_EQ(expected, MsiAllocation::Create(cnt, &alloc, MsiAllocate, MsiFree, MsiIsSupportedTrue,
                                              &rsrc_storage));
  }

  fbl::RefPtr<MsiAllocation> alloc;
  // And check the failure cases.
  ASSERT_EQ(ZX_ERR_INVALID_ARGS, MsiAllocation::Create(0, &alloc, MsiAllocate, MsiFree,
                                                       MsiIsSupportedTrue, &rsrc_storage));
  ASSERT_EQ(ZX_ERR_INVALID_ARGS,
            MsiAllocation::Create(MsiAllocation::kMsiAllocationCountMax + 1, &alloc, MsiAllocate,
                                  MsiFree, MsiIsSupportedTrue, &rsrc_storage));

  END_TEST;
}

static bool allocation_reservation_test() {
  BEGIN_TEST;

  ResourceDispatcher::ResourceStorage rsrc_storage;
  fbl::RefPtr<MsiAllocation> alloc;
  ASSERT_EQ(ZX_OK, create_resource_storage_and_allocation(&rsrc_storage, &alloc,
                                                          MsiAllocation::kMsiAllocationCountMax));

  // Verify the bounds checking and state of id reservations.
  ASSERT_EQ(ZX_ERR_BAD_STATE, alloc->ReleaseId(0));
  ASSERT_EQ(ZX_OK, alloc->ReserveId(0));
  ASSERT_EQ(ZX_ERR_ALREADY_BOUND, alloc->ReserveId(0));
  ASSERT_EQ(ZX_OK, alloc->ReleaseId(0));
  ASSERT_EQ(ZX_ERR_INVALID_ARGS, alloc->ReserveId(MsiAllocation::kMsiAllocationCountMax));
  ASSERT_EQ(ZX_ERR_INVALID_ARGS, alloc->ReleaseId(MsiAllocation::kMsiAllocationCountMax));
  END_TEST;
}

static bool allocation_support_test() {
  BEGIN_TEST;
  ResourceDispatcher::ResourceStorage rsrc_storage;
  ASSERT_EQ(ZX_OK, ResourceDispatcher::InitializeAllocator(ZX_RSRC_KIND_IRQ, 0, kVectorMax,
                                                           &rsrc_storage));

  {
    fbl::RefPtr<MsiAllocation> alloc;
    ASSERT_EQ(ZX_ERR_NOT_SUPPORTED,
              MsiAllocation::Create(1, &alloc, MsiAllocateAssert, MsiFreeAssert,
                                    MsiIsSupportedFalse, &rsrc_storage));
    ASSERT_EQ(0u, rsrc_storage.resource_list.size_slow());
  }

  END_TEST;
}

// Use a static var for tracking calls rather than a lambda to avoid storage issues with lambda
// captures and function pointers without having to increase complexity in the dispatcher.
static uint32_t register_call_count = 0;
void register_fn(const msi_block_t*, uint, int_handler, void*) { register_call_count++; }

static bool interrupt_duplication_test() {
  BEGIN_TEST;
  ResourceDispatcher::ResourceStorage rsrc_storage;
  fbl::RefPtr<MsiAllocation> alloc;
  ASSERT_EQ(ZX_OK, create_resource_storage_and_allocation(&rsrc_storage, &alloc,
                                                          MsiAllocation::kMsiAllocationCountMax));

  fbl::RefPtr<VmObject> vmo;
  fbl::RefPtr<VmMapping> mapping;
  volatile MsiCapability* cap;
  ASSERT_EQ(ZX_OK, create_valid_msi_vmo(&vmo, &mapping, &cap));

  // Now to the meat of the test. Ensure that two MsiDispatchers cannot share
  // the same MSI id, and that when a dispatcher is cleaned up it releases the
  // Id reservation in the allocation.
  zx_rights_t rights;
  KernelHandle<InterruptDispatcher> d1, d2;
  ASSERT_EQ(ZX_OK, MsiDispatcher::Create(alloc, 0, vmo, /*cap_offset=*/0, /*options=*/0, &rights,
                                         &d1, register_fn));
  ASSERT_EQ(ZX_ERR_ALREADY_BOUND, MsiDispatcher::Create(alloc, 0, vmo, /*cap_offset=*/0,
                                                        /*options=*/0, &rights, &d2, register_fn));
  d1.reset();
  ASSERT_EQ(ZX_OK, MsiDispatcher::Create(alloc, 0, vmo, /*cap_offset=*/0, /*options=*/0, &rights,
                                         &d2, register_fn));

  END_TEST;
}

static bool interrupt_vmo_test() {
  BEGIN_TEST;
  register_call_count = 0;
  ResourceDispatcher::ResourceStorage rsrc_storage;
  fbl::RefPtr<MsiAllocation> alloc;
  ASSERT_EQ(ZX_OK, create_resource_storage_and_allocation(&rsrc_storage, &alloc,
                                                          MsiAllocation::kMsiAllocationCountMax));

  // This test emulates a block of MSI interrupts each taking up a given bit in a register for
  // their own masking. It validates that the MsiDispatcher masks / unmasks the correct bit, and
  // that the operation of the inherited InterruptDispatcher side of things behaves correctly when
  // interrupts are triggered.
  KernelHandle<InterruptDispatcher> interrupt;
  zx_rights_t rights;
  {
    fbl::RefPtr<VmObjectPaged> vmo, vmo_noncontig;
    size_t vmo_size = sizeof(MsiCapability);
    ASSERT_EQ(ZX_OK,
              VmObjectPaged::CreateContiguous(PMM_ALLOC_FLAG_ANY, vmo_size, /*options=*/0, &vmo));
    ASSERT_EQ(ZX_OK,
              VmObjectPaged::Create(PMM_ALLOC_FLAG_ANY, /*options=*/0, vmo_size, &vmo_noncontig));

    // This should fail because the VMO is non-contiguous.
    ASSERT_EQ(ZX_ERR_INVALID_ARGS,
              MsiDispatcher::Create(alloc, 0, vmo_noncontig, /*cap_offset=*/0, /*options=*/0,
                                    &rights, &interrupt, register_fn));
    // This should fail because the VMO has not had a cache policy set.
    ASSERT_EQ(ZX_ERR_INVALID_ARGS,
              MsiDispatcher::Create(alloc, 0, vmo, /*cap_offset=*/0, /*options=*/0, &rights,
                                    &interrupt, register_fn));
    ASSERT_EQ(ZX_OK, vmo->SetMappingCachePolicy(ZX_CACHE_POLICY_UNCACHED_DEVICE));
    // Create will still fail because the VMO doesn't look like an MSI capability.
    ASSERT_EQ(ZX_ERR_INVALID_ARGS,
              MsiDispatcher::Create(alloc, 0, vmo, /*cap_offset=*/0, /*options=*/0, &rights,
                                    &interrupt, register_fn));
  }

  fbl::RefPtr<VmObject> vmo;
  fbl::RefPtr<VmMapping> mapping;
  volatile MsiCapability* cap;
  ASSERT_EQ(ZX_OK, create_valid_msi_vmo(&vmo, &mapping, &cap));
  // Now Create() should succeed.
  ASSERT_EQ(ZX_OK, MsiDispatcher::Create(alloc, 0, vmo, /*cap_offset=*/0, /*options=*/0, &rights,
                                         &interrupt, register_fn));
  ASSERT_EQ(1u, register_call_count);
  END_TEST;
}

static bool interrupt_creation_mask_test() {
  BEGIN_TEST;
  ResourceDispatcher::ResourceStorage rsrc_storage;
  fbl::RefPtr<MsiAllocation> alloc;
  ASSERT_EQ(ZX_OK, create_resource_storage_and_allocation(&rsrc_storage, &alloc,
                                                          MsiAllocation::kMsiAllocationCountMax));
  fbl::RefPtr<VmObject> vmo;
  fbl::RefPtr<VmMapping> mapping;
  volatile MsiCapability* cap;
  ASSERT_EQ(ZX_OK, create_valid_msi_vmo(&vmo, &mapping, &cap));

  zx_rights_t rights;
  // Below test all the mask variants around PVM. This also serves to ensure
  // that the dtor properly releases the msi registration in all cases.
  // Test 32 bit / no pvm
  {
    cap->control = ~(kMsiPvmSupported | kMsi64bitSupported);
    for (uint32_t msi_id = 0; msi_id < MsiAllocation::kMsiAllocationCountMax; msi_id++) {
      cap->mask_bits_32 = 0;
      cap->mask_bits_64 = 0;
      KernelHandle<InterruptDispatcher> interrupt;
      ASSERT_EQ(ZX_OK, MsiDispatcher::Create(alloc, msi_id, vmo, /*cap_offset=*/0, /*options=*/0,
                                             &rights, &interrupt, register_fn));
      auto val_32 = cap->mask_bits_32;
      auto val_64 = cap->mask_bits_64;
      EXPECT_EQ(val_32, 0u);
      EXPECT_EQ(val_64, 0u);
    }
  }

  // Test 32 bit / pvm
  {
    cap->control = ~(kMsi64bitSupported);
    for (uint32_t msi_id = 0; msi_id < MsiAllocation::kMsiAllocationCountMax; msi_id++) {
      cap->mask_bits_32 = 0;
      cap->mask_bits_64 = 0;
      KernelHandle<InterruptDispatcher> interrupt;
      ASSERT_EQ(ZX_OK, MsiDispatcher::Create(alloc, msi_id, vmo, /*cap_offset=*/0, /*options=*/0,
                                             &rights, &interrupt, register_fn));
      auto val_32 = cap->mask_bits_32;
      auto val_64 = cap->mask_bits_64;
      EXPECT_EQ(0u, val_32 & (1u << msi_id));
      EXPECT_EQ(val_64, 0u);
    }
  }

  // Test 64 bit / no pvm
  {
    cap->control = kMsi64bitSupported;
    for (uint32_t msi_id = 0; msi_id < MsiAllocation::kMsiAllocationCountMax; msi_id++) {
      cap->mask_bits_32 = 0;
      cap->mask_bits_64 = 0;
      KernelHandle<InterruptDispatcher> interrupt;
      ASSERT_EQ(ZX_OK, MsiDispatcher::Create(alloc, msi_id, vmo, /*cap_offset=*/0, /*options=*/0,
                                             &rights, &interrupt, register_fn));
      auto val_32 = cap->mask_bits_32;
      auto val_64 = cap->mask_bits_64;
      EXPECT_EQ(val_32, 0u);
      EXPECT_EQ(val_64, 0u);
    }
  }

  // Test 32 bit / pvm
  {
    cap->control = kMsiPvmSupported | kMsi64bitSupported;
    for (uint32_t msi_id = 0; msi_id < MsiAllocation::kMsiAllocationCountMax; msi_id++) {
      cap->mask_bits_32 = 0;
      cap->mask_bits_64 = 0;
      KernelHandle<InterruptDispatcher> interrupt;
      ASSERT_EQ(ZX_OK, MsiDispatcher::Create(alloc, msi_id, vmo, /*cap_offset=*/0, /*options=*/0,
                                             &rights, &interrupt, register_fn));
      auto val_32 = cap->mask_bits_32;
      auto val_64 = cap->mask_bits_64;
      EXPECT_EQ(val_32, 0u);
      EXPECT_EQ(0u, val_64 & (1u << msi_id));
    }
  }

  END_TEST;
}

static bool out_of_order_ownership_test() {
  BEGIN_TEST;
  ResourceDispatcher::ResourceStorage rsrc_storage;
  KernelHandle<InterruptDispatcher> interrupt1, interrupt2;
  fbl::RefPtr<VmObject> vmo;
  fbl::RefPtr<VmMapping> mapping;
  volatile MsiCapability* cap;

  ASSERT_EQ(ZX_OK, create_valid_msi_vmo(&vmo, &mapping, &cap));
  {
    zx_rights_t rights;
    fbl::RefPtr<MsiAllocation> alloc;
    ASSERT_EQ(ZX_OK, create_resource_storage_and_allocation(&rsrc_storage, &alloc,
                                                            MsiAllocation::kMsiAllocationCountMax));
    ASSERT_EQ(ZX_OK, MsiDispatcher::Create(alloc, /*msi_id=*/0, vmo, /*cap_offset=*/0,
                                           /*options=*/0, &rights, &interrupt1, register_fn));
    ASSERT_EQ(ZX_OK, MsiDispatcher::Create(alloc, /*msi_id=*/1, vmo, /*cap_offset=*/0,
                                           /*options=*/0, &rights, &interrupt2, register_fn));
  }

  // This test verifies that although our allocation order was Alloc -> 1 -> 2,
  // freeing in the same order behaves properly due to the reference ownership.
  interrupt1.release();

  END_TEST;
}

UNITTEST_START_TESTCASE(msi_object)
UNITTEST("Test that Create() and get_info() operate properly", allocation_creation_and_info_test)
UNITTEST("Test allocation limits", allocation_irq_count_test)
UNITTEST("Test reservations for MSI ids", allocation_reservation_test)
UNITTEST("Test for MSI platform support hooks", allocation_support_test)
UNITTEST("Test that MsiDispatchers cannot overlap on an MSI id", interrupt_duplication_test)
UNITTEST("Test that MsiDispatcher validates the VMO", interrupt_vmo_test)
UNITTEST("Test that MsiDispatcher unmasks on creation", interrupt_creation_mask_test)
UNITTEST("Test that MsiAllocation & MsiDispatcher ownership is correct",
         out_of_order_ownership_test)
UNITTEST_END_TESTCASE(msi_object, "msi", "Tests for MSI objects")
