diff --git a/repos/libports/include/libdrm/ioctl_dispatch.h b/repos/libports/include/libdrm/ioctl_dispatch.h
new file mode 100644
index 0000000000..182961b55d
--- /dev/null
+++ b/repos/libports/include/libdrm/ioctl_dispatch.h
@@ -0,0 +1,24 @@
+/*
+ * \brief Libdrm ioctl back end dispatcher
+ * \author Josef Soentgen
+ * \date 2022-07-15
+ */
+
+/*
+ * Copyright (C) 2022 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU Affero General Public License version 3.
+ */
+
+
+#ifndef _INCLUDE__LIBDRM__IOCTL_DISPATCH_H_
+#define _INCLUDE__LIBDRM__IOCTL_DISPATCH_H_
+
+namespace Libdrm {
+ enum Driver { INVALID, ETNAVIV };
+}; /* namespace Libdrm */
+
+void drm_init(Libdrm::Driver);
+
+#endif /* #ifndef _INCLUDE__LIBDRM__IOCTL_DISPATCH_H_ */
diff --git a/repos/libports/lib/import/import-libdrm.mk b/repos/libports/lib/import/import-libdrm.mk
index 2e233fbbb4..e9761840d1 100644
--- a/repos/libports/lib/import/import-libdrm.mk
+++ b/repos/libports/lib/import/import-libdrm.mk
@@ -5,6 +5,7 @@ DRM_SRC_DIR = $(call select_from_ports,libdrm)/src/lib/libdrm
endif
INC_DIR += $(DRM_SRC_DIR)
+INC_DIR += $(DRM_SRC_DIR)/include
INC_DIR += $(addprefix $(DRM_SRC_DIR)/,include/etnaviv include/drm include)
INC_DIR += $(addprefix $(DRM_SRC_DIR)/,etnaviv)
INC_DIR += $(addprefix $(DRM_SRC_DIR)/,iris)
diff --git a/repos/libports/lib/mk/libdrm.inc b/repos/libports/lib/mk/libdrm.inc
index c2b873a469..36e9a5b868 100644
--- a/repos/libports/lib/mk/libdrm.inc
+++ b/repos/libports/lib/mk/libdrm.inc
@@ -2,9 +2,11 @@ LIB_DIR := $(REP_DIR)/src/lib/libdrm
# include before to shadow libdrm_macros.h
INC_DIR += $(LIB_DIR)/include
+INC_DIR += $(REP_DIR)/src/lib/libdrm
LIBDRM_PORT_DIR := $(call select_from_ports,libdrm)/src/lib/libdrm
+REP_INC_DIR += include/libdrm
REP_INC_DIR += include/drm
LIBS := libc
diff --git a/repos/libports/lib/mk/spec/arm_v8/libdrm.mk b/repos/libports/lib/mk/spec/arm_v8/libdrm.mk
index ebc65c86eb..38d22b67ed 100644
--- a/repos/libports/lib/mk/spec/arm_v8/libdrm.mk
+++ b/repos/libports/lib/mk/spec/arm_v8/libdrm.mk
@@ -4,4 +4,4 @@ LIBS += vfs_gpu
include $(call select_from_repositories,lib/import/import-libdrm.mk)
-SRC_CC := ioctl_etnaviv.cc
+SRC_CC := ioctl_dispatch.cc ioctl_etnaviv.cc
diff --git a/repos/libports/recipes/api/libdrm/content.mk b/repos/libports/recipes/api/libdrm/content.mk
index 9938d01386..3790641f41 100644
--- a/repos/libports/recipes/api/libdrm/content.mk
+++ b/repos/libports/recipes/api/libdrm/content.mk
@@ -19,6 +19,8 @@ include:
cp -r $(PORT_DIR)/src/lib/libdrm/intel/*.h $@/intel
mkdir -p $@/etnaviv
cp -r $(PORT_DIR)/src/lib/libdrm/etnaviv/*.h $@/etnaviv
+ mkdir -p $@/libdrm
+ cp $(REP_DIR)/include/libdrm/ioctl_dispatch.h $@/libdrm
content: LICENSE
diff --git a/repos/libports/recipes/src/libdrm/content.mk b/repos/libports/recipes/src/libdrm/content.mk
index 9810c29aef..7872ba245b 100644
--- a/repos/libports/recipes/src/libdrm/content.mk
+++ b/repos/libports/recipes/src/libdrm/content.mk
@@ -2,11 +2,13 @@ MIRROR_FROM_REP_DIR := lib/mk/libdrm.mk \
lib/mk/libdrm.inc \
lib/mk/spec/arm_v8/libdrm.mk \
lib/mk/spec/x86_64/libdrm.mk \
+ include/libdrm/ioctl_dispatch.h \
src/lib/libdrm/include \
src/lib/libdrm/dummies.c \
src/lib/libdrm/ioctl_dummy.cc \
src/lib/libdrm/ioctl_iris.cc \
src/lib/libdrm/ioctl_etnaviv.cc \
+ src/lib/libdrm/ioctl_dispatch.cc
content: $(MIRROR_FROM_REP_DIR) src/lib/libdrm/target.mk
diff --git a/repos/libports/src/lib/libdrm/ioctl_dispatch.cc b/repos/libports/src/lib/libdrm/ioctl_dispatch.cc
new file mode 100644
index 0000000000..0f8fee1b41
--- /dev/null
+++ b/repos/libports/src/lib/libdrm/ioctl_dispatch.cc
@@ -0,0 +1,98 @@
+/*
+ * \brief DRM ioctl back end dispatcher
+ * \author Josef Soentgen
+ * \date 2022-07-15
+ */
+
+/*
+ * Copyright (C) 2022 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU Affero General Public License version 3.
+ */
+
+/* Genode includes */
+#include
+#include
+
+extern "C" {
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+}
+
+
+/* etnaviv driver */
+
+extern void etnaviv_drm_init();
+extern int etnaviv_drm_ioctl(unsigned long, void *);
+extern void *etnaviv_drm_mmap(off_t, size_t);
+extern int etnaviv_drm_munmap(void *);
+
+
+static Libdrm::Driver drm_backend_type = Libdrm::Driver::INVALID;
+
+
+/**
+ * Initialize DRM back end and set type
+ */
+void drm_init(Libdrm::Driver driver)
+{
+ switch (driver) {
+ case Libdrm::Driver::ETNAVIV:
+ etnaviv_drm_init();
+ drm_backend_type = Libdrm::Driver::ETNAVIV;
+ break;
+ default:
+ Genode::error(__func__, ": unknown back end, abort");
+ abort();
+ }
+}
+
+
+/**
+ * Perfom I/O control request
+ */
+extern "C" int genode_ioctl(int /* fd */, unsigned long request, void *arg)
+{
+ switch (drm_backend_type) {
+ case Libdrm::Driver::ETNAVIV: return etnaviv_drm_ioctl(request, arg);
+ default: return -1;
+ }
+}
+
+
+/**
+ * Map DRM buffer-object
+ */
+extern "C" void *drm_mmap(void *addr, size_t length, int prot, int flags,
+ int fd, off_t offset)
+{
+ (void)addr;
+ (void)prot;
+ (void)flags;
+ (void)fd;
+
+ switch (drm_backend_type) {
+ case Libdrm::Driver::ETNAVIV: return etnaviv_drm_mmap(offset, length);
+ default: return NULL;
+ }
+}
+
+
+/**
+ * Unmap DRM buffer-object
+ */
+extern "C" int drm_munmap(void *addr, size_t length)
+{
+ (void)length;
+
+ switch (drm_backend_type) {
+ case Libdrm::Driver::ETNAVIV: return etnaviv_drm_munmap(addr);
+ default: return -1;
+ }
+}
diff --git a/repos/libports/src/lib/libdrm/ioctl_etnaviv.cc b/repos/libports/src/lib/libdrm/ioctl_etnaviv.cc
index 0a15bc2749..f8a0994926 100644
--- a/repos/libports/src/lib/libdrm/ioctl_etnaviv.cc
+++ b/repos/libports/src/lib/libdrm/ioctl_etnaviv.cc
@@ -24,6 +24,8 @@
#include
extern "C" {
+#include
+#include
#include
#include
#include
@@ -36,6 +38,7 @@ extern "C" {
enum { verbose_ioctl = false };
+namespace {
/**
* Get DRM command number
@@ -105,8 +108,10 @@ const char *command_name(unsigned long request)
}
}
+} /* anonymous namespace */
-namespace Drm {
+
+namespace Etnaviv {
size_t get_payload_size(drm_etnaviv_gem_submit const &submit);
@@ -128,7 +133,7 @@ namespace Drm {
} /* anonymous namespace */
-size_t Drm::get_payload_size(drm_etnaviv_gem_submit const &submit)
+size_t Etnaviv::get_payload_size(drm_etnaviv_gem_submit const &submit)
{
size_t size = 0;
@@ -141,7 +146,7 @@ size_t Drm::get_payload_size(drm_etnaviv_gem_submit const &submit)
}
-void Drm::serialize(drm_etnaviv_gem_submit *submit, char *content)
+void Etnaviv::serialize(drm_etnaviv_gem_submit *submit, char *content)
{
size_t offset = 0;
@@ -204,7 +209,7 @@ void Drm::serialize(drm_etnaviv_gem_submit *submit, char *content)
}
-size_t Drm::get_payload_size(drm_version const &version)
+size_t Etnaviv::get_payload_size(drm_version const &version)
{
size_t size = 0;
size += version.name_len;
@@ -214,7 +219,7 @@ size_t Drm::get_payload_size(drm_version const &version)
}
-void Drm::serialize(drm_version *version, char *content)
+void Etnaviv::serialize(drm_version *version, char *content)
{
size_t offset = 0;
char *start = 0;
@@ -236,7 +241,7 @@ void Drm::serialize(drm_version *version, char *content)
}
-void Drm::deserialize(drm_version *version, char *content)
+void Etnaviv::deserialize(drm_version *version, char *content)
{
drm_version *cversion = reinterpret_cast(content);
@@ -258,8 +263,9 @@ void Drm::deserialize(drm_version *version, char *content)
}
-namespace Gpu {
+namespace Etnaviv {
using namespace Genode;
+ using namespace Gpu;
struct Call;
} /* namespace Gpu */
@@ -269,16 +275,16 @@ struct Gpu::Buffer
{
Gpu::Connection &_gpu;
- Id_space::Element const _elem;
+ Genode::Id_space::Element const _elem;
- Dataspace_capability const cap;
- size_t const size;
+ Genode::Dataspace_capability const cap;
+ size_t const size;
- Constructible _attached_buffer { };
+ Genode::Constructible _attached_buffer { };
- Buffer(Gpu::Connection &gpu,
- size_t size,
- Id_space &space)
+ Buffer(Gpu::Connection &gpu,
+ size_t size,
+ Genode::Id_space &space)
:
_gpu { gpu },
_elem { *this, space },
@@ -312,7 +318,7 @@ struct Gpu::Buffer
};
-class Gpu::Call
+class Etnaviv::Call
{
private:
@@ -477,7 +483,7 @@ class Gpu::Call
int _drm_etnaviv_gem_submit(drm_etnaviv_gem_submit &arg)
{
- size_t const payload_size = Drm::get_payload_size(arg);
+ size_t const payload_size = Etnaviv::get_payload_size(arg);
if (payload_size > EXEC_BUFFER_SIZE) {
Genode::error(__func__, ": exec buffer too small (",
(unsigned)EXEC_BUFFER_SIZE, ") needed ", payload_size);
@@ -490,7 +496,7 @@ class Gpu::Call
*/
char *local_exec_buffer = (char*)_exec_buffer->mmap_addr();
Genode::memset(local_exec_buffer, 0, EXEC_BUFFER_SIZE);
- Drm::serialize(&arg, local_exec_buffer);
+ Etnaviv::serialize(&arg, local_exec_buffer);
try {
Genode::uint64_t const pending_exec_buffer =
@@ -673,10 +679,10 @@ class Gpu::Call
};
-static Genode::Constructible _drm;
+static Genode::Constructible _drm;
-void drm_init()
+void etnaviv_drm_init()
{
struct ::stat buf;
if (stat("/dev/gpu", &buf) < 0) {
@@ -689,9 +695,6 @@ void drm_init()
}
-/**
- * Dump I/O control request to LOG
- */
static void dump_ioctl(unsigned long request)
{
using namespace Genode;
@@ -705,10 +708,7 @@ static void dump_ioctl(unsigned long request)
}
-/**
- * Perfom I/O control request
- */
-extern "C" int genode_ioctl(int /* fd */, unsigned long request, void *arg)
+int etnaviv_drm_ioctl(unsigned long request, void *arg)
{
if (verbose_ioctl)
dump_ioctl(request);
@@ -726,28 +726,14 @@ extern "C" int genode_ioctl(int /* fd */, unsigned long request, void *arg)
}
-/**
- * Map DRM buffer-object
- */
-void *drm_mmap(void *addr, size_t length, int prot, int flags,
- int fd, off_t offset)
+void *etnaviv_drm_mmap(off_t offset, size_t length)
{
- (void)addr;
- (void)prot;
- (void)flags;
- (void)fd;
-
return _drm->mmap(offset, length);
}
-/**
- * Unmap DRM buffer-object
- */
-int drm_munmap(void *addr, size_t length)
+int etnaviv_drm_munmap(void *addr)
{
- (void)length;
-
_drm->munmap(addr);
return 0;
}
diff --git a/repos/libports/src/lib/mesa/etnaviv/drm_init.cc b/repos/libports/src/lib/mesa/etnaviv/drm_init.cc
index 027c8459a5..90a8306551 100644
--- a/repos/libports/src/lib/mesa/etnaviv/drm_init.cc
+++ b/repos/libports/src/lib/mesa/etnaviv/drm_init.cc
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2021 Genode Labs GmbH
+ * Copyright (C) 2021-2022 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
@@ -15,13 +15,13 @@
#include <../include/util/list.h>
#include
+#include
+
extern "C" {
#include
}
-extern void drm_init();
-
void genode_drm_init()
{
- drm_init();
+ drm_init(Libdrm::Driver::ETNAVIV);
}