| /* |
| * 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, kMagmaIntelGenQuerySubsliceAndEuTotal, &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; |
| } |
| } |