Path: blob/21.2-virgl/src/intel/tools/intel_noop_drm_shim.c
4547 views
/*1* Copyright © 2020 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER20* DEALINGS IN THE SOFTWARE.21*/2223#include <stdio.h>24#include <stdlib.h>25#include <unistd.h>26#include <sys/ioctl.h>27#include <sys/mman.h>28#include <sys/types.h>29#include <sys/socket.h>30#include <sys/time.h>31#include <sys/resource.h>32#include <sys/un.h>3334#include "common/intel_gem.h"35#include "dev/intel_device_info.h"36#include "drm-uapi/i915_drm.h"37#include "drm-shim/drm_shim.h"38#include "util/macros.h"39#include "util/vma.h"4041struct i915_device {42struct intel_device_info devinfo;43uint32_t device_id;44};4546struct i915_bo {47struct shim_bo base;48};4950static struct i915_device i915 = {};5152bool drm_shim_driver_prefers_first_render_node = true;5354static int55i915_ioctl_noop(int fd, unsigned long request, void *arg)56{57return 0;58}5960static int61i915_ioctl_gem_create(int fd, unsigned long request, void *arg)62{63struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);64struct drm_i915_gem_create *create = arg;65struct i915_bo *bo = calloc(1, sizeof(*bo));6667drm_shim_bo_init(&bo->base, create->size);6869create->handle = drm_shim_bo_get_handle(shim_fd, &bo->base);7071drm_shim_bo_put(&bo->base);7273return 0;74}7576static int77i915_ioctl_gem_mmap(int fd, unsigned long request, void *arg)78{79struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);80struct drm_i915_gem_mmap *mmap_arg = arg;81struct shim_bo *bo = drm_shim_bo_lookup(shim_fd, mmap_arg->handle);8283if (!bo)84return -1;8586if (!bo->map)87bo->map = drm_shim_mmap(shim_fd, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, -1, (uintptr_t)bo);8889mmap_arg->addr_ptr = (uint64_t) (bo->map + mmap_arg->offset);9091return 0;92}9394static int95i915_ioctl_gem_userptr(int fd, unsigned long request, void *arg)96{97struct shim_fd *shim_fd = drm_shim_fd_lookup(fd);98struct drm_i915_gem_userptr *userptr = arg;99struct i915_bo *bo = calloc(1, sizeof(*bo));100101drm_shim_bo_init(&bo->base, userptr->user_size);102103userptr->handle = drm_shim_bo_get_handle(shim_fd, &bo->base);104105drm_shim_bo_put(&bo->base);106107return 0;108}109110static int111i915_ioctl_gem_context_create(int fd, unsigned long request, void *arg)112{113struct drm_i915_gem_context_create *create = arg;114115create->ctx_id = 1; /* Just return a fake non zero ID. */116117return 0;118}119120static int121i915_ioctl_gem_context_getparam(int fd, unsigned long request, void *arg)122{123struct drm_i915_gem_context_param *param = arg;124125if (param->param == I915_CONTEXT_PARAM_GTT_SIZE) {126if (i915.devinfo.ver >= 8 && !i915.devinfo.is_cherryview)127param->value = 1ull << 48;128else129param->value = 1ull << 31;130} else {131param->value = 0;132}133134return 0;135}136137static int138i915_ioctl_get_param(int fd, unsigned long request, void *arg)139{140drm_i915_getparam_t *gp = arg;141142switch (gp->param) {143case I915_PARAM_CHIPSET_ID:144*gp->value = i915.device_id;145return 0;146case I915_PARAM_REVISION:147*gp->value = 0;148return 0;149case I915_PARAM_CS_TIMESTAMP_FREQUENCY:150*gp->value = i915.devinfo.timestamp_frequency;151return 0;152case I915_PARAM_HAS_ALIASING_PPGTT:153if (i915.devinfo.ver < 6)154*gp->value = I915_GEM_PPGTT_NONE;155else if (i915.devinfo.ver <= 7)156*gp->value = I915_GEM_PPGTT_ALIASING;157else158*gp->value = I915_GEM_PPGTT_FULL;159return 0;160161case I915_PARAM_NUM_FENCES_AVAIL:162*gp->value = 8; /* gfx2/3 value, unused in brw/iris */163return 0;164165case I915_PARAM_HAS_BLT:166*gp->value = 1; /* gfx2/3 value, unused in brw/iris */167return 0;168169case I915_PARAM_HAS_BSD:170case I915_PARAM_HAS_LLC:171case I915_PARAM_HAS_VEBOX:172*gp->value = 0; /* gfx2/3 value, unused in brw/iris */173return 0;174175case I915_PARAM_HAS_GEM:176case I915_PARAM_HAS_RELAXED_DELTA:177case I915_PARAM_HAS_RELAXED_FENCING:178case I915_PARAM_HAS_WAIT_TIMEOUT:179case I915_PARAM_HAS_EXECBUF2:180case I915_PARAM_HAS_EXEC_SOFTPIN:181case I915_PARAM_HAS_EXEC_CAPTURE:182case I915_PARAM_HAS_EXEC_FENCE:183case I915_PARAM_HAS_EXEC_FENCE_ARRAY:184case I915_PARAM_HAS_CONTEXT_ISOLATION:185case I915_PARAM_HAS_EXEC_ASYNC:186case I915_PARAM_HAS_EXEC_NO_RELOC:187case I915_PARAM_HAS_EXEC_BATCH_FIRST:188*gp->value = true;189return 0;190case I915_PARAM_HAS_EXEC_TIMELINE_FENCES:191*gp->value = false;192return 0;193case I915_PARAM_CMD_PARSER_VERSION:194/* Most recent version in drivers/gpu/drm/i915/i915_cmd_parser.c */195*gp->value = 10;196return 0;197case I915_PARAM_MMAP_VERSION:198case I915_PARAM_MMAP_GTT_VERSION:199*gp->value = 1;200return 0;201case I915_PARAM_SUBSLICE_TOTAL:202*gp->value = 0;203for (uint32_t s = 0; s < i915.devinfo.num_slices; s++)204*gp->value += i915.devinfo.num_subslices[s];205return 0;206case I915_PARAM_EU_TOTAL:207*gp->value = 0;208for (uint32_t s = 0; s < i915.devinfo.num_slices; s++)209*gp->value += i915.devinfo.num_subslices[s] * i915.devinfo.num_eu_per_subslice;210return 0;211case I915_PARAM_PERF_REVISION:212*gp->value = 3;213return 0;214default:215break;216}217218fprintf(stderr, "Unknown DRM_IOCTL_I915_GET_PARAM %d\n", gp->param);219return -1;220}221222static int223query_write_topology(struct drm_i915_query_item *item)224{225struct drm_i915_query_topology_info *info =226(void *) (uintptr_t) item->data_ptr;227int32_t length =228sizeof(*info) +229DIV_ROUND_UP(i915.devinfo.num_slices, 8) +230i915.devinfo.num_slices * DIV_ROUND_UP(i915.devinfo.num_subslices[0], 8) +231i915.devinfo.num_slices * i915.devinfo.num_subslices[0] *232DIV_ROUND_UP(i915.devinfo.num_eu_per_subslice, 8);233234if (item->length == 0) {235item->length = length;236return 0;237}238239if (item->length < length) {240fprintf(stderr, "size too small\n");241return -EINVAL;242}243244if (info->flags) {245fprintf(stderr, "invalid topology flags\n");246return -EINVAL;247}248249info->max_slices = i915.devinfo.num_slices;250info->max_subslices = i915.devinfo.num_subslices[0];251info->max_eus_per_subslice = i915.devinfo.num_eu_per_subslice;252253info->subslice_offset = DIV_ROUND_UP(i915.devinfo.num_slices, 8);254info->subslice_stride = DIV_ROUND_UP(i915.devinfo.num_subslices[0], 8);255info->eu_offset = info->subslice_offset + info->max_slices * info->subslice_stride;256257uint32_t slice_mask = (1u << i915.devinfo.num_slices) - 1;258for (uint32_t i = 0; i < info->subslice_offset; i++)259info->data[i] = (slice_mask >> (8 * i)) & 0xff;260261for (uint32_t s = 0; s < i915.devinfo.num_slices; s++) {262uint32_t subslice_mask = (1u << i915.devinfo.num_subslices[s]) - 1;263for (uint32_t i = 0; i < info->subslice_stride; i++) {264info->data[info->subslice_offset + s * info->subslice_stride + i] =265(subslice_mask >> (8 * i)) & 0xff;266}267}268269for (uint32_t s = 0; s < i915.devinfo.num_slices; s++) {270for (uint32_t ss = 0; ss < i915.devinfo.num_subslices[s]; ss++) {271uint32_t eu_mask = (1u << info->max_eus_per_subslice) - 1;272for (uint32_t i = 0; i < DIV_ROUND_UP(info->max_eus_per_subslice, 8); i++) {273info->data[info->eu_offset +274(s * info->max_subslices + ss) * DIV_ROUND_UP(info->max_eus_per_subslice, 8) + i] =275(eu_mask >> (8 * i)) & 0xff;276}277}278}279280return 0;281}282283static int284i915_ioctl_query(int fd, unsigned long request, void *arg)285{286struct drm_i915_query *query = arg;287struct drm_i915_query_item *items = (void *) (uintptr_t) query->items_ptr;288289if (query->flags) {290fprintf(stderr, "invalid query flags\n");291return -EINVAL;292}293294for (uint32_t i = 0; i < query->num_items; i++) {295struct drm_i915_query_item *item = &items[i];296297switch (item->query_id) {298case DRM_I915_QUERY_TOPOLOGY_INFO: {299int ret = query_write_topology(item);300if (ret)301item->length = ret;302break;303}304305default:306fprintf(stderr, "Unknown drm_i915_query_item id=%lli\n", item->query_id);307item->length = -EINVAL;308break;309}310}311312return 0;313}314315static int316i915_gem_get_aperture(int fd, unsigned long request, void *arg)317{318struct drm_i915_gem_get_aperture *aperture = arg;319320if (i915.devinfo.ver >= 8 &&321!i915.devinfo.is_cherryview) {322aperture->aper_size = 1ull << 48;323aperture->aper_available_size = 1ull << 48;324} else {325aperture->aper_size = 1ull << 31;326aperture->aper_size = 1ull << 31;327}328329return 0;330}331332static ioctl_fn_t driver_ioctls[] = {333[DRM_I915_GETPARAM] = i915_ioctl_get_param,334[DRM_I915_QUERY] = i915_ioctl_query,335336[DRM_I915_GET_RESET_STATS] = i915_ioctl_noop,337338[DRM_I915_GEM_CREATE] = i915_ioctl_gem_create,339[DRM_I915_GEM_MMAP] = i915_ioctl_gem_mmap,340[DRM_I915_GEM_SET_TILING] = i915_ioctl_noop,341[DRM_I915_GEM_CONTEXT_CREATE] = i915_ioctl_gem_context_create,342[DRM_I915_GEM_CONTEXT_DESTROY] = i915_ioctl_noop,343[DRM_I915_GEM_CONTEXT_GETPARAM] = i915_ioctl_gem_context_getparam,344[DRM_I915_GEM_CONTEXT_SETPARAM] = i915_ioctl_noop,345[DRM_I915_GEM_EXECBUFFER2] = i915_ioctl_noop,346[DRM_I915_GEM_EXECBUFFER2_WR] = i915_ioctl_noop,347348[DRM_I915_GEM_USERPTR] = i915_ioctl_gem_userptr,349350[DRM_I915_GEM_GET_APERTURE] = i915_gem_get_aperture,351352[DRM_I915_REG_READ] = i915_ioctl_noop,353354[DRM_I915_GEM_SET_DOMAIN] = i915_ioctl_noop,355[DRM_I915_GEM_GET_CACHING] = i915_ioctl_noop,356[DRM_I915_GEM_SET_CACHING] = i915_ioctl_noop,357[DRM_I915_GEM_GET_TILING] = i915_ioctl_noop,358[DRM_I915_GEM_MADVISE] = i915_ioctl_noop,359[DRM_I915_GEM_WAIT] = i915_ioctl_noop,360[DRM_I915_GEM_BUSY] = i915_ioctl_noop,361};362363void364drm_shim_driver_init(void)365{366const char *user_platform = getenv("INTEL_STUB_GPU_PLATFORM");367368/* Use SKL if nothing is specified. */369i915.device_id = intel_device_name_to_pci_device_id(user_platform ?: "skl");370if (!intel_get_device_info_from_pci_id(i915.device_id, &i915.devinfo))371return;372373shim_device.bus_type = DRM_BUS_PCI;374shim_device.driver_name = "i915";375shim_device.driver_ioctls = driver_ioctls;376shim_device.driver_ioctl_count = ARRAY_SIZE(driver_ioctls);377378char uevent_content[1024];379snprintf(uevent_content, sizeof(uevent_content),380"DRIVER=i915\n"381"PCI_CLASS=30000\n"382"PCI_ID=8086:%x\n"383"PCI_SUBSYS_ID=1028:075B\n"384"PCI_SLOT_NAME=0000:00:02.0\n"385"MODALIAS=pci:v00008086d00005916sv00001028sd0000075Bbc03sc00i00\n",386i915.device_id);387drm_shim_override_file(uevent_content,388"/sys/dev/char/%d:%d/device/uevent",389DRM_MAJOR, render_node_minor);390drm_shim_override_file("0x0\n",391"/sys/dev/char/%d:%d/device/revision",392DRM_MAJOR, render_node_minor);393char device_content[10];394snprintf(device_content, sizeof(device_content),395"0x%x\n", i915.device_id);396drm_shim_override_file("0x8086",397"/sys/dev/char/%d:%d/device/vendor",398DRM_MAJOR, render_node_minor);399drm_shim_override_file("0x8086",400"/sys/devices/pci0000:00/0000:00:02.0/vendor");401drm_shim_override_file(device_content,402"/sys/dev/char/%d:%d/device/device",403DRM_MAJOR, render_node_minor);404drm_shim_override_file(device_content,405"/sys/devices/pci0000:00/0000:00:02.0/device");406drm_shim_override_file("0x1234",407"/sys/dev/char/%d:%d/device/subsystem_vendor",408DRM_MAJOR, render_node_minor);409drm_shim_override_file("0x1234",410"/sys/devices/pci0000:00/0000:00:02.0/subsystem_vendor");411drm_shim_override_file("0x1234",412"/sys/dev/char/%d:%d/device/subsystem_device",413DRM_MAJOR, render_node_minor);414drm_shim_override_file("0x1234",415"/sys/devices/pci0000:00/0000:00:02.0/subsystem_device");416}417418419