// 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 <zircon/syscalls/hypervisor.h>

#include <arch/hypervisor.h>
#include <dev/interrupt/arm_gic_hw_interface.h>
#include <hypervisor/guest_physical_address_space.h>
#include <vm/pmm.h>

#include "el2_cpu_state_priv.h"

static constexpr zx_gpaddr_t kGicvAddress = 0x800001000;
static constexpr size_t kGicvSize = 0x2000;

// static
zx_status_t Guest::Create(ktl::unique_ptr<Guest>* out) {
  if (arm64_get_boot_el() < 2) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  uint8_t vmid;
  zx_status_t status = alloc_vmid(&vmid);
  if (status != ZX_OK) {
    return status;
  }

  fbl::AllocChecker ac;
  ktl::unique_ptr<Guest> guest(new (&ac) Guest(vmid));
  if (!ac.check()) {
    free_vmid(vmid);
    return ZX_ERR_NO_MEMORY;
  }

  Guard<Mutex> lock{&guest->vcpu_mutex_};
  status = guest->vpid_allocator_.Init();
  if (status != ZX_OK) {
    return status;
  }

  status = hypervisor::GuestPhysicalAddressSpace::Create(vmid, &guest->gpas_);
  if (status != ZX_OK) {
    return status;
  }

  zx_paddr_t gicv_paddr;
  status = gic_get_gicv(&gicv_paddr);

  // If status == ZX_ERR_NOT_FOUND, we are running GICv3
  // There is no need to map GICV to the guest
  // Handle other cases below
  if (status == ZX_OK) {
    status = guest->gpas_->MapInterruptController(kGicvAddress, gicv_paddr, kGicvSize);
    if (status != ZX_OK) {
      return status;
    }
  } else if (status == ZX_ERR_NOT_SUPPORTED) {
    return status;
  }

  *out = ktl::move(guest);
  return ZX_OK;
}

Guest::Guest(uint8_t vmid) : vmid_(vmid) {}

Guest::~Guest() { free_vmid(vmid_); }

zx_status_t Guest::SetTrap(uint32_t kind, zx_gpaddr_t addr, size_t len,
                           fbl::RefPtr<PortDispatcher> port, uint64_t key) {
  switch (kind) {
    case ZX_GUEST_TRAP_MEM:
      if (port) {
        return ZX_ERR_INVALID_ARGS;
      }
      break;
    case ZX_GUEST_TRAP_BELL:
      if (!port) {
        return ZX_ERR_INVALID_ARGS;
      }
      break;
    case ZX_GUEST_TRAP_IO:
      return ZX_ERR_NOT_SUPPORTED;
    default:
      return ZX_ERR_INVALID_ARGS;
  }

  if (SIZE_MAX - len < addr) {
    return ZX_ERR_OUT_OF_RANGE;
  } else if (!IS_PAGE_ALIGNED(addr) || !IS_PAGE_ALIGNED(len) || len == 0) {
    return ZX_ERR_INVALID_ARGS;
  }
  zx_status_t status = gpas_->UnmapRange(addr, len);
  if (status != ZX_OK) {
    return status;
  }
  return traps_.InsertTrap(kind, addr, len, ktl::move(port), key);
}

zx_status_t Guest::AllocVpid(uint8_t* vpid) {
  Guard<Mutex> lock{&vcpu_mutex_};
  return vpid_allocator_.AllocId(vpid);
}

zx_status_t Guest::FreeVpid(uint8_t vpid) {
  Guard<Mutex> lock{&vcpu_mutex_};
  return vpid_allocator_.FreeId(vpid);
}
