From 93639532f06c7216143ea32db623600c8927eb0f Mon Sep 17 00:00:00 2001 From: Johannes Kliemann Date: Fri, 27 Oct 2017 14:07:09 +0200 Subject: [PATCH] base-linux: core session support (IO_PORT, IO_MEM, IRQ) --- .../recipes/src/base-linux/content.mk | 7 +- .../src/core/include/core_linux_syscalls.h | 35 +++++ .../src/core/include/dataspace_component.h | 9 +- .../core/include/io_mem_session_component.h | 15 ++- .../base-linux/src/core/include/irq_object.h | 50 ++++++++ .../src/core/include/irq_session_component.h | 17 +-- .../src/core/io_mem_session_component.cc | 25 ---- repos/base-linux/src/core/linux/target.mk | 61 +++++---- .../core/spec/linux/dataspace_component.cc | 77 +++++++++++ .../spec/linux/io_mem_session_component.cc | 58 +++++++++ .../spec/linux/io_port_session_component.cc | 27 ++++ .../core/spec/linux/irq_session_component.cc | 82 ++++++++++++ .../src/core/spec/linux/platform_services.cc | 37 ++++++ .../core/{ => spec/pc}/dataspace_component.cc | 7 + .../core/spec/pc/io_mem_session_component.cc | 78 ++++++++++++ .../core/spec/pc/io_port_session_component.cc | 29 +++++ .../src/core/spec/pc/irq_session_component.cc | 120 ++++++++++++++++++ .../src/core/spec/pc/platform_services.cc | 44 +++++++ .../src/lib/base/region_map_client.cc | 3 + .../src/lib/base/region_map_mmap.cc | 3 + repos/base-linux/src/lib/initramfs/init.c | 45 +++++++ repos/base-linux/src/lib/initramfs/target.mk | 20 +++ 22 files changed, 778 insertions(+), 71 deletions(-) create mode 100644 repos/base-linux/src/core/include/irq_object.h delete mode 100644 repos/base-linux/src/core/io_mem_session_component.cc create mode 100644 repos/base-linux/src/core/spec/linux/dataspace_component.cc create mode 100644 repos/base-linux/src/core/spec/linux/io_mem_session_component.cc create mode 100644 repos/base-linux/src/core/spec/linux/io_port_session_component.cc create mode 100644 repos/base-linux/src/core/spec/linux/irq_session_component.cc create mode 100644 repos/base-linux/src/core/spec/linux/platform_services.cc rename repos/base-linux/src/core/{ => spec/pc}/dataspace_component.cc (87%) create mode 100644 repos/base-linux/src/core/spec/pc/io_mem_session_component.cc create mode 100644 repos/base-linux/src/core/spec/pc/io_port_session_component.cc create mode 100644 repos/base-linux/src/core/spec/pc/irq_session_component.cc create mode 100644 repos/base-linux/src/core/spec/pc/platform_services.cc create mode 100644 repos/base-linux/src/lib/initramfs/init.c create mode 100644 repos/base-linux/src/lib/initramfs/target.mk diff --git a/repos/base-linux/recipes/src/base-linux/content.mk b/repos/base-linux/recipes/src/base-linux/content.mk index edb03c63e..6027b8f88 100644 --- a/repos/base-linux/recipes/src/base-linux/content.mk +++ b/repos/base-linux/recipes/src/base-linux/content.mk @@ -8,7 +8,8 @@ lib/import src/ld: content: for spec in x86_32 x86_64 arm; do \ mv lib/mk/spec/$$spec/ld-linux.mk lib/mk/spec/$$spec/ld.mk; done; - sed -i "s/core-linux/core/" src/core/linux/target.mk - sed -i "s/ld-linux/ld/" src/lib/ld/linux/target.mk - sed -i "s/linux_timer_drv/timer/" src/timer/linux/target.mk + sed -i "s/core-linux/core/" src/core/linux/target.mk + sed -i "s/BOARD.*unknown/BOARD := linux/" src/core/linux/target.mk + sed -i "s/ld-linux/ld/" src/lib/ld/linux/target.mk + sed -i "s/linux_timer_drv/timer/" src/timer/linux/target.mk diff --git a/repos/base-linux/src/core/include/core_linux_syscalls.h b/repos/base-linux/src/core/include/core_linux_syscalls.h index 0620a8b0c..7e13ed603 100644 --- a/repos/base-linux/src/core/include/core_linux_syscalls.h +++ b/repos/base-linux/src/core/include/core_linux_syscalls.h @@ -22,6 +22,8 @@ #include #undef size_t +#include + /******************************************************* ** Functions used by core's ram-session support code ** @@ -70,6 +72,39 @@ inline int lx_stat(const char *path, struct stat64 *buf) #endif } +/*********************************************************** + ** Functions used by core's io port session support code ** + ***********************************************************/ + +inline int lx_ioperm(unsigned long from, unsigned long num, int turn_on) +{ + return lx_syscall(SYS_ioperm, from, num, turn_on); +} + +inline int lx_iopl(int level) +{ + return lx_syscall(SYS_iopl, level); +} + +/************************************************** + ** Functions used by core's io mem session code ** + **************************************************/ + +/* specific ioctl call for /dev/hwio since I don't want to handle variant args */ +inline int lx_ioctl_iomem(int fd, unsigned long phys, Genode::size_t offset) +{ + struct { + unsigned long phys; + Genode::size_t length; + } range = {phys, offset}; + + return lx_syscall(SYS_ioctl, fd, _IOW('g', 1, void *), &range); +} + +inline int lx_ioctl_irq(int fd, int irq) +{ + return lx_syscall(SYS_ioctl, fd, _IOW('g', 2, int*), &irq); +} /************************************** ** Process creation and destruction ** diff --git a/repos/base-linux/src/core/include/dataspace_component.h b/repos/base-linux/src/core/include/dataspace_component.h index 7503e2252..eafb044f1 100644 --- a/repos/base-linux/src/core/include/dataspace_component.h +++ b/repos/base-linux/src/core/include/dataspace_component.h @@ -79,14 +79,7 @@ namespace Genode { * reasons and should not be used. */ Dataspace_component(size_t size, addr_t, addr_t phys_addr, - Cache_attribute, bool, Dataspace_owner *_owner) - : - _size(size), _addr(phys_addr), _fd(-1), _writable(false), - _owner(_owner) - { - warning("Should only be used for IOMEM and not within Linux."); - _fname.buf[0] = 0; - } + Cache_attribute, bool writable, Dataspace_owner *_owner); /** * This constructor is especially used for ROM dataspaces diff --git a/repos/base-linux/src/core/include/io_mem_session_component.h b/repos/base-linux/src/core/include/io_mem_session_component.h index 67846f325..ea011de8d 100644 --- a/repos/base-linux/src/core/include/io_mem_session_component.h +++ b/repos/base-linux/src/core/include/io_mem_session_component.h @@ -26,6 +26,18 @@ namespace Genode { class Io_mem_session_component : public Rpc_object { + + private: + + Range_allocator &_io_mem_alloc; + Dataspace_component _ds; + Rpc_entrypoint &_ds_ep; + Io_mem_dataspace_capability _ds_cap; + + size_t get_arg_size(const char *); + addr_t get_arg_phys(const char *); + Cache_attribute get_arg_wc(const char *); + public: /** @@ -55,8 +67,7 @@ namespace Genode { ** Io-mem session interface ** *****************************/ - Io_mem_dataspace_capability dataspace() override { - return Io_mem_dataspace_capability(); } + Io_mem_dataspace_capability dataspace() override; }; } diff --git a/repos/base-linux/src/core/include/irq_object.h b/repos/base-linux/src/core/include/irq_object.h new file mode 100644 index 000000000..e2fcb21f9 --- /dev/null +++ b/repos/base-linux/src/core/include/irq_object.h @@ -0,0 +1,50 @@ +/* + * \brief Core-specific instance of the IRQ session interface (Linux) + * \author Johannes Kliemann + * \date 2019-11-25 + */ + +/* + * Copyright (C) 2007-2019 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 _IRQ_OBJECT_H_ +#define _IRQ_OBJECT_H_ + +#include + +namespace Genode +{ + class Irq_object; +}; + +class Genode::Irq_object : public Thread_deprecated<4096> +{ + + private: + + Genode::Signal_context_capability _sig_cap; + Genode::Lock _sync_ack; + Genode::Lock _sync_bootup; + unsigned const _irq; + int _fd; + + bool _associate(); + + void entry() override; + + public: + + Irq_object(unsigned irq); + void sigh(Signal_context_capability cap); + void ack_irq(); + + void start() override; + +}; + +#endif /* ifndef _IRQ_OBJECT_H_ */ + diff --git a/repos/base-linux/src/core/include/irq_session_component.h b/repos/base-linux/src/core/include/irq_session_component.h index c2af40951..1a56cc967 100644 --- a/repos/base-linux/src/core/include/irq_session_component.h +++ b/repos/base-linux/src/core/include/irq_session_component.h @@ -16,7 +16,9 @@ #include #include +#include #include +#include namespace Genode { class Irq_session_component; @@ -28,30 +30,29 @@ class Genode::Irq_session_component : public Rpc_object, private: friend class List; + unsigned _irq_number; + Genode::Irq_object _irq_object; public: /** * Constructor */ - Irq_session_component(Range_allocator &, const char *) { } + Irq_session_component(Range_allocator &, const char *); /** * Destructor */ - ~Irq_session_component() { } + ~Irq_session_component(); /*************************** ** Irq session interface ** ***************************/ - void ack_irq() override { } - void sigh(Signal_context_capability) override { } - Info info() override { - return { .type = Genode::Irq_session::Info::Type::INVALID, - .address = 0, - .value = 0 }; } + void ack_irq() override; + void sigh(Signal_context_capability) override; + Info info() override; }; #endif /* _CORE__INCLUDE__IRQ_SESSION_COMPONENT_H_ */ diff --git a/repos/base-linux/src/core/io_mem_session_component.cc b/repos/base-linux/src/core/io_mem_session_component.cc deleted file mode 100644 index 6b7ac87ec..000000000 --- a/repos/base-linux/src/core/io_mem_session_component.cc +++ /dev/null @@ -1,25 +0,0 @@ -/* - * \brief Linux-specific IO_MEM service - * \author Christian Helmuth - * \date 2006-09-01 - */ - -/* - * Copyright (C) 2006-2017 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. - */ - -#include - -#include - -using namespace Genode; - - -Io_mem_session_component::Io_mem_session_component(Range_allocator &, - Range_allocator &, - Rpc_entrypoint &, - const char *args) { - warning("no io_mem support on Linux (args=\"", args, "\")"); } diff --git a/repos/base-linux/src/core/linux/target.mk b/repos/base-linux/src/core/linux/target.mk index dc747b170..40958b81b 100644 --- a/repos/base-linux/src/core/linux/target.mk +++ b/repos/base-linux/src/core/linux/target.mk @@ -2,6 +2,8 @@ TARGET = core-linux REQUIRES = linux LIBS = cxx base-linux-common syscall-linux startup-linux +BOARD ?= unknown + GEN_CORE_DIR = $(BASE_DIR)/src/core SRC_CC = main.cc \ @@ -23,6 +25,9 @@ SRC_CC = main.cc \ ram_dataspace_factory.cc \ core_rpc_cap_alloc.cc \ io_mem_session_component.cc \ + io_port_session_component.cc \ + io_port_session_support.cc \ + irq_session_component.cc \ signal_source_component.cc \ signal_transmitter_proxy.cc \ signal_receiver.cc \ @@ -34,7 +39,8 @@ SRC_CC = main.cc \ default_log.cc \ env_reinit.cc \ heartbeat.cc \ - thread.cc thread_myself.cc + thread.cc \ + thread_myself.cc INC_DIR += $(REP_DIR)/src/core/include \ $(GEN_CORE_DIR)/include \ @@ -48,27 +54,32 @@ LD_SCRIPT_STATIC = $(BASE_DIR)/src/ld/genode.ld \ include $(GEN_CORE_DIR)/version.inc -vpath main.cc $(GEN_CORE_DIR) -vpath pd_session_component.cc $(GEN_CORE_DIR) -vpath core_log.cc $(GEN_CORE_DIR) -vpath cpu_session_component.cc $(GEN_CORE_DIR) -vpath cpu_session_support.cc $(GEN_CORE_DIR) -vpath cpu_thread_component.cc $(GEN_CORE_DIR) -vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) -vpath pd_session_support.cc $(GEN_CORE_DIR) -vpath capability_space.cc $(GEN_CORE_DIR) -vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR) -vpath ram_dataspace_factory.cc $(GEN_CORE_DIR) -vpath platform_services.cc $(GEN_CORE_DIR) -vpath signal_source_component.cc $(GEN_CORE_DIR) -vpath signal_transmitter_proxy.cc $(GEN_CORE_DIR) -vpath signal_receiver.cc $(GEN_CORE_DIR) -vpath trace_session_component.cc $(GEN_CORE_DIR) -vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) -vpath default_log.cc $(GEN_CORE_DIR) -vpath heartbeat.cc $(GEN_CORE_DIR) -vpath thread.cc $(BASE_DIR)/src/lib/base -vpath thread_myself.cc $(BASE_DIR)/src/lib/base -vpath trace.cc $(BASE_DIR)/src/lib/base -vpath env_reinit.cc $(REP_DIR)/src/lib/base -vpath %.cc $(REP_DIR)/src/core +vpath main.cc $(GEN_CORE_DIR) +vpath pd_session_component.cc $(GEN_CORE_DIR) +vpath core_log.cc $(GEN_CORE_DIR) +vpath cpu_session_component.cc $(GEN_CORE_DIR) +vpath cpu_session_support.cc $(GEN_CORE_DIR) +vpath cpu_thread_component.cc $(GEN_CORE_DIR) +vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) +vpath pd_session_support.cc $(GEN_CORE_DIR) +vpath capability_space.cc $(GEN_CORE_DIR) +vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR) +vpath ram_dataspace_factory.cc $(GEN_CORE_DIR) +vpath signal_source_component.cc $(GEN_CORE_DIR) +vpath signal_transmitter_proxy.cc $(GEN_CORE_DIR) +vpath signal_receiver.cc $(GEN_CORE_DIR) +vpath trace_session_component.cc $(GEN_CORE_DIR) +vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) +vpath default_log.cc $(GEN_CORE_DIR) +vpath heartbeat.cc $(GEN_CORE_DIR) +vpath io_port_session_support.cc $(GEN_CORE_DIR)/spec/x86 +vpath thread.cc $(BASE_DIR)/src/lib/base +vpath thread_myself.cc $(BASE_DIR)/src/lib/base +vpath trace.cc $(BASE_DIR)/src/lib/base +vpath env_reinit.cc $(REP_DIR)/src/lib/base +vpath dataspace_component.cc $(REP_DIR)/src/core/spec/$(BOARD) +vpath io_mem_session_component.cc $(REP_DIR)/src/core/spec/$(BOARD) +vpath irq_session_component.cc $(REP_DIR)/src/core/spec/$(BOARD) +vpath io_port_session_component.cc $(REP_DIR)/src/core/spec/$(BOARD) +vpath platform_services.cc $(REP_DIR)/src/core/spec/$(BOARD) +vpath %.cc $(REP_DIR)/src/core diff --git a/repos/base-linux/src/core/spec/linux/dataspace_component.cc b/repos/base-linux/src/core/spec/linux/dataspace_component.cc new file mode 100644 index 000000000..90f4df660 --- /dev/null +++ b/repos/base-linux/src/core/spec/linux/dataspace_component.cc @@ -0,0 +1,77 @@ +/* + * \brief Linux-specific core implementation of the dataspace component + * \author Stefan Kalkowski + * \date 2015-09-25 + * + * The Linux version of ROM session component does not use the + * Rom_fs as provided as constructor argument. Instead, we map + * rom modules directly to files of the host file system. + */ + +/* + * Copyright (C) 2015-2017 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. + */ + +/* Linux includes */ +#include +#include + +/* Genode includes */ +#include +#include +#include +#include + +/* local includes */ +#include "dataspace_component.h" + +using namespace Genode; + + +Linux_dataspace::Filename Dataspace_component::_file_name(const char *args) +{ + Session_label const label = label_from_args(args); + Linux_dataspace::Filename fname; + + if (label.last_element().length() > sizeof(fname.buf)) { + Genode::error("file name too long: ", label.last_element()); + throw Service_denied(); + } + + strncpy(fname.buf, label.last_element().string(), sizeof(fname.buf)); + + /* only files inside the current working directory are allowed */ + for (const char *c = fname.buf; *c; ++c) + if (*c == '/') throw Service_denied(); + + return fname; +} + + +Genode::size_t Dataspace_component::_file_size() +{ + struct stat64 s; + if (lx_stat(_fname.buf, &s) < 0) throw Service_denied(); + + return s.st_size; +} + + +Dataspace_component::Dataspace_component(const char *args) +: _fname(_file_name(args)), + _size(_file_size()), + _addr(0), + _fd(lx_open(_fname.buf, O_RDONLY | LX_O_CLOEXEC, S_IRUSR | S_IXUSR)), + _writable(false), + _owner(0) { } + +Dataspace_component::Dataspace_component(size_t size, addr_t, addr_t phys_addr, + Cache_attribute, bool, Dataspace_owner *_owner) : + _size(size), _addr(phys_addr), _fd(-1), _writable(false), _owner(_owner) +{ + warning("Should only be used for IOMEM and not within Linux."); + _fname.buf[0] = 0; +} diff --git a/repos/base-linux/src/core/spec/linux/io_mem_session_component.cc b/repos/base-linux/src/core/spec/linux/io_mem_session_component.cc new file mode 100644 index 000000000..e2f7c7bc8 --- /dev/null +++ b/repos/base-linux/src/core/spec/linux/io_mem_session_component.cc @@ -0,0 +1,58 @@ +/* + * \brief Linux-specific IO_MEM service + * \author Johannes Kliemann + * \date 2019-11-25 + */ + +/* + * Copyright (C) 2006-2017 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. + */ + +#include +#include +#include + +#include + +#include + + +using namespace Genode; + +size_t Io_mem_session_component::get_arg_size(const char *) +{ + warning(__func__, " not implemented"); + return 0; +} + + +addr_t Io_mem_session_component::get_arg_phys(const char *) +{ + warning(__func__, " not implemented"); + return 0; +} + +Io_mem_session_component::Io_mem_session_component(Range_allocator &io_mem_alloc, + Range_allocator &, + Rpc_entrypoint &ds_ep, + const char *args) : + _io_mem_alloc(io_mem_alloc), + _ds(0, 0, 0, UNCACHED, true, 0), + _ds_ep(ds_ep), + _ds_cap(Io_mem_dataspace_capability()) +{ + warning("no io_mem support on Linux (args=\"", args, "\")"); } + +Cache_attribute Io_mem_session_component::get_arg_wc(const char *) +{ + warning(__func__, " not implemented"); + return UNCACHED; +} + +Io_mem_dataspace_capability Io_mem_session_component::dataspace() +{ + return Io_mem_dataspace_capability(); +} diff --git a/repos/base-linux/src/core/spec/linux/io_port_session_component.cc b/repos/base-linux/src/core/spec/linux/io_port_session_component.cc new file mode 100644 index 000000000..41ea036da --- /dev/null +++ b/repos/base-linux/src/core/spec/linux/io_port_session_component.cc @@ -0,0 +1,27 @@ +/* + * \brief Linux-specific IO_PORT service + * \author Johannes Kliemann + * \date 2019-11-25 + */ + +/* + * Copyright (C) 2006-2019 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. + */ + +#include +#include +#include +#include + + +Genode::Io_port_session_component::Io_port_session_component(Genode::Range_allocator &io_port_alloc, const char *) +: _io_port_alloc(io_port_alloc) +{ + Genode::warning("IO PORTS are not supported on base linux"); +} + +Genode::Io_port_session_component::~Io_port_session_component() +{} diff --git a/repos/base-linux/src/core/spec/linux/irq_session_component.cc b/repos/base-linux/src/core/spec/linux/irq_session_component.cc new file mode 100644 index 000000000..200bec0a3 --- /dev/null +++ b/repos/base-linux/src/core/spec/linux/irq_session_component.cc @@ -0,0 +1,82 @@ +/* + * \brief IRQ session implementation for base-linux + * \author Johannes Kliemann + * \date 2018-03-14 + * + */ + +/* + * Copyright (C) 2018 Genode Labs GmbH + * Copyright (C) 2018 Componolit 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. + */ + +#include +#include + +#include + +#include + +Genode::Irq_session_component::Irq_session_component(Genode::Range_allocator &, const char *) +: + _irq_number(0), + _irq_object(_irq_number) +{ } + +Genode::Irq_session_component::~Irq_session_component() +{ + warning(__func__, " not implemented"); +} + +void Genode::Irq_session_component::ack_irq() +{ } + +void Genode::Irq_session_component::sigh(Genode::Signal_context_capability) +{ } + +Genode::Irq_session::Info Genode::Irq_session_component::info() +{ + return { .type = Genode::Irq_session::Info::Type::INVALID, .address = 0, .value = 0 }; +} + +Genode::Irq_object::Irq_object(unsigned irq) : + Thread_deprecated<4096>("irq"), + _sig_cap(Signal_context_capability()), + _sync_ack(Lock::LOCKED), + _sync_bootup(Lock::LOCKED), + _irq(irq), + _fd(-1) +{ + Genode::warning(__func__, " not implemented"); +} + +bool Genode::Irq_object::_associate() +{ + Genode::warning(__func__, " not implemented"); + return false; +} + +void Genode::Irq_object::entry() +{ + Genode::warning(__func__, " not implemented"); +} + +void Genode::Irq_object::ack_irq() +{ + Genode::warning(__func__, " not implemented"); +} + +void Genode::Irq_object::start() +{ + Genode::warning(__func__, " not implemented"); +} + +void Genode::Irq_object::sigh(Signal_context_capability) +{ + Genode::warning(__func__, " not implemented"); +} + + diff --git a/repos/base-linux/src/core/spec/linux/platform_services.cc b/repos/base-linux/src/core/spec/linux/platform_services.cc new file mode 100644 index 000000000..f3524d284 --- /dev/null +++ b/repos/base-linux/src/core/spec/linux/platform_services.cc @@ -0,0 +1,37 @@ +/* + * \brief Platform specific services for Linux + * \author Johannes Kliemann + * \date 2017-11-08 + */ + +/* + * Copyright (C) 2018 Genode Labs GmbH + * Copyright (C) 2018 Componolit 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 + +/* core includes */ +#include +#include +#include +#include + +#include + +/** + * Add x86 specific ioport service + */ + +namespace Genode +{ + void platform_add_local_services(Rpc_entrypoint &, + Sliced_heap &, + Registry &, + Trace::Source_registry &) + { } +} diff --git a/repos/base-linux/src/core/dataspace_component.cc b/repos/base-linux/src/core/spec/pc/dataspace_component.cc similarity index 87% rename from repos/base-linux/src/core/dataspace_component.cc rename to repos/base-linux/src/core/spec/pc/dataspace_component.cc index e2f0e3a5a..3d3b54218 100644 --- a/repos/base-linux/src/core/dataspace_component.cc +++ b/repos/base-linux/src/core/spec/pc/dataspace_component.cc @@ -67,3 +67,10 @@ Dataspace_component::Dataspace_component(const char *args) _fd(lx_open(_fname.buf, O_RDONLY | LX_O_CLOEXEC, S_IRUSR | S_IXUSR)), _writable(false), _owner(0) { } + +Dataspace_component::Dataspace_component(size_t size, addr_t, addr_t phys_addr, + Cache_attribute, bool writable, Dataspace_owner *_owner) : + _size(size), _addr(phys_addr), _fd(-1), _writable(writable), _owner(_owner) +{ + _fname.buf[0] = 0; +} diff --git a/repos/base-linux/src/core/spec/pc/io_mem_session_component.cc b/repos/base-linux/src/core/spec/pc/io_mem_session_component.cc new file mode 100644 index 000000000..b8e438f9c --- /dev/null +++ b/repos/base-linux/src/core/spec/pc/io_mem_session_component.cc @@ -0,0 +1,78 @@ +/* + * \brief Linux-specific IO_MEM service + * \author Johannes Kliemann + * \date 2019-11-25 + */ + +/* + * Copyright (C) 2006-2019 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. + */ + +#include +#include +#include + +#include + +#include + + +using namespace Genode; + +size_t Io_mem_session_component::get_arg_size(const char *args) +{ + size_t const size = Arg_string::find_arg(args, "size").ulong_value(0); + addr_t base = Arg_string::find_arg(args, "base").ulong_value(0); + + addr_t end = align_addr(base + size, get_page_size_log2()); + base = base & ~(get_page_size() - 1); + return (size_t)(end - base); +} + + +addr_t Io_mem_session_component::get_arg_phys(const char *args) +{ + return Arg_string::find_arg(args, "base").ulong_value(0); +} + +Cache_attribute Io_mem_session_component::get_arg_wc(const char *args) +{ + Arg a = Arg_string::find_arg("wc", args); + if (a.valid() && a.bool_value(0)) { + return WRITE_COMBINED; + } else { + return UNCACHED; + } +} + + +Io_mem_session_component::Io_mem_session_component(Range_allocator &io_mem_alloc, + Range_allocator &, + Rpc_entrypoint &ds_ep, + const char *args) : + _io_mem_alloc(io_mem_alloc), + _ds(get_arg_size(args), 0, get_arg_phys(args), get_arg_wc(args), true, 0), + _ds_ep(ds_ep), + _ds_cap(Io_mem_dataspace_capability()) +{ + int _fd = -1; + + _fd = lx_open("/dev/hwio", O_RDWR | O_SYNC); + lx_ioctl_iomem(_fd, (unsigned long)get_arg_phys(args), get_arg_size(args)); + if (_fd > 0) { + _ds.fd(_fd); + } else { + error("Failed to open /dev/hwio"); + throw Genode::Service_denied(); + } + + _ds_cap = static_cap_cast(static_cap_cast(_ds_ep.manage(&_ds))); +} + +Io_mem_dataspace_capability Io_mem_session_component::dataspace() +{ + return _ds_cap; +} diff --git a/repos/base-linux/src/core/spec/pc/io_port_session_component.cc b/repos/base-linux/src/core/spec/pc/io_port_session_component.cc new file mode 100644 index 000000000..e26f45e28 --- /dev/null +++ b/repos/base-linux/src/core/spec/pc/io_port_session_component.cc @@ -0,0 +1,29 @@ +/* + * \brief Linux-specific IO_PORT service + * \author Johannes Kliemann + * \date 2019-11-25 + */ + +/* + * Copyright (C) 2006-2019 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. + */ + +#include +#include +#include +#include + + +Genode::Io_port_session_component::Io_port_session_component(Genode::Range_allocator &io_port_alloc, const char *args) +: _io_port_alloc(io_port_alloc) +{ + /* parse for port properties */ + _base = Arg_string::find_arg(args, "io_port_base").ulong_value(0); + _size = Arg_string::find_arg(args, "io_port_size").ulong_value(0); +} + +Genode::Io_port_session_component::~Io_port_session_component() +{} diff --git a/repos/base-linux/src/core/spec/pc/irq_session_component.cc b/repos/base-linux/src/core/spec/pc/irq_session_component.cc new file mode 100644 index 000000000..8d51cebb0 --- /dev/null +++ b/repos/base-linux/src/core/spec/pc/irq_session_component.cc @@ -0,0 +1,120 @@ +/* + * \brief IRQ session implementation for base-linux + * \author Johannes Kliemann + * \date 2018-03-14 + * + */ + +/* + * Copyright (C) 2018 Genode Labs GmbH + * Copyright (C) 2018 Componolit 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. + */ + +#include +#include + +#include +#include + +#include + +Genode::Irq_session_component::Irq_session_component(Genode::Range_allocator &, const char *args) +: + _irq_number(Arg_string::find_arg(args, "irq_number").long_value(-1)), + _irq_object(_irq_number) +{ + _irq_object.start(); +} + +Genode::Irq_session_component::~Irq_session_component() +{ + warning(__func__, " not implemented"); +} + +void Genode::Irq_session_component::ack_irq() +{ + _irq_object.ack_irq(); +} + +void Genode::Irq_session_component::sigh(Genode::Signal_context_capability cap) +{ + _irq_object.sigh(cap); +} + +Genode::Irq_session::Info Genode::Irq_session_component::info() +{ + return { .type = Genode::Irq_session::Info::Type::INVALID, .address = 0, .value = 0 }; +} + + +Genode::Irq_object::Irq_object(unsigned irq) : + Thread_deprecated<4096>("irq"), + _sig_cap(Signal_context_capability()), + _sync_ack(Lock::LOCKED), + _sync_bootup(Lock::LOCKED), + _irq(irq), + _fd(-1) +{ } + +bool Genode::Irq_object::_associate() +{ + _fd = lx_open("/dev/hwio", O_RDWR | O_SYNC); + + if (_fd < 0){ + Genode::error("failed to open /dev/hwio"); + return false; + } + + if (lx_ioctl_irq(_fd, _irq) < 0){ + Genode::error("failed to request irq"); + return false; + } + + return true; +} + +void Genode::Irq_object::entry() +{ + if (!_associate()) { + error("failed to register IRQ ", _irq); + } + + _sync_bootup.unlock(); + _sync_ack.lock(); + + while (true) { + + if (lx_read(_fd, 0, 0) < 0) { + Genode::warning("failed to read on /dev/hwio"); + } + + if(!_sig_cap.valid()){ + continue; + } + + Genode::Signal_transmitter(_sig_cap).submit(1); + + _sync_ack.lock(); + } +} + +void Genode::Irq_object::ack_irq() +{ + _sync_ack.unlock(); +} + +void Genode::Irq_object::start() +{ + Genode::Thread::start(); + _sync_bootup.lock(); +} + +void Genode::Irq_object::sigh(Signal_context_capability cap) +{ + _sig_cap = cap; +} + + diff --git a/repos/base-linux/src/core/spec/pc/platform_services.cc b/repos/base-linux/src/core/spec/pc/platform_services.cc new file mode 100644 index 000000000..aeb09e757 --- /dev/null +++ b/repos/base-linux/src/core/spec/pc/platform_services.cc @@ -0,0 +1,44 @@ +/* + * \brief Platform specific services for Linux + * \author Johannes Kliemann + * \date 2017-11-08 + */ + +/* + * Copyright (C) 2018 Genode Labs GmbH + * Copyright (C) 2018 Componolit 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 + +/* core includes */ +#include +#include +#include +#include + +#include + +/** + * Add x86 specific ioport service + */ +namespace Genode +{ + void platform_add_local_services(Rpc_entrypoint &, + Sliced_heap &md, + Registry ®, + Trace::Source_registry &) + { + if (!lx_iopl(3)) { + static Io_port_root io_port_root(*core_env().pd_session(), + platform().io_port_alloc(), md); + + static Core_service + io_port_ls(reg, io_port_root); + } + } +} diff --git a/repos/base-linux/src/lib/base/region_map_client.cc b/repos/base-linux/src/lib/base/region_map_client.cc index c5b55d8f0..3b50f50f9 100644 --- a/repos/base-linux/src/lib/base/region_map_client.cc +++ b/repos/base-linux/src/lib/base/region_map_client.cc @@ -19,6 +19,7 @@ using namespace Genode; +class Invalid_capability : public Genode::Exception {}; /** * Return pointer to locally implemented region map @@ -27,6 +28,8 @@ using namespace Genode; */ static Region_map *_local(Capability cap) { + if (!cap.valid()) + throw Invalid_capability(); return Local_capability::deref(cap); } diff --git a/repos/base-linux/src/lib/base/region_map_mmap.cc b/repos/base-linux/src/lib/base/region_map_mmap.cc index 675ea95d1..2401e29c6 100644 --- a/repos/base-linux/src/lib/base/region_map_mmap.cc +++ b/repos/base-linux/src/lib/base/region_map_mmap.cc @@ -188,6 +188,9 @@ Region_map::Local_addr Region_map_mmap::attach(Dataspace_capability ds, throw Region_conflict(); } + if (!ds.valid()) + throw Invalid_dataspace(); + size_t const remaining_ds_size = _dataspace_size(ds) > (addr_t)offset ? _dataspace_size(ds) - (addr_t)offset : 0; diff --git a/repos/base-linux/src/lib/initramfs/init.c b/repos/base-linux/src/lib/initramfs/init.c new file mode 100644 index 000000000..935a4ccd2 --- /dev/null +++ b/repos/base-linux/src/lib/initramfs/init.c @@ -0,0 +1,45 @@ +/* + * \brief Linux initramfs init binary to load Genode as init process + * \author Johannes Kliemann + * \date 2018-04-19 + * + */ + +/* + * Copyright (C) 2018 Genode Labs GmbH + * Copyright (C) 2018 Componolit 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) +{ + char *args = "core"; + + printf("preparing environment for Genode\n"); + if (mount("none", "/dev", "devtmpfs", 0, "")) + perror("mount"); + + close(open("/dev/platform_info", O_RDONLY)); + + printf("loading Genode on Linux\n"); + if (chdir("/genode")){ + perror("failed to chdir into /genode"); + return 1; + } + if (execve("core", &args, NULL)){ + perror("failed to start core"); + return 1; + } +} diff --git a/repos/base-linux/src/lib/initramfs/target.mk b/repos/base-linux/src/lib/initramfs/target.mk new file mode 100644 index 000000000..0ebf7c931 --- /dev/null +++ b/repos/base-linux/src/lib/initramfs/target.mk @@ -0,0 +1,20 @@ +TARGET = lx_init + +INITRAMFS = initramfs +INITRAMFS_SRC_C = init.c + +EXT_OBJECTS += $(BUILD_BASE_DIR)/lib/initramfs/$(INITRAMFS) + +$(TARGET): $(INITRAMFS) + +$(INITRAMFS): $(INITRAMFS_SRC_C) + $(MSG_BUILD)$(INITRAMFS) + $(VERBOSE)gcc $^ -O0 $(CC_MARCH) -Wall -W -Wextra -Werror -std=gnu99 -o $@ -Wl,-O3 -Wl,--as-needed -static + $(VERBOSE)ln -sf $(BUILD_BASE_DIR)/lib/initramfs/$(INITRAMFS) $(BUILD_BASE_DIR)/bin/ + +clean_initramfs: + $(VERBOSE)rm -rf $(INITRAMFS) + +clean: clean_initramfs + +vpath init.c $(PRG_DIR)