blob: 296cb82d1ab07ce8ce7b2fdbc37aadb17c1601a1 [file] [log] [blame]
/*
* 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;
}
}