diff --git a/src/intel/common/intel_gem.h b/src/intel/common/intel_gem.h index c2d76fcae96..95921392182 100644 --- a/src/intel/common/intel_gem.h +++ b/src/intel/common/intel_gem.h @@ -38,6 +38,7 @@ extern "C" { #include #include "intel_engine.h" +#include "drm-uapi/drm.h" #include "util/macros.h" #define RCS_TIMESTAMP 0x2358 @@ -130,6 +131,15 @@ bool intel_gem_create_context_ext(int fd, enum intel_gem_create_context_flags fl bool intel_gem_supports_protected_context(int fd, enum intel_kmd_type kmd_type); +#define DRM_IOCTL_I915_LAST DRM_IO(DRM_COMMAND_END - 1) + +struct drm_intel_stub_devinfo { + uint64_t addr; + uint32_t size; +}; + +#define DRM_IOCTL_INTEL_STUB_DEVINFO DRM_IOR(DRM_IOCTL_I915_LAST, struct drm_intel_stub_devinfo) + #ifdef __cplusplus } #endif diff --git a/src/intel/dev/intel_device_info.c b/src/intel/dev/intel_device_info.c index 200899ab764..88f49be0f92 100644 --- a/src/intel/dev/intel_device_info.c +++ b/src/intel/dev/intel_device_info.c @@ -35,6 +35,7 @@ #include "i915/intel_device_info.h" #include "xe/intel_device_info.h" +#include "common/intel_gem.h" #include "util/u_debug.h" #include "util/log.h" #include "util/macros.h" @@ -1631,6 +1632,21 @@ intel_device_info_calc_engine_prefetch(const struct intel_device_info *devinfo, bool intel_get_device_info_from_fd(int fd, struct intel_device_info *devinfo, int min_ver, int max_ver) { + if (NULL != getenv("INTEL_STUB_GPU_JSON")) { + /* This call will succeed when shim-drm has been initialized with a + * serialized intel_device_info structure. + */ + struct drm_intel_stub_devinfo arg = { + .addr = (uintptr_t)devinfo, + .size = sizeof(*devinfo), + }; + if (0 == intel_ioctl(fd, DRM_IOCTL_INTEL_STUB_DEVINFO, &arg)) { + intel_device_info_init_was(devinfo); + intel_device_info_apply_workarounds(devinfo); + return true; + } + } + /* Get PCI info. * * Some callers may already have a valid drm device which holds values of @@ -1780,3 +1796,4 @@ intel_device_info_wa_stepping(struct intel_device_info *devinfo) /* all other platforms support only released steppings */ return INTEL_STEPPING_RELEASE; } + diff --git a/src/intel/tools/intel_noop_drm_shim.c b/src/intel/tools/intel_noop_drm_shim.c index a61e0cbfcef..c8bd908dfce 100644 --- a/src/intel/tools/intel_noop_drm_shim.c +++ b/src/intel/tools/intel_noop_drm_shim.c @@ -34,6 +34,7 @@ #include "common/intel_gem.h" #include "dev/intel_device_info.h" +#include "dev/intel_device_info_serialize.h" #include "drm-uapi/i915_drm.h" #include "drm-shim/drm_shim.h" #include "util/macros.h" @@ -51,6 +52,7 @@ struct i915_bo { }; static struct i915_device i915 = {}; +static bool i915_device_from_json = false; bool drm_shim_driver_prefers_first_render_node = true; @@ -489,6 +491,31 @@ i915_gem_get_aperture(int fd, unsigned long request, void *arg) return 0; } +/* Provide a binary blob of struct intel_device_info to the caller + * + * This is used in conjunction with INTEL_STUB_GPU_JSON to initialize a + * stubbed driver with device info from a file. + */ +static int +i915_ioctl_load_device_info(int fd, unsigned long request, void *arg) +{ + if(!i915_device_from_json) + return -1; + + struct drm_intel_stub_devinfo *stub_arg = (struct drm_intel_stub_devinfo*) arg; + struct intel_device_info *stub_info = (struct intel_device_info*) stub_arg->addr; + + if (stub_arg->size != sizeof(i915.devinfo)) { + assert(false); + return -1; + } + memcpy(stub_info, &i915.devinfo, sizeof(i915.devinfo)); + return 0; +} + +#define DRM_I915_LAST (DRM_COMMAND_END - DRM_COMMAND_BASE - 1) +#define DRM_I915_LOAD_STUB_DEVINFO DRM_I915_LAST + static ioctl_fn_t driver_ioctls[] = { [DRM_I915_GETPARAM] = i915_ioctl_get_param, [DRM_I915_QUERY] = i915_ioctl_query, @@ -521,25 +548,33 @@ static ioctl_fn_t driver_ioctls[] = { [DRM_I915_GEM_MADVISE] = i915_ioctl_noop, [DRM_I915_GEM_WAIT] = i915_ioctl_noop, [DRM_I915_GEM_BUSY] = i915_ioctl_noop, + [DRM_I915_LOAD_STUB_DEVINFO] = i915_ioctl_load_device_info, }; void drm_shim_driver_init(void) { i915.device_id = 0; - const char *device_id_str = getenv("INTEL_STUB_GPU_DEVICE_ID"); - if (device_id_str != NULL) { - /* Set as 0 if strtoul fails */ - i915.device_id = strtoul(device_id_str, NULL, 16); + const char *json_dev_str = getenv("INTEL_STUB_GPU_JSON"); + if (json_dev_str != NULL) { + if (!intel_device_info_from_json(json_dev_str, &i915.devinfo)) + return; + i915.device_id = i915.devinfo.pci_device_id; + i915_device_from_json = true; + } else { + const char *device_id_str = getenv("INTEL_STUB_GPU_DEVICE_ID"); + if (device_id_str != NULL) { + /* Set as 0 if strtoul fails */ + i915.device_id = strtoul(device_id_str, NULL, 16); + } + if (i915.device_id == 0) { + const char *user_platform = getenv("INTEL_STUB_GPU_PLATFORM"); + /* Use SKL if nothing is specified. */ + i915.device_id = intel_device_name_to_pci_device_id(user_platform ?: "skl"); + } + if (!intel_get_device_info_from_pci_id(i915.device_id, &i915.devinfo)) + return; } - if (i915.device_id == 0) { - const char *user_platform = getenv("INTEL_STUB_GPU_PLATFORM"); - /* Use SKL if nothing is specified. */ - i915.device_id = intel_device_name_to_pci_device_id(user_platform ?: "skl"); - } - - if (!intel_get_device_info_from_pci_id(i915.device_id, &i915.devinfo)) - return; shim_device.bus_type = DRM_BUS_PCI; shim_device.driver_name = "i915"; diff --git a/src/intel/tools/meson.build b/src/intel/tools/meson.build index 374035a0924..a4be4444a6a 100644 --- a/src/intel/tools/meson.build +++ b/src/intel/tools/meson.build @@ -156,9 +156,9 @@ if with_tools.contains('drm-shim') libintel_stub_gpu = shared_library( 'intel_noop_drm_shim', - 'intel_noop_drm_shim.c', + ['intel_noop_drm_shim.c', intel_dev_serialize_src], include_directories: [inc_include, inc_src, inc_intel], - dependencies: [dep_libdrm, dep_drm_shim, idep_mesautil, idep_libintel_common, idep_intel_dev], + dependencies: [dep_libdrm, dep_drm_shim, idep_mesautil, idep_libintel_common, idep_intel_dev, idep_parson], gnu_symbol_visibility : 'hidden', install : true, )