// Copyright 2018 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 "msd_vsl_device.h"

#include <chrono>
#include <thread>

#include "instructions.h"
#include "magma_util/macros.h"
#include "magma_vendor_queries.h"
#include "msd.h"
#include "platform_barriers.h"
#include "platform_logger.h"
#include "platform_mmio.h"
#include "platform_thread.h"
#include "registers.h"

static constexpr uint32_t kInterruptIndex = 0;

MsdVslDevice::~MsdVslDevice() {
  DisableInterrupts();

  stop_interrupt_thread_ = true;
  if (interrupt_) {
    interrupt_->Signal();
  }
  if (interrupt_thread_.joinable()) {
    interrupt_thread_.join();
    DLOG("Joined interrupt thread");
  }
}

std::unique_ptr<MsdVslDevice> MsdVslDevice::Create(void* device_handle) {
  auto device = std::make_unique<MsdVslDevice>();

  if (!device->Init(device_handle))
    return DRETP(nullptr, "Failed to initialize device");

  return device;
}

bool MsdVslDevice::Init(void* device_handle) {
  platform_device_ = magma::PlatformDevice::Create(device_handle);
  if (!platform_device_)
    return DRETF(false, "Failed to create platform device");

  std::unique_ptr<magma::PlatformMmio> mmio =
      platform_device_->CpuMapMmio(0, magma::PlatformMmio::CACHE_POLICY_UNCACHED_DEVICE);
  if (!mmio)
    return DRETF(false, "failed to map registers");

  register_io_ = std::make_unique<magma::RegisterIo>(std::move(mmio));

  device_id_ = registers::ChipId::Get().ReadFrom(register_io_.get()).chip_id().get();
  DLOG("Detected vsl chip id 0x%x", device_id_);

  if (device_id_ != 0x7000 && device_id_ != 0x8000)
    return DRETF(false, "Unspported gpu model 0x%x\n", device_id_);

  gpu_features_ = std::make_unique<GpuFeatures>(register_io_.get());
  DLOG("gpu features: 0x%x minor features 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
       gpu_features_->features().reg_value(), gpu_features_->minor_features(0),
       gpu_features_->minor_features(1), gpu_features_->minor_features(2),
       gpu_features_->minor_features(3), gpu_features_->minor_features(4),
       gpu_features_->minor_features(5));
  DLOG("halti5: %d mmu: %d", gpu_features_->halti5(), gpu_features_->has_mmu());

  DLOG(
      "stream count %u register_max %u thread_count %u vertex_cache_size %u shader_core_count "
      "%u pixel_pipes %u vertex_output_buffer_size %u\n",
      gpu_features_->stream_count(), gpu_features_->register_max(), gpu_features_->thread_count(),
      gpu_features_->vertex_cache_size(), gpu_features_->shader_core_count(),
      gpu_features_->pixel_pipes(), gpu_features_->vertex_output_buffer_size());
  DLOG("instruction count %u buffer_size %u num_constants %u varyings_count %u\n",
       gpu_features_->instruction_count(), gpu_features_->buffer_size(),
       gpu_features_->num_constants(), gpu_features_->varyings_count());

  if (!gpu_features_->features().pipe_3d().get())
    return DRETF(false, "Gpu has no 3d pipe: features 0x%x\n",
                 gpu_features_->features().reg_value());

  bus_mapper_ = magma::PlatformBusMapper::Create(platform_device_->GetBusTransactionInitiator());
  if (!bus_mapper_)
    return DRETF(false, "failed to create bus mapper");

  page_table_arrays_ = PageTableArrays::Create(bus_mapper_.get());
  if (!page_table_arrays_)
    return DRETF(false, "failed to create page table arrays");

  // TODO(fxb/43043): Implement and test ringbuffer wrapping.
  const uint32_t kRingbufferSize = magma::page_size();
  auto buffer = MsdVslBuffer::Create(kRingbufferSize, "ring-buffer");
  buffer->platform_buffer()->SetCachePolicy(MAGMA_CACHE_POLICY_UNCACHED);
  ringbuffer_ = std::make_unique<Ringbuffer>(std::move(buffer), 0 /* start_offset */);

  Reset();
  if (!HardwareInit()) {
    return DRETF(false, "Failed to initialize hardware");
  }

  interrupt_thread_ = std::thread([this] { this->InterruptThreadLoop(); });

  return true;
}

bool MsdVslDevice::HardwareInit() {
  interrupt_ = platform_device_->RegisterInterrupt(kInterruptIndex);
  if (!interrupt_) {
    return DRETF(false, "Failed to register interrupt");
  }

  {
    auto reg = registers::IrqEnable::Get().FromValue(~0);
    reg.WriteTo(register_io_.get());
  }

  {
    auto reg = registers::SecureAhbControl::Get().ReadFrom(register_io_.get());
    reg.non_secure_access().set(1);
    reg.WriteTo(register_io_.get());
  }

  page_table_arrays_->HardwareInit(register_io_.get());

  page_table_slot_allocator_ = std::make_unique<PageTableSlotAllocator>(page_table_arrays_->size());
  return true;
}

void MsdVslDevice::DisableInterrupts() {
  if (!register_io_) {
    DLOG("Register io was not initialized, skipping disabling interrupts");
    return;
  }
  auto reg = registers::IrqEnable::Get().FromValue(0);
  reg.WriteTo(register_io_.get());
}

int MsdVslDevice::InterruptThreadLoop() {
  magma::PlatformThreadHelper::SetCurrentThreadName("VSL InterruptThread");
  DLOG("VSL Interrupt thread started");

  std::unique_ptr<magma::PlatformHandle> profile = platform_device_->GetSchedulerProfile(
      magma::PlatformDevice::kPriorityHigher, "msd-vsl-gc/vsl-interrupt-thread");
  if (!profile) {
    return DRETF(0, "Failed to get higher priority");
  }
  if (!magma::PlatformThreadHelper::SetProfile(profile.get())) {
    return DRETF(0, "Failed to set priority");
  }

  while (!stop_interrupt_thread_) {
    interrupt_->Wait();

    if (stop_interrupt_thread_) {
      break;
    }

    auto irq_status = registers::IrqAck::Get().ReadFrom(register_io_.get());
    auto mmu_exception = irq_status.mmu_exception().get();
    auto bus_error = irq_status.bus_error().get();
    auto value = irq_status.value().get();
    if (mmu_exception) {
      DMESSAGE("Interrupt thread received mmu_exception");
    }
    if (bus_error) {
      DMESSAGE("Interrupt thread received bus error");
    }
    // Check which bits are set and complete the corresponding event.
    for (unsigned int i = 0; i < kNumEvents; i++) {
      if (value & (1 << i)) {
        // TODO(fxb/43235): this should be processed on the driver device thread once it exists.
        if (!CompleteInterruptEvent(i)) {
          DLOG("Failed to complete event %u\n", i);
        }
      }
    }
    interrupt_->Complete();
  }
  DLOG("VSL Interrupt thread exiting");
  return 0;
}

bool MsdVslDevice::AllocInterruptEvent(uint32_t* out_event_id) {
  std::lock_guard<std::mutex> lock(events_mutex_);

  for (uint32_t i = 0; i < kNumEvents; i++) {
    if (!events_[i].allocated) {
      events_[i].allocated = true;
      *out_event_id = i;
      return true;
    }
  }
  return DRETF(false, "No events are currently available");
}

bool MsdVslDevice::FreeInterruptEvent(uint32_t event_id) {
  std::lock_guard<std::mutex> lock(events_mutex_);

  if (event_id >= kNumEvents) {
    return DRETF(false, "Invalid event id %u", event_id);
  }
  if (!events_[event_id].allocated) {
    return DRETF(false, "Event id %u was not allocated", event_id);
  }
  events_[event_id] = {};
  return true;
}

// Writes an event into the end of the ringbuffer.
bool MsdVslDevice::WriteInterruptEvent(uint32_t event_id,
                                       std::shared_ptr<magma::PlatformSemaphore> signal) {
  std::lock_guard<std::mutex> lock(events_mutex_);

  if (event_id >= kNumEvents) {
    return DRETF(false, "Invalid event id %u", event_id);
  }
  if (!events_[event_id].allocated) {
    return DRETF(false, "Event id %u was not allocated", event_id);
  }
  if (events_[event_id].submitted) {
    return DRETF(false, "Event id %u was already submitted", event_id);
  }
  events_[event_id].submitted = true;
  events_[event_id].signal = signal;
  MiEvent::write(ringbuffer_.get(), event_id);
  return true;
}

bool MsdVslDevice::CompleteInterruptEvent(uint32_t event_id) {
  std::lock_guard<std::mutex> lock(events_mutex_);

  if (event_id >= kNumEvents) {
    return DRETF(false, "Invalid event id %u", event_id);
  }
  if (!events_[event_id].allocated || !events_[event_id].submitted) {
    return DRETF(false, "Cannot complete event %u, allocated %u submitted %u",
                 event_id, events_[event_id].allocated, events_[event_id].submitted);
  }
  if (events_[event_id].signal) {
    events_[event_id].signal->Signal();
  }
  events_[event_id].submitted = false;
  events_[event_id].signal = nullptr;
  return true;
}

void MsdVslDevice::Reset() {
  DLOG("Reset start");

  auto clock_control = registers::ClockControl::Get().FromValue(0);
  clock_control.isolate_gpu().set(1);
  clock_control.WriteTo(register_io());

  {
    auto reg = registers::SecureAhbControl::Get().FromValue(0);
    reg.reset().set(1);
    reg.WriteTo(register_io_.get());
  }

  std::this_thread::sleep_for(std::chrono::microseconds(100));

  clock_control.soft_reset().set(0);
  clock_control.WriteTo(register_io());

  clock_control.isolate_gpu().set(0);
  clock_control.WriteTo(register_io());

  clock_control = registers::ClockControl::Get().ReadFrom(register_io_.get());

  if (!IsIdle() || !clock_control.idle_3d().get()) {
    MAGMA_LOG(WARNING, "Gpu reset: failed to idle");
  }

  DLOG("Reset complete");
}

bool MsdVslDevice::IsIdle() {
  return registers::IdleState::Get().ReadFrom(register_io_.get()).IsIdle();
}

bool MsdVslDevice::StopRingbuffer() {
  if (IsIdle()) {
    return true;
  }
  // Overwrite the last WAIT with an END.
  uint32_t prev_wait_link = ringbuffer_->SubtractOffset(kWaitLinkDwords * sizeof(uint32_t));
  if (!ringbuffer_->Overwrite32(prev_wait_link, MiEnd::kCommandType)) {
    return DRETF(false, "Failed to overwrite WAIT in ringbuffer");
  }
  return true;
}

bool MsdVslDevice::WaitUntilIdle(uint32_t timeout_ms) {
  auto start = std::chrono::high_resolution_clock::now();
  while (!IsIdle() && std::chrono::duration_cast<std::chrono::milliseconds>(
                          std::chrono::high_resolution_clock::now() - start)
                              .count() < timeout_ms) {
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
  }
  return IsIdle();
}

bool MsdVslDevice::LoadInitialAddressSpace(std::shared_ptr<AddressSpace> address_space,
                                           uint32_t address_space_index) {
  // Check if we have already configured an address space and enabled the MMU.
  if (page_table_arrays_->IsEnabled(register_io())) {
    return DRETF(false, "MMU already enabled");
  }
  static constexpr uint32_t kPageCount = 1;

  std::unique_ptr<magma::PlatformBuffer> buffer =
      magma::PlatformBuffer::Create(PAGE_SIZE * kPageCount, "address space config");
  if (!buffer) {
    return DRETF(false, "failed to create buffer");
  }

  auto bus_mapping = GetBusMapper()->MapPageRangeBus(buffer.get(), 0, kPageCount);
  if (!bus_mapping) {
    return DRETF(false, "failed to create bus mapping");
  }

  uint32_t* cmd_ptr;
  if (!buffer->MapCpu(reinterpret_cast<void**>(&cmd_ptr))) {
    return DRETF(false, "failed to map command buffer");
  }

  BufferWriter buf_writer(cmd_ptr, buffer->size(), 0);
  auto reg = registers::MmuPageTableArrayConfig::Get().addr();
  MiLoadState::write(&buf_writer, reg, address_space_index);
  MiEnd::write(&buf_writer);

  if (!buffer->UnmapCpu()) {
    return DRETF(false, "failed to unmap cpu");
  }
  if (!buffer->CleanCache(0, PAGE_SIZE * kPageCount, false)) {
    return DRETF(false, "failed to clean buffer cache");
  }

  auto res = SubmitCommandBufferNoMmu(bus_mapping->Get()[0], buf_writer.bytes_written());
  if (!res) {
    return DRETF(false, "failed to submit command buffer");
  }
  constexpr uint32_t kTimeoutMs = 100;
  if (!WaitUntilIdle(kTimeoutMs)) {
    return DRETF(false, "failed to wait for device to be idle");
  }

  page_table_arrays_->Enable(register_io(), true);

  DLOG("Address space loaded, index %u", address_space_index);

  return true;
}

bool MsdVslDevice::SubmitCommandBufferNoMmu(uint64_t bus_addr, uint32_t length,
                                            uint16_t* prefetch_out) {
  if (bus_addr & 0xFFFFFFFF00000000ul)
    return DRETF(false, "Can't submit address > 32 bits without mmu: 0x%08lx", bus_addr);

  uint32_t prefetch = magma::round_up(length, sizeof(uint64_t)) / sizeof(uint64_t);
  if (prefetch & 0xFFFF0000)
    return DRETF(false, "Can't submit length %u (prefetch 0x%x)", length, prefetch);

  prefetch &= 0xFFFF;
  if (prefetch_out) {
    *prefetch_out = prefetch;
  }

  DLOG("Submitting buffer at bus addr 0x%lx", bus_addr);

  auto reg_cmd_addr = registers::FetchEngineCommandAddress::Get().FromValue(0);
  reg_cmd_addr.addr().set(bus_addr & 0xFFFFFFFF);

  auto reg_cmd_ctrl = registers::FetchEngineCommandControl::Get().FromValue(0);
  reg_cmd_ctrl.enable().set(1);
  reg_cmd_ctrl.prefetch().set(prefetch);

  auto reg_sec_cmd_ctrl = registers::SecureCommandControl::Get().FromValue(0);
  reg_sec_cmd_ctrl.enable().set(1);
  reg_sec_cmd_ctrl.prefetch().set(prefetch);

  reg_cmd_addr.WriteTo(register_io_.get());
  reg_cmd_ctrl.WriteTo(register_io_.get());
  reg_sec_cmd_ctrl.WriteTo(register_io_.get());

  return true;
}

bool MsdVslDevice::StartRingbuffer(std::shared_ptr<AddressSpace> address_space) {
  if (!IsIdle()) {
    return true;  // Already running and looping on WAIT-LINK.
  }
  bool res = ringbuffer_->Map(address_space);
  if (!res) {
    return DRETF(res, "Could not map ringbuffer");
  }
  uint64_t rb_gpu_addr;
  res = ringbuffer_->GetGpuAddress(&rb_gpu_addr);
  if (!res) {
    return DRETF(res, "Could not get ringbuffer gpu address");
  }

  const uint16_t kRbPrefetch = 2;
  // Write the initial WAIT-LINK to the ringbuffer. The LINK points back to the WAIT,
  // and will keep looping until the WAIT is replaced with a LINK on command buffer submission.
  uint32_t wait_gpu_addr = rb_gpu_addr + ringbuffer_->tail();
  MiWait::write(ringbuffer_.get());
  MiLink::write(ringbuffer_.get(), kRbPrefetch, wait_gpu_addr);

  auto reg_cmd_addr = registers::FetchEngineCommandAddress::Get().FromValue(0);
  reg_cmd_addr.addr().set(static_cast<uint32_t>(wait_gpu_addr));

  auto reg_cmd_ctrl = registers::FetchEngineCommandControl::Get().FromValue(0);
  reg_cmd_ctrl.enable().set(1);
  reg_cmd_ctrl.prefetch().set(kRbPrefetch);

  auto reg_sec_cmd_ctrl = registers::SecureCommandControl::Get().FromValue(0);
  reg_sec_cmd_ctrl.enable().set(1);
  reg_sec_cmd_ctrl.prefetch().set(kRbPrefetch);

  reg_cmd_addr.WriteTo(register_io_.get());
  reg_cmd_ctrl.WriteTo(register_io_.get());
  reg_sec_cmd_ctrl.WriteTo(register_io_.get());
  return true;
}

bool MsdVslDevice::AddRingbufferWaitLink() {
  uint64_t rb_gpu_addr;
  bool res = ringbuffer_->GetGpuAddress(&rb_gpu_addr);
  if (!res) {
    return DRETF(false, "Failed to get ringbuffer gpu address");
  }
  uint32_t wait_gpu_addr = rb_gpu_addr + ringbuffer_->tail();
  MiWait::write(ringbuffer_.get());
  MiLink::write(ringbuffer_.get(), 2 /* prefetch */, wait_gpu_addr);
  return true;
}

bool MsdVslDevice::LinkRingbuffer(uint32_t wait_link_offset, uint32_t gpu_addr,
                                  uint32_t dest_prefetch) {
  DASSERT(ringbuffer_->IsOffsetPopulated(wait_link_offset));
  // We can assume the instruction was written as 8 contiguous bytes.
  DASSERT(ringbuffer_->IsOffsetPopulated(wait_link_offset + sizeof(uint32_t)));

  // Replace the penultimate WAIT (before the newly added one) with a LINK to the command buffer.
  // We will first modify the second dword which specifies the address,
  // as the hardware may be executing at the address of the current WAIT.
  ringbuffer_->Overwrite32(wait_link_offset + sizeof(uint32_t), gpu_addr);
  magma::barriers::Barrier();
  ringbuffer_->Overwrite32(wait_link_offset, MiLink::kCommandType | dest_prefetch);
  magma::barriers::Barrier();
  return true;
}

bool MsdVslDevice::WriteLinkCommand(magma::PlatformBuffer* buf, uint32_t length,
                                    uint16_t link_prefetch, uint32_t link_addr) {
  // Check if we have enough space for the LINK command.
  uint32_t link_instr_size = kInstructionDwords * sizeof(uint32_t);

  if (buf->size() < length + link_instr_size) {
    return DRETF(false, "Buffer does not have %d free bytes for ringbuffer LINK", link_instr_size);
  }

  uint32_t* buf_cpu_addr;
  bool res = buf->MapCpu(reinterpret_cast<void**>(&buf_cpu_addr));
  if (!res) {
    return DRETF(false, "Failed to map command buffer");
  }

  BufferWriter buf_writer(buf_cpu_addr, buf->size(), length);
  MiLink::write(&buf_writer, link_prefetch, link_addr);
  if (!buf->UnmapCpu()) {
    return DRETF(false, "Failed to unmap command buffer");
  }
  return true;
}

// When submitting a command buffer, we modify the following:
//  1) add a LINK from the command buffer to the end of the ringbuffer
//  2) add an EVENT and WAIT-LINK pair to the end of the ringbuffer
//  3) modify the penultimate WAIT in the ringbuffer to LINK to the command buffer
bool MsdVslDevice::SubmitCommandBuffer(std::shared_ptr<AddressSpace> address_space,
                                       uint32_t address_space_index,
                                       magma::PlatformBuffer* buf, uint32_t gpu_addr,
                                       uint32_t length, uint32_t event_id,
                                       std::shared_ptr<magma::PlatformSemaphore> signal,
                                       uint16_t* prefetch_out) {
  // Check if we have loaded an address space and enabled the MMU.
  if (!page_table_arrays_->IsEnabled(register_io())) {
    if (!LoadInitialAddressSpace(address_space, address_space_index)) {
      return DRETF(false, "Failed to load initial address space");
    }
  }
  // Check if we have started the ringbuffer WAIT-LINK loop.
  if (IsIdle()) {
    if (!StartRingbuffer(address_space)) {
      return DRETF(false, "Failed to start ringbuffer");
    }
  }
  // Check if we need to switch address spaces.
  auto mapped_address_space = ringbuffer_->GetMappedAddressSpace().lock();
  // TODO(fxb/43718): support switching address spaces.
  // We will need to keep the previous address space alive until the switch is completed
  // by the hardware.
  if (!mapped_address_space || (mapped_address_space.get() != address_space.get())) {
    return DRETF(false, "Switching ringbuffer contexts not yet supported");
  }
  uint64_t rb_gpu_addr;
  bool res = ringbuffer_->GetGpuAddress(&rb_gpu_addr);
  if (!res) {
    return DRETF(false, "Failed to get ringbuffer gpu address");
  }
  length = magma::round_up(length, sizeof(uint64_t));

  // Number of new commands to be added to the ringbuffer - EVENT WAIT LINK.
  const uint16_t kRbPrefetch = 3;
  uint32_t prev_wait_link = ringbuffer_->SubtractOffset(kWaitLinkDwords * sizeof(uint32_t));

  if (buf) {
    // Write a LINK at the end of the command buffer that links back to the ringbuffer.
    if (!WriteLinkCommand(buf, length, kRbPrefetch,
                          static_cast<uint32_t>(rb_gpu_addr + ringbuffer_->tail()))) {
      return DRETF(false, "Failed to write LINK from command buffer to ringbuffer");
    }
    // Increment the command buffer length to account for the LINK command size.
    length += (kInstructionDwords * sizeof(uint32_t));
  } else {
    // If there is no command buffer, we link directly to the new ringbuffer commands.
    gpu_addr = rb_gpu_addr + ringbuffer_->tail();
    length = kRbPrefetch * sizeof(uint64_t);
  }

  uint32_t prefetch = magma::round_up(length, sizeof(uint64_t)) / sizeof(uint64_t);
  if (prefetch & 0xFFFF0000)
    return DRETF(false, "Can't submit length %u (prefetch 0x%x)", length, prefetch);

  *prefetch_out = prefetch & 0xFFFF;

  // Write the new commands to the end of the ringbuffer.
  // Add an EVENT to the end to the ringbuffer.
  if (!WriteInterruptEvent(event_id, signal)) {
    return DRETF(false, "Failed to write interrupt event %u\n", event_id);
  }
  // Add a new WAIT-LINK to the end of the ringbuffer.
  if (!AddRingbufferWaitLink()) {
    return DRETF(false, "Failed to add WAIT-LINK to ringbuffer");
  }

  DLOG("Submitting buffer at gpu addr 0x%x", gpu_addr);

  if (!LinkRingbuffer(prev_wait_link, gpu_addr, *prefetch_out)) {
    return DRETF(false, "Failed to link ringbuffer");
  }
  return true;
}

std::unique_ptr<MsdVslConnection> MsdVslDevice::Open(msd_client_id_t client_id) {
  uint32_t page_table_array_slot;
  if (!page_table_slot_allocator_->Alloc(&page_table_array_slot))
    return DRETP(nullptr, "couldn't allocate page table slot");

  auto address_space = AddressSpace::Create(this);
  if (!address_space)
    return DRETP(nullptr, "failed to create address space");

  page_table_arrays_->AssignAddressSpace(page_table_array_slot, address_space.get());

  return std::make_unique<MsdVslConnection>(this, page_table_array_slot, std::move(address_space),
                                            client_id);
}

magma_status_t MsdVslDevice::ChipIdentity(magma_vsl_gc_chip_identity* out_identity) {
  if (device_id() != 0x8000) {
    // TODO(fxb/37962): Read hardcoded values from features database instead.
    return DRET_MSG(MAGMA_STATUS_UNIMPLEMENTED, "unhandled device id 0x%x", device_id());
  }
  memset(out_identity, 0, sizeof(*out_identity));
  out_identity->chip_model = device_id();
  out_identity->chip_revision =
      registers::Revision::Get().ReadFrom(register_io_.get()).chip_revision().get();
  out_identity->chip_date =
      registers::ChipDate::Get().ReadFrom(register_io_.get()).chip_date().get();

  out_identity->stream_count = gpu_features_->stream_count();
  out_identity->pixel_pipes = gpu_features_->pixel_pipes();
  out_identity->resolve_pipes = 0x0;
  out_identity->instruction_count = gpu_features_->instruction_count();
  out_identity->num_constants = gpu_features_->num_constants();
  out_identity->varyings_count = gpu_features_->varyings_count();
  out_identity->gpu_core_count = 0x1;

  out_identity->product_id =
      registers::ProductId::Get().ReadFrom(register_io_.get()).product_id().get();
  out_identity->chip_flags = 0x4;
  out_identity->eco_id = registers::EcoId::Get().ReadFrom(register_io_.get()).eco_id().get();
  out_identity->customer_id =
      registers::CustomerId::Get().ReadFrom(register_io_.get()).customer_id().get();
  return MAGMA_STATUS_OK;
}

magma_status_t MsdVslDevice::ChipOption(magma_vsl_gc_chip_option* out_option) {
  if (device_id() != 0x8000) {
    // TODO(fxb/37962): Read hardcoded values from features database instead.
    return DRET_MSG(MAGMA_STATUS_UNIMPLEMENTED, "unhandled device id 0x%x", device_id());
  }
  memset(out_option, 0, sizeof(*out_option));
  out_option->gpu_profiler = false;
  out_option->allow_fast_clear = false;
  out_option->power_management = false;
  out_option->enable_mmu = true;
  out_option->compression = kVslGcCompressionOptionNone;
  out_option->usc_l1_cache_ratio = 0;
  out_option->secure_mode = kVslGcSecureModeNormal;
  return MAGMA_STATUS_OK;
}

//////////////////////////////////////////////////////////////////////////////////////////////////

msd_connection_t* msd_device_open(msd_device_t* device, msd_client_id_t client_id) {
  auto connection = MsdVslDevice::cast(device)->Open(client_id);
  if (!connection)
    return DRETP(nullptr, "failed to create connection");
  return new MsdVslAbiConnection(std::move(connection));
}

void msd_device_destroy(msd_device_t* device) { delete MsdVslDevice::cast(device); }

magma_status_t msd_device_query(msd_device_t* device, uint64_t id, uint64_t* value_out) {
  switch (id) {
    case MAGMA_QUERY_VENDOR_ID:
      // VK_VENDOR_ID_VIV
      *value_out = 0x10001;
      return MAGMA_STATUS_OK;

    case MAGMA_QUERY_DEVICE_ID:
      *value_out = MsdVslDevice::cast(device)->device_id();
      return MAGMA_STATUS_OK;

    case MAGMA_QUERY_IS_TOTAL_TIME_SUPPORTED:
      *value_out = 0;
      return MAGMA_STATUS_OK;
  }
  return DRET_MSG(MAGMA_STATUS_INVALID_ARGS, "unhandled id %" PRIu64, id);
}

static magma_status_t DataToBuffer(const char* name, void* data, uint64_t size,
                                   uint32_t* buffer_out) {
  std::unique_ptr<magma::PlatformBuffer> buffer = magma::PlatformBuffer::Create(size, name);
  if (!buffer) {
    return DRET_MSG(MAGMA_STATUS_INTERNAL_ERROR, "Failed to allocate buffer");
  }
  if (!buffer->Write(data, 0, size)) {
    return DRET_MSG(MAGMA_STATUS_INTERNAL_ERROR, "Failed to write result to buffer");
  }
  if (!buffer->duplicate_handle(buffer_out)) {
    return DRET_MSG(MAGMA_STATUS_INTERNAL_ERROR, "Failed to duplicate handle");
  }
  return MAGMA_STATUS_OK;
}

magma_status_t msd_device_query_returns_buffer(msd_device_t* device, uint64_t id,
                                               uint32_t* buffer_out) {
  switch (id) {
    case kMsdVslVendorQueryChipIdentity: {
      magma_vsl_gc_chip_identity result;
      magma_status_t status = MsdVslDevice::cast(device)->ChipIdentity(&result);
      if (status != MAGMA_STATUS_OK) {
        return status;
      }
      return DataToBuffer("chip_identity", &result, sizeof(result), buffer_out);
    }
    case kMsdVslVendorQueryChipOption: {
      magma_vsl_gc_chip_option result;
      magma_status_t status = MsdVslDevice::cast(device)->ChipOption(&result);
      if (status != MAGMA_STATUS_OK) {
        return status;
      }
      return DataToBuffer("chip_option", &result, sizeof(result), buffer_out);
    }
    default:
      return DRET_MSG(MAGMA_STATUS_UNIMPLEMENTED, "unhandled id %" PRIu64, id);
  }
}

void msd_device_dump_status(msd_device_t* device, uint32_t dump_type) {}
