From 0f4f1d70bfe96fc9e218ef5c2196bb677aaa251b Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Thu, 16 Apr 2020 00:17:39 +0300 Subject: [PATCH] intel: add stub_gpu tool Run shaderdb like this : intel_stub_gpu -p bxt ./run ./shaders/* List of platform names is available from gen_device_name_to_pci_device_id() (src/intel/dev/gen_device_info.c). v2: Add missing getparam support Raise max soft limit of file descriptors Signed-off-by: Lionel Landwerlin Reviewed-by: Eric Anholt Acked-by: Matt Turner Part-of: --- src/intel/tools/intel_noop_drm_shim.c | 371 ++++++++++++++++++++++++++ src/intel/tools/intel_stub_gpu.in | 73 +++++ src/intel/tools/meson.build | 24 ++ 3 files changed, 468 insertions(+) create mode 100644 src/intel/tools/intel_noop_drm_shim.c create mode 100755 src/intel/tools/intel_stub_gpu.in diff --git a/src/intel/tools/intel_noop_drm_shim.c b/src/intel/tools/intel_noop_drm_shim.c new file mode 100644 index 00000000000..205dc2df3da --- /dev/null +++ b/src/intel/tools/intel_noop_drm_shim.c @@ -0,0 +1,371 @@ +/* + * Copyright © 2020 Intel Corporation + * + * 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 (including the next + * paragraph) 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common/gen_gem.h" +#include "dev/gen_device_info.h" +#include "drm-uapi/i915_drm.h" +#include "drm-shim/drm_shim.h" +#include "util/macros.h" +#include "util/vma.h" + +struct i915_device { + struct gen_device_info devinfo; + uint32_t device_id; +}; + +struct i915_bo { + struct shim_bo base; +}; + +static struct i915_device i915 = {}; + +bool drm_shim_driver_prefers_first_render_node = true; + +static int +i915_ioctl_noop(int fd, unsigned long request, void *arg) +{ + return 0; +} + +static int +i915_ioctl_gem_create(int fd, unsigned long request, void *arg) +{ + struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); + struct drm_i915_gem_create *create = arg; + struct i915_bo *bo = calloc(1, sizeof(*bo)); + + drm_shim_bo_init(&bo->base, create->size); + + create->handle = drm_shim_bo_get_handle(shim_fd, &bo->base); + + drm_shim_bo_put(&bo->base); + + return 0; +} + +static int +i915_ioctl_gem_mmap(int fd, unsigned long request, void *arg) +{ + struct shim_fd *shim_fd = drm_shim_fd_lookup(fd); + struct drm_i915_gem_mmap *mmap_arg = arg; + struct shim_bo *bo = drm_shim_bo_lookup(shim_fd, mmap_arg->handle); + + if (!bo) + return -1; + + if (!bo->map) + bo->map = drm_shim_mmap(shim_fd, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, -1, (uintptr_t)bo); + + mmap_arg->addr_ptr = (uint64_t) (bo->map + mmap_arg->offset); + + return 0; +} + +static int +i915_ioctl_gem_context_create(int fd, unsigned long request, void *arg) +{ + struct drm_i915_gem_context_create *create = arg; + + create->ctx_id = 1; /* Just return a fake non zero ID. */ + + return 0; +} + +static int +i915_ioctl_gem_context_getparam(int fd, unsigned long request, void *arg) +{ + struct drm_i915_gem_context_param *param = arg; + + if (param->param == I915_CONTEXT_PARAM_GTT_SIZE) { + if (i915.devinfo.gen >= 8 && !i915.devinfo.is_cherryview) + param->value = 1ull << 48; + else + param->value = 1ull << 31; + } else { + param->value = 0; + } + + return 0; +} + +static int +i915_ioctl_get_param(int fd, unsigned long request, void *arg) +{ + drm_i915_getparam_t *gp = arg; + + switch (gp->param) { + case I915_PARAM_CHIPSET_ID: + *gp->value = i915.device_id; + return 0; + case I915_PARAM_REVISION: + *gp->value = 0; + return 0; + case I915_PARAM_CS_TIMESTAMP_FREQUENCY: + *gp->value = i915.devinfo.timestamp_frequency; + return 0; + case I915_PARAM_HAS_ALIASING_PPGTT: + *gp->value = i915.devinfo.is_haswell || i915.devinfo.gen >= 8; + return 0; + case I915_PARAM_HAS_WAIT_TIMEOUT: + case I915_PARAM_HAS_EXECBUF2: + case I915_PARAM_HAS_EXEC_SOFTPIN: + case I915_PARAM_HAS_EXEC_CAPTURE: + case I915_PARAM_HAS_EXEC_FENCE: + case I915_PARAM_HAS_EXEC_FENCE_ARRAY: + case I915_PARAM_HAS_CONTEXT_ISOLATION: + case I915_PARAM_HAS_EXEC_ASYNC: + case I915_PARAM_HAS_EXEC_NO_RELOC: + case I915_PARAM_HAS_EXEC_BATCH_FIRST: + *gp->value = true; + return 0; + case I915_PARAM_CMD_PARSER_VERSION: + /* Most recent version in drivers/gpu/drm/i915/i915_cmd_parser.c */ + *gp->value = 10; + return 0; + case I915_PARAM_MMAP_VERSION: + case I915_PARAM_MMAP_GTT_VERSION: + *gp->value = 1; + return 0; + case I915_PARAM_SUBSLICE_TOTAL: + *gp->value = 0; + for (uint32_t s = 0; s < i915.devinfo.num_slices; s++) + *gp->value += i915.devinfo.num_subslices[s]; + return 0; + case I915_PARAM_EU_TOTAL: + *gp->value = 0; + for (uint32_t s = 0; s < i915.devinfo.num_slices; s++) + *gp->value += i915.devinfo.num_subslices[s] * i915.devinfo.num_eu_per_subslice; + return 0; + case I915_PARAM_PERF_REVISION: + *gp->value = 3; + return 0; + default: + break; + } + + fprintf(stderr, "Unknown DRM_IOCTL_I915_GET_PARAM %d\n", gp->param); + return -1; +} + +static int +query_write_topology(struct drm_i915_query_item *item) +{ + struct drm_i915_query_topology_info *info = + (void *) (uintptr_t) item->data_ptr; + int32_t length = + sizeof(*info) + + DIV_ROUND_UP(i915.devinfo.num_slices, 8) + + i915.devinfo.num_slices * DIV_ROUND_UP(i915.devinfo.num_subslices[0], 8) + + i915.devinfo.num_slices * i915.devinfo.num_subslices[0] * + DIV_ROUND_UP(i915.devinfo.num_eu_per_subslice, 8); + + if (item->length == 0) { + item->length = length; + return 0; + } + + if (item->length < length) { + fprintf(stderr, "size too small\n"); + return -EINVAL; + } + + if (info->flags) { + fprintf(stderr, "invalid topology flags\n"); + return -EINVAL; + } + + info->max_slices = i915.devinfo.num_slices; + info->max_subslices = i915.devinfo.num_subslices[0]; + info->max_eus_per_subslice = i915.devinfo.num_eu_per_subslice; + + info->subslice_offset = DIV_ROUND_UP(i915.devinfo.num_slices, 8); + info->subslice_stride = DIV_ROUND_UP(i915.devinfo.num_subslices[0], 8); + info->eu_offset = info->subslice_offset + info->max_slices * info->subslice_stride; + + uint32_t slice_mask = (1u << i915.devinfo.num_slices) - 1; + for (uint32_t i = 0; i < info->subslice_offset; i++) + info->data[i] = (slice_mask >> (8 * i)) & 0xff; + + for (uint32_t s = 0; s < i915.devinfo.num_slices; s++) { + uint32_t subslice_mask = (1u << i915.devinfo.num_subslices[s]) - 1; + for (uint32_t i = 0; i < info->subslice_stride; i++) { + info->data[info->subslice_offset + s * info->subslice_stride + i] = + (subslice_mask >> (8 * i)) & 0xff; + } + } + + for (uint32_t s = 0; s < i915.devinfo.num_slices; s++) { + for (uint32_t ss = 0; ss < i915.devinfo.num_subslices[s]; ss++) { + uint32_t eu_mask = (1u << info->max_eus_per_subslice) - 1; + for (uint32_t i = 0; i < DIV_ROUND_UP(info->max_eus_per_subslice, 8); i++) { + info->data[info->eu_offset + + (s * info->max_subslices + ss) * DIV_ROUND_UP(info->max_eus_per_subslice, 8) + i] = + (eu_mask >> (8 * i)) & 0xff; + } + } + } + + return 0; +} + +static int +i915_ioctl_query(int fd, unsigned long request, void *arg) +{ + struct drm_i915_query *query = arg; + struct drm_i915_query_item *items = (void *) (uintptr_t) query->items_ptr; + + if (query->flags) { + fprintf(stderr, "invalid query flags\n"); + return -EINVAL; + } + + for (uint32_t i = 0; i < query->num_items; i++) { + struct drm_i915_query_item *item = &items[i]; + + switch (item->query_id) { + case DRM_I915_QUERY_TOPOLOGY_INFO: { + int ret = query_write_topology(item); + if (ret) + item->length = ret; + break; + } + + default: + fprintf(stderr, "Unknown drm_i915_query_item id=%lli\n", item->query_id); + item->length = -EINVAL; + break; + } + } + + return 0; +} + +static int +i915_gem_get_aperture(int fd, unsigned long request, void *arg) +{ + struct drm_i915_gem_get_aperture *aperture = arg; + + if (i915.devinfo.gen >= 8 && + !i915.devinfo.is_cherryview) { + aperture->aper_size = 1ull << 48; + aperture->aper_available_size = 1ull << 48; + } else { + aperture->aper_size = 1ull << 31; + aperture->aper_size = 1ull << 31; + } + + return 0; +} + +static ioctl_fn_t driver_ioctls[] = { + [DRM_I915_GETPARAM] = i915_ioctl_get_param, + [DRM_I915_QUERY] = i915_ioctl_query, + + [DRM_I915_GET_RESET_STATS] = i915_ioctl_noop, + + [DRM_I915_GEM_CREATE] = i915_ioctl_gem_create, + [DRM_I915_GEM_MMAP] = i915_ioctl_gem_mmap, + [DRM_I915_GEM_CONTEXT_CREATE] = i915_ioctl_gem_context_create, + [DRM_I915_GEM_CONTEXT_DESTROY] = i915_ioctl_noop, + [DRM_I915_GEM_CONTEXT_GETPARAM] = i915_ioctl_gem_context_getparam, + [DRM_I915_GEM_CONTEXT_SETPARAM] = i915_ioctl_noop, + [DRM_I915_GEM_EXECBUFFER2] = i915_ioctl_noop, + [DRM_I915_GEM_EXECBUFFER2_WR] = i915_ioctl_noop, + + [DRM_I915_GEM_GET_APERTURE] = i915_gem_get_aperture, + + [DRM_I915_REG_READ] = i915_ioctl_noop, + + [DRM_I915_GEM_SET_DOMAIN] = i915_ioctl_noop, + [DRM_I915_GEM_GET_CACHING] = i915_ioctl_noop, + [DRM_I915_GEM_SET_CACHING] = i915_ioctl_noop, + [DRM_I915_GEM_MADVISE] = i915_ioctl_noop, + [DRM_I915_GEM_WAIT] = i915_ioctl_noop, + [DRM_I915_GEM_BUSY] = i915_ioctl_noop, +}; + +void +drm_shim_driver_init(void) +{ + const char *user_platform = getenv("INTEL_STUB_GPU_PLATFORM"); + + /* Use SKL if nothing is specified. */ + i915.device_id = gen_device_name_to_pci_device_id(user_platform ?: "skl"); + if (!gen_get_device_info_from_pci_id(i915.device_id, &i915.devinfo)) + return; + + shim_device.bus_type = DRM_BUS_PCI; + shim_device.driver_name = "i915"; + shim_device.driver_ioctls = driver_ioctls; + shim_device.driver_ioctl_count = ARRAY_SIZE(driver_ioctls); + + char uevent_content[1024]; + snprintf(uevent_content, sizeof(uevent_content), + "DRIVER=i915\n" + "PCI_CLASS=30000\n" + "PCI_ID=8086:%x\n" + "PCI_SUBSYS_ID=1028:075B\n" + "PCI_SLOT_NAME=0000:00:02.0\n" + "MODALIAS=pci:v00008086d00005916sv00001028sd0000075Bbc03sc00i00\n", + i915.device_id); + drm_shim_override_file(uevent_content, + "/sys/dev/char/%d:%d/device/uevent", + DRM_MAJOR, render_node_minor); + drm_shim_override_file("0x0\n", + "/sys/dev/char/%d:%d/device/revision", + DRM_MAJOR, render_node_minor); + char device_content[10]; + snprintf(device_content, sizeof(device_content), + "0x%x\n", i915.device_id); + drm_shim_override_file("0x8086", + "/sys/dev/char/%d:%d/device/vendor", + DRM_MAJOR, render_node_minor); + drm_shim_override_file("0x8086", + "/sys/devices/pci0000:00/0000:00:02.0/vendor"); + drm_shim_override_file(device_content, + "/sys/dev/char/%d:%d/device/device", + DRM_MAJOR, render_node_minor); + drm_shim_override_file(device_content, + "/sys/devices/pci0000:00/0000:00:02.0/device"); + drm_shim_override_file("0x1234", + "/sys/dev/char/%d:%d/device/subsystem_vendor", + DRM_MAJOR, render_node_minor); + drm_shim_override_file("0x1234", + "/sys/devices/pci0000:00/0000:00:02.0/subsystem_vendor"); + drm_shim_override_file("0x1234", + "/sys/dev/char/%d:%d/device/subsystem_device", + DRM_MAJOR, render_node_minor); + drm_shim_override_file("0x1234", + "/sys/devices/pci0000:00/0000:00:02.0/subsystem_device"); +} diff --git a/src/intel/tools/intel_stub_gpu.in b/src/intel/tools/intel_stub_gpu.in new file mode 100755 index 00000000000..71a2df65c8c --- /dev/null +++ b/src/intel/tools/intel_stub_gpu.in @@ -0,0 +1,73 @@ +#!/bin/bash +# -*- mode: sh -*- + +function show_help() { + cat <