diff --git a/repos/dde_zircon/README b/repos/dde_zircon/README new file mode 100644 index 000000000..4f02c291c --- /dev/null +++ b/repos/dde_zircon/README @@ -0,0 +1,14 @@ + +Device drivers ported from the Zircon kernel + +zircon.lib.so +############# + +The zircon.lib.so provides the interfacing between Genode and Zircon APIs. +It is meant to be extended if required and is required by any Zircon driver. + +PS2 +### + +The zx_pc_ps2_drv can be used as a drop in replacement of the +ps2_drv. Its RAM resources needs to be increased to at least 2M. diff --git a/repos/dde_zircon/lib/import/import-zircon.mk b/repos/dde_zircon/lib/import/import-zircon.mk new file mode 100644 index 000000000..23b13377b --- /dev/null +++ b/repos/dde_zircon/lib/import/import-zircon.mk @@ -0,0 +1,19 @@ + +LIB_DIR = $(REP_DIR)/src/lib/zircon +ZIRCON_SYSTEM = $(call select_from_ports,dde_zircon)/zircon/src/system +ZIRCON_KERNEL = $(call select_from_ports,dde_zircon)/zircon/src/kernel +ZIRCON_THIRD_PARTY = $(call select_from_ports,dde_zircon)/zircon/src/third_party + +INC_DIR += $(LIB_DIR)/pre_include \ + $(ZIRCON_SYSTEM)/ulib/ddk/include \ + $(ZIRCON_SYSTEM)/ulib/hid/include \ + $(ZIRCON_SYSTEM)/public \ + $(ZIRCON_KERNEL)/lib/libc/include \ + $(ZIRCON_KERNEL)/lib/io/include \ + $(ZIRCON_KERNEL)/lib/heap/include \ + $(ZIRCON_KERNEL)/arch/x86/include \ + $(ZIRCON_THIRD_PARTY)/ulib/musl/include \ + $(LIB_DIR)/include + +CC_C_OPT += -D_ALL_SOURCE -Wno-multichar +CC_CXX_OPT += -Wno-multichar diff --git a/repos/dde_zircon/lib/mk/zircon.mk b/repos/dde_zircon/lib/mk/zircon.mk new file mode 100644 index 000000000..604763ae8 --- /dev/null +++ b/repos/dde_zircon/lib/mk/zircon.mk @@ -0,0 +1,21 @@ + +include $(REP_DIR)/lib/import/import-zircon.mk + +SHARED_LIB = yes + +LIBS += base + +SRC_C = stdio.c\ + printf.c + +SRC_CC = libc.cc \ + mutex.cc \ + threads.cc \ + device.cc \ + syscalls.cc \ + io_port.cc \ + irq.cc \ + debug.cc + +vpath %.cc $(LIB_DIR) +vpath %.c $(ZIRCON_KERNEL)/lib/libc diff --git a/repos/dde_zircon/ports/dde_zircon.hash b/repos/dde_zircon/ports/dde_zircon.hash new file mode 100644 index 000000000..f7fe8c510 --- /dev/null +++ b/repos/dde_zircon/ports/dde_zircon.hash @@ -0,0 +1 @@ +cb1a09b52cc0c47fb67647b48ffb1678b32ec325 diff --git a/repos/dde_zircon/ports/dde_zircon.port b/repos/dde_zircon/ports/dde_zircon.port new file mode 100644 index 000000000..6288e6a1f --- /dev/null +++ b/repos/dde_zircon/ports/dde_zircon.port @@ -0,0 +1,7 @@ +LICENSE := MIT +VERSION := git +DOWNLOADS := zircon.git + +URL(zircon) := https://github.com/fuchsia-mirror/zircon.git +REV(zircon) := eaed741a38d648f6f2236d3dd171059d4b0c4c7a +DIR(zircon) := zircon/src diff --git a/repos/dde_zircon/run/zx_pc_ps2.run b/repos/dde_zircon/run/zx_pc_ps2.run new file mode 100644 index 000000000..9bcc95b2b --- /dev/null +++ b/repos/dde_zircon/run/zx_pc_ps2.run @@ -0,0 +1,147 @@ +# +# Build +# + +assert_spec x86 + +set build_components { + core init + drivers/timer + server/dynamic_rom + test/input + drivers/input/zx_pc_ps2 +} + +source ${genode_dir}/repos/base/run/platform_drv.inc +append_platform_drv_build_components + +build $build_components + +create_boot_directory + +# +# Generate config +# + +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + } + +append_platform_drv_config + +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + +append config { +} + +install_config $config + +# +# Boot modules +# + +# generic modules +set boot_modules { + core ld.lib.so init + timer dynamic_rom + test-input + zircon.lib.so + zx_pc_ps2_drv +} + +# platform-specific modules +append_platform_drv_boot_modules + +build_boot_image $boot_modules + + +run_genode_until forever diff --git a/repos/dde_zircon/src/drivers/input/zx_pc_ps2/include/keymap.h b/repos/dde_zircon/src/drivers/input/zx_pc_ps2/include/keymap.h new file mode 100644 index 000000000..fd19c4528 --- /dev/null +++ b/repos/dde_zircon/src/drivers/input/zx_pc_ps2/include/keymap.h @@ -0,0 +1,262 @@ +/* + * \brief Mapping of USB to Genode keycodes + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 _KEYMAP_H_ +#define _KEYMAP_H_ + +#include + +#include + +static Input::Keycode zxg_keymap[] = + { + Input::KEY_RESERVED, + Input::KEY_RESERVED, + Input::KEY_RESERVED, + Input::KEY_RESERVED, + Input::KEY_A, + Input::KEY_B, + Input::KEY_C, + Input::KEY_D, + Input::KEY_E, + Input::KEY_F, + Input::KEY_G, + Input::KEY_H, + Input::KEY_I, + Input::KEY_J, + Input::KEY_K, + Input::KEY_L, + Input::KEY_M, + Input::KEY_N, + Input::KEY_O, + Input::KEY_P, + Input::KEY_Q, + Input::KEY_R, + Input::KEY_S, + Input::KEY_T, + Input::KEY_U, + Input::KEY_V, + Input::KEY_W, + Input::KEY_X, + Input::KEY_Y, + Input::KEY_Z, + Input::KEY_1, + Input::KEY_2, + Input::KEY_3, + Input::KEY_4, + Input::KEY_5, + Input::KEY_6, + Input::KEY_7, + Input::KEY_8, + Input::KEY_9, + Input::KEY_0, + Input::KEY_ENTER, + Input::KEY_ESC, + Input::KEY_BACKSPACE, + Input::KEY_TAB, + Input::KEY_SPACE, + Input::KEY_MINUS, + Input::KEY_EQUAL, + Input::KEY_LEFTBRACE, + Input::KEY_RIGHTBRACE, + Input::KEY_BACKSLASH, + Input::KEY_UNKNOWN, + Input::KEY_SEMICOLON, + Input::KEY_APOSTROPHE, + Input::KEY_GRAVE, + Input::KEY_COMMA, + Input::KEY_DOT, + Input::KEY_SLASH, + Input::KEY_CAPSLOCK, + Input::KEY_F1, + Input::KEY_F2, + Input::KEY_F3, + Input::KEY_F4, + Input::KEY_F5, + Input::KEY_F6, + Input::KEY_F7, + Input::KEY_F8, + Input::KEY_F9, + Input::KEY_F10, + Input::KEY_F11, + Input::KEY_F12, + Input::KEY_PRINT, + Input::KEY_SCROLLLOCK, + Input::KEY_PAUSE, + Input::KEY_INSERT, + Input::KEY_HOME, + Input::KEY_PAGEUP, + Input::KEY_DELETE, + Input::KEY_END, + Input::KEY_PAGEDOWN, + Input::KEY_RIGHT, + Input::KEY_LEFT, + Input::KEY_DOWN, + Input::KEY_UP, + Input::KEY_NUMLOCK, + Input::KEY_KPSLASH, + Input::KEY_KPASTERISK, + Input::KEY_KPMINUS, + Input::KEY_KPPLUS, + Input::KEY_KPENTER, + Input::KEY_KP1, + Input::KEY_KP2, + Input::KEY_KP3, + Input::KEY_KP4, + Input::KEY_KP5, + Input::KEY_KP6, + Input::KEY_KP7, + Input::KEY_KP8, + Input::KEY_KP9, + Input::KEY_KP0, + Input::KEY_KPDOT, + Input::KEY_UNKNOWN, + /* see system/ulib/hid/include/hid/usages.h:115 */ + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + Input::KEY_UNKNOWN, + /* */ + Input::KEY_LEFTCTRL, + Input::KEY_LEFTSHIFT, + Input::KEY_LEFTALT, + Input::KEY_UNKNOWN, + Input::KEY_RIGHTCTRL, + Input::KEY_RIGHTSHIFT, + Input::KEY_RIGHTALT, + Input::KEY_UNKNOWN, + Input::KEY_VOLUMEDOWN, + Input::KEY_VOLUMEUP + }; + +#endif /* ifndef _KEYMAP_H_ */ diff --git a/repos/dde_zircon/src/drivers/input/zx_pc_ps2/main.cc b/repos/dde_zircon/src/drivers/input/zx_pc_ps2/main.cc new file mode 100644 index 000000000..b8a69e156 --- /dev/null +++ b/repos/dde_zircon/src/drivers/input/zx_pc_ps2/main.cc @@ -0,0 +1,221 @@ +/* + * \brief Zircon pc-ps2 driver + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +struct Main +{ + static Genode::uint8_t mouse_btn; + static Genode::uint8_t kbd_button[8]; + + void mouse_button_event(int old_st, int new_st, int key) + { + int old_state = old_st & key; + int new_state = new_st & key; + int key_code; + + if (old_state == new_state){ + return; + } + + switch (key){ + case 1: key_code = Input::BTN_LEFT; + break; + case 2: key_code = Input::BTN_RIGHT; + break; + case 4: key_code = Input::BTN_MIDDLE; + break; + default: Genode::log("unsupported mouse button: ", key); + } + + if (new_state){ + _ev_queue.add(Input::Press{Input::Keycode(key_code)}); + }else{ + _ev_queue.add(Input::Release{Input::Keycode(key_code)}); + } + } + + bool contains(Genode::uint8_t const *buf, Genode::uint8_t const val) + { + for (int i = 2; i < 8; i++){ + if (buf[i] == val){ + return true; + } + } + return false; + } + + void handle_modifier(Genode::uint8_t current, int key) + { + int c_mod = current & key; + int o_mod = kbd_button[0] & key; + int key_code; + + if (c_mod == o_mod){ + return; + } + + switch (key){ + case 1: + key_code = Input::KEY_LEFTCTRL; + break; + case 2: + key_code = Input::KEY_LEFTSHIFT; + break; + case 4: + key_code = Input::KEY_LEFTALT; + break; + case 8: + key_code = Input::KEY_LEFTMETA; + break; + case 16: + key_code = Input::KEY_RIGHTCTRL; + break; + case 64: + key_code = Input::KEY_RIGHTALT; + break; + default: + Genode::log("unsupported modifier: ", key, " ", current); + return; + } + + if (c_mod){ + _ev_queue.add(Input::Press{Input::Keycode(key_code)}); + }else{ + _ev_queue.add(Input::Release{Input::Keycode(key_code)}); + } + + } + + void handle_keyboard(Genode::uint8_t const *current) + { + const Genode::uint8_t rollover[6] = {1, 1, 1, 1, 1, 1}; + if (!Genode::memcmp(¤t[2], rollover, 6)){ + return; + } + + for (int i = 2; i < 8; i++){ + if (current[i] != 0){ + if (!contains(kbd_button, current[i])){ + _ev_queue.add(Input::Press{Input::Keycode(zxg_keymap[current[i]])}); + } + } + if (kbd_button[i] != 0){ + if (!contains(current, kbd_button[i])){ + _ev_queue.add(Input::Release{Input::Keycode(zxg_keymap[kbd_button[i]])}); + } + } + } + + handle_modifier(current[0], 1); + handle_modifier(current[0], 2); + handle_modifier(current[0], 4); + handle_modifier(current[0], 8); + handle_modifier(current[0], 16); + handle_modifier(current[0], 64); + + Genode::memcpy(kbd_button, current, sizeof(kbd_button)); + } + + void handle_mouse(boot_mouse_report_t const *report) + { + if (report->rel_x || report->rel_y){ + _ev_queue.add(Input::Relative_motion{report->rel_x, report->rel_y}); + } + mouse_button_event(mouse_btn, report->buttons, 1); + mouse_button_event(mouse_btn, report->buttons, 2); + mouse_button_event(mouse_btn, report->buttons, 4); + mouse_btn = report->buttons; + } + + static void io_queue(void *cookie, const uint8_t *data, size_t size) + { + switch (size){ + case sizeof(boot_kbd_report_t): + static_cast
(cookie)->handle_keyboard(data); + break; + case sizeof(boot_mouse_report_t): + static_cast
(cookie)->handle_mouse(reinterpret_cast(data)); + break; + default: + Genode::warning("invalid data received"); + break; + } + } + + Genode::Env &_env; + Genode::Heap _heap; + Timer::Connection _timer; + Platform::Connection _platform; + Platform::Device_client _ps2_dev; + + ZX::Platform::Io_port _io_config[2] = { {0x60, 0x0}, {0x64, 0x1} }; + ZX::Platform::Irq _irq_config[2] = { {0x1, 0x0}, {0xc, 0x1} }; + hidbus_ifc_t _hidbus = { Main::io_queue }; + ZX::Device _zx_dev; + + Input::Session_component _session; + Input::Root_component _root; + Input::Event_queue &_ev_queue; + + Main(Genode::Env &env) : + _env(env), + _heap(env.ram(), env.rm()), + _timer(env), + _platform(env), + _ps2_dev(_platform.with_upgrade([&] () { + return _platform.device("PS2"); })), + _zx_dev(this, true), + _session(_env, _env.ram()), + _root(_env.ep().rpc_ep(), _session), + _ev_queue(_session.event_queue()) + { + Genode::log("zircon pc-ps2 driver"); + _zx_dev.set_io_port(_io_config, 2); + _zx_dev.set_irq(_irq_config, 2); + _zx_dev.set_hidbus(&_hidbus); + ZX::Resource::set_component(_env); + ZX::Resource::set_component(_heap); + ZX::Resource::set_component(_timer); + ZX::Resource::set_component(_ps2_dev); + ZX::Resource::set_component(_zx_dev); + bind_driver(nullptr, nullptr); + _env.parent().announce(_env.ep().manage(_root)); + } +}; + +Genode::uint8_t Main::mouse_btn = 0; +Genode::uint8_t Main::kbd_button[8] = {}; + +void Component::construct(Genode::Env &env) +{ + env.exec_static_constructors(); + static Main main(env); +} diff --git a/repos/dde_zircon/src/drivers/input/zx_pc_ps2/target.mk b/repos/dde_zircon/src/drivers/input/zx_pc_ps2/target.mk new file mode 100644 index 000000000..347405056 --- /dev/null +++ b/repos/dde_zircon/src/drivers/input/zx_pc_ps2/target.mk @@ -0,0 +1,15 @@ +REQUIRES = x86 + +TARGET = zx_pc_ps2_drv +LIBS = base zircon + +SRC_CC += main.cc + +SRC_C += i8042.c + +ZIRCON_SYSTEM = $(call select_from_ports,dde_zircon)/zircon/src/system + +INC_DIR += $(PRG_DIR)/include + +vpath %.cc $(PRG_DIR) +vpath i8042.c $(ZIRCON_SYSTEM)/dev/input/pc-ps2 diff --git a/repos/dde_zircon/src/lib/zircon/debug.cc b/repos/dde_zircon/src/lib/zircon/debug.cc new file mode 100644 index 000000000..d94c5e9eb --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/debug.cc @@ -0,0 +1,36 @@ +/* + * \brief Zircon debug functions + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 + +extern "C" { + + void platform_dputc(char c) + { + Genode::warning(__func__, " called with ", c); + } + + void platform_dputs_thread(const char *str, size_t len) + { + Genode::warning(__func__, " called with (", len, ") ", Genode::Cstring(str)); + } + + int platform_dgetc(char *, bool) + { + return ZX_ERR_NOT_SUPPORTED; + } + +} diff --git a/repos/dde_zircon/src/lib/zircon/device.cc b/repos/dde_zircon/src/lib/zircon/device.cc new file mode 100644 index 000000000..ddc0cd938 --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/device.cc @@ -0,0 +1,82 @@ +/* + * \brief Zircon platform configuration + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 + +ZX::Device::Device(void *component, bool use_platform) : + _use_platform(use_platform), + _io_port(nullptr), + _io_port_count(0), + _irq(nullptr), + _irq_count(0), + _interfaces({false}), + _hidbus(0), + _component(component) +{ } + +bool ZX::Device::platform() +{ + return _use_platform; +} + +void *ZX::Device::component() +{ + return _component; +} + +void ZX::Device::set_io_port(ZX::Platform::Io_port *io_port, int count) +{ + _io_port = io_port; + _io_port_count = count; +} + +void ZX::Device::set_irq(ZX::Platform::Irq *irq, int count) +{ + _irq = irq; + _irq_count = count; +} + +void ZX::Device::set_hidbus(hidbus_ifc_t *bus) +{ + _hidbus = bus; + _interfaces.hidbus = bus != nullptr; +} + +bool ZX::Device::hidbus(hidbus_ifc_t **bus) +{ + *bus = _hidbus; + return _interfaces.hidbus; +} + +Genode::Io_port_session_capability ZX::Device::io_port_resource(Genode::uint16_t port) +{ + for (int i = 0; _io_port && i < _io_port_count; i++){ + if (_io_port[i].port == port){ + return ZX::Resource<::Platform::Device_client>::get_component().io_port(_io_port[i].resource); + } + } + return Genode::Io_port_session_capability(); +} + +Genode::Irq_session_capability ZX::Device::irq_resource(Genode::uint32_t irq) +{ + for (int i = 0; _irq && i < _irq_count; i++){ + if (_irq[i].irq == irq){ + return ZX::Resource<::Platform::Device_client>::get_component().irq(_irq[i].resource); + } + } + return Genode::Irq_session_capability(); +} diff --git a/repos/dde_zircon/src/lib/zircon/include/debug.h b/repos/dde_zircon/src/lib/zircon/include/debug.h new file mode 100644 index 000000000..e69de29bb diff --git a/repos/dde_zircon/src/lib/zircon/include/list.h b/repos/dde_zircon/src/lib/zircon/include/list.h new file mode 100644 index 000000000..2f702a16e --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/include/list.h @@ -0,0 +1,2 @@ + +#include diff --git a/repos/dde_zircon/src/lib/zircon/include/platform/debug.h b/repos/dde_zircon/src/lib/zircon/include/platform/debug.h new file mode 100644 index 000000000..b7b6e7933 --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/include/platform/debug.h @@ -0,0 +1,4 @@ + +int platform_dgetc(char *c, bool wait); +void platform_dputc(char c); +void platform_dputs_thread(const char* str, size_t len); diff --git a/repos/dde_zircon/src/lib/zircon/include/zircon/syscalls/definitions.h b/repos/dde_zircon/src/lib/zircon/include/zircon/syscalls/definitions.h new file mode 100644 index 000000000..e3e70efbb --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/include/zircon/syscalls/definitions.h @@ -0,0 +1,38 @@ +/* + * \brief Zircon syscall declarations + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 _DDE_ZIRCON_DEFINITIONS_H_ +#define _DDE_ZIRCON_DEFINITIONS_H_ + +zx_status_t zx_ioports_request( + ZX_SYSCALL_PARAM_ATTR(handle_use) zx_handle_t resource, + uint16_t io_addr, + uint32_t len) __LEAF_FN; + +zx_status_t zx_interrupt_wait( + ZX_SYSCALL_PARAM_ATTR(handle_use) zx_handle_t handle, + zx_time_t *out_timestamp) __LEAF_FN; + +zx_status_t zx_interrupt_destroy( + ZX_SYSCALL_PARAM_ATTR(handle_use) zx_handle_t handle) __LEAF_FN; + +zx_status_t zx_handle_close( + ZX_SYSCALL_PARAM_ATTR(handle_release_always) zx_handle_t handle) __LEAF_FN; + +zx_status_t zx_interrupt_create( + ZX_SYSCALL_PARAM_ATTR(handle_use) zx_handle_t src_obj, + uint32_t src_num, + uint32_t options, + zx_handle_t *out) __NONNULL((4)) __LEAF_FN; + +#endif /* ifndef _DDE_ZIRCON_DEFINITIONS_H_ */ diff --git a/repos/dde_zircon/src/lib/zircon/include/zx/device.h b/repos/dde_zircon/src/lib/zircon/include/zx/device.h new file mode 100644 index 000000000..c9629ef7e --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/include/zx/device.h @@ -0,0 +1,82 @@ +/* + * \brief Zircon platform configuration + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 _ZX_DEVICE_H_ +#define _ZX_DEVICE_H_ + +#include +#include + +#include +#include + +namespace ZX +{ + namespace Platform + { + struct Io_port; + struct Irq; + } + namespace Interface + { + struct Available; + } + class Device; +} + +struct ZX::Platform::Io_port +{ + Genode::uint16_t port; + Genode::uint8_t resource; +}; + +struct ZX::Platform::Irq +{ + Genode::uint32_t irq; + Genode::uint8_t resource; +}; + +struct ZX::Interface::Available +{ + bool hidbus; +}; + +class ZX::Device +{ + private: + bool _use_platform; + Platform::Io_port *_io_port; + int _io_port_count; + Platform::Irq *_irq; + int _irq_count; + + ZX::Interface::Available _interfaces; + hidbus_ifc_t *_hidbus; + + void *_component; + + public: + Device(void *, bool); + bool platform(); + void *component(); + void set_io_port(Platform::Io_port *, int); + void set_irq(Platform::Irq *, int); + + void set_hidbus(hidbus_ifc_t *); + bool hidbus(hidbus_ifc_t **); + + Genode::Io_port_session_capability io_port_resource(Genode::uint16_t); + Genode::Irq_session_capability irq_resource(Genode::uint32_t); +}; + +#endif /* ifndef _ZX_DEVICE_H_ */ diff --git a/repos/dde_zircon/src/lib/zircon/include/zx/driver.h b/repos/dde_zircon/src/lib/zircon/include/zx/driver.h new file mode 100644 index 000000000..2b6992990 --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/include/zx/driver.h @@ -0,0 +1,35 @@ +/* + * \brief Helper for Zircon driver start mechanism + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 _ZX_DRIVER_H_ +#define _ZX_DRIVER_H_ + +#include + +#include + +extern zx_driver_rec_t __zircon_driver_rec__; + +static inline int bind_driver(void *ctx, zx_device_t* parent) +{ + int ret = -1; + if (__zircon_driver_rec__.ops->version == DRIVER_OPS_VERSION){ + ret = __zircon_driver_rec__.ops->bind(ctx, parent); + }else{ + Genode::error("Failed to start driver, invalid DRIVER_OPS_VERSION ", + Genode::Hex(__zircon_driver_rec__.ops->version)); + } + return ret; +} + +#endif /* ifndef _ZX_DRIVER_H_ */ diff --git a/repos/dde_zircon/src/lib/zircon/include/zx/irq.h b/repos/dde_zircon/src/lib/zircon/include/zx/irq.h new file mode 100644 index 000000000..14c9e773d --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/include/zx/irq.h @@ -0,0 +1,66 @@ +/* + * \brief Zircon interrupt handler + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 _ZX_IRQ_H_ +#define _ZX_IRQ_H_ + +#include +#include +#include +#include + +namespace ZX{ + enum { + IRQ_LINES = 256 + /* we assume that a single driver will never need more than 256 interrupt lines */ + }; + + template + class Irq + { + private: + tsession _irq; + Genode::Signal_handler _irq_handler; + Genode::Lock _lock; + + void _unlock() + { + _lock.unlock(); + } + + public: + Irq(Genode::Env &env, int irq) : + _irq(env, irq), + _irq_handler(env.ep(), *this, &Irq::_unlock), + _lock() + { + _irq.sigh(_irq_handler); + } + + Irq(Genode::Env &env, Genode::Irq_session_capability cap) : + _irq(cap), + _irq_handler(env.ep(), *this, &Irq::_unlock), + _lock() + { + _irq.sigh(_irq_handler); + } + + void wait() + { + _irq.ack_irq(); + _lock.lock(); + } + }; +} + +#endif /* ifndef_ZX_IRQ_H_ */ diff --git a/repos/dde_zircon/src/lib/zircon/include/zx/static_resource.h b/repos/dde_zircon/src/lib/zircon/include/zx/static_resource.h new file mode 100644 index 000000000..9aaf95ebe --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/include/zx/static_resource.h @@ -0,0 +1,88 @@ +/* + * \brief Utility to provide resources via type based static singletons + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 _ZX_STATIC_RESOURCE_H_ +#define _ZX_STATIC_RESOURCE_H_ + +#include +#include + +namespace ZX +{ + template + class Resource_uninitialized : Genode::Exception {}; + + template + class Resource_already_initialized : Genode::Exception {}; + + template + class Container + { + private: + + Component &_component; + + public: + + Container(Component &component) : _component(component) + { } + + Component &component() + { + return _component; + } + }; + + template + class Resource + { + private: + + static Genode::Constructible> _container; + + Resource() {} + + public: + + static Component &get_component() + { + if (_container.constructed()){ + return _container->component(); + } + Genode::error("Uninitialized resource: ", __PRETTY_FUNCTION__); + throw Resource_uninitialized(); + } + + static void set_component(Component &component) + { + if (!_container.constructed()){ + _container.construct(component); + return; + } + Genode::error("Already initialized resource: ", __PRETTY_FUNCTION__); + throw Resource_already_initialized(); + } + + static bool initialized() + { + return _container.constructed(); + } + + }; + +} + +template +Genode::Constructible> ZX::Resource::_container; + +#endif /* ifndef _ZX_STATIC_RESOURCE_H_ */ diff --git a/repos/dde_zircon/src/lib/zircon/include/zx/thread.h b/repos/dde_zircon/src/lib/zircon/include/zx/thread.h new file mode 100644 index 000000000..5487fbf80 --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/include/zx/thread.h @@ -0,0 +1,42 @@ +/* + * \brief Zircon thread wrapper + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 _ZX_THREAD_H_ +#define _ZX_THREAD_H_ + +#include + +#include + +namespace ZX +{ + class Thread; +} + +class ZX::Thread : public Genode::Thread +{ + private: + + thrd_start_t _thread_worker; + unsigned long _arg; + int _result; + + void entry() override; + + public: + + Thread(Genode::Env &, thrd_start_t, const char *, void *); + int result(); +}; + +#endif /* ifndef _ZX_THREAD_H_ */ diff --git a/repos/dde_zircon/src/lib/zircon/io_port.cc b/repos/dde_zircon/src/lib/zircon/io_port.cc new file mode 100644 index 000000000..17af0a2c3 --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/io_port.cc @@ -0,0 +1,66 @@ +/* + * \brief Zircon IO port handling + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 + +static Genode::Io_port_session_capability _port_reg[65536] = {}; + +extern "C" { + + Genode::uint8_t inp(Genode::uint16_t port) + { + if (ZX::Resource::get_component().platform() && _port_reg[port].valid()){ + return Genode::Io_port_session_client(_port_reg[port]).inb(port); + }else{ + return ZX::Resource::get_component().inb(port); + } + } + + void outp(Genode::uint16_t port, Genode::uint8_t data) + { + if (ZX::Resource::get_component().platform() && _port_reg[port].valid()){ + Genode::Io_port_session_client(_port_reg[port]).outb(port, data); + }else{ + ZX::Resource::get_component().outb(port, data); + } + } + + zx_status_t zx_ioports_request(zx_handle_t, + Genode::uint16_t io_addr, + Genode::uint32_t len) + { + ZX::Device &dev = ZX::Resource::get_component(); + if (dev.platform()){ + for (Genode::uint32_t i = io_addr; i < io_addr + len && io_addr + len < 65536; i++){ + _port_reg[i] = dev.io_port_resource(i); + if (!_port_reg[i].valid()){ + Genode::warning("No valid resource available for IO port ", Genode::Hex(i)); + return ZX_ERR_NO_RESOURCES; + } + } + }else{ + if (!ZX::Resource::initialized()){ + Genode::error("IO_PORT request ", Genode::Hex(io_addr), " x ", len, " not satisfied"); + return ZX_ERR_NO_RESOURCES; + } + } + return ZX_OK; + } + +} diff --git a/repos/dde_zircon/src/lib/zircon/irq.cc b/repos/dde_zircon/src/lib/zircon/irq.cc new file mode 100644 index 000000000..4126efc1d --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/irq.cc @@ -0,0 +1,89 @@ +/* + * \brief Zircon interrupt handling + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 +#include + +static Genode::Constructible> _irq_reg_connection[ZX::IRQ_LINES] = {}; +static Genode::Constructible> _irq_reg_client[ZX::IRQ_LINES] = {}; + +extern "C" { + + zx_status_t zx_interrupt_create(zx_handle_t, + Genode::uint32_t irq, + Genode::uint32_t, + zx_handle_t *irq_handle) + { + ZX::Device &dev = ZX::Resource::get_component(); + if (irq < ZX::IRQ_LINES){ + if (dev.platform()){ + try{ + _irq_reg_client[irq].construct(ZX::Resource::get_component(), + dev.irq_resource(irq)); + *irq_handle = irq; + return ZX_OK; + }catch (...){ + Genode::error("Failed to register for IRQ ", irq); + } + }else{ + if (!_irq_reg_connection[irq].constructed()){ + _irq_reg_connection[irq].construct(ZX::Resource::get_component(), irq); + *irq_handle = irq; + return ZX_OK; + } + } + } + return ZX_ERR_NO_RESOURCES; + } + + zx_status_t zx_interrupt_wait(zx_handle_t irq, zx_time_t *) + { + if (irq < ZX::IRQ_LINES){ + if (ZX::Resource::get_component().platform()){ + if (_irq_reg_client[irq].constructed()){ + _irq_reg_client[irq]->wait(); + return ZX_OK; + } + }else{ + if (_irq_reg_connection[irq].constructed()){ + _irq_reg_connection[irq]->wait(); + return ZX_OK; + } + } + } + return ZX_ERR_BAD_HANDLE; + } + + zx_status_t zx_interrupt_destroy(zx_handle_t irq) + { + if (irq < ZX::IRQ_LINES){ + if (ZX::Resource::get_component().platform()){ + if (_irq_reg_client[irq].constructed()){ + _irq_reg_client[irq].destruct(); + } + }else{ + if (_irq_reg_connection[irq].constructed()){ + _irq_reg_connection[irq].destruct(); + } + } + return ZX_OK; + } + return ZX_ERR_BAD_HANDLE; + } +} diff --git a/repos/dde_zircon/src/lib/zircon/libc.cc b/repos/dde_zircon/src/lib/zircon/libc.cc new file mode 100644 index 000000000..c10a49025 --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/libc.cc @@ -0,0 +1,92 @@ +/* + * \brief Zircon libc definitions + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 + + +class Format_String +{ + private: + static char _buffer[1024]; + + public: + Format_String(const char *prefix, const char *str, Genode::size_t len) + { + Genode::size_t last = Genode::strlen(_buffer); + Genode::memcpy(_buffer + last, str, Genode::min(len, 1023 - last)); + for (Genode::size_t i = 0; i < Genode::min(len, 1023 - last); i++){ + _buffer[i + last] = str[i]; + if (_buffer[i + last] == '\n'){ + Genode::log(Genode::Cstring(prefix), " ", *this); + Genode::memset(_buffer, '\0', 1024); + last = 0; + } + } + } + + void print(Genode::Output &out) const + { + _buffer[Genode::strlen(_buffer) - 1] = '\0'; + Genode::print(out, Genode::Cstring(_buffer)); + } +}; + +char Format_String::_buffer[1024] = {}; + +extern "C" { + + int usleep(unsigned usecs) + { + ZX::Resource::get_component().usleep(usecs); + return 0; + } + + int __printf_output_func(const char *str, Genode::size_t len, void *) + { + Format_String fmt("ZIRCON:", str, len); + return 0; + } + + Genode::size_t strlen(char *str) + { + Genode::size_t len = 0; + while (str[++len] != '\0'); + return len; + } + + void *malloc(Genode::size_t size) + { + void *mem; + Genode::Heap &heap = ZX::Resource::get_component(); + if (!heap.alloc(size, &mem)){ + return nullptr; + } + return mem; + } + + void free(void *ptr) + { + Genode::Heap &heap = ZX::Resource::get_component(); + heap.free(ptr, 0); + } + + void *calloc(Genode::size_t elem, Genode::size_t size) + { + return malloc(elem * size); + } + +} diff --git a/repos/dde_zircon/src/lib/zircon/mutex.cc b/repos/dde_zircon/src/lib/zircon/mutex.cc new file mode 100644 index 000000000..b0363f91c --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/mutex.cc @@ -0,0 +1,46 @@ +/* + * \brief Zircon mutex definitions + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 + +extern "C" { + + int mtx_init(mtx_t *mtx, int type) + { + if (type & mtx_recursive){ + return thrd_error; + } + Genode::Allocator &alloc = ZX::Resource::get_component(); + mtx->lock = static_cast(new (alloc) Genode::Lock()); + return thrd_success; + } + + int mtx_lock(mtx_t *mtx) + { + static_cast(mtx->lock)->lock(); + return thrd_success; + } + + int mtx_unlock(mtx_t *mtx) + { + static_cast(mtx->lock)->unlock(); + return thrd_success; + } + +} diff --git a/repos/dde_zircon/src/lib/zircon/pre_include/bits/alltypes.h b/repos/dde_zircon/src/lib/zircon/pre_include/bits/alltypes.h new file mode 100644 index 000000000..27fdf2562 --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/pre_include/bits/alltypes.h @@ -0,0 +1,24 @@ +/* + * \brief Overwrite Zircon specific mutex type + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 __DEFINED_mtx_t +#define __DEFINED_mtx_t + +typedef struct +{ + void *lock; +} mtx_t; + +#endif /* __DEFINED_mtx_t */ + +#include_next diff --git a/repos/dde_zircon/src/lib/zircon/pre_include/hw/inout.h b/repos/dde_zircon/src/lib/zircon/pre_include/hw/inout.h new file mode 100644 index 000000000..8fde9be0b --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/pre_include/hw/inout.h @@ -0,0 +1,20 @@ +/* + * \brief Custom define of system/ulib/ddk/include/hw/inout.h + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 _INOUT_H_ +#define _INOUT_H_ + +uint8_t inp(uint16_t); +void outp(uint16_t, uint8_t); + +#endif diff --git a/repos/dde_zircon/src/lib/zircon/syscalls.cc b/repos/dde_zircon/src/lib/zircon/syscalls.cc new file mode 100644 index 000000000..0d5f65147 --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/syscalls.cc @@ -0,0 +1,50 @@ +/* + * \brief Definition of Zircon system calls + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 + +#include +#include + +extern "C" { + + zx_handle_t get_root_resource() + { + return 0; + } + + zx_status_t zx_handle_close(zx_handle_t) + { + return ZX_OK; + } + + zx_status_t device_add_from_driver(zx_driver_t *, + zx_device_t *, + device_add_args_t *args, + zx_device_t **) + { + ZX::Device &dev = ZX::Resource::get_component(); + hidbus_ifc_t *hidbus; + if (dev.hidbus(&hidbus)){ + static_cast(args->proto_ops)->start( + args->ctx, hidbus, dev.component()); + } + return ZX_OK; + } + +} diff --git a/repos/dde_zircon/src/lib/zircon/threads.cc b/repos/dde_zircon/src/lib/zircon/threads.cc new file mode 100644 index 000000000..435c91492 --- /dev/null +++ b/repos/dde_zircon/src/lib/zircon/threads.cc @@ -0,0 +1,74 @@ +/* + * \brief Zircon threading implementation + * \author Johannes Kliemann + * \date 2018-07-25 + */ + +/* + * Copyright (C) 2018 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 + +ZX::Thread::Thread(Genode::Env &env, thrd_start_t worker, const char *label, void *arg) : + Genode::Thread(env, label, 4096), + _thread_worker(worker), + _arg(reinterpret_cast(arg)), + _result(-1) +{ + if (sizeof(arg) > sizeof(_arg)){ + Genode::warning("unsigned long < void *! things can go horribly wrong!"); + } +} + +void ZX::Thread::entry() +{ + _result = _thread_worker(reinterpret_cast(_arg)); +} + +int ZX::Thread::result() +{ + return _result; +} + +extern "C" { + + int thrd_create_with_name(thrd_t* thread, thrd_start_t run, void* arg, const char* name) + { + Genode::Allocator &alloc = ZX::Resource::get_component(); + Genode::Env &env = ZX::Resource::get_component(); + + ZX::Thread *gthread = new (alloc) ZX::Thread(env, run, name, arg); + *thread = reinterpret_cast(gthread); + + if (sizeof(gthread) != sizeof(*thread)){ + Genode::warning("thrd_t * != ZX::Thread *! things can go horribly wrong!"); + } + + gthread->start(); + + return thrd_success; + } + + int thrd_join(thrd_t thread, int *result) + { + ZX::Thread *gthread = reinterpret_cast(thread); + + if (sizeof(gthread) != sizeof(thread)){ + Genode::warning("thrd_t * != ZX::Thread *! things can go horribly wrong!"); + } + + gthread->join(); + if (result){ + *result = gthread->result(); + } + return thrd_success; + } + +} diff --git a/tool/builddir/build.conf/repos_x86 b/tool/builddir/build.conf/repos_x86 index 027c92cf8..3207144dd 100644 --- a/tool/builddir/build.conf/repos_x86 +++ b/tool/builddir/build.conf/repos_x86 @@ -8,3 +8,8 @@ # #REPOSITORIES += $(GENODE_DIR)/repos/dde_ipxe +# +# Drivers ported from Zircon +# +#REPOSITORIES += $(GENODE_DIR)/repos/dde_zircon +