// Copyright 2017 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 "garnet/bin/guest/vmm/vcpu.h"

#include <limits.h>
#include <stdio.h>
#include <string.h>

#include <lib/fit/function.h>
#include <lib/fxl/logging.h>
#include <lib/fxl/strings/string_printf.h>
#include <trace/event.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/hypervisor.h>
#include <zircon/syscalls/port.h>
#include <zx/thread.h>

#include "garnet/bin/guest/vmm/guest.h"
#include "garnet/bin/guest/vmm/io.h"

static thread_local Vcpu* thread_vcpu = nullptr;

#if __aarch64__
static zx_status_t HandleMemArm(const zx_packet_guest_mem_t& mem,
                                uint64_t trap_key, uint64_t* reg) {
  TRACE_DURATION("machina", "mmio", "addr", mem.addr, "access_size",
                 mem.access_size);

  IoValue mmio = {mem.access_size, {.u64 = mem.data}};
  IoMapping* mapping = IoMapping::FromPortKey(trap_key);
  if (!mem.read) {
    return mapping->Write(mem.addr, mmio);
  }

  zx_status_t status = mapping->Read(mem.addr, &mmio);
  if (status != ZX_OK) {
    return status;
  }
  *reg = mmio.u64;
  if (mem.sign_extend && *reg & (1ul << (mmio.access_size * CHAR_BIT - 1))) {
    *reg |= UINT64_MAX << mmio.access_size;
  }
  return ZX_OK;
}
#elif __x86_64__
#include "garnet/bin/guest/vmm/arch/x64/decode.h"

static zx_status_t HandleMemX86(const zx_packet_guest_mem_t& mem,
                                uint64_t trap_key, const Instruction* inst) {
  TRACE_DURATION("machina", "mmio", "addr", mem.addr, "access_size",
                 inst->access_size);

  zx_status_t status;
  IoValue mmio = {inst->access_size, {.u64 = 0}};
  switch (inst->type) {
    case INST_MOV_WRITE:
      switch (inst->access_size) {
        case 1:
          status = inst_write8(inst, &mmio.u8);
          break;
        case 2:
          status = inst_write16(inst, &mmio.u16);
          break;
        case 4:
          status = inst_write32(inst, &mmio.u32);
          break;
        default:
          return ZX_ERR_NOT_SUPPORTED;
      }
      if (status != ZX_OK) {
        return status;
      }
      return IoMapping::FromPortKey(trap_key)->Write(mem.addr, mmio);

    case INST_MOV_READ:
      status = IoMapping::FromPortKey(trap_key)->Read(mem.addr, &mmio);
      if (status != ZX_OK) {
        return status;
      }
      switch (inst->access_size) {
        case 1:
          return inst_read8(inst, mmio.u8);
        case 2:
          return inst_read16(inst, mmio.u16);
        case 4:
          return inst_read32(inst, mmio.u32);
        default:
          return ZX_ERR_NOT_SUPPORTED;
      }

    case INST_TEST:
      status = IoMapping::FromPortKey(trap_key)->Read(mem.addr, &mmio);
      if (status != ZX_OK) {
        return status;
      }
      switch (inst->access_size) {
        case 1:
          return inst_test8(inst, static_cast<uint8_t>(inst->imm), mmio.u8);
        default:
          return ZX_ERR_NOT_SUPPORTED;
      }

    default:
      return ZX_ERR_INVALID_ARGS;
  }
}
#endif

Vcpu::Vcpu(uint64_t id, Guest* guest, zx_gpaddr_t entry, zx_gpaddr_t boot_ptr)
    : id_(id), guest_(guest), entry_(entry), boot_ptr_(boot_ptr) {}

void Vcpu::Start() {
  std::promise<void> barrier;
  std::future<void> barrier_future = barrier.get_future();
  future_ = std::async(std::launch::async, fit::bind_member(this, &Vcpu::Loop),
                       std::move(barrier));
  barrier_future.wait();
}

zx_status_t Vcpu::Join() { return future_.get(); }

Vcpu* Vcpu::GetCurrent() {
  FXL_DCHECK(thread_vcpu != nullptr) << "Thread does not have a VCPU";
  return thread_vcpu;
}

zx_status_t Vcpu::Loop(std::promise<void> barrier) {
  FXL_DCHECK(thread_vcpu == nullptr) << "Thread has multiple VCPUs";

  // Set the thread state.
  {
    thread_vcpu = this;
    auto name = fxl::StringPrintf("vcpu-%lu", id_);
    zx_status_t status = zx::thread::self()->set_property(
        ZX_PROP_NAME, name.c_str(), name.size());
    if (status != ZX_OK) {
      FXL_LOG(WARNING) << "Failed to set VCPU " << id_ << " thread name "
                       << status;
    }
  }

  // Create the VCPU.
  {
    std::lock_guard<std::shared_mutex> lock(mutex_);
    zx_status_t status = zx::vcpu::create(guest_->object(), 0, entry_, &vcpu_);
    if (status != ZX_OK) {
      FXL_LOG(ERROR) << "Failed to create VCPU " << id_ << " " << status;
      return status;
    }
  }

  // Set the initial VCPU state.
  std::shared_lock<std::shared_mutex> lock(mutex_);
  {
    zx_vcpu_state_t vcpu_state = {};
#if __aarch64__
    vcpu_state.x[0] = boot_ptr_;
#elif __x86_64__
    vcpu_state.rsi = boot_ptr_;
#endif

    zx_status_t status =
        vcpu_.write_state(ZX_VCPU_STATE, &vcpu_state, sizeof(vcpu_state));
    if (status != ZX_OK) {
      FXL_LOG(ERROR) << "Failed to set VCPU " << id_ << " state " << status;
      return status;
    }
  }

  // Unblock VCPU startup barrier.
  barrier.set_value();

  while (true) {
    zx_port_packet_t packet;
    zx_status_t status = vcpu_.resume(&packet);
    if (status == ZX_ERR_STOP) {
      return ZX_OK;
    }
    if (status != ZX_OK) {
      FXL_LOG(ERROR) << "Failed to resume VCPU " << id_ << " " << status;
      exit(status);
    }

    status = HandlePacketLocked(packet);
    if (status == ZX_ERR_STOP) {
      return ZX_OK;
    }
    if (status != ZX_OK) {
      FXL_LOG(ERROR) << "Failed to handle packet " << packet.type << " "
                     << status;
      exit(status);
    }
  }
}

zx_status_t Vcpu::Interrupt(uint32_t vector) {
  std::shared_lock<std::shared_mutex> lock(mutex_);
  return vcpu_.interrupt(vector);
}

zx_status_t Vcpu::HandlePacketLocked(const zx_port_packet_t& packet) {
  switch (packet.type) {
    case ZX_PKT_TYPE_GUEST_MEM:
      return HandleMemLocked(packet.guest_mem, packet.key);
#if __x86_64__
    case ZX_PKT_TYPE_GUEST_IO:
      return HandleIo(packet.guest_io, packet.key);
#endif  // __x86_64__
    case ZX_PKT_TYPE_GUEST_VCPU:
      return HandleVcpu(packet.guest_vcpu, packet.key);
    default:
      FXL_LOG(ERROR) << "Unhandled guest packet " << packet.type;
      return ZX_ERR_NOT_SUPPORTED;
  }
}

zx_status_t Vcpu::HandleMemLocked(const zx_packet_guest_mem_t& mem,
                                  uint64_t trap_key) {
  zx_vcpu_state_t vcpu_state;
  zx_status_t status;
#if __aarch64__
  if (mem.read)
#endif
  {
    status = vcpu_.read_state(ZX_VCPU_STATE, &vcpu_state, sizeof(vcpu_state));
    if (status != ZX_OK) {
      return status;
    }
  }

  bool do_write = false;
#if __aarch64__
  do_write = mem.read;
  status = HandleMemArm(mem, trap_key, &vcpu_state.x[mem.xt]);
#elif __x86_64__
  Instruction inst;
  status = inst_decode(mem.inst_buf, mem.inst_len, mem.default_operand_size,
                       &vcpu_state, &inst);
  if (status != ZX_OK) {
    std::string inst;
    for (uint8_t i = 0; i < mem.inst_len; i++) {
      fxl::StringAppendf(&inst, " %x", mem.inst_buf[i]);
    }
    FXL_LOG(ERROR) << "Unsupported instruction:" << inst;
  } else {
    status = HandleMemX86(mem, trap_key, &inst);
    // If there was an attempt to read or test memory, update the GPRs.
    do_write = inst.type == INST_MOV_READ || inst.type == INST_TEST;
  }
#endif  // __x86_64__

  if (status == ZX_OK && do_write) {
    return vcpu_.write_state(ZX_VCPU_STATE, &vcpu_state, sizeof(vcpu_state));
  }

  return status;
}

#if __x86_64__
zx_status_t Vcpu::HandleInput(const zx_packet_guest_io_t& io,
                              uint64_t trap_key) {
  TRACE_DURATION("machina", "pio_in", "port", io.port, "access_size",
                 io.access_size);

  IoValue value = {};
  value.access_size = io.access_size;
  zx_status_t status = IoMapping::FromPortKey(trap_key)->Read(io.port, &value);
  if (status != ZX_OK) {
    FXL_LOG(ERROR) << "Failed to handle port in 0x" << std::hex << io.port
                   << " " << std::dec << status;
    return status;
  }

  zx_vcpu_io_t vcpu_io;
  memset(&vcpu_io, 0, sizeof(vcpu_io));
  vcpu_io.access_size = value.access_size;
  vcpu_io.u32 = value.u32;
  if (vcpu_io.access_size != io.access_size) {
    FXL_LOG(ERROR) << "Unexpected size (" << vcpu_io.access_size
                   << " != " << io.access_size << ") for port in 0x" << std::hex
                   << io.port;
    return ZX_ERR_IO_DATA_INTEGRITY;
  }
  return vcpu_.write_state(ZX_VCPU_IO, &vcpu_io, sizeof(vcpu_io));
}

zx_status_t Vcpu::HandleOutput(const zx_packet_guest_io_t& io,
                               uint64_t trap_key) {
  TRACE_DURATION("machina", "pio_out", "port", io.port, "access_size",
                 io.access_size);

  IoValue value;
  value.access_size = io.access_size;
  value.u32 = io.u32;
  zx_status_t status = IoMapping::FromPortKey(trap_key)->Write(io.port, value);
  if (status != ZX_OK) {
    FXL_LOG(ERROR) << "Failed to handle port out 0x" << std::hex << io.port
                   << " " << std::dec << status;
  }
  return status;
}

zx_status_t Vcpu::HandleIo(const zx_packet_guest_io_t& io, uint64_t trap_key) {
  return io.input ? HandleInput(io, trap_key) : HandleOutput(io, trap_key);
}
#endif  // __x86_64__

zx_status_t Vcpu::HandleVcpu(const zx_packet_guest_vcpu_t& packet,
                             uint64_t trap_key) {
  switch (packet.type) {
    case ZX_PKT_GUEST_VCPU_INTERRUPT:
      return guest_->Interrupt(packet.interrupt.mask, packet.interrupt.vector);
    case ZX_PKT_GUEST_VCPU_STARTUP:
      if (id_ != 0) {
        FXL_LOG(WARNING)
            << "Ignoring startup of VCPU " << packet.startup.id << " from VCPU "
            << id_ << ", secondary VCPUs must be started by the primary VCPU";
        return ZX_OK;
      }
      return guest_->StartVcpu(packet.startup.id, packet.startup.entry,
                               boot_ptr_);
    default:
      return ZX_ERR_NOT_SUPPORTED;
  }
}
