libdrm: update to version 2.4.120

Prerequisites for Mesa 24.0.1

* generic:
  * add patch to retrieve PCI/Platform information from Genode side of the DRM
    interface (in drmGetDevice2)
  * add generated 'fourcc' file

* iris:
  * report back-end (currently 'i915', 'xe' is unsupported)
  * add various I915_CONTEXT_PARAM* and I915_PARAM*
  * allocate 'Buffer's starting with ID 1 (0 is invalid)
  * enforce 48-bit-address limit on unmap also
  * disable I915_EXEC_FENCE_ARRAY array check, because we do not support
    sync objects right now and rendering in synchronous

* etnaviv:
  * create 'Fenceobj' only *once* for each GPU context

issue #5224
This commit is contained in:
Sebastian Sumpf 2024-04-13 21:10:14 +02:00 committed by Christian Helmuth
parent b83b53d3b2
commit dca3b12109
8 changed files with 313 additions and 84 deletions

View File

@ -20,7 +20,7 @@ SRC_C := xf86drm.c \
SRC_C += dummies.c
CC_OPT = -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1 -DHAVE_SYS_SYSCTL_H=1
CC_OPT = -D__GENODE__ -DHAVE_LIBDRM_ATOMIC_PRIMITIVES=1 -DHAVE_SYS_SYSCTL_H=1
#
# We rename 'ioctl' calls to 'genode_ioctl' calls, this way we are not required

View File

@ -1 +1 @@
b9c5f6ab814f107e5eb743892281c6ef0e80d860
cacc86de9adf92f7dc7212928555d9e7f640da76

View File

@ -1,9 +1,9 @@
LICENSE := MIT
VERSION := 2.4.105
VERSION := 2.4.120
DOWNLOADS := libdrm.archive
URL(libdrm) := https://dri.freedesktop.org/libdrm/libdrm-$(VERSION).tar.xz
SHA(libdrm) := 1d1d024b7cadc63e2b59cddaca94f78864940ab440843841113fbac6afaf2a46
SHA(libdrm) := 3bf55363f76c7250946441ab51d3a6cc0ae518055c0ff017324ab76cdefb327a
DIR(libdrm) := src/lib/libdrm
FILE_LIST := $(REP_DIR)/src/lib/libdrm/files.list
TAR_OPT(libdrm) := --strip-components=1 --files-from $(FILE_LIST)

View File

@ -1,42 +1,41 @@
libdrm-2.4.105/etnaviv/etnaviv_bo.c
libdrm-2.4.105/etnaviv/etnaviv_bo_cache.c
libdrm-2.4.105/etnaviv/etnaviv_cmd_stream.c
libdrm-2.4.105/etnaviv/etnaviv_device.c
libdrm-2.4.105/etnaviv/etnaviv_drm.h
libdrm-2.4.105/etnaviv/etnaviv_drmif.h
libdrm-2.4.105/etnaviv/etnaviv_gpu.c
libdrm-2.4.105/etnaviv/etnaviv_perfmon.c
libdrm-2.4.105/etnaviv/etnaviv_pipe.c
libdrm-2.4.105/etnaviv/etnaviv_priv.h
libdrm-2.4.105/include/drm/drm.h
libdrm-2.4.105/include/drm/drm_mode.h
libdrm-2.4.105/include/drm/i915_drm.h
libdrm-2.4.105/intel/i915_pciids.h
libdrm-2.4.105/intel/intel_aub.h
libdrm-2.4.105/intel/intel_bufmgr.c
libdrm-2.4.105/intel/intel_bufmgr.h
libdrm-2.4.105/intel/intel_bufmgr_fake.c
libdrm-2.4.105/intel/intel_bufmgr_gem.c
libdrm-2.4.105/intel/intel_bufmgr_priv.h
libdrm-2.4.105/intel/intel_chipset.c
libdrm-2.4.105/intel/intel_chipset.h
libdrm-2.4.105/intel/intel_debug.h
libdrm-2.4.105/intel/intel_decode.c
libdrm-2.4.105/intel/mm.c
libdrm-2.4.105/intel/mm.h
libdrm-2.4.105/intel/test_decode.c
libdrm-2.4.105/intel/uthash.h
libdrm-2.4.105/libdrm_lists.h
libdrm-2.4.105/libsync.h
libdrm-2.4.105/util_double_list.h
libdrm-2.4.105/util_math.h
libdrm-2.4.105/xf86atomic.h
libdrm-2.4.105/xf86drm.c
libdrm-2.4.105/xf86drm.h
libdrm-2.4.105/xf86drmHash.c
libdrm-2.4.105/xf86drmHash.h
libdrm-2.4.105/xf86drmMode.c
libdrm-2.4.105/xf86drmMode.h
libdrm-2.4.105/xf86drmRandom.c
libdrm-2.4.105/xf86drmRandom.h
libdrm-2.4.105/xf86drmSL.c
libdrm-2.4.120/etnaviv/etnaviv_bo.c
libdrm-2.4.120/etnaviv/etnaviv_bo_cache.c
libdrm-2.4.120/etnaviv/etnaviv_cmd_stream.c
libdrm-2.4.120/etnaviv/etnaviv_device.c
libdrm-2.4.120/etnaviv/etnaviv_drm.h
libdrm-2.4.120/etnaviv/etnaviv_drmif.h
libdrm-2.4.120/etnaviv/etnaviv_gpu.c
libdrm-2.4.120/etnaviv/etnaviv_perfmon.c
libdrm-2.4.120/etnaviv/etnaviv_pipe.c
libdrm-2.4.120/etnaviv/etnaviv_priv.h
libdrm-2.4.120/include/drm/drm.h
libdrm-2.4.120/include/drm/drm_fourcc.h
libdrm-2.4.120/include/drm/drm_mode.h
libdrm-2.4.120/include/drm/i915_drm.h
libdrm-2.4.120/intel/intel_aub.h
libdrm-2.4.120/intel/intel_bufmgr.c
libdrm-2.4.120/intel/intel_bufmgr.h
libdrm-2.4.120/intel/intel_bufmgr_fake.c
libdrm-2.4.120/intel/intel_bufmgr_gem.c
libdrm-2.4.120/intel/intel_bufmgr_priv.h
libdrm-2.4.120/intel/intel_chipset.h
libdrm-2.4.120/intel/intel_debug.h
libdrm-2.4.120/intel/intel_decode.c
libdrm-2.4.120/intel/mm.c
libdrm-2.4.120/intel/mm.h
libdrm-2.4.120/intel/test_decode.c
libdrm-2.4.120/intel/uthash.h
libdrm-2.4.120/libdrm_lists.h
libdrm-2.4.120/libsync.h
libdrm-2.4.120/util_double_list.h
libdrm-2.4.120/util_math.h
libdrm-2.4.120/xf86atomic.h
libdrm-2.4.120/xf86drm.c
libdrm-2.4.120/xf86drm.h
libdrm-2.4.120/xf86drmHash.c
libdrm-2.4.120/xf86drmHash.h
libdrm-2.4.120/xf86drmMode.c
libdrm-2.4.120/xf86drmMode.h
libdrm-2.4.120/xf86drmRandom.c
libdrm-2.4.120/xf86drmRandom.h
libdrm-2.4.120/xf86drmSL.c

View File

@ -0,0 +1,58 @@
/* AUTOMATICALLY GENERATED by gen_table_fourcc.py. You should modify
that script instead of adding here entries manually! */
static const struct drmFormatModifierInfo drm_format_modifier_table[] = {
{ DRM_MODIFIER_INVALID(NONE, INVALID) },
{ DRM_MODIFIER_LINEAR(NONE, LINEAR) },
{ DRM_MODIFIER_INTEL(X_TILED, X_TILED) },
{ DRM_MODIFIER_INTEL(Y_TILED, Y_TILED) },
{ DRM_MODIFIER_INTEL(Yf_TILED, Yf_TILED) },
{ DRM_MODIFIER_INTEL(Y_TILED_CCS, Y_TILED_CCS) },
{ DRM_MODIFIER_INTEL(Yf_TILED_CCS, Yf_TILED_CCS) },
{ DRM_MODIFIER_INTEL(Y_TILED_GEN12_RC_CCS, Y_TILED_GEN12_RC_CCS) },
{ DRM_MODIFIER_INTEL(Y_TILED_GEN12_MC_CCS, Y_TILED_GEN12_MC_CCS) },
{ DRM_MODIFIER_INTEL(Y_TILED_GEN12_RC_CCS_CC, Y_TILED_GEN12_RC_CCS_CC) },
{ DRM_MODIFIER_INTEL(4_TILED, 4_TILED) },
{ DRM_MODIFIER_INTEL(4_TILED_DG2_RC_CCS, 4_TILED_DG2_RC_CCS) },
{ DRM_MODIFIER_INTEL(4_TILED_DG2_MC_CCS, 4_TILED_DG2_MC_CCS) },
{ DRM_MODIFIER_INTEL(4_TILED_DG2_RC_CCS_CC, 4_TILED_DG2_RC_CCS_CC) },
{ DRM_MODIFIER_INTEL(4_TILED_MTL_RC_CCS, 4_TILED_MTL_RC_CCS) },
{ DRM_MODIFIER_INTEL(4_TILED_MTL_MC_CCS, 4_TILED_MTL_MC_CCS) },
{ DRM_MODIFIER_INTEL(4_TILED_MTL_RC_CCS_CC, 4_TILED_MTL_RC_CCS_CC) },
{ DRM_MODIFIER(SAMSUNG, 64_32_TILE, 64_32_TILE) },
{ DRM_MODIFIER(SAMSUNG, 16_16_TILE, 16_16_TILE) },
{ DRM_MODIFIER(QCOM, COMPRESSED, COMPRESSED) },
{ DRM_MODIFIER(QCOM, TILED3, TILED3) },
{ DRM_MODIFIER(QCOM, TILED2, TILED2) },
{ DRM_MODIFIER(VIVANTE, TILED, TILED) },
{ DRM_MODIFIER(VIVANTE, SUPER_TILED, SUPER_TILED) },
{ DRM_MODIFIER(VIVANTE, SPLIT_TILED, SPLIT_TILED) },
{ DRM_MODIFIER(VIVANTE, SPLIT_SUPER_TILED, SPLIT_SUPER_TILED) },
{ DRM_MODIFIER(NVIDIA, TEGRA_TILED, TEGRA_TILED) },
{ DRM_MODIFIER(NVIDIA, 16BX2_BLOCK_ONE_GOB, 16BX2_BLOCK_ONE_GOB) },
{ DRM_MODIFIER(NVIDIA, 16BX2_BLOCK_TWO_GOB, 16BX2_BLOCK_TWO_GOB) },
{ DRM_MODIFIER(NVIDIA, 16BX2_BLOCK_FOUR_GOB, 16BX2_BLOCK_FOUR_GOB) },
{ DRM_MODIFIER(NVIDIA, 16BX2_BLOCK_EIGHT_GOB, 16BX2_BLOCK_EIGHT_GOB) },
{ DRM_MODIFIER(NVIDIA, 16BX2_BLOCK_SIXTEEN_GOB, 16BX2_BLOCK_SIXTEEN_GOB) },
{ DRM_MODIFIER(NVIDIA, 16BX2_BLOCK_THIRTYTWO_GOB, 16BX2_BLOCK_THIRTYTWO_GOB) },
{ DRM_MODIFIER(BROADCOM, VC4_T_TILED, VC4_T_TILED) },
{ DRM_MODIFIER(BROADCOM, SAND32, SAND32) },
{ DRM_MODIFIER(BROADCOM, SAND64, SAND64) },
{ DRM_MODIFIER(BROADCOM, SAND128, SAND128) },
{ DRM_MODIFIER(BROADCOM, SAND256, SAND256) },
{ DRM_MODIFIER(BROADCOM, UIF, UIF) },
{ DRM_MODIFIER(ARM, 16X16_BLOCK_U_INTERLEAVED, 16X16_BLOCK_U_INTERLEAVED) },
{ DRM_MODIFIER(ALLWINNER, TILED, TILED) },
};
static const struct drmFormatModifierVendorInfo drm_format_modifier_vendor_table[] = {
{ DRM_FORMAT_MOD_VENDOR_NONE, "NONE" },
{ DRM_FORMAT_MOD_VENDOR_INTEL, "INTEL" },
{ DRM_FORMAT_MOD_VENDOR_AMD, "AMD" },
{ DRM_FORMAT_MOD_VENDOR_NVIDIA, "NVIDIA" },
{ DRM_FORMAT_MOD_VENDOR_SAMSUNG, "SAMSUNG" },
{ DRM_FORMAT_MOD_VENDOR_QCOM, "QCOM" },
{ DRM_FORMAT_MOD_VENDOR_VIVANTE, "VIVANTE" },
{ DRM_FORMAT_MOD_VENDOR_BROADCOM, "BROADCOM" },
{ DRM_FORMAT_MOD_VENDOR_ARM, "ARM" },
{ DRM_FORMAT_MOD_VENDOR_ALLWINNER, "ALLWINNER" },
{ DRM_FORMAT_MOD_VENDOR_AMLOGIC, "AMLOGIC" },
};

View File

@ -446,6 +446,7 @@ class Etnaviv::Call
public:
bool defer_destruction { false };
bool fenced { false };
static constexpr size_t _exec_buffer_size = { 256u << 10 };
@ -780,9 +781,12 @@ class Etnaviv::Call
arg.fence = pending_exec_buffer & 0xffffffffu;
/* XXX make part of context ? */
new (&_heap) Fenceobj(_fenceobj_space,
Gpu_context_space::Id { .value = gc.id() },
arg.fence);
if (gc.fenced == false) {
new (&_heap) Fenceobj(_fenceobj_space,
Gpu_context_space::Id { .value = gc.id() },
arg.fence);
gc.fenced = true;
}
result = true;
} catch (Gpu::Session::Invalid_state) {

View File

@ -31,7 +31,7 @@ extern "C" {
#include <errno.h>
#include <drm.h>
#include <i915_drm.h>
#include <xf86drm.h>
#define DRM_NUMBER(req) ((req) & 0xff)
}
@ -39,9 +39,35 @@ namespace Libc {
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
}
/*
* This is currently not in upstream libdrm (2.4.120) but in internal Mesa
* 'i195_drm.h'
*/
#ifndef I915_PARAM_PXP_STATUS
/*
* Query the status of PXP support in i915.
*
* The query can fail in the following scenarios with the listed error codes:
* -ENODEV = PXP support is not available on the GPU device or in the
* kernel due to missing component drivers or kernel configs.
*
* If the IOCTL is successful, the returned parameter will be set to one of
* the following values:
* 1 = PXP feature is supported and is ready for use.
* 2 = PXP feature is supported but should be ready soon (pending
* initialization of non-i915 system dependencies).
*
* NOTE: When param is supported (positive return values), user space should
* still refer to the GEM PXP context-creation UAPI header specs to be
* aware of possible failure due to system state machine at the time.
*/
#define I915_PARAM_PXP_STATUS 58
#endif
using Genode::addr_t;
using Genode::Attached_dataspace;
using Genode::Constructible;
@ -284,11 +310,18 @@ struct Drm::Buffer
Vram::Allocation _allocation;
Gpu::addr_t _local_addr { 0 };
/* handle id's have to start at 1 (0) is invalid */
static Drm::Buffer_id _new_id()
{
static unsigned long _id = 0;
return Drm::Buffer_id { ++_id };
}
Buffer(Genode::Env &env,
Genode::Id_space<Buffer> &space,
Vram::Allocation allocation)
:
_env { env }, _elem { *this, space }, _allocation { allocation }
_env { env }, _elem { *this, space, _new_id() }, _allocation { allocation }
{ }
~Buffer()
@ -319,6 +352,7 @@ struct Drm::Buffer
Drm::Buffer_id id() const
{
/* skip first id (0) */
return Drm::Buffer_id { _elem.id().value };
}
};
@ -460,7 +494,7 @@ struct Drm::Context
_gpu.unmap_gpu(buffer.vram.id,
buffer.vram.offset,
buffer.gpu_vaddr);
Utils::limit_to_48bit(buffer.gpu_vaddr));
buffer.gpu_vaddr_valid = false;
}
@ -882,6 +916,18 @@ class Drm::Call
if (verbose_ioctl)
Genode::warning("I915_PARAM_MMAP_GTT_VERSION ", *value);
return 0;
/* validates user pointer and size */
case I915_PARAM_HAS_USERPTR_PROBE:
*value = 0;
return 0;
/*
* Protected Xe Path (PXP) hardware/ME feature (encrypted video memory, TEE,
* ...)
*/
case I915_PARAM_PXP_STATUS:
*value = 0;
errno = ENODEV;
return -1;
default:
Genode::error("Unhandled device param:", Genode::Hex(param));
return -1;
@ -951,6 +997,18 @@ class Drm::Call
return 0;
case I915_CONTEXT_PARAM_RECOVERABLE:
return 0;
/*
* The id of the associated virtual memory address space (ppGTT) of
* this context. Can be retrieved and passed to another context
* (on the same fd) for both to use the same ppGTT and so share
* address layouts, and avoid reloading the page tables on context
* switches between themselves.
*
* This is currently not supported.
*/
case I915_CONTEXT_PARAM_VM:
return 0;
default:
Genode::error(__func__, " unknown param=", p->param);
return -1;
@ -964,6 +1022,16 @@ class Drm::Call
switch (p->param) {
case I915_CONTEXT_PARAM_SSEU:
return 0;
/* addressable VM area (PPGTT 48Bit - one page) for GEN8+ */
case I915_CONTEXT_PARAM_GTT_SIZE:
p->value = (1ull << 48) - 0x1000;
return 0;
/* global VM used for sharing BOs between contexts -> not supported so far */
case I915_CONTEXT_PARAM_VM:
return 0;
default:
Genode::error(__func__, " ctx=", p->ctx_id, " param=", p->param, " size=", p->size, " value=", Genode::Hex(p->value));
return -1;
@ -1025,28 +1093,9 @@ class Drm::Call
return -1;
}
if (p->flags & I915_EXEC_FENCE_ARRAY) {
bool unsupported = false;
for (unsigned i = 0; i < p->num_cliprects; i++) {
auto &fence = reinterpret_cast<drm_i915_gem_exec_fence *>(p->cliprects_ptr)[i];
Sync_obj::Id const id { .value = fence.handle };
_sync_objects.apply<Sync_obj>(id, [&](Sync_obj &) {
/**
* skipping signal fences should be save as long as
* no one tries to wait for ...
* - fence.flags & I915_EXEC_FENCE_SIGNAL
*/
if (fence.flags & I915_EXEC_FENCE_WAIT)
unsupported = true;
});
}
if (unsupported) {
Genode::error("fence wait not supported");
return -1;
}
if (verbose_ioctl && p->flags & I915_EXEC_FENCE_ARRAY) {
Genode::warning("unsupported: Fence array with Sync-objects with "
"FENCE_WAIT/SIGNAL");
}
auto const obj =
@ -1055,7 +1104,6 @@ class Drm::Call
return _context_space.apply<Drm::Context>(Drm::Context::id(ctx_id),
[&] (Drm::Context &context) {
return context.exec_buffer(obj, p->buffer_count, bb_id, p->batch_len); });
}
int _device_gem_busy(void *arg)
@ -1230,13 +1278,14 @@ class Drm::Call
}
if (ok) {
errno = 62 /* ETIME */;
return -1;
return 0;
} else
Genode::error("unknown sync object handle ", handles[0]);
errno = EINVAL;
return -1;
}
int _generic_syncobj_destroy(void *arg)
{
auto * const p = reinterpret_cast<drm_syncobj_destroy *>(arg);
@ -1311,11 +1360,35 @@ class Drm::Call
} catch (Genode::Id_space<Buffer>::Unknown_id) {
return -1;
}
p->fd = prime_fd;
return 0;
}
/*
* This is used to distinguish between the "i915" and the "xe" kernel
* drivers. Genode's driver is "i915" for now.
*/
int _generic_version(void *arg)
{
auto *version = reinterpret_cast<drm_version_t *>(arg);
char const *driver = "i915";
version->name_len = 5;
if (version->name)
Genode::copy_cstring(version->name, driver, 5);
/*
* dummy alloc remaining member, since they are de-allocated using 'free'
* in xf86drm.c
*/
if (!version->date) version->date = (char *)Libc::malloc(1);
if (!version->desc) version->desc = (char *)Libc::malloc(1);
return 0;
}
int _generic_ioctl(unsigned cmd, void *arg)
{
if (!arg) {
@ -1324,13 +1397,14 @@ class Drm::Call
}
switch (cmd) {
case DRM_NUMBER(DRM_IOCTL_GEM_CLOSE): return _generic_gem_close(arg);
case DRM_NUMBER(DRM_IOCTL_GEM_FLINK): return _generic_gem_flink(arg);
case DRM_NUMBER(DRM_IOCTL_SYNCOBJ_CREATE): return _generic_syncobj_create(arg);
case DRM_NUMBER(DRM_IOCTL_SYNCOBJ_WAIT): return _generic_syncobj_wait(arg);
case DRM_NUMBER(DRM_IOCTL_GEM_CLOSE): return _generic_gem_close(arg);
case DRM_NUMBER(DRM_IOCTL_GEM_FLINK): return _generic_gem_flink(arg);
case DRM_NUMBER(DRM_IOCTL_GEM_OPEN): return _generic_gem_open(arg);
case DRM_NUMBER(DRM_IOCTL_GET_CAP): return _generic_get_cap(arg);
case DRM_NUMBER(DRM_IOCTL_SYNCOBJ_CREATE): return _generic_syncobj_create(arg);
case DRM_NUMBER(DRM_IOCTL_SYNCOBJ_DESTROY): return _generic_syncobj_destroy(arg);
case DRM_NUMBER(DRM_IOCTL_GEM_OPEN): return _generic_gem_open(arg);
case DRM_NUMBER(DRM_IOCTL_GET_CAP): return _generic_get_cap(arg);
case DRM_NUMBER(DRM_IOCTL_SYNCOBJ_WAIT): return _generic_syncobj_wait(arg);
case DRM_NUMBER(DRM_IOCTL_VERSION): return _generic_version(arg);
case DRM_NUMBER(DRM_IOCTL_PRIME_FD_TO_HANDLE):
return _generic_prime_fd_to_handle(arg);
case DRM_NUMBER(DRM_IOCTL_PRIME_HANDLE_TO_FD):
@ -1351,6 +1425,9 @@ class Drm::Call
drm_syncobj_create reserve_id_0 { };
if (_generic_syncobj_create(&reserve_id_0))
Genode::warning("syncobject 0 not reserved");
/* make handle id 0 unavailable in buffer space */
_alloc_buffer(0x1000, [](Buffer &) { });
}
~Call()
@ -1425,6 +1502,18 @@ class Drm::Call
return device ? _device_ioctl(device_number(request), arg)
: _generic_ioctl(command_number(request), arg);
}
/*
* Mesa 24+ way to retrieve device information (incomplete, expand as
* needed). Before it was done via '_device_getparam'
*/
int drm_pci_device(drmDevicePtr device)
{
device->deviceinfo.pci->device_id = _gpu_info.chip_id;
device->deviceinfo.pci->revision_id = _gpu_info.revision.value;
return 0;
}
};
@ -1493,3 +1582,17 @@ extern "C" int genode_ioctl(int /* fd */, unsigned long request, void *arg)
if (verbose_ioctl) { Genode::log("returned ", ret, " from ", __builtin_return_address(0)); }
return ret;
}
extern "C" int genode_drmGetPciDevice(int fd, uint32_t flags, drmDevicePtr device)
{
if (_call.constructed() == false) { errno = EIO; return -1; }
/* TODO create constant */
if (fd != 43) {
Genode::error(__func__, " fd is not Genode Iris (43)");
return -ENODEV;
}
return _call->drm_pci_device(device);
}

View File

@ -0,0 +1,65 @@
diff --git a/src/lib/libdrm/xf86drm.c b/src/lib/libdrm/xf86drm.c
index 2e76f0e..ff7e432 100644
--- a/src/lib/libdrm/xf86drm.c
+++ b/src/lib/libdrm/xf86drm.c
@@ -4562,6 +4562,7 @@ drm_device_has_rdev(drmDevicePtr device, dev_t find_rdev)
*/
#define MAX_DRM_NODES 256
+
/**
* Get information about a device from its dev_t identifier
*
@@ -4704,6 +4705,10 @@ drm_public int drmGetNodeTypeFromDevId(dev_t devid)
return node_type;
}
+#ifdef __GENODE__
+int genode_drmGetPciDevice(int fd, uint32_t flags, drmDevicePtr device);
+#endif
+
/**
* Get information about the opened drm device
*
@@ -4724,6 +4729,41 @@ drm_public int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
if (fd == -1)
return -EINVAL;
+#ifdef __GENODE__
+ /* PCI only */
+ int node_type = DRM_NODE_PRIMARY;
+ char const * node = "genode";
+ char *addr;
+ int ret;
+ drmDevicePtr dev;
+
+
+ if (flags & DRM_DEVICE_GET_PCI_REVISION) {
+ dev = drmDeviceAlloc(node_type, node, sizeof(drmPciBusInfo),
+ sizeof(drmPciDeviceInfo), &addr);
+ if (!dev) return -ENOMEM;
+ dev->bustype = DRM_BUS_PCI;
+ dev->businfo.pci = (drmPciBusInfoPtr)addr;
+
+ addr += sizeof(drmPciBusInfo);
+ dev->deviceinfo.pci = (drmPciDeviceInfoPtr)addr;
+
+ if ((ret = genode_drmGetPciDevice(fd, flags, dev))) return ret;
+ } else {
+ dev = drmDeviceAlloc(node_type, node, sizeof(drmPlatformBusInfo),
+ sizeof(drmPlatformDeviceInfo), &addr);
+ if (!dev) return -ENOMEM;
+
+ dev->bustype = DRM_BUS_PLATFORM;
+ dev->businfo.platform = addr;
+ dev->deviceinfo.platform = NULL;
+ }
+
+ *device = dev;
+
+ return 0;
+#endif
+
if (fstat(fd, &sbuf))
return -errno;