/*
* Copyright (c) 2021, The Fuchsia Authors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

#include "magma_fd.h"

#include <i915_drm.h>
#include <magma.h>
#include <magma_intel_gen_defs.h>

#include <assert.h>
#include <map>
#include <mutex>

namespace {

struct FakeFdMap {
  std::map<int32_t, uintptr_t> map;
  std::mutex mutex;
  int32_t next_fd = -1;
};

FakeFdMap* gMap; // never destroyed
std::once_flag gOnceFlag;

} // namespace

int get_magma_fd_for_device(uintptr_t device) {
  std::call_once(gOnceFlag, []() { gMap = new FakeFdMap; });

  std::lock_guard<std::mutex> lock(gMap->mutex);

  if (gMap->next_fd < 0)
    gMap->next_fd = 1;

  int fd = gMap->next_fd++;

  // Roll over fails because we never release fds
  assert(gMap->map.find(fd) == gMap->map.end());

  gMap->map[fd] = device;
  return fd;
}

uintptr_t get_device_for_magma_fd(int fd) {
  assert(gMap);
  std::lock_guard<std::mutex> lock(gMap->mutex);

  auto iter = gMap->map.find(fd);
  if (iter == gMap->map.end())
    return 0;

  uintptr_t device = iter->second;
  return device;
}

bool query_magma_fd(int fd, int32_t param, uint32_t* value_out) {
  magma_device_t device = get_device_for_magma_fd(fd);
  if (!device)
    return false;

  magma_status_t status;
  uint64_t val64;

  switch (param) {
    case I915_PARAM_HAS_BSD: // 1st video command streamer instance
    case I915_PARAM_HAS_VEBOX:
    case I915_PARAM_HAS_ALIASING_PPGTT:
      *value_out = 1;
      return true;

    case I915_PARAM_HAS_BSD2: // 2nd video command streamer instance
    case 42: //I915_PARAM_HAS_HUC
    case I915_PARAM_REVISION:
      *value_out = 0;
      return true;

    case I915_PARAM_CHIPSET_ID:
      status = magma_query2(device, MAGMA_QUERY_DEVICE_ID, &val64);
      if (status != MAGMA_STATUS_OK)
        return false;
      *value_out = static_cast<uint32_t>(val64);
      return true;

    case I915_PARAM_EU_TOTAL:
    case I915_PARAM_SUBSLICE_TOTAL:
      status = magma_query2(device, kMsdIntelGenQuerySubsliceAndEuTotal, &val64);
      if (status != MAGMA_STATUS_OK)
        return false;
      *value_out = (param == I915_PARAM_EU_TOTAL) ? static_cast<uint32_t>(val64) : val64 >> 32;
      return true;

    default:
      return false;
  }
}
