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 <base/log.h> +#include <libdrm/ioctl_dispatch.h> + +extern "C" { +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <poll.h> +} + + +/* 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 <vfs_gpu.h> extern "C" { +#include <sys/types.h> +#include <sys/stat.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> @@ -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<drm_version*>(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<Gpu::Buffer>::Element const _elem; + Genode::Id_space<Gpu::Buffer>::Element const _elem; - Dataspace_capability const cap; - size_t const size; + Genode::Dataspace_capability const cap; + size_t const size; - Constructible<Genode::Attached_dataspace> _attached_buffer { }; + Genode::Constructible<Genode::Attached_dataspace> _attached_buffer { }; - Buffer(Gpu::Connection &gpu, - size_t size, - Id_space<Gpu::Buffer> &space) + Buffer(Gpu::Connection &gpu, + size_t size, + Genode::Id_space<Gpu::Buffer> &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<Gpu::Call> _drm; +static Genode::Constructible<Etnaviv::Call> _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 <base/env.h> +#include <libdrm/ioctl_dispatch.h> + extern "C" { #include <platform.h> } -extern void drm_init(); - void genode_drm_init() { - drm_init(); + drm_init(Libdrm::Driver::ETNAVIV); }