From 85599c072f5d08812c72561a03d56fb2a0709380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Tue, 14 Apr 2015 13:56:26 +0200 Subject: [PATCH] os: use async IRQ and server lib in drivers Use the new asynchronous IRQ interface in the mostly used drivers, e.g.: * ahci_drv: x86/exynos5 * gpio_drv: imx53/omap4 * input_drv: imx53/dummy * ps2_drv: x86/pl050 * timer_drv Now, the Irq_session is requested from Gpio::Session: From now on we use an asynchronous IRQ interface. To prevent triggering another GPIO IRQ while currently handling the former one, IRQs must now by acknowledged explicitly. While here, we also changed the GPIO session interface regarding IRQ management. The generic GPIO component now wraps the Irq_session managed by the backend instead of using the GPIO backend methods directly. A client using the GPIO session may request the Irq_session_capability by calling 'Gpio::Session::irq_session()' and can use this capability when using a local Irq_session_client. Issue #1456. --- repos/os/include/gpio/component.h | 81 +++++--- repos/os/include/gpio/driver.h | 9 +- repos/os/include/gpio_session/client.h | 16 +- repos/os/include/gpio_session/gpio_session.h | 39 ++-- repos/os/lib/mk/timer.inc | 2 +- .../src/drivers/ahci/exynos5/ahci_driver.cc | 15 +- .../drivers/ahci/include/ahci_device_base.h | 6 +- repos/os/src/drivers/ahci/x86/ahci_device.h | 4 + .../src/drivers/framebuffer/exynos5/driver.cc | 55 +++--- .../src/drivers/framebuffer/exynos5/driver.h | 1 + .../src/drivers/framebuffer/exynos5/main.cc | 82 ++++---- .../src/drivers/framebuffer/exynos5/target.mk | 2 +- repos/os/src/drivers/gpio/imx53/driver.h | 180 +++++++++++------- repos/os/src/drivers/gpio/imx53/main.cc | 53 ++++-- repos/os/src/drivers/gpio/imx53/target.mk | 2 +- repos/os/src/drivers/gpio/omap4/driver.h | 160 ++++++++++------ repos/os/src/drivers/gpio/omap4/main.cc | 52 +++-- repos/os/src/drivers/gpio/omap4/target.mk | 2 +- repos/os/src/drivers/input/dummy/main.cc | 46 +++-- repos/os/src/drivers/input/dummy/target.mk | 2 +- repos/os/src/drivers/input/imx53/driver.h | 94 +++++---- repos/os/src/drivers/input/imx53/egalax_ts.h | 16 +- repos/os/src/drivers/input/imx53/i2c.h | 33 ++-- .../os/src/drivers/input/imx53/irq_handler.h | 48 +++++ repos/os/src/drivers/input/imx53/main.cc | 57 +++--- repos/os/src/drivers/input/imx53/mpr121.h | 9 +- repos/os/src/drivers/input/imx53/target.mk | 4 +- repos/os/src/drivers/input/ps2/irq_handler.h | 34 ++-- .../src/drivers/input/ps2/pl050/irq_handler.h | 60 +++--- repos/os/src/drivers/input/ps2/pl050/main.cc | 49 ++--- .../os/src/drivers/input/ps2/pl050/target.mk | 2 +- repos/os/src/drivers/input/ps2/x86/main.cc | 49 +++-- repos/os/src/drivers/input/ps2/x86/target.mk | 2 +- repos/os/src/drivers/sd_card/exynos5/driver.h | 10 +- repos/os/src/drivers/sd_card/exynos5/dwmmc.h | 25 ++- repos/os/src/drivers/sd_card/exynos5/main.cc | 10 +- .../src/drivers/sd_card/imx53/bench/main.cc | 155 ++++++++------- .../src/drivers/sd_card/imx53/bench/target.mk | 2 +- repos/os/src/drivers/sd_card/imx53/driver.h | 3 +- repos/os/src/drivers/sd_card/imx53/esdhcv2.h | 40 +++- repos/os/src/drivers/sd_card/imx53/main.cc | 7 +- .../src/drivers/sd_card/omap4/bench/main.cc | 146 +++++++------- .../src/drivers/sd_card/omap4/bench/target.mk | 2 +- repos/os/src/drivers/sd_card/omap4/driver.h | 3 +- repos/os/src/drivers/sd_card/omap4/main.cc | 9 +- repos/os/src/drivers/sd_card/omap4/mmchs.h | 20 +- .../os/src/drivers/timer/hw/platform_timer.h | 27 ++- .../os/src/drivers/timer/include/timer_root.h | 13 +- .../timer/include_periodic/platform_timer.h | 5 +- .../timer/include_pit/platform_timer.h | 14 +- repos/os/src/drivers/timer/main.cc | 52 ++--- .../src/drivers/timer/nova/platform_timer.h | 4 +- repos/os/src/test/gpio_drv/gpio_test.h | 59 +++--- 53 files changed, 1114 insertions(+), 758 deletions(-) create mode 100644 repos/os/src/drivers/input/imx53/irq_handler.h mode change 100755 => 100644 repos/os/src/drivers/timer/hw/platform_timer.h diff --git a/repos/os/include/gpio/component.h b/repos/os/include/gpio/component.h index 13b541c43..2e58a63bd 100644 --- a/repos/os/include/gpio/component.h +++ b/repos/os/include/gpio/component.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011-2013 Genode Labs GmbH + * Copyright (C) 2011-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -30,39 +30,62 @@ class Gpio::Session_component : public Genode::Rpc_object { private: - Driver &_driver; - unsigned long _pin; - Genode::Signal_context_capability _sigh; + struct Irq_session_component : public Genode::Rpc_object + { + Driver &_driver; + unsigned long _pin; + + Irq_session_component(Driver &driver, unsigned long pin) + : _driver(driver), _pin(pin) { } + + + /*************************** + ** Irq_session interface ** + ***************************/ + + void ack_irq() override { _driver.ack_irq(_pin); } + void sigh(Genode::Signal_context_capability sigh) override { + _driver.register_signal(_pin, sigh); } + }; + + Genode::Rpc_entrypoint &_ep; + Driver &_driver; + unsigned long _pin; + + Irq_session_component _irq_component; + Genode::Irq_session_capability _irq_cap; + public: - Session_component(Driver &driver, unsigned long gpio_pin) - : _driver(driver), _pin(gpio_pin) { } + Session_component(Genode::Rpc_entrypoint &ep, + Driver &driver, + unsigned long gpio_pin) + : _ep(ep), _driver(driver), _pin(gpio_pin), + _irq_component(_driver, _pin), + _irq_cap(_ep.manage(&_irq_component)) { } - ~Session_component() - { - if (_sigh.valid()) - _driver.unregister_signal(_pin); - } + ~Session_component() { _ep.dissolve(&_irq_component); } - /************************************ + + /***************************** ** Gpio::Session interface ** - ************************************/ + *****************************/ void direction(Direction d) { _driver.direction(_pin, (d == IN)); } void write(bool level) { _driver.write(_pin, level); } bool read() { return _driver.read(_pin); } - void irq_enable(bool enable) { _driver.irq_enable(_pin, enable); } - void irq_sigh(Genode::Signal_context_capability cap) + void debouncing(unsigned int us) { - if (cap.valid()) { - _sigh = cap; - _driver.register_signal(_pin, cap); - } + if (us) { + _driver.debounce_time(_pin, us); + _driver.debounce_enable(_pin, true); + } else + _driver.debounce_enable(_pin, false); } - void irq_type(Irq_type type) + Genode::Irq_session_capability irq_session(Irq_type type) { switch (type) { case HIGH_LEVEL: @@ -77,15 +100,10 @@ class Gpio::Session_component : public Genode::Rpc_object case FALLING_EDGE: _driver.falling_detect(_pin); }; - } - void debouncing(unsigned int us) - { - if (us) { - _driver.debounce_time(_pin, us); - _driver.debounce_enable(_pin, true); - } else - _driver.debounce_enable(_pin, false); + _driver.irq_enable(_pin, true); + + return _irq_cap; } }; @@ -94,7 +112,8 @@ class Gpio::Root : public Genode::Root_component { private: - Driver &_driver; + Genode::Rpc_entrypoint &_ep; + Driver &_driver; protected: @@ -114,7 +133,7 @@ class Gpio::Root : public Genode::Root_component throw Genode::Root::Quota_exceeded(); } - return new (md_alloc()) Session_component(_driver, pin); + return new (md_alloc()) Session_component(_ep, _driver, pin); } public: @@ -122,7 +141,7 @@ class Gpio::Root : public Genode::Root_component Root(Genode::Rpc_entrypoint *session_ep, Genode::Allocator *md_alloc, Driver &driver) : Genode::Root_component(session_ep, md_alloc), - _driver(driver) { } + _ep(*session_ep), _driver(driver) { } }; diff --git a/repos/os/include/gpio/driver.h b/repos/os/include/gpio/driver.h index 6e5f867b8..e53bf37c9 100644 --- a/repos/os/include/gpio/driver.h +++ b/repos/os/include/gpio/driver.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2011-2013 Genode Labs GmbH + * Copyright (C) 2011-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -92,6 +92,13 @@ struct Gpio::Driver */ virtual void irq_enable(unsigned gpio, bool enable) = 0; + /** + * Acknowledge IRQ for specified GPIO pin + * + * \param gpio corresponding gpio pin number + */ + virtual void ack_irq(unsigned gpio) = 0; + /** * Register signal handler for interrupts * diff --git a/repos/os/include/gpio_session/client.h b/repos/os/include/gpio_session/client.h index 5fa76dd7d..2edfffe59 100644 --- a/repos/os/include/gpio_session/client.h +++ b/repos/os/include/gpio_session/client.h @@ -7,7 +7,7 @@ /* * Copyright (C) 2012 Ksys Labs LLC - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -27,15 +27,13 @@ struct Gpio::Session_client : Genode::Rpc_client explicit Session_client(Session_capability session) : Genode::Rpc_client(session) { } - void direction(Direction d) override { call(d); } - void write(bool level) override { call(level); } - bool read() override { return call(); } - void debouncing(unsigned int us) override { call(us); } - void irq_type(Irq_type it) override { call(it); } - void irq_enable(bool enable) override { call(enable); } + void direction(Direction d) override { call(d); } + void write(bool level) override { call(level); } + bool read() override { return call(); } + void debouncing(unsigned int us) override { call(us); } - void irq_sigh(Genode::Signal_context_capability cap) override { - call(cap); } + Genode::Irq_session_capability irq_session(Irq_type type) override { + return call(type); } }; #endif /* _INCLUDE__GPIO_SESSION_H__CLIENT_H_ */ diff --git a/repos/os/include/gpio_session/gpio_session.h b/repos/os/include/gpio_session/gpio_session.h index 532036c9f..4f2833d72 100644 --- a/repos/os/include/gpio_session/gpio_session.h +++ b/repos/os/include/gpio_session/gpio_session.h @@ -7,7 +7,7 @@ /* * Copyright (C) 2012 Ksys Labs LLC - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -19,6 +19,7 @@ #include #include #include +#include namespace Gpio { struct Session; } @@ -62,42 +63,26 @@ struct Gpio::Session : Genode::Session virtual void debouncing(unsigned int us) = 0; /** - * Configure the type of interrupt for the GPIO pin + * Rquest IRQ session * - * \param it type of IRQ + * \param type type of IRQ */ - virtual void irq_type(Irq_type it) = 0; - - /** - * Enable or disable the interrupt of the GPIO pin - * - * \param enable interrupt status( true - enable, false - disable) - */ - virtual void irq_enable(bool enable) = 0; - - /** - * Register signal handler to be notified on interrupt - * - * \param cap capability of signal-context to handle GPIO interrupt - */ - virtual void irq_sigh(Genode::Signal_context_capability cap) = 0; + virtual Genode::Irq_session_capability irq_session(Irq_type type) = 0; /******************* ** RPC interface ** *******************/ - GENODE_RPC(Rpc_direction, void, direction, Direction); - GENODE_RPC(Rpc_write, void, write, bool); - GENODE_RPC(Rpc_read, bool, read); - GENODE_RPC(Rpc_debouncing, void, debouncing, unsigned int); - GENODE_RPC(Rpc_irq_type, void, irq_type, Irq_type); - GENODE_RPC(Rpc_irq_enable, void, irq_enable, bool); - GENODE_RPC(Rpc_irq_sigh, void, irq_sigh, Genode::Signal_context_capability); + GENODE_RPC(Rpc_direction, void, direction, Direction); + GENODE_RPC(Rpc_write, void, write, bool); + GENODE_RPC(Rpc_read, bool, read); + GENODE_RPC(Rpc_debouncing, void, debouncing, unsigned int); + GENODE_RPC(Rpc_irq_session, Genode::Irq_session_capability, + irq_session, Irq_type); GENODE_RPC_INTERFACE(Rpc_direction, Rpc_write, Rpc_read, - Rpc_debouncing, Rpc_irq_type, Rpc_irq_enable, - Rpc_irq_sigh); + Rpc_debouncing, Rpc_irq_session); }; #endif /* _INCLUDE__GPIO_SESSION__GPIO_SESSION_H_ */ diff --git a/repos/os/lib/mk/timer.inc b/repos/os/lib/mk/timer.inc index 744872093..6edc73322 100644 --- a/repos/os/lib/mk/timer.inc +++ b/repos/os/lib/mk/timer.inc @@ -1,5 +1,5 @@ SRC_CC += main.cc -LIBS += base alarm +LIBS += base alarm server INC_DIR += $(REP_DIR)/src/drivers/timer/include vpath main.cc $(REP_DIR)/src/drivers/timer diff --git a/repos/os/src/drivers/ahci/exynos5/ahci_driver.cc b/repos/os/src/drivers/ahci/exynos5/ahci_driver.cc index 9524edc69..15ad874b6 100644 --- a/repos/os/src/drivers/ahci/exynos5/ahci_driver.cc +++ b/repos/os/src/drivers/ahci/exynos5/ahci_driver.cc @@ -902,6 +902,8 @@ struct Sata_ahci : Attached_mmio /* port 0 settings */ unsigned p0_speed; Irq_connection p0_irq; + Genode::Signal_receiver p0_irq_rec; + Genode::Signal_context p0_irq_ctx; enum { SATA_3_MAX_SPEED = 3 }; @@ -922,7 +924,10 @@ struct Sata_ahci : Attached_mmio dbc_stable_trials(5), p0_speed(SATA_3_MAX_SPEED), p0_irq(Genode::Board_base::SATA_IRQ) - { } + { + p0_irq.sigh(p0_irq_rec.manage(&p0_irq_ctx)); + p0_irq.ack_irq(); + } /** * Clear all interrupts at port 0 @@ -1145,7 +1150,7 @@ struct Sata_ahci : Attached_mmio { typedef typename P0IS_BIT::Bitfield_base P0is_bit; write(1 << tag); - p0_irq.wait_for_irq(); + p0_irq_rec.wait_for_signal(); if (!read()) { PERR("ATA0 no IRQ raised"); return -1; @@ -1269,6 +1274,7 @@ struct Sata_ahci : Attached_mmio printf("ATA0 supports UDMA-133 and NCQ with queue depth %u\n", dev_id->queue_depth + 1); write(1); + p0_irq.ack_irq(); /* destroy receive buffer DMA */ env()->rm_session()->detach(dev_id_virt); @@ -1300,6 +1306,7 @@ struct Sata_ahci : Attached_mmio /* end command */ write(1); + p0_irq.ack_irq(); /* check for hidden blocks */ return max_native_addr + 1 != block_cnt; @@ -1344,6 +1351,7 @@ struct Sata_ahci : Attached_mmio } /* end command */ write(1); + p0_irq.ack_irq(); return 0; } @@ -1668,7 +1676,7 @@ struct Sata_ahci : Attached_mmio /* issue command and wait for completion */ write(1 << tag); write(1 << tag); - p0_irq.wait_for_irq(); + p0_irq_rec.wait_for_signal(); /* get port back ready and deteremine command state */ int ret = p0_handle_irqs(lba); @@ -1684,6 +1692,7 @@ struct Sata_ahci : Attached_mmio return -1; } write(1); + p0_irq.ack_irq(); } return ret; } diff --git a/repos/os/src/drivers/ahci/include/ahci_device_base.h b/repos/os/src/drivers/ahci/include/ahci_device_base.h index 6e8e5297f..a0183b5d1 100644 --- a/repos/os/src/drivers/ahci/include/ahci_device_base.h +++ b/repos/os/src/drivers/ahci/include/ahci_device_base.h @@ -370,6 +370,8 @@ class Ahci_device_base Generic_ctrl *_ctrl; /* generic host control */ Ahci_port *_port; /* port base of device */ Irq_connection *_irq; /* device IRQ */ + Genode::Signal_receiver _irq_rec; /* IRQ signal receiver */ + Genode::Signal_context _irq_ctx; /* IRQ signal context */ size_t _block_cnt; /* number of blocks on device */ Command_list *_cmd_list; /* pointer to command list */ Command_table *_cmd_table; /* pointer to command table */ @@ -453,7 +455,7 @@ class Ahci_device_base while (!status) { /* wait for interrupt */ - _irq->wait_for_irq(); + _irq_rec.wait_for_signal(); if (verbose) PDBG("Int status (IRQ): global: %x port: %x error: %x", @@ -479,6 +481,8 @@ class Ahci_device_base /* acknowledge global port interrupt */ _ctrl->hba_interrupt_ack(); + _irq->ack_irq(); + /* disable hba */ _port->hba_disable(); } diff --git a/repos/os/src/drivers/ahci/x86/ahci_device.h b/repos/os/src/drivers/ahci/x86/ahci_device.h index 366482b49..db50d1d14 100644 --- a/repos/os/src/drivers/ahci/x86/ahci_device.h +++ b/repos/os/src/drivers/ahci/x86/ahci_device.h @@ -184,6 +184,10 @@ class Ahci_device : public Ahci_device_base _disable_msi(pci_device); device->_irq = new(env()->heap()) Irq_connection(intr & 0xff); + Genode::Signal_context_capability cap = device->_irq_rec.manage(&device->_irq_ctx); + device->_irq->sigh(cap); + device->_irq->ack_irq(); + /* remember pci_device to be able to allocate ram memory which is dma able */ device->_pci_device_cap = device_cap; device->_pci_device = pci_device; diff --git a/repos/os/src/drivers/framebuffer/exynos5/driver.cc b/repos/os/src/drivers/framebuffer/exynos5/driver.cc index f431e0aa5..1b527e3e2 100644 --- a/repos/os/src/drivers/framebuffer/exynos5/driver.cc +++ b/repos/os/src/drivers/framebuffer/exynos5/driver.cc @@ -113,7 +113,19 @@ class I2c_interface : public Attached_mmio TX_DELAY_US = 1, }; - Irq_connection _irq; + Irq_connection _irq; + Genode::Signal_receiver _irq_rec; + Genode::Signal_context _irq_ctx; + + /** + * Wait until the IRQ signal was received + */ + void _wait_for_irq() + { + _irq_rec.wait_for_signal(); + + _irq.ack_irq(); + } /** * Stop a running transfer as master @@ -166,7 +178,7 @@ class I2c_interface : public Attached_mmio write(con); Stat::Busy::set(stat, 1); write(stat); - _irq.wait_for_irq(); + _wait_for_irq(); if (_arbitration_error()) return -1; return 0; } @@ -196,6 +208,7 @@ class I2c_interface : public Attached_mmio return 0; } + public: /** @@ -224,8 +237,13 @@ class I2c_interface : public Attached_mmio Lc::Sda_out_delay::set(lc, 2); Lc::Filter_en::set(lc, 1); write(lc); + + _irq.sigh(_irq_rec.manage(&_irq_ctx)); + _irq.ack_irq(); } + ~I2c_interface() { _irq_rec.dissolve(&_irq_ctx); } + /** * Transmit an I2C message as master * @@ -252,7 +270,7 @@ class I2c_interface : public Attached_mmio /* finish last byte and prepare for next one */ off++; write(0); - _irq.wait_for_irq(); + _wait_for_irq(); if (_arbitration_error()) return -1; } /* end message transfer */ @@ -285,7 +303,7 @@ class I2c_interface : public Attached_mmio while (1) { /* receive next message byte */ - _irq.wait_for_irq(); + _wait_for_irq(); if (_arbitration_error()) return -1; buf[off] = read(); off++; @@ -619,14 +637,6 @@ class I2c_hdmi : public I2c_interface } }; -/** - * Return singleton of device instance - */ -static I2c_hdmi * i2c_hdmi() -{ - static I2c_hdmi s; - return &s; -} /** * Converts input stream from video mixer into HDMI packet stream for HDMI PHY @@ -942,12 +952,15 @@ class Hdmi : public Attached_mmio write(0); } + I2c_hdmi _i2c_hdmi; + public: /** * Constructor */ - Hdmi() : Attached_mmio(0x14530000, 0xa0000) { } + Hdmi() + : Attached_mmio(0x14530000, 0xa0000), _i2c_hdmi() { } /** * Initialize HDMI controller for video output only @@ -978,12 +991,12 @@ class Hdmi : public Attached_mmio } /* set-up HDMI PHY */ write(0); - if (i2c_hdmi()->stop_hdmi_phy()) return -1; + if (_i2c_hdmi.stop_hdmi_phy()) return -1; write(1); delayer()->usleep(10000); write(0); delayer()->usleep(10000); - if (i2c_hdmi()->setup_and_start_hdmi_phy(pixel_clk)) return -1; + if (_i2c_hdmi.setup_and_start_hdmi_phy(pixel_clk)) return -1; /* reset HDMI CORE */ write(0); @@ -1095,15 +1108,6 @@ class Hdmi : public Attached_mmio } }; -/** - * Return singleton of device instance - */ -static Hdmi * hdmi() -{ - static Hdmi s; - return &s; -} - /************************* ** Framebuffer::Driver ** @@ -1140,7 +1144,8 @@ int Framebuffer::Driver::_init_hdmi(addr_t fb_phys) if (err) { return -1; } /* set-up HDMI to feed connected device */ - err = hdmi()->init_hdmi(_fb_width, _fb_height); + static Hdmi hdmi; + err = hdmi.init_hdmi(_fb_width, _fb_height); if (err) { return -1; } return 0; } diff --git a/repos/os/src/drivers/framebuffer/exynos5/driver.h b/repos/os/src/drivers/framebuffer/exynos5/driver.h index 43a59c8e7..a8698e63a 100644 --- a/repos/os/src/drivers/framebuffer/exynos5/driver.h +++ b/repos/os/src/drivers/framebuffer/exynos5/driver.h @@ -17,6 +17,7 @@ /* Genode includes */ #include #include +#include namespace Framebuffer { diff --git a/repos/os/src/drivers/framebuffer/exynos5/main.cc b/repos/os/src/drivers/framebuffer/exynos5/main.cc index 586c199bd..21d480555 100644 --- a/repos/os/src/drivers/framebuffer/exynos5/main.cc +++ b/repos/os/src/drivers/framebuffer/exynos5/main.cc @@ -11,9 +11,6 @@ * under the terms of the GNU General Public License version 2. */ -/* local includes */ -#include - /* Genode includes */ #include #include @@ -22,6 +19,10 @@ #include #include #include +#include + +/* local includes */ +#include namespace Framebuffer { @@ -111,47 +112,52 @@ class Framebuffer::Session_component }; -/** - * Program entrypoint - */ -int main(int, char **) +struct Main { - using namespace Framebuffer; + Server::Entrypoint &ep; + Framebuffer::Driver driver; - /* default config */ - size_t width = 1920; - size_t height = 1080; - Driver::Output output = Driver::OUTPUT_HDMI; + Main(Server::Entrypoint &ep) + : ep(ep), driver() + { + using namespace Framebuffer; - /* try to read custom user config */ - try { - char out[5] = { }; - Genode::Xml_node config_node = Genode::config()->xml_node(); - config_node.attribute("width").value(&width); - config_node.attribute("height").value(&height); - config_node.attribute("output").value(out, sizeof(out)); - if (!Genode::strcmp(out, "LCD")) { - output = Driver::OUTPUT_LCD; + /* default config */ + size_t width = 1920; + size_t height = 1080; + Driver::Output output = Driver::OUTPUT_HDMI; + + /* try to read custom user config */ + try { + char out[5] = { 0 }; + Genode::Xml_node config_node = Genode::config()->xml_node(); + config_node.attribute("width").value(&width); + config_node.attribute("height").value(&height); + config_node.attribute("output").value(out, sizeof(out)); + if (!Genode::strcmp(out, "LCD")) { + output = Driver::OUTPUT_LCD; + } } + catch (...) { + PDBG("using default configuration: HDMI@%dx%d", width, height); + } + + /* let entrypoint serve the framebuffer session and root interfaces */ + static Session_component fb_session(driver, width, height, output); + static Static_root fb_root(ep.manage(fb_session)); + + /* announce service and relax */ + env()->parent()->announce(ep.manage(fb_root)); } - catch (...) { - PDBG("using default configuration: HDMI@%dx%d", width, height); - } - /* create server backend */ - static Driver driver; +}; - /* create server entrypoint */ - enum { STACK_SIZE = 4096 }; - static Cap_connection cap; - static Rpc_entrypoint ep(&cap, STACK_SIZE, "fb_ep"); - /* let entrypoint serve the framebuffer session and root interfaces */ - static Session_component fb_session(driver, width, height, output); - static Static_root fb_root(ep.manage(&fb_session)); +/************ + ** Server ** + ************/ - /* announce service and relax */ - env()->parent()->announce(ep.manage(&fb_root)); - sleep_forever(); - return 0; +namespace Server { + char const *name() { return "fb_drv_ep"; } + size_t stack_size() { return 1024*sizeof(long); } + void construct(Entrypoint &ep) { static Main server(ep); } } - diff --git a/repos/os/src/drivers/framebuffer/exynos5/target.mk b/repos/os/src/drivers/framebuffer/exynos5/target.mk index f047dcf90..61616ae1a 100644 --- a/repos/os/src/drivers/framebuffer/exynos5/target.mk +++ b/repos/os/src/drivers/framebuffer/exynos5/target.mk @@ -1,5 +1,5 @@ TARGET = fb_drv REQUIRES = exynos5 SRC_CC += main.cc driver.cc -LIBS += base config +LIBS += base config server INC_DIR += $(PRG_DIR) diff --git a/repos/os/src/drivers/gpio/imx53/driver.h b/repos/os/src/drivers/gpio/imx53/driver.h index 74b0735e8..544944aad 100644 --- a/repos/os/src/drivers/gpio/imx53/driver.h +++ b/repos/os/src/drivers/gpio/imx53/driver.h @@ -22,6 +22,7 @@ #include #include #include +#include /* local includes */ #include "gpio.h" @@ -34,6 +35,7 @@ class Imx53_driver : public Gpio::Driver private: enum { + PIN_SHIFT = 5, MAX_BANKS = 7, MAX_PINS = 32 }; @@ -52,31 +54,44 @@ class Imx53_driver : public Gpio::Driver { public: - void handle_irq(); + void handle_irq() + { + unsigned long status = _reg.read(); + + for(unsigned i = 0; i < MAX_PINS; i++) { + if ((status & (1 << i)) && _irq_enabled[i] && + _sig_cap[i].valid()) + Genode::Signal_transmitter(_sig_cap[i]).submit(); + } + } private: - class Irq_handler : public Genode::Thread<4096> + class Irq_handler { private: - Genode::Irq_connection _irq; - Gpio_bank *_bank; + Genode::Irq_connection _irq; + Genode::Signal_rpc_member _dispatcher; + Gpio_bank *_bank; + + void _handle(unsigned) + { + _bank->handle_irq(); + _irq.ack_irq(); + } + public: - Irq_handler(unsigned irq, Gpio_bank *bank) - : Genode::Thread<4096>("irq handler"), - _irq(irq), _bank(bank) { start(); } - - void entry() + Irq_handler(Server::Entrypoint &ep, + unsigned irq, Gpio_bank *bank) + : _irq(irq), _dispatcher(ep, *this, &Irq_handler::_handle), + _bank(bank) { - while (true) { - _irq.wait_for_irq(); - _bank->handle_irq(); - } + _irq.sigh(_dispatcher); + _irq.ack_irq(); } - }; Gpio_reg _reg; @@ -84,15 +99,14 @@ class Imx53_driver : public Gpio::Driver Irq_handler _irqh_high; Genode::Signal_context_capability _sig_cap[MAX_PINS]; bool _irq_enabled[MAX_PINS]; - Genode::Lock _lock; public: - Gpio_bank(Genode::addr_t base, Genode::size_t size, - unsigned irq_low, unsigned irq_high) + Gpio_bank(Server::Entrypoint &ep, Genode::addr_t base, + Genode::size_t size, unsigned irq_low, unsigned irq_high) : _reg(base, size), - _irqh_low(irq_low, this), - _irqh_high(irq_high, this) { } + _irqh_low(ep, irq_low, this), + _irqh_high(ep, irq_high, this) { } Gpio_reg* regs() { return &_reg; } @@ -102,20 +116,70 @@ class Imx53_driver : public Gpio::Driver _irq_enabled[pin] = enable; } + void ack_irq(int pin) + { + _reg.write(1, pin); + } + void sigh(int pin, Genode::Signal_context_capability cap) { _sig_cap[pin] = cap; } }; + Server::Entrypoint &_ep; - static Gpio_bank _gpio_bank[MAX_BANKS]; + Gpio_bank _gpio_bank_0; + Gpio_bank _gpio_bank_1; + Gpio_bank _gpio_bank_2; + Gpio_bank _gpio_bank_3; + Gpio_bank _gpio_bank_4; + Gpio_bank _gpio_bank_5; + Gpio_bank _gpio_bank_6; + + Gpio_bank *_gpio_bank(int gpio) + { + switch (gpio >> PIN_SHIFT) { + case 0: + return &_gpio_bank_0; + case 1: + return &_gpio_bank_1; + case 2: + return &_gpio_bank_2; + case 3: + return &_gpio_bank_3; + case 4: + return &_gpio_bank_4; + case 5: + return &_gpio_bank_5; + case 6: + return &_gpio_bank_6; + } + + PERR("no Gpio_bank for pin %d available", gpio); + return 0; + } - int _gpio_bank_index(int gpio) { return gpio >> 5; } int _gpio_index(int gpio) { return gpio & 0x1f; } - Imx53_driver() + Imx53_driver(Server::Entrypoint &ep) + : + _ep(ep), + _gpio_bank_0(_ep, Genode::Board_base::GPIO1_MMIO_BASE, Genode::Board_base::GPIO1_MMIO_SIZE, + Genode::Board_base::GPIO1_IRQL, Genode::Board_base::GPIO1_IRQH), + _gpio_bank_1(_ep, Genode::Board_base::GPIO2_MMIO_BASE, Genode::Board_base::GPIO2_MMIO_SIZE, + Genode::Board_base::GPIO2_IRQL, Genode::Board_base::GPIO2_IRQH), + _gpio_bank_2(_ep, Genode::Board_base::GPIO3_MMIO_BASE, Genode::Board_base::GPIO3_MMIO_SIZE, + Genode::Board_base::GPIO3_IRQL, Genode::Board_base::GPIO3_IRQH), + _gpio_bank_3(_ep, Genode::Board_base::GPIO4_MMIO_BASE, Genode::Board_base::GPIO4_MMIO_SIZE, + Genode::Board_base::GPIO4_IRQL, Genode::Board_base::GPIO4_IRQH), + _gpio_bank_4(_ep, Genode::Board_base::GPIO5_MMIO_BASE, Genode::Board_base::GPIO5_MMIO_SIZE, + Genode::Board_base::GPIO5_IRQL, Genode::Board_base::GPIO5_IRQH), + _gpio_bank_5(_ep, Genode::Board_base::GPIO6_MMIO_BASE, Genode::Board_base::GPIO6_MMIO_SIZE, + Genode::Board_base::GPIO6_IRQL, Genode::Board_base::GPIO6_IRQH), + _gpio_bank_6(_ep, Genode::Board_base::GPIO7_MMIO_BASE, Genode::Board_base::GPIO7_MMIO_SIZE, + Genode::Board_base::GPIO7_IRQL, Genode::Board_base::GPIO7_IRQH) { for (unsigned i = 0; i < MAX_BANKS; ++i) { - Gpio_reg *regs = _gpio_bank[i].regs(); + Gpio_reg *regs = _gpio_bank(i << PIN_SHIFT)->regs(); for (unsigned j = 0; j < MAX_PINS; j++) { regs->write(Gpio_reg::Int_conf::LOW_LEVEL, j); regs->write(0, j); @@ -124,10 +188,10 @@ class Imx53_driver : public Gpio::Driver } } + public: - static Imx53_driver& factory(); - + static Imx53_driver &factory(Server::Entrypoint &ep); /****************************** ** Gpio::Driver interface ** @@ -137,7 +201,7 @@ class Imx53_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d input=%d", gpio, input); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); gpio_reg->write(input ? 0 : 1, _gpio_index(gpio)); } @@ -146,7 +210,7 @@ class Imx53_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d level=%d", gpio, level); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); gpio_reg->write(level ? 1 : 0, _gpio_index(gpio)); @@ -156,7 +220,7 @@ class Imx53_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d", gpio); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); return gpio_reg->read(_gpio_index(gpio)); } @@ -174,7 +238,7 @@ class Imx53_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d", gpio); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); gpio_reg->write(Gpio_reg::Int_conf::FAL_EDGE, _gpio_index(gpio)); } @@ -183,7 +247,7 @@ class Imx53_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d", gpio); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); gpio_reg->write(Gpio_reg::Int_conf::RIS_EDGE, _gpio_index(gpio)); } @@ -192,7 +256,7 @@ class Imx53_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d", gpio); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); gpio_reg->write(Gpio_reg::Int_conf::HIGH_LEVEL, _gpio_index(gpio)); } @@ -201,7 +265,7 @@ class Imx53_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d", gpio); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); gpio_reg->write(Gpio_reg::Int_conf::LOW_LEVEL, _gpio_index(gpio)); } @@ -210,7 +274,14 @@ class Imx53_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d enable=%d", gpio, enable); - _gpio_bank[_gpio_bank_index(gpio)].irq(_gpio_index(gpio), enable); + _gpio_bank(gpio)->irq(_gpio_index(gpio), enable); + } + + void ack_irq(unsigned gpio) + { + if (verbose) PDBG("gpio=%d ack_irq", gpio); + + _gpio_bank(gpio)->ack_irq(_gpio_index(gpio)); } void register_signal(unsigned gpio, @@ -218,59 +289,24 @@ class Imx53_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d", gpio); - _gpio_bank[_gpio_bank_index(gpio)].sigh(_gpio_index(gpio), cap); } + _gpio_bank(gpio)->sigh(_gpio_index(gpio), cap); } void unregister_signal(unsigned gpio) { if (verbose) PDBG("gpio=%d", gpio); Genode::Signal_context_capability cap; - _gpio_bank[_gpio_bank_index(gpio)].sigh(_gpio_index(gpio), cap); + _gpio_bank(gpio)->sigh(_gpio_index(gpio), cap); } bool gpio_valid(unsigned gpio) { return gpio < (MAX_PINS*MAX_BANKS); } }; -Imx53_driver::Gpio_bank Imx53_driver::_gpio_bank[Imx53_driver::MAX_BANKS] = { - { Genode::Board_base::GPIO1_MMIO_BASE, Genode::Board_base::GPIO1_MMIO_SIZE, - Genode::Board_base::GPIO1_IRQL, Genode::Board_base::GPIO1_IRQH }, - { Genode::Board_base::GPIO2_MMIO_BASE, Genode::Board_base::GPIO2_MMIO_SIZE, - Genode::Board_base::GPIO2_IRQL, Genode::Board_base::GPIO2_IRQH }, - { Genode::Board_base::GPIO3_MMIO_BASE, Genode::Board_base::GPIO3_MMIO_SIZE, - Genode::Board_base::GPIO3_IRQL, Genode::Board_base::GPIO3_IRQH }, - { Genode::Board_base::GPIO4_MMIO_BASE, Genode::Board_base::GPIO4_MMIO_SIZE, - Genode::Board_base::GPIO4_IRQL, Genode::Board_base::GPIO4_IRQH }, - { Genode::Board_base::GPIO5_MMIO_BASE, Genode::Board_base::GPIO5_MMIO_SIZE, - Genode::Board_base::GPIO5_IRQL, Genode::Board_base::GPIO5_IRQH }, - { Genode::Board_base::GPIO6_MMIO_BASE, Genode::Board_base::GPIO6_MMIO_SIZE, - Genode::Board_base::GPIO6_IRQL, Genode::Board_base::GPIO6_IRQH }, - { Genode::Board_base::GPIO7_MMIO_BASE, Genode::Board_base::GPIO7_MMIO_SIZE, - Genode::Board_base::GPIO7_IRQL, Genode::Board_base::GPIO7_IRQH } -}; - - -Imx53_driver& Imx53_driver::factory() +Imx53_driver &Imx53_driver::factory(Server::Entrypoint &ep) { - static Imx53_driver driver; + static Imx53_driver driver(ep); return driver; } - -void Imx53_driver::Gpio_bank::handle_irq() -{ - Genode::Lock::Guard lock_guard(_lock); - - unsigned long status = _reg.read(); - - for(unsigned i = 0; i < MAX_PINS; i++) { - if ((status & (1 << i)) && _irq_enabled[i] && - _sig_cap[i].valid()) - Genode::Signal_transmitter(_sig_cap[i]).submit(); - } - - _reg.write(0xffffffff); -} - - #endif /* _DRIVER_H_ */ diff --git a/repos/os/src/drivers/gpio/imx53/main.cc b/repos/os/src/drivers/gpio/imx53/main.cc index 9462ccbc4..45af0733f 100644 --- a/repos/os/src/drivers/gpio/imx53/main.cc +++ b/repos/os/src/drivers/gpio/imx53/main.cc @@ -8,7 +8,7 @@ /* * Copyright (C) 2012 Ksys Labs LLC - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -20,35 +20,46 @@ #include #include #include +#include /* local includes */ #include -int main(int, char **) +struct Main { - using namespace Genode; + Server::Entrypoint &ep; + Genode::Sliced_heap sliced_heap; + Imx53_driver &driver; + Gpio::Root root; - printf("--- i.MX53 gpio driver ---\n"); + Main(Server::Entrypoint &ep) + : + ep(ep), + sliced_heap(Genode::env()->ram_session(), Genode::env()->rm_session()), + driver(Imx53_driver::factory(ep)), + root(&ep.rpc_ep(), &sliced_heap, driver) + { + using namespace Genode; - Imx53_driver &driver = Imx53_driver::factory(); - Gpio::process_config(driver); + printf("--- i.MX53 gpio driver ---\n"); - /* - * Initialize server entry point - */ - enum { STACK_SIZE = 4096 }; - static Cap_connection cap; - Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session()); - static Rpc_entrypoint ep(&cap, STACK_SIZE, "gpio_ep"); - static Gpio::Root gpio_root(&ep, &sliced_heap, driver); + Gpio::process_config(driver); - /* - * Announce service - */ - env()->parent()->announce(ep.manage(&gpio_root)); + /* + * Announce service + */ + env()->parent()->announce(ep.manage(root)); + } +}; - Genode::sleep_forever(); - return 0; + +/************ + ** Server ** + ************/ + +namespace Server { + char const *name() { return "gpio_drv_ep"; } + size_t stack_size() { return 1024*sizeof(long); } + void construct(Entrypoint &ep) { static Main server(ep); } } - diff --git a/repos/os/src/drivers/gpio/imx53/target.mk b/repos/os/src/drivers/gpio/imx53/target.mk index bea14586b..864ae6c67 100644 --- a/repos/os/src/drivers/gpio/imx53/target.mk +++ b/repos/os/src/drivers/gpio/imx53/target.mk @@ -1,7 +1,7 @@ TARGET = gpio_drv REQUIRES = imx53 SRC_CC = main.cc -LIBS = base config +LIBS = base config server INC_DIR += $(PRG_DIR) vpath main.cc $(PRG_DIR) diff --git a/repos/os/src/drivers/gpio/omap4/driver.h b/repos/os/src/drivers/gpio/omap4/driver.h index f53fad60a..eeb73a1d9 100644 --- a/repos/os/src/drivers/gpio/omap4/driver.h +++ b/repos/os/src/drivers/gpio/omap4/driver.h @@ -33,6 +33,7 @@ class Omap4_driver : public Gpio::Driver private: enum { + PIN_SHIFT = 5, MAX_BANKS = 6, MAX_PINS = 32 }; @@ -47,44 +48,45 @@ class Omap4_driver : public Gpio::Driver } _delayer; - class Gpio_bank : public Genode::Thread<4096> + class Gpio_bank { private: - Gpio_reg _reg; - Genode::Irq_connection _irq; - Genode::Signal_context_capability _sig_cap[MAX_PINS]; - bool _irq_enabled[MAX_PINS]; + Gpio_reg _reg; + Genode::Irq_connection _irq; + Genode::Signal_rpc_member _dispatcher; + Genode::Signal_context_capability _sig_cap[MAX_PINS]; + bool _irq_enabled[MAX_PINS]; + + void _handle(unsigned) + { + _reg.write(0xffffffff); + + unsigned long status = _reg.read(); + + for(unsigned i = 0; i < MAX_PINS; i++) { + if ((status & (1 << i)) && _irq_enabled[i] && + _sig_cap[i].valid()) + Genode::Signal_transmitter(_sig_cap[i]).submit(); + } + + _irq.ack_irq(); + } + public: - Gpio_bank(Genode::addr_t base, Genode::size_t size, + Gpio_bank(Server::Entrypoint &ep, + Genode::addr_t base, Genode::size_t size, unsigned irq) - : Genode::Thread<4096>("irq handler"), - _reg(base, size), _irq(irq) + : _reg(base, size), _irq(irq), + _dispatcher(ep, *this, &Gpio_bank::_handle) { for (unsigned i = 0; i < MAX_PINS; i++) _irq_enabled[i] = false; - start(); - } - void entry() - { - unsigned long status; - - while (true) { - _reg.write(0xffffffff); - - _irq.wait_for_irq(); - - status = _reg.read(); - - for(unsigned i = 0; i < MAX_PINS; i++) { - if ((status & (1 << i)) && _irq_enabled[i] && - _sig_cap[i].valid()) - Genode::Signal_transmitter(_sig_cap[i]).submit(); - } - } + _irq.sigh(_dispatcher); + _irq.ack_irq(); } Gpio_reg* regs() { return &_reg; } @@ -100,28 +102,71 @@ class Omap4_driver : public Gpio::Driver _irq_enabled[pin] = enable; } + void ack_irq(int pin) { PDBG("not implemented"); } + void sigh(int pin, Genode::Signal_context_capability cap) { _sig_cap[pin] = cap; } }; + Server::Entrypoint &_ep; - static Gpio_bank _gpio_bank[MAX_BANKS]; + Gpio_bank _gpio_bank_0; + Gpio_bank _gpio_bank_1; + Gpio_bank _gpio_bank_2; + Gpio_bank _gpio_bank_3; + Gpio_bank _gpio_bank_4; + Gpio_bank _gpio_bank_5; + + Gpio_bank *_gpio_bank(int gpio) + { + switch (gpio >> PIN_SHIFT) { + case 0: + return &_gpio_bank_0; + case 1: + return &_gpio_bank_1; + case 2: + return &_gpio_bank_2; + case 3: + return &_gpio_bank_3; + case 4: + return &_gpio_bank_4; + case 5: + return &_gpio_bank_5; + } + + PERR("no Gpio_bank for pin %d available", gpio); + return 0; + } - int _gpio_bank_index(int gpio) { return gpio >> 5; } int _gpio_index(int gpio) { return gpio & 0x1f; } - Omap4_driver() + Omap4_driver(Server::Entrypoint &ep) + : + _ep(ep), + _gpio_bank_0(_ep, Genode::Board_base::GPIO1_MMIO_BASE, Genode::Board_base::GPIO1_MMIO_SIZE, + Genode::Board_base::GPIO1_IRQ), + _gpio_bank_1(_ep, Genode::Board_base::GPIO2_MMIO_BASE, Genode::Board_base::GPIO2_MMIO_SIZE, + Genode::Board_base::GPIO2_IRQ), + _gpio_bank_2(_ep, Genode::Board_base::GPIO3_MMIO_BASE, Genode::Board_base::GPIO3_MMIO_SIZE, + Genode::Board_base::GPIO3_IRQ), + _gpio_bank_3(_ep, Genode::Board_base::GPIO4_MMIO_BASE, Genode::Board_base::GPIO4_MMIO_SIZE, + Genode::Board_base::GPIO4_IRQ), + _gpio_bank_4(_ep, Genode::Board_base::GPIO5_MMIO_BASE, Genode::Board_base::GPIO5_MMIO_SIZE, + Genode::Board_base::GPIO5_IRQ), + _gpio_bank_5(_ep, Genode::Board_base::GPIO6_MMIO_BASE, Genode::Board_base::GPIO6_MMIO_SIZE, + Genode::Board_base::GPIO6_IRQ) { for (int i = 0; i < MAX_BANKS; ++i) { if (verbose) PDBG("GPIO%d ctrl=%08x", - i+1, _gpio_bank[i].regs()->read()); + i+1, _gpio_bank(i << PIN_SHIFT)->regs()->read()); } } + public: - static Omap4_driver& factory(); + static Omap4_driver& factory(Server::Entrypoint &ep); /****************************** @@ -132,7 +177,7 @@ class Omap4_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d input=%d", gpio, input); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); gpio_reg->write(input ? 1 : 0, _gpio_index(gpio)); } @@ -140,7 +185,7 @@ class Omap4_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d level=%d", gpio, level); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); if (level) gpio_reg->write(1 << _gpio_index(gpio)); @@ -152,7 +197,7 @@ class Omap4_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d", gpio); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); return gpio_reg->read(_gpio_index(gpio)); } @@ -160,7 +205,7 @@ class Omap4_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d enable=%d", gpio, enable); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); gpio_reg->write(enable ? 1 : 0, _gpio_index(gpio)); } @@ -178,7 +223,7 @@ class Omap4_driver : public Gpio::Driver else debounce = (us / 0x1f) - 1; - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); gpio_reg->write(debounce); } @@ -186,7 +231,7 @@ class Omap4_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d", gpio); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); gpio_reg->write (0, _gpio_index(gpio)); gpio_reg->write (0, _gpio_index(gpio)); gpio_reg->write(1, _gpio_index(gpio)); @@ -197,7 +242,7 @@ class Omap4_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d", gpio); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); gpio_reg->write (0, _gpio_index(gpio)); gpio_reg->write (0, _gpio_index(gpio)); gpio_reg->write(0, _gpio_index(gpio)); @@ -208,7 +253,7 @@ class Omap4_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d", gpio); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); gpio_reg->write (0, _gpio_index(gpio)); gpio_reg->write (1, _gpio_index(gpio)); gpio_reg->write(0, _gpio_index(gpio)); @@ -219,7 +264,7 @@ class Omap4_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d", gpio); - Gpio_reg *gpio_reg = _gpio_bank[_gpio_bank_index(gpio)].regs(); + Gpio_reg *gpio_reg = _gpio_bank(gpio)->regs(); gpio_reg->write (1, _gpio_index(gpio)); gpio_reg->write (0, _gpio_index(gpio)); gpio_reg->write(0, _gpio_index(gpio)); @@ -230,7 +275,14 @@ class Omap4_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d enable=%d", gpio, enable); - _gpio_bank[_gpio_bank_index(gpio)].irq(_gpio_index(gpio), enable); + _gpio_bank(gpio)->irq(_gpio_index(gpio), enable); + } + + void ack_irq(unsigned gpio) + { + if (verbose) PDBG("gpio=%d", gpio); + + _gpio_bank(gpio)->ack_irq(_gpio_index(gpio)); } void register_signal(unsigned gpio, @@ -238,39 +290,23 @@ class Omap4_driver : public Gpio::Driver { if (verbose) PDBG("gpio=%d", gpio); - _gpio_bank[_gpio_bank_index(gpio)].sigh(_gpio_index(gpio), cap); } + _gpio_bank(gpio)->sigh(_gpio_index(gpio), cap); } void unregister_signal(unsigned gpio) { if (verbose) PDBG("gpio=%d", gpio); Genode::Signal_context_capability cap; - _gpio_bank[_gpio_bank_index(gpio)].sigh(_gpio_index(gpio), cap); + _gpio_bank(gpio)->sigh(_gpio_index(gpio), cap); } bool gpio_valid(unsigned gpio) { return gpio < (MAX_PINS*MAX_BANKS); } }; -Omap4_driver::Gpio_bank Omap4_driver::_gpio_bank[Omap4_driver::MAX_BANKS] = { - { Genode::Board_base::GPIO1_MMIO_BASE, Genode::Board_base::GPIO1_MMIO_SIZE, - Genode::Board_base::GPIO1_IRQ }, - { Genode::Board_base::GPIO2_MMIO_BASE, Genode::Board_base::GPIO2_MMIO_SIZE, - Genode::Board_base::GPIO2_IRQ }, - { Genode::Board_base::GPIO3_MMIO_BASE, Genode::Board_base::GPIO3_MMIO_SIZE, - Genode::Board_base::GPIO3_IRQ }, - { Genode::Board_base::GPIO4_MMIO_BASE, Genode::Board_base::GPIO4_MMIO_SIZE, - Genode::Board_base::GPIO4_IRQ }, - { Genode::Board_base::GPIO5_MMIO_BASE, Genode::Board_base::GPIO5_MMIO_SIZE, - Genode::Board_base::GPIO5_IRQ }, - { Genode::Board_base::GPIO6_MMIO_BASE, Genode::Board_base::GPIO6_MMIO_SIZE, - Genode::Board_base::GPIO6_IRQ }, -}; - - -Omap4_driver& Omap4_driver::factory() +Omap4_driver& Omap4_driver::factory(Server::Entrypoint &ep) { - static Omap4_driver driver; + static Omap4_driver driver(ep); return driver; } diff --git a/repos/os/src/drivers/gpio/omap4/main.cc b/repos/os/src/drivers/gpio/omap4/main.cc index b49edba91..1b4bf6c98 100644 --- a/repos/os/src/drivers/gpio/omap4/main.cc +++ b/repos/os/src/drivers/gpio/omap4/main.cc @@ -7,7 +7,7 @@ /* * Copyright (C) 2012 Ksys Labs LLC - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -19,35 +19,45 @@ #include #include #include +#include /* local includes */ #include -int main(int, char **) +struct Main { - using namespace Genode; + Server::Entrypoint &ep; + Genode::Sliced_heap sliced_heap; + Omap4_driver &driver; + Gpio::Root root; - printf("--- omap4 gpio driver ---\n"); + Main(Server::Entrypoint &ep) + : + ep(ep), + sliced_heap(Genode::env()->ram_session(), Genode::env()->rm_session()), + driver(Omap4_driver::factory(ep)), + root(&ep.rpc_ep(), &sliced_heap, driver) + { + using namespace Genode; - Omap4_driver &driver = Omap4_driver::factory(); - Gpio::process_config(driver); + printf("--- omap4 gpio driver ---\n"); - /* - * Initialize server entry point - */ - enum { STACK_SIZE = 4096 }; - static Cap_connection cap; - Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session()); - static Rpc_entrypoint ep(&cap, STACK_SIZE, "gpio_ep"); - static Gpio::Root gpio_root(&ep, &sliced_heap, driver); + Gpio::process_config(driver); - /* - * Announce service - */ - env()->parent()->announce(ep.manage(&gpio_root)); + /* + * Announce service + */ + env()->parent()->announce(ep.manage(root)); + } +}; - Genode::sleep_forever(); - return 0; +/************ + ** Server ** + ************/ + +namespace Server { + char const *name() { return "gpio_drv_ep"; } + size_t stack_size() { return 1024*sizeof(long); } + void construct(Entrypoint &ep) { static Main server(ep); } } - diff --git a/repos/os/src/drivers/gpio/omap4/target.mk b/repos/os/src/drivers/gpio/omap4/target.mk index 2a1e92b8c..ae48a8cef 100644 --- a/repos/os/src/drivers/gpio/omap4/target.mk +++ b/repos/os/src/drivers/gpio/omap4/target.mk @@ -1,7 +1,7 @@ TARGET = gpio_drv REQUIRES = omap4 SRC_CC = main.cc -LIBS = base config +LIBS = base config server INC_DIR += $(PRG_DIR) vpath main.cc $(PRG_DIR) diff --git a/repos/os/src/drivers/input/dummy/main.cc b/repos/os/src/drivers/input/dummy/main.cc index 4e5d5c313..5295c6262 100644 --- a/repos/os/src/drivers/input/dummy/main.cc +++ b/repos/os/src/drivers/input/dummy/main.cc @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2006-2013 Genode Labs GmbH + * Copyright (C) 2006-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -22,6 +22,7 @@ #include #include #include +#include using namespace Genode; @@ -71,28 +72,33 @@ namespace Input { } -int main(int argc, char **argv) +struct Main { - /* create dataspace for event buffer that is shared with the client */ - try { ev_ds_cap = env()->ram_session()->alloc(MAX_EVENTS*sizeof(Input::Event)); } - catch (Ram_session::Alloc_failed) { - PERR("Could not allocate dataspace for event buffer"); - return 1; + Server::Entrypoint &ep; + Input::Root root; + + Main(Server::Entrypoint &ep) + : ep(ep), root(&ep.rpc_ep(), Genode::env()->heap()) + { + /* create dataspace for event buffer that is shared with the client */ + try { ev_ds_cap = env()->ram_session()->alloc(MAX_EVENTS*sizeof(Input::Event)); } + catch (Ram_session::Alloc_failed) { + PERR("Could not allocate dataspace for event buffer"); + throw Genode::Exception(); + } + + /* tell parent about the service */ + env()->parent()->announce(ep.manage(root)); } +}; - /* initialize server entry point */ - enum { STACK_SIZE = 4096 }; - static Cap_connection cap; - static Rpc_entrypoint ep(&cap, STACK_SIZE, "input_ep"); - /* entry point serving input root interface */ - static Input::Root input_root(&ep, env()->heap()); +/************ + ** Server ** + ************/ - /* tell parent about the service */ - env()->parent()->announce(ep.manage(&input_root)); - - /* main's done - go to sleep */ - - sleep_forever(); - return 0; +namespace Server { + char const *name() { return "input_drv_ep"; } + size_t stack_size() { return 1024*sizeof(long); } + void construct(Entrypoint &ep) { static Main server(ep); } } diff --git a/repos/os/src/drivers/input/dummy/target.mk b/repos/os/src/drivers/input/dummy/target.mk index 7d8163429..b783ba718 100644 --- a/repos/os/src/drivers/input/dummy/target.mk +++ b/repos/os/src/drivers/input/dummy/target.mk @@ -1,3 +1,3 @@ TARGET = dummy_input_drv SRC_CC = main.cc -LIBS = base +LIBS = base server diff --git a/repos/os/src/drivers/input/imx53/driver.h b/repos/os/src/drivers/input/imx53/driver.h index 85bf8b0eb..ebb3c2071 100644 --- a/repos/os/src/drivers/input/imx53/driver.h +++ b/repos/os/src/drivers/input/imx53/driver.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2013 Genode Labs GmbH + * Copyright (C) 2013-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -16,7 +16,6 @@ /* Genode includes */ #include -#include #include #include @@ -29,7 +28,7 @@ namespace Input { } -class Input::Tablet_driver : Genode::Thread<8192> +class Input::Tablet_driver { private: @@ -38,69 +37,66 @@ class Input::Tablet_driver : Genode::Thread<8192> GPIO_BUTTON = 132, }; - Event_queue &_ev_queue; - Gpio::Connection _gpio_ts; - Gpio::Connection _gpio_bt; - Genode::Signal_receiver _receiver; - Genode::Signal_context _ts_rx; - Genode::Signal_context _bt_rx; - Genode::Signal_context_capability _ts_sig_cap; - Genode::Signal_context_capability _bt_sig_cap; - Touchscreen _touchscreen; - Buttons _buttons; + Event_queue &_ev_queue; + Gpio::Connection _gpio_ts; + Gpio::Connection _gpio_bt; + Genode::Irq_session_client _irq_ts; + Genode::Irq_session_client _irq_bt; + Genode::Signal_rpc_member _ts_dispatcher; + Genode::Signal_rpc_member _bt_dispatcher; + Touchscreen _touchscreen; + Buttons _buttons; - Genode::Signal_context_capability _init_ts_gpio() + void _handle_ts(unsigned) { - Genode::Signal_context_capability ret = _receiver.manage(&_ts_rx); + _touchscreen.event(_ev_queue); + _irq_ts.ack_irq(); + } + + void _handle_bt(unsigned) + { + _buttons.event(_ev_queue); + _irq_bt.ack_irq(); + } + + Tablet_driver(Server::Entrypoint &ep, Event_queue &ev_queue) + : + _ev_queue(ev_queue), + _gpio_ts(GPIO_TOUCH), + _gpio_bt(GPIO_BUTTON), + _irq_ts(_gpio_ts.irq_session(Gpio::Session::LOW_LEVEL)), + _irq_bt(_gpio_bt.irq_session(Gpio::Session::FALLING_EDGE)), + _ts_dispatcher(ep, *this, &Tablet_driver::_handle_ts), + _bt_dispatcher(ep, *this, &Tablet_driver::_handle_bt), + _touchscreen(ep), _buttons(ep) + { + /* GPIO touchscreen handling */ _gpio_ts.direction(Gpio::Session::OUT); _gpio_ts.write(true); _gpio_ts.direction(Gpio::Session::IN); - _gpio_ts.irq_sigh(_ts_sig_cap); - _gpio_ts.irq_type(Gpio::Session::LOW_LEVEL); - _gpio_ts.irq_enable(true); - return ret; - } - Genode::Signal_context_capability _init_bt_gpio() - { - Genode::Signal_context_capability ret = _receiver.manage(&_bt_rx); + _irq_ts.sigh(_ts_dispatcher); + _irq_ts.ack_irq(); + + /* GPIO button handling */ _gpio_bt.direction(Gpio::Session::OUT); _gpio_bt.write(true); _gpio_bt.direction(Gpio::Session::IN); - _gpio_bt.irq_sigh(_bt_sig_cap); - _gpio_bt.irq_type(Gpio::Session::FALLING_EDGE); - _gpio_bt.irq_enable(true); - return ret; - } - Tablet_driver(Event_queue &ev_queue) - : Thread("touchscreen_signal_handler"), - _ev_queue(ev_queue), - _gpio_ts(GPIO_TOUCH), - _gpio_bt(GPIO_BUTTON), - _ts_sig_cap(_init_ts_gpio()), - _bt_sig_cap(_init_bt_gpio()) { start(); } + _irq_bt.sigh(_bt_dispatcher); + _irq_bt.ack_irq(); + } public: - static Tablet_driver* factory(Event_queue &ev_queue); - - void entry() - { - while (true) { - Genode::Signal sig = _receiver.wait_for_signal(); - if (sig.context() == &_ts_rx) - _touchscreen.event(_ev_queue); - else if (sig.context() == &_bt_rx) - _buttons.event(_ev_queue); - } - } + static Tablet_driver* factory(Server::Entrypoint &ep, Event_queue &ev_queue); }; -Input::Tablet_driver* Input::Tablet_driver::factory(Event_queue &ev_queue) +Input::Tablet_driver* Input::Tablet_driver::factory(Server::Entrypoint &ep, + Event_queue &ev_queue) { - static Input::Tablet_driver driver(ev_queue); + static Input::Tablet_driver driver(ep, ev_queue); return &driver; } diff --git a/repos/os/src/drivers/input/imx53/egalax_ts.h b/repos/os/src/drivers/input/imx53/egalax_ts.h index 8baf9b176..c2353c7cb 100644 --- a/repos/os/src/drivers/input/imx53/egalax_ts.h +++ b/repos/os/src/drivers/input/imx53/egalax_ts.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2013 Genode Labs GmbH + * Copyright (C) 2013-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -36,6 +36,7 @@ class Input::Touchscreen { enum I2c_addresses { I2C_ADDR = 0x4 }; enum Finger_state { PRESSED, RELEASED }; + Irq_handler _irq_handler; Genode::Attached_io_mem_dataspace _i2c_ds; I2c::I2c _i2c; Genode::uint8_t _buf[10]; @@ -43,11 +44,14 @@ class Input::Touchscreen { public: - Touchscreen() : _i2c_ds(Genode::Board_base::I2C_3_BASE, - Genode::Board_base::I2C_3_SIZE), - _i2c((Genode::addr_t)_i2c_ds.local_addr(), - Genode::Board_base::I2C_3_IRQ), - _state(RELEASED) + Touchscreen(Server::Entrypoint &ep) + : + _irq_handler(ep, Genode::Board_base::I2C_3_IRQ), + _i2c_ds(Genode::Board_base::I2C_3_BASE, + Genode::Board_base::I2C_3_SIZE), + _i2c((Genode::addr_t)_i2c_ds.local_addr(), + _irq_handler), + _state(RELEASED) { /* ask for touchscreen firmware version */ Genode::uint8_t cmd[10] = { 0x03, 0x03, 0xa, 0x01, 0x41 }; diff --git a/repos/os/src/drivers/input/imx53/i2c.h b/repos/os/src/drivers/input/imx53/i2c.h index 637abbe30..ab0731a0c 100644 --- a/repos/os/src/drivers/input/imx53/i2c.h +++ b/repos/os/src/drivers/input/imx53/i2c.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2013 Genode Labs GmbH + * Copyright (C) 2013-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -17,7 +17,9 @@ /* Genode includes */ #include #include -#include + +/* local includes */ +#include "irq_handler.h" namespace I2c { @@ -61,11 +63,10 @@ class I2c::I2c : Genode::Mmio class No_ack : Genode::Exception {}; - class No_irq : Genode::Exception {}; - Timer::Connection _timer; - Genode::Irq_connection _irq; + Timer::Connection _timer; + Irq_handler &_irq_handler; void _busy() { while (!read()); } @@ -101,15 +102,19 @@ class I2c::I2c : Genode::Mmio { write(value); - _irq.wait_for_irq(); - if (!read()) throw No_irq(); + do { _irq_handler.wait(); } + while (!read()); + write(0); if (read()) throw No_ack(); + + _irq_handler.ack(); } public: - I2c(Genode::addr_t const base, unsigned irq) : Mmio(base), _irq(irq) + I2c(Genode::addr_t const base, Irq_handler &irq_handler) + : Mmio(base), _irq_handler(irq_handler) { write(0); write(0); @@ -128,9 +133,7 @@ class I2c::I2c : Genode::Mmio _stop(); return; - } catch(No_ack) { - } catch(No_irq) { - } + } catch(No_ack) { } _stop(); } } @@ -150,8 +153,9 @@ class I2c::I2c : Genode::Mmio for (Genode::size_t i = 0; i < num; i++) { - _irq.wait_for_irq(); - if (!read()) throw No_irq(); + do { _irq_handler.wait(); } + while (!read()); + write(0); if (i == num-1) { @@ -167,8 +171,7 @@ class I2c::I2c : Genode::Mmio _stop(); return; - } catch(No_irq) { - } + } catch(No_ack) { } _stop(); } } diff --git a/repos/os/src/drivers/input/imx53/irq_handler.h b/repos/os/src/drivers/input/imx53/irq_handler.h new file mode 100644 index 000000000..42a4e66c4 --- /dev/null +++ b/repos/os/src/drivers/input/imx53/irq_handler.h @@ -0,0 +1,48 @@ +/* + * \brief Input-interrupt handler + * \author Josef Soentgen + * \date 2015-04-08 + */ + +/* + * Copyright (C) 2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _IRQ_HANDLER_H_ +#define _IRQ_HANDLER_H_ + +/* Genode includes */ +#include +#include + +class Irq_handler +{ + private: + + Genode::Irq_connection _irq; + Genode::Signal_receiver _sig_rec; + Genode::Signal_dispatcher _dispatcher; + + void _handle(unsigned) { } + + + public: + + Irq_handler(Server::Entrypoint &ep, int irq_number) + : + _irq(irq_number), + _dispatcher(_sig_rec, *this, &Irq_handler::_handle) + { + _irq.sigh(_dispatcher); + _irq.ack_irq(); + } + + void wait() { _sig_rec.wait_for_signal(); } + + void ack() { _irq.ack_irq(); } +}; + +#endif /* _IRQ_HANDLER_H_ */ diff --git a/repos/os/src/drivers/input/imx53/main.cc b/repos/os/src/drivers/input/imx53/main.cc index 9d3444f55..42b15c093 100644 --- a/repos/os/src/drivers/input/imx53/main.cc +++ b/repos/os/src/drivers/input/imx53/main.cc @@ -7,7 +7,7 @@ */ /* - * Copyright (C) 2006-2013 Genode Labs GmbH + * Copyright (C) 2006-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -22,40 +22,47 @@ #include #include #include +#include /* local includes */ #include using namespace Genode; -int main(int argc, char **argv) + +struct Main { - /* initialize server entry point */ - enum { STACK_SIZE = 4096 }; - static Cap_connection cap; - static Rpc_entrypoint ep(&cap, STACK_SIZE, "input_ep"); + Server::Entrypoint &ep; - static Input::Session_component session; + Input::Session_component session; + Input::Root_component root; - Platform::Connection plat_drv; - switch (plat_drv.revision()) { - case Platform::Session::SMD: - plat_drv.enable(Platform::Session::I2C_2); - plat_drv.enable(Platform::Session::I2C_3); - plat_drv.enable(Platform::Session::BUTTONS); - Input::Tablet_driver::factory(session.event_queue()); - break; - default: - PWRN("No input driver available for this board"); + Main(Server::Entrypoint &ep) + : ep(ep), root(ep.rpc_ep(), session) + { + Platform::Connection plat_drv; + switch (plat_drv.revision()) { + case Platform::Session::SMD: + plat_drv.enable(Platform::Session::I2C_2); + plat_drv.enable(Platform::Session::I2C_3); + plat_drv.enable(Platform::Session::BUTTONS); + Input::Tablet_driver::factory(ep, session.event_queue()); + break; + default: + PWRN("No input driver available for this board"); + } + + /* tell parent about the service */ + env()->parent()->announce(ep.manage(root)); } +}; - /* entry point serving input root interface */ - static Input::Root_component root(ep, session); +/************ + ** Server ** + ************/ - /* tell parent about the service */ - env()->parent()->announce(ep.manage(&root)); - - /* main's done - go to sleep */ - sleep_forever(); - return 0; +namespace Server { + char const *name() { return "input_drv_ep"; } + size_t stack_size() { return 2*1024*sizeof(long); } + void construct(Entrypoint &ep) { static Main server(ep); } } diff --git a/repos/os/src/drivers/input/imx53/mpr121.h b/repos/os/src/drivers/input/imx53/mpr121.h index cdc80395b..04ed97fe0 100644 --- a/repos/os/src/drivers/input/imx53/mpr121.h +++ b/repos/os/src/drivers/input/imx53/mpr121.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2013 Genode Labs GmbH + * Copyright (C) 2013-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -45,16 +45,19 @@ class Input::Buttons { POWER = 8, }; + Irq_handler _irq_handler; Genode::Attached_io_mem_dataspace _i2c_ds; I2c::I2c _i2c; Genode::uint8_t _state; public: - Buttons() : _i2c_ds(Genode::Board_base::I2C_2_BASE, + Buttons(Server::Entrypoint &ep) : + _irq_handler(ep, Genode::Board_base::I2C_2_IRQ), + _i2c_ds(Genode::Board_base::I2C_2_BASE, Genode::Board_base::I2C_2_SIZE), _i2c((Genode::addr_t)_i2c_ds.local_addr(), - Genode::Board_base::I2C_2_IRQ), + _irq_handler), _state(0) { static Genode::uint8_t init_cmd[][2] = { diff --git a/repos/os/src/drivers/input/imx53/target.mk b/repos/os/src/drivers/input/imx53/target.mk index 234b757d0..b75e500b9 100644 --- a/repos/os/src/drivers/input/imx53/target.mk +++ b/repos/os/src/drivers/input/imx53/target.mk @@ -1,5 +1,5 @@ TARGET = input_drv REQUIRES = imx53 SRC_CC = main.cc -LIBS = base -INC_DIR += $(PRG_DIR) \ No newline at end of file +LIBS = base server +INC_DIR += $(PRG_DIR) diff --git a/repos/os/src/drivers/input/ps2/irq_handler.h b/repos/os/src/drivers/input/ps2/irq_handler.h index 56bc507d5..4c7b76191 100644 --- a/repos/os/src/drivers/input/ps2/irq_handler.h +++ b/repos/os/src/drivers/input/ps2/irq_handler.h @@ -14,37 +14,43 @@ #ifndef _IRQ_HANDLER_H_ #define _IRQ_HANDLER_H_ +/* Genode includes */ #include #include +#include +/* local includes */ #include "input_driver.h" -class Irq_handler : Genode::Thread<4096> +class Irq_handler { private: - Genode::Irq_connection _irq; - Input_driver &_input_driver; + Genode::Irq_connection _irq; + Genode::Signal_rpc_member _dispatcher; + Input_driver &_input_driver; + + void _handle(unsigned) + { + _irq.ack_irq(); + + while (_input_driver.event_pending()) + _input_driver.handle_event(); + } public: - Irq_handler(int irq_number, Input_driver &input_driver) + Irq_handler(Server::Entrypoint &ep, + int irq_number, Input_driver &input_driver) : - Thread("irq_handler"), _irq(irq_number), + _dispatcher(ep, *this, &Irq_handler::_handle), _input_driver(input_driver) { - start(); + _irq.sigh(_dispatcher); + _irq.ack_irq(); } - void entry() - { - while (1) { - _irq.wait_for_irq(); - while (_input_driver.event_pending()) - _input_driver.handle_event(); - } - } }; #endif /* _IRQ_HANDLER_H_ */ diff --git a/repos/os/src/drivers/input/ps2/pl050/irq_handler.h b/repos/os/src/drivers/input/ps2/pl050/irq_handler.h index ebba3cf8f..c6328d076 100644 --- a/repos/os/src/drivers/input/ps2/pl050/irq_handler.h +++ b/repos/os/src/drivers/input/ps2/pl050/irq_handler.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2007-2013 Genode Labs GmbH + * Copyright (C) 2007-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -15,52 +15,52 @@ #define _IRQ_HANDLER_H_ /* Genode includes */ -#include #include +#include /* local includes */ #include "input_driver.h" #include "serial_interface.h" -class Irq_handler : Genode::Thread<4096> +class Irq_handler { private: - Genode::Irq_connection _irq; - Serial_interface *_channel; - Input_driver &_input_driver; + Genode::Irq_connection _irq; + Genode::Signal_rpc_member _dispatcher; + Serial_interface *_channel; + Input_driver &_input_driver; + + void _handle(unsigned) + { + _irq.ack_irq(); + +#ifdef __CODEZERO__ + /* + * (Re-)enable device interrupt because Codezero tends to + * disable it in its IRQ handler. + */ + _channel->enable_irq(); +#endif + + /* check for pending PS/2 input */ + while (_input_driver.event_pending()) + _input_driver.handle_event(); + } public: - Irq_handler(int irq_number, Serial_interface *channel, Input_driver &input_driver) + Irq_handler(Server::Entrypoint &ep, + int irq_number, Serial_interface *channel, + Input_driver &input_driver) : - Thread("irq_handler"), _irq(irq_number), + _dispatcher(ep, *this, &Irq_handler::_handle), _channel(channel), _input_driver(input_driver) { - start(); - } - - void entry() - { - while (1) { - -#ifdef __CODEZERO__ - /* - * (Re-)enable device interrupt because Codezero tends to - * disable it in its IRQ handler. - */ - _channel->enable_irq(); -#endif - - /* check for pending PS/2 input */ - while (_input_driver.event_pending()) - _input_driver.handle_event(); - - /* block for new PS/2 data */ - _irq.wait_for_irq(); - } + _irq.sigh(_dispatcher); + _irq.ack_irq(); } }; diff --git a/repos/os/src/drivers/input/ps2/pl050/main.cc b/repos/os/src/drivers/input/ps2/pl050/main.cc index 58eb59cc0..8e861ade0 100644 --- a/repos/os/src/drivers/input/ps2/pl050/main.cc +++ b/repos/os/src/drivers/input/ps2/pl050/main.cc @@ -18,6 +18,7 @@ #include #include #include +#include /* local includes */ #include "ps2_keyboard.h" @@ -28,34 +29,38 @@ using namespace Genode; -int main(int argc, char **argv) +struct Main { - Pl050 pl050; + Server::Entrypoint &ep; - Serial_interface *kbd = pl050.kbd_interface(); - Serial_interface *aux = pl050.aux_interface(); + Pl050 pl050; + Input::Session_component session; + Input::Root_component root; - /* - * Initialize server entry point - */ - enum { STACK_SIZE = 4096 }; - static Cap_connection cap; - static Rpc_entrypoint ep(&cap, STACK_SIZE, "ps2_ep"); + Ps2_mouse ps2_mouse; + Ps2_keyboard ps2_keybd; - static Input::Session_component session; - static Input::Root_component root(ep, session); + Irq_handler ps2_mouse_irq; + Irq_handler ps2_keybd_irq; - Ps2_mouse ps2_mouse(*aux, session.event_queue()); - Ps2_keyboard ps2_keybd(*kbd, session.event_queue(), true); + Main(Server::Entrypoint &ep) + : ep(ep), root(ep.rpc_ep(), session), + ps2_mouse(*pl050.aux_interface(), session.event_queue()), + ps2_keybd(*pl050.kbd_interface(), session.event_queue(), true), + ps2_mouse_irq(ep, PL050_MOUSE_IRQ, pl050.aux_interface(), ps2_mouse), + ps2_keybd_irq(ep, PL050_KEYBD_IRQ, pl050.kbd_interface(), ps2_keybd) + { + env()->parent()->announce(ep.manage(root)); + } +}; - Irq_handler ps2_mouse_irq(PL050_MOUSE_IRQ, aux, ps2_mouse); - Irq_handler ps2_keybd_irq(PL050_KEYBD_IRQ, kbd, ps2_keybd); - /* - * Let the entry point serve the input root interface - */ - env()->parent()->announce(ep.manage(&root)); +/************ + ** Server ** + ************/ - Genode::sleep_forever(); - return 0; +namespace Server { + char const *name() { return "ps2_drv_ep"; } + size_t stack_size() { return 1024*sizeof(long); } + void construct(Entrypoint &ep) { static Main server(ep); } } diff --git a/repos/os/src/drivers/input/ps2/pl050/target.mk b/repos/os/src/drivers/input/ps2/pl050/target.mk index 3311bd404..4867e6562 100644 --- a/repos/os/src/drivers/input/ps2/pl050/target.mk +++ b/repos/os/src/drivers/input/ps2/pl050/target.mk @@ -1,6 +1,6 @@ TARGET = ps2_drv REQUIRES = pl050 SRC_CC = main.cc -LIBS = base +LIBS = base server INC_DIR += $(PRG_DIR) $(PRG_DIR)/.. diff --git a/repos/os/src/drivers/input/ps2/x86/main.cc b/repos/os/src/drivers/input/ps2/x86/main.cc index 5760bc18e..5562bca36 100644 --- a/repos/os/src/drivers/input/ps2/x86/main.cc +++ b/repos/os/src/drivers/input/ps2/x86/main.cc @@ -11,13 +11,16 @@ * under the terms of the GNU General Public License version 2. */ +/* Genode includes */ #include #include #include #include #include #include +#include +/* local includes */ #include "i8042.h" #include "ps2_keyboard.h" #include "ps2_mouse.h" @@ -26,31 +29,39 @@ using namespace Genode; -int main(int argc, char **argv) +struct Main { - I8042 i8042; + Server::Entrypoint &ep; - Serial_interface *kbd = i8042.kbd_interface(); - Serial_interface *aux = i8042.aux_interface(); + I8042 i8042; + Input::Session_component session; + Input::Root_component root; - /* - * Initialize server entry point - */ - enum { STACK_SIZE = 4096 }; - static Cap_connection cap; - static Rpc_entrypoint ep(&cap, STACK_SIZE, "ps2_ep"); + Ps2_mouse ps2_mouse; + Ps2_keyboard ps2_keybd; - static Input::Session_component session; - static Input::Root_component root(ep, session); + Irq_handler ps2_mouse_irq; + Irq_handler ps2_keybd_irq; - Ps2_mouse ps2_mouse(*aux, session.event_queue()); - Ps2_keyboard ps2_keybd(*kbd, session.event_queue(), i8042.kbd_xlate()); + Main(Server::Entrypoint &ep) + : ep(ep), root(ep.rpc_ep(), session), + ps2_mouse(*i8042.aux_interface(), session.event_queue()), + ps2_keybd(*i8042.kbd_interface(), session.event_queue(), + i8042.kbd_xlate()), + ps2_mouse_irq(ep, 12, ps2_mouse), + ps2_keybd_irq(ep, 1, ps2_keybd) + { + env()->parent()->announce(ep.manage(root)); + } +}; - Irq_handler ps2_mouse_irq(12, ps2_mouse); - Irq_handler ps2_keybd_irq( 1, ps2_keybd); - env()->parent()->announce(ep.manage(&root)); +/************ + ** Server ** + ************/ - Genode::sleep_forever(); - return 0; +namespace Server { + char const *name() { return "ps2_drv_ep"; } + size_t stack_size() { return 1024*sizeof(long); } + void construct(Entrypoint &ep) { static Main server(ep); } } diff --git a/repos/os/src/drivers/input/ps2/x86/target.mk b/repos/os/src/drivers/input/ps2/x86/target.mk index 21a7e738b..dfd42079d 100644 --- a/repos/os/src/drivers/input/ps2/x86/target.mk +++ b/repos/os/src/drivers/input/ps2/x86/target.mk @@ -1,6 +1,6 @@ TARGET = ps2_drv REQUIRES = x86 ps2 SRC_CC = main.cc -LIBS = base +LIBS = base server INC_DIR = $(PRG_DIR)/.. diff --git a/repos/os/src/drivers/sd_card/exynos5/driver.h b/repos/os/src/drivers/sd_card/exynos5/driver.h index 44844fc64..b91f49bf9 100644 --- a/repos/os/src/drivers/sd_card/exynos5/driver.h +++ b/repos/os/src/drivers/sd_card/exynos5/driver.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2013 Genode Labs GmbH + * Copyright (C) 2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -19,6 +19,7 @@ #include #include #include +#include /* local includes */ #include @@ -54,6 +55,8 @@ class Block::Exynos5_driver : public Block::Driver }; + Server::Entrypoint &_ep; + /* display sub system registers */ Attached_io_mem_dataspace _mmio; @@ -64,10 +67,11 @@ class Block::Exynos5_driver : public Block::Driver public: - Exynos5_driver(bool use_dma) + Exynos5_driver(Server::Entrypoint &ep, bool use_dma) : + _ep(ep), _mmio(MSH_BASE, MSH_SIZE), - _controller((addr_t)_mmio.local_addr(), + _controller(ep, (addr_t)_mmio.local_addr(), _delayer, use_dma), _use_dma(use_dma) { diff --git a/repos/os/src/drivers/sd_card/exynos5/dwmmc.h b/repos/os/src/drivers/sd_card/exynos5/dwmmc.h index 75627d08e..aef1f058f 100644 --- a/repos/os/src/drivers/sd_card/exynos5/dwmmc.h +++ b/repos/os/src/drivers/sd_card/exynos5/dwmmc.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2013 Genode Labs GmbH + * Copyright (C) 2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -318,7 +318,9 @@ struct Exynos5_msh_controller : private Dwmmc, Sd_card::Host_controller Delayer &_delayer; Sd_card::Card_info _card_info; - Genode::Irq_connection _irq; + Genode::Irq_connection _irq; + Genode::Signal_receiver _irq_rec; + Genode::Signal_context _irq_ctx; Sd_card::Card_info _init() { @@ -464,10 +466,21 @@ struct Exynos5_msh_controller : private Dwmmc, Sd_card::Host_controller return true; } + void _wait_for_irq() + { + /* + * Acknowledge the IRQ first to implicitly activate + * receiving of further IRQ signals on the first usage + * of this method. + */ + _irq.ack_irq(); + _irq_rec.wait_for_signal(); + } + bool _wait_for_transfer_complete() { while (1) { - _irq.wait_for_irq(); + _wait_for_irq(); if (read()) { write(~0U); @@ -491,11 +504,13 @@ struct Exynos5_msh_controller : private Dwmmc, Sd_card::Host_controller } } + public: enum { IRQ_NUMBER = Genode::Board_base::SDMMC0_IRQ }; - Exynos5_msh_controller(Genode::addr_t const mmio_base, Delayer &delayer, + Exynos5_msh_controller(Server::Entrypoint &ep, + Genode::addr_t const mmio_base, Delayer &delayer, bool use_dma) : Dwmmc(mmio_base), _idmac_desc_ds(Genode::env()->ram_session(), @@ -505,8 +520,10 @@ struct Exynos5_msh_controller : private Dwmmc, Sd_card::Host_controller _idmac_desc_phys(Genode::Dataspace_client(_idmac_desc_ds.cap()).phys_addr()), _delayer(delayer), _card_info(_init()), _irq(IRQ_NUMBER) { + _irq.sigh(_irq_rec.manage(&_irq_ctx)); } + ~Exynos5_msh_controller() { _irq_rec.dissolve(&_irq_ctx); } bool _issue_command(Sd_card::Command_base const &command) { diff --git a/repos/os/src/drivers/sd_card/exynos5/main.cc b/repos/os/src/drivers/sd_card/exynos5/main.cc index aac576764..54a2b5b83 100644 --- a/repos/os/src/drivers/sd_card/exynos5/main.cc +++ b/repos/os/src/drivers/sd_card/exynos5/main.cc @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2013 Genode Labs GmbH + * Copyright (C) 2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -26,8 +26,12 @@ struct Main struct Factory : Block::Driver_factory { + Server::Entrypoint &ep; + + Factory(Server::Entrypoint &ep) : ep(ep) { } + Block::Driver *create() { - return new (Genode::env()->heap()) Block::Exynos5_driver(true); } + return new (Genode::env()->heap()) Block::Exynos5_driver(ep, true); } void destroy(Block::Driver *driver) { Genode::destroy(Genode::env()->heap(), @@ -38,7 +42,7 @@ struct Main Block::Root root; Main(Server::Entrypoint &ep) - : ep(ep), regulator(Regulator::CLK_MMC0), + : ep(ep), factory(ep), regulator(Regulator::CLK_MMC0), root(ep, Genode::env()->heap(), factory) { Genode::printf("--- Arndale eMMC card driver ---\n"); diff --git a/repos/os/src/drivers/sd_card/imx53/bench/main.cc b/repos/os/src/drivers/sd_card/imx53/bench/main.cc index 43abb5353..602c6d67c 100644 --- a/repos/os/src/drivers/sd_card/imx53/bench/main.cc +++ b/repos/os/src/drivers/sd_card/imx53/bench/main.cc @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -16,6 +16,7 @@ #include #include #include +#include /* local includes */ #include @@ -86,81 +87,93 @@ static void run_benchmark(Block::Driver &driver, } -int main(int argc, char **argv) +struct Main { - using namespace Genode; - - printf("--- i.MX53 SD card benchmark ---\n"); - - bool const use_dma = true; - - static Block::Imx53_driver driver(use_dma); - - static Timer::Connection timer; - - long const request_sizes[] = { - 512, 1024, 2048, 4096, 8192, 16384, 32768, 64*1024, 128*1024, 0 }; - - /* total size of communication buffer */ - size_t const buffer_size = 10 * 1024 * 1024; - - /* allocate read/write buffer */ - static Attached_ram_dataspace buffer(env()->ram_session(), buffer_size, Genode::UNCACHED); - char * const buffer_virt = buffer.local_addr(); - addr_t const buffer_phys = Dataspace_client(buffer.cap()).phys_addr(); - - /* - * Benchmark reading from SD card - */ - - printf("\n-- reading from SD card --\n"); - - struct Read : Operation + Main(Server::Entrypoint &ep) { - void operator () (Block::Driver &driver, - addr_t number, size_t count, addr_t phys, char *virt) - { - Block::Packet_descriptor p; - if (driver.dma_enabled()) - driver.read_dma(number, count, phys, p); - else - driver.read(number, count, virt, p); - } - } read_operation; + using namespace Genode; - for (unsigned i = 0; request_sizes[i]; i++) { - run_benchmark(driver, timer, buffer_virt, buffer_phys, buffer_size, - request_sizes[i], read_operation); + printf("--- i.MX53 SD card benchmark ---\n"); + + bool const use_dma = true; + + static Block::Imx53_driver driver(use_dma); + + static Timer::Connection timer; + + long const request_sizes[] = { + 512, 1024, 2048, 4096, 8192, 16384, 32768, 64*1024, 128*1024, 0 }; + + /* total size of communication buffer */ + size_t const buffer_size = 10 * 1024 * 1024; + + /* allocate read/write buffer */ + static Attached_ram_dataspace buffer(env()->ram_session(), buffer_size, Genode::UNCACHED); + char * const buffer_virt = buffer.local_addr(); + addr_t const buffer_phys = Dataspace_client(buffer.cap()).phys_addr(); + + /* + * Benchmark reading from SD card + */ + + printf("\n-- reading from SD card --\n"); + + struct Read : Operation + { + void operator () (Block::Driver &driver, + addr_t number, size_t count, addr_t phys, char *virt) + { + Block::Packet_descriptor p; + if (driver.dma_enabled()) + driver.read_dma(number, count, phys, p); + else + driver.read(number, count, virt, p); + } + } read_operation; + + for (unsigned i = 0; request_sizes[i]; i++) { + run_benchmark(driver, timer, buffer_virt, buffer_phys, buffer_size, + request_sizes[i], read_operation); + } + + /* + * Benchmark writing to SD card + * + * We write back the content of the buffer, which we just filled during the + * read benchmark. If both read and write succeed, the SD card will retain + * its original content. + */ + + printf("\n-- writing to SD card --\n"); + + struct Write : Operation + { + void operator () (Block::Driver &driver, + addr_t number, size_t count, addr_t phys, char *virt) + { + Block::Packet_descriptor p; + if (driver.dma_enabled()) + driver.write_dma(number, count, phys, p); + else + driver.write(number, count, virt, p); + } + } write_operation; + + for (unsigned i = 0; request_sizes[i]; i++) + run_benchmark(driver, timer, buffer_virt, buffer_phys, buffer_size, + request_sizes[i], write_operation); + + printf("\n--- i.MX53 SD card benchmark finished ---\n"); } +}; - /* - * Benchmark writing to SD card - * - * We write back the content of the buffer, which we just filled during the - * read benchmark. If both read and write succeed, the SD card will retain - * its original content. - */ - printf("\n-- writing to SD card --\n"); +/************ + ** Server ** + ************/ - struct Write : Operation - { - void operator () (Block::Driver &driver, - addr_t number, size_t count, addr_t phys, char *virt) - { - Block::Packet_descriptor p; - if (driver.dma_enabled()) - driver.write_dma(number, count, phys, p); - else - driver.write(number, count, virt, p); - } - } write_operation; - - for (unsigned i = 0; request_sizes[i]; i++) - run_benchmark(driver, timer, buffer_virt, buffer_phys, buffer_size, - request_sizes[i], write_operation); - - printf("\n--- i.MX53 SD card benchmark finished ---\n"); - sleep_forever(); - return 0; +namespace Server { + char const *name() { return "sd_card_bench_ep"; } + size_t stack_size() { return 2*1024*sizeof(long); } + void construct(Entrypoint &ep) { static Main server(ep); } } diff --git a/repos/os/src/drivers/sd_card/imx53/bench/target.mk b/repos/os/src/drivers/sd_card/imx53/bench/target.mk index 256953e6e..51a252a0a 100644 --- a/repos/os/src/drivers/sd_card/imx53/bench/target.mk +++ b/repos/os/src/drivers/sd_card/imx53/bench/target.mk @@ -1,5 +1,5 @@ TARGET = sd_card_bench REQUIRES = imx53 SRC_CC = main.cc -LIBS = base +LIBS = base server INC_DIR += $(PRG_DIR)/.. $(PRG_DIR)/../.. diff --git a/repos/os/src/drivers/sd_card/imx53/driver.h b/repos/os/src/drivers/sd_card/imx53/driver.h index edbdaf31c..2e7bb2863 100644 --- a/repos/os/src/drivers/sd_card/imx53/driver.h +++ b/repos/os/src/drivers/sd_card/imx53/driver.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -20,6 +20,7 @@ #include #include #include +#include /* local includes */ #include diff --git a/repos/os/src/drivers/sd_card/imx53/esdhcv2.h b/repos/os/src/drivers/sd_card/imx53/esdhcv2.h index 74229d180..f195330aa 100644 --- a/repos/os/src/drivers/sd_card/imx53/esdhcv2.h +++ b/repos/os/src/drivers/sd_card/imx53/esdhcv2.h @@ -414,11 +414,13 @@ struct Esdhcv2_controller : private Esdhcv2, public Sd_card::Host_controller BURST_WORDS = 8, }; - Genode::Irq_connection _irq; - Delayer & _delayer; - Sd_card::Card_info _card_info; - bool const _use_dma; - Adma2::Table _adma2_table; + Genode::Irq_connection _irq; + Genode::Signal_receiver _irq_rec; + Genode::Signal_context _irq_ctx; + Delayer & _delayer; + Sd_card::Card_info _card_info; + bool const _use_dma; + Adma2::Table _adma2_table; /** * Print 'err' and throw detection-error exception @@ -569,6 +571,20 @@ struct Esdhcv2_controller : private Esdhcv2, public Sd_card::Host_controller return card_info; } + /** + * Wait until we received the IRQ signal + */ + void _wait_for_irq() + { + /* + * Acknowledge the IRQ first to implicitly activate + * receiving of further IRQ signals on the first usage + * of this method. + */ + _irq.ack_irq(); + _irq_rec.wait_for_signal(); + } + /* * Wait till sending a new command is allowed * @@ -596,7 +612,7 @@ struct Esdhcv2_controller : private Esdhcv2, public Sd_card::Host_controller */ bool _wait_for_cmd_complete() { - _irq.wait_for_irq(); + _wait_for_irq(); if (read() != Irqstat::Cc::reg_mask()) { PWRN("received unexpected host signal"); reset_command(_delayer); @@ -634,7 +650,7 @@ struct Esdhcv2_controller : private Esdhcv2, public Sd_card::Host_controller bool _wait_for_mbc_complete(bool const r) { /* wait for a signal */ - _irq.wait_for_irq(); + _wait_for_irq(); Irqstat::access_t const irq = read(); /* @@ -741,9 +757,13 @@ struct Esdhcv2_controller : private Esdhcv2, public Sd_card::Host_controller Esdhcv2_controller(addr_t const mmio_base, unsigned const irq, Delayer & delayer, bool const use_dma) : - Esdhcv2(mmio_base), _irq(irq), _delayer(delayer), - _card_info(_init()), _use_dma(use_dma) - { } + Esdhcv2(mmio_base), _irq(irq), + _delayer(delayer), _card_info(_init()), _use_dma(use_dma) + { + _irq.sigh(_irq_rec.manage(&_irq_ctx)); + } + + ~Esdhcv2_controller() { _irq_rec.dissolve(&_irq_ctx); } /**************************************** diff --git a/repos/os/src/drivers/sd_card/imx53/main.cc b/repos/os/src/drivers/sd_card/imx53/main.cc index f9ed3cb50..fd2aa56a4 100644 --- a/repos/os/src/drivers/sd_card/imx53/main.cc +++ b/repos/os/src/drivers/sd_card/imx53/main.cc @@ -25,6 +25,10 @@ struct Main struct Factory : Block::Driver_factory { + Server::Entrypoint &ep; + + Factory(Server::Entrypoint &ep) : ep(ep) { } + Block::Driver *create() { return new (Genode::env()->heap()) Block::Imx53_driver(true); } @@ -36,7 +40,7 @@ struct Main Block::Root root; Main(Server::Entrypoint &ep) - : ep(ep), root(ep, Genode::env()->heap(), factory) + : ep(ep), factory(ep), root(ep, Genode::env()->heap(), factory) { Genode::printf("--- Imx53 SD card driver ---\n"); @@ -54,4 +58,3 @@ namespace Server { size_t stack_size() { return 2*1024*sizeof(long); } void construct(Entrypoint &ep) { static Main server(ep); } } - diff --git a/repos/os/src/drivers/sd_card/omap4/bench/main.cc b/repos/os/src/drivers/sd_card/omap4/bench/main.cc index fd5a73d29..ce8fb60e8 100644 --- a/repos/os/src/drivers/sd_card/omap4/bench/main.cc +++ b/repos/os/src/drivers/sd_card/omap4/bench/main.cc @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -77,80 +77,92 @@ static void run_benchmark(Block::Driver &driver, } -int main(int argc, char **argv) +struct Main { - using namespace Genode; - - printf("--- OMAP4 SD card benchmark ---\n"); - - bool const use_dma = false; - - static Block::Omap4_driver driver(use_dma); - - static Timer::Connection timer; - - long const request_sizes[] = { - 512, 1024, 2048, 4096, 8192, 16384, 32768, 64*1024, 128*1024, 0 }; - - /* total size of communication buffer */ - size_t const buffer_size = 10*1024*1024; - - /* allocate read/write buffer */ - static Attached_ram_dataspace buffer(env()->ram_session(), buffer_size, Genode::UNCACHED); - char * const buffer_virt = buffer.local_addr(); - addr_t const buffer_phys = Dataspace_client(buffer.cap()).phys_addr(); - - /* - * Benchmark reading from SD card - */ - - printf("\n-- reading from SD card --\n"); - - struct Read : Operation + Main(Server::Entrypoint &ep) { - void operator () (Block::Driver &driver, - addr_t number, size_t count, addr_t phys, char *virt) + using namespace Genode; + + printf("--- OMAP4 SD card benchmark ---\n"); + + bool const use_dma = false; + + static Block::Omap4_driver driver(use_dma); + + static Timer::Connection timer; + + long const request_sizes[] = { + 512, 1024, 2048, 4096, 8192, 16384, 32768, 64*1024, 128*1024, 0 }; + + /* total size of communication buffer */ + size_t const buffer_size = 10*1024*1024; + + /* allocate read/write buffer */ + static Attached_ram_dataspace buffer(env()->ram_session(), buffer_size, Genode::UNCACHED); + char * const buffer_virt = buffer.local_addr(); + addr_t const buffer_phys = Dataspace_client(buffer.cap()).phys_addr(); + + /* + * Benchmark reading from SD card + */ + + printf("\n-- reading from SD card --\n"); + + struct Read : Operation { - Block::Packet_descriptor p; - if (driver.dma_enabled()) - driver.read_dma(number, count, phys, p); - else - driver.read(number, count, virt, p); - } - } read_operation; + void operator () (Block::Driver &driver, + addr_t number, size_t count, addr_t phys, char *virt) + { + Block::Packet_descriptor p; + if (driver.dma_enabled()) + driver.read_dma(number, count, phys, p); + else + driver.read(number, count, virt, p); + } + } read_operation; - for (unsigned i = 0; request_sizes[i]; i++) - run_benchmark(driver, timer, buffer_virt, buffer_phys, buffer_size, - request_sizes[i], read_operation); + for (unsigned i = 0; request_sizes[i]; i++) + run_benchmark(driver, timer, buffer_virt, buffer_phys, buffer_size, + request_sizes[i], read_operation); - /* - * Benchmark writing to SD card - * - * We write back the content of the buffer, which we just filled during the - * read benchmark. If both read and write succeed, the SD card will retain - * its original content. - */ + /* + * Benchmark writing to SD card + * + * We write back the content of the buffer, which we just filled during the + * read benchmark. If both read and write succeed, the SD card will retain + * its original content. + */ - printf("\n-- writing to SD card --\n"); + printf("\n-- writing to SD card --\n"); - struct Write : Operation - { - void operator () (Block::Driver &driver, - addr_t number, size_t count, addr_t phys, char *virt) + struct Write : Operation { - Block::Packet_descriptor p; - if (driver.dma_enabled()) - driver.write_dma(number, count, phys, p); - else - driver.write(number, count, virt, p); - } - } write_operation; + void operator () (Block::Driver &driver, + addr_t number, size_t count, addr_t phys, char *virt) + { + Block::Packet_descriptor p; + if (driver.dma_enabled()) + driver.write_dma(number, count, phys, p); + else + driver.write(number, count, virt, p); + } + } write_operation; - for (unsigned i = 0; request_sizes[i]; i++) - run_benchmark(driver, timer, buffer_virt, buffer_phys, buffer_size, - request_sizes[i], write_operation); + for (unsigned i = 0; request_sizes[i]; i++) + run_benchmark(driver, timer, buffer_virt, buffer_phys, buffer_size, + request_sizes[i], write_operation); - printf("\n--- OMAP4 SD card benchmark finished ---\n"); - sleep_forever(); - return 0; + printf("\n--- OMAP4 SD card benchmark finished ---\n"); + } +}; + + +/************ + ** Server ** + ************/ + +namespace Server { + char const *name() { return "sd_card_bench_ep"; } + size_t stack_size() { return 2*1024*sizeof(long); } + void construct(Entrypoint &ep) { static Main server(ep); } } diff --git a/repos/os/src/drivers/sd_card/omap4/bench/target.mk b/repos/os/src/drivers/sd_card/omap4/bench/target.mk index f6c3950f9..2af09402b 100644 --- a/repos/os/src/drivers/sd_card/omap4/bench/target.mk +++ b/repos/os/src/drivers/sd_card/omap4/bench/target.mk @@ -1,5 +1,5 @@ TARGET = sd_card_bench REQUIRES = omap4 SRC_CC = main.cc -LIBS = base +LIBS = base server INC_DIR += $(PRG_DIR)/.. $(PRG_DIR)/../.. diff --git a/repos/os/src/drivers/sd_card/omap4/driver.h b/repos/os/src/drivers/sd_card/omap4/driver.h index c967bb34f..17fc9736f 100644 --- a/repos/os/src/drivers/sd_card/omap4/driver.h +++ b/repos/os/src/drivers/sd_card/omap4/driver.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -19,6 +19,7 @@ #include #include #include +#include /* local includes */ #include diff --git a/repos/os/src/drivers/sd_card/omap4/main.cc b/repos/os/src/drivers/sd_card/omap4/main.cc index 36f023378..adf733c40 100644 --- a/repos/os/src/drivers/sd_card/omap4/main.cc +++ b/repos/os/src/drivers/sd_card/omap4/main.cc @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -25,6 +25,10 @@ struct Main struct Factory : Block::Driver_factory { + Server::Entrypoint &ep; + + Factory(Server::Entrypoint &ep) : ep(ep) { } + Block::Driver *create() { return new (Genode::env()->heap()) Block::Omap4_driver(true); } @@ -36,7 +40,7 @@ struct Main Block::Root root; Main(Server::Entrypoint &ep) - : ep(ep), root(ep, Genode::env()->heap(), factory) + : ep(ep), factory(ep), root(ep, Genode::env()->heap(), factory) { Genode::printf("--- OMAP4 SD card driver ---\n"); @@ -54,4 +58,3 @@ namespace Server { size_t stack_size() { return 2*1024*sizeof(long); } void construct(Entrypoint &ep) { static Main server(ep); } } - diff --git a/repos/os/src/drivers/sd_card/omap4/mmchs.h b/repos/os/src/drivers/sd_card/omap4/mmchs.h index 048a23863..37ee68865 100644 --- a/repos/os/src/drivers/sd_card/omap4/mmchs.h +++ b/repos/os/src/drivers/sd_card/omap4/mmchs.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -500,7 +500,9 @@ struct Omap4_hsmmc_controller : private Mmchs, public Sd_card::Host_controller Adma_desc::access_t * const _adma_desc; Genode::addr_t const _adma_desc_phys; - Genode::Irq_connection _irq; + Genode::Irq_connection _irq; + Genode::Signal_receiver _irq_rec; + Genode::Signal_context _irq_ctx; Sd_card::Card_info _init() { @@ -729,7 +731,12 @@ struct Omap4_hsmmc_controller : private Mmchs, public Sd_card::Host_controller * running processes. */ for (;;) { - _irq.wait_for_irq(); + /* + * We ack the IRQ first to implicitly active receiving + * IRQ signals when entering this loop for the first time. + */ + _irq.ack_irq(); + _irq_rec.wait_for_signal(); /* check for transfer completion */ if (read() == 1) { @@ -748,6 +755,7 @@ struct Omap4_hsmmc_controller : private Mmchs, public Sd_card::Host_controller } } + public: enum { IRQ_NUMBER = Genode::Board_base::HSMMC_IRQ }; @@ -768,7 +776,11 @@ struct Omap4_hsmmc_controller : private Mmchs, public Sd_card::Host_controller _adma_desc(_adma_desc_ds.local_addr()), _adma_desc_phys(Genode::Dataspace_client(_adma_desc_ds.cap()).phys_addr()), _irq(IRQ_NUMBER) - { } + { + _irq.sigh(_irq_rec.manage(&_irq_ctx)); + } + + ~Omap4_hsmmc_controller() { _irq_rec.dissolve(&_irq_ctx); } /**************************************** diff --git a/repos/os/src/drivers/timer/hw/platform_timer.h b/repos/os/src/drivers/timer/hw/platform_timer.h old mode 100755 new mode 100644 index a0337475c..e4a4b3e1a --- a/repos/os/src/drivers/timer/hw/platform_timer.h +++ b/repos/os/src/drivers/timer/hw/platform_timer.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -16,6 +16,7 @@ /* Genode includes */ #include +#include /* Local includes */ #include @@ -30,10 +31,13 @@ class Platform_timer : public Platform_timer_base, enum { MAX_TIMER_IRQS_PER_MS = 1 }; - unsigned long const _max_timeout_us; /* maximum timeout in microsecs */ - unsigned long mutable _curr_time_us; /* accumulate already measured timeouts */ - unsigned long mutable _init_value; /* mark last processed timer value */ - Genode::Lock mutable _update_curr_time_lock; /* serialize curr_time access */ + unsigned long const _max_timeout_us; /* maximum timeout in microsecs */ + unsigned long mutable _curr_time_us; /* accumulate already measured timeouts */ + unsigned long mutable _init_value; /* mark last processed timer value */ + Genode::Lock mutable _update_curr_time_lock; /* serialize curr_time access */ + + Genode::Signal_receiver _irq_rec; + Genode::Signal_context _irq_ctx; public: @@ -45,7 +49,12 @@ class Platform_timer : public Platform_timer_base, Irq_connection(Platform_timer_base::IRQ), _max_timeout_us(tics_to_us(max_value())), _curr_time_us(0), _init_value(0) - { } + { + Irq_connection::sigh(_irq_rec.manage(&_irq_ctx)); + Irq_connection::ack_irq(); + } + + ~Platform_timer() { _irq_rec.dissolve(&_irq_ctx); } /** * Refresh and return our instance-own "now"-time in microseconds @@ -109,7 +118,11 @@ class Platform_timer : public Platform_timer_base, /** * Await the lastly scheduled timeout */ - void wait_for_timeout(Genode::Thread_base *) { wait_for_irq(); } + void wait_for_timeout(Genode::Thread_base *) + { + _irq_rec.wait_for_signal(); + Irq_connection::ack_irq(); + } }; #endif /* _OS__SRC__DRIVERS__TIMER__HW__PLATFORM_TIMER_H_ */ diff --git a/repos/os/src/drivers/timer/include/timer_root.h b/repos/os/src/drivers/timer/include/timer_root.h index afc4c1fd0..1ba73139c 100644 --- a/repos/os/src/drivers/timer/include/timer_root.h +++ b/repos/os/src/drivers/timer/include/timer_root.h @@ -14,12 +14,15 @@ #ifndef _TIMER_ROOT_H_ #define _TIMER_ROOT_H_ +/* Genode includes */ #include #include #include #include #include +#include +/* local includes */ #include "timer_session_component.h" @@ -56,12 +59,12 @@ class Timer::Root_component : public Genode::Root_component * The 'cap' argument is not used by the single-threaded server * variant. */ - Root_component(Genode::Rpc_entrypoint *session_ep, - Genode::Allocator *md_alloc, - Genode::Cap_session *cap) + Root_component(Server::Entrypoint &ep, + Genode::Allocator *md_alloc, + Genode::Cap_session *cap) : - Genode::Root_component(session_ep, md_alloc), - _timeout_scheduler(&_platform_timer, session_ep) + Genode::Root_component(&ep.rpc_ep(), md_alloc), + _timeout_scheduler(&_platform_timer, &ep.rpc_ep()) { } }; diff --git a/repos/os/src/drivers/timer/include_periodic/platform_timer.h b/repos/os/src/drivers/timer/include_periodic/platform_timer.h index 36c961a8d..b7b3d2db2 100644 --- a/repos/os/src/drivers/timer/include_periodic/platform_timer.h +++ b/repos/os/src/drivers/timer/include_periodic/platform_timer.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2009-2013 Genode Labs GmbH + * Copyright (C) 2009-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -14,8 +14,9 @@ #ifndef _PLATFORM_TIMER_H_ #define _PLATFORM_TIMER_H_ -/* Genode inludes **/ +/* Genode inludes */ #include +#include class Platform_timer diff --git a/repos/os/src/drivers/timer/include_pit/platform_timer.h b/repos/os/src/drivers/timer/include_pit/platform_timer.h index 98630cb81..ebd5b4c9f 100644 --- a/repos/os/src/drivers/timer/include_pit/platform_timer.h +++ b/repos/os/src/drivers/timer/include_pit/platform_timer.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2009-2013 Genode Labs GmbH + * Copyright (C) 2009-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -14,8 +14,10 @@ #ifndef _PLATFORM_TIMER_H_ #define _PLATFORM_TIMER_H_ +/* Genode includes */ #include #include +#include class Platform_timer { @@ -64,6 +66,8 @@ class Platform_timer unsigned long mutable _curr_time_usec; Genode::uint16_t mutable _counter_init_value; bool mutable _handled_wrap; + Genode::Signal_receiver _irq_rec; + Genode::Signal_context _irq_ctx; /** * Set PIT counter value @@ -111,8 +115,13 @@ class Platform_timer /* operate PIT in one-shot mode */ _io_port.outb(PIT_CMD_PORT, PIT_CMD_SELECT_CHANNEL_0 | PIT_CMD_ACCESS_LO_HI | PIT_CMD_MODE_IRQ); + + _timer_irq.sigh(_irq_rec.manage(&_irq_ctx)); + _timer_irq.ack_irq(); } + ~Platform_timer() { _irq_rec.dissolve(&_irq_ctx); } + /** * Return current time-counter value in microseconds * @@ -188,7 +197,8 @@ class Platform_timer */ void wait_for_timeout(Genode::Thread_base *blocking_thread) { - _timer_irq.wait_for_irq(); + _irq_rec.wait_for_signal(); + _timer_irq.ack_irq(); } }; diff --git a/repos/os/src/drivers/timer/main.cc b/repos/os/src/drivers/timer/main.cc index 777cbc387..87c46e67b 100644 --- a/repos/os/src/drivers/timer/main.cc +++ b/repos/os/src/drivers/timer/main.cc @@ -5,50 +5,52 @@ */ /* - * Copyright (C) 2006-2013 Genode Labs GmbH + * Copyright (C) 2006-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ +/* Genode includes */ #include #include #include #include +#include +/* local includes */ #include "timer_root.h" using namespace Genode; using namespace Timer; -/** - * Main program - */ -int main(int argc, char **argv) +struct Main { - /* - * Initialize server entry point that serves the root interface. - */ - static Cap_connection cap; - static Rpc_entrypoint ep(&cap, STACK_SIZE, "timer_ep"); + Server::Entrypoint &ep; + Sliced_heap sliced_heap; + Timer::Root_component root; - /* - * Use sliced heap to allocate each session component at a separate - * dataspace. - */ - static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session()); + Main(Server::Entrypoint &ep) + : + ep(ep), + sliced_heap(Genode::env()->ram_session(), Genode::env()->rm_session()), + root(ep, &sliced_heap, 0) + { + /* + * Announce timer service at our parent. + */ + env()->parent()->announce(ep.manage(root)); + } +}; - /* - * Create root interface for timer service - */ - static Timer::Root_component timer_root(&ep, &sliced_heap, &cap); - /* - * Announce timer service at our parent. - */ - env()->parent()->announce(ep.manage(&timer_root)); +/************ + ** Server ** + ************/ - sleep_forever(); - return 0; +namespace Server { + char const *name() { return "timer_drv_ep"; } + size_t stack_size() { return 1024*sizeof(long); } + void construct(Entrypoint &ep) { static Main server(ep); } } diff --git a/repos/os/src/drivers/timer/nova/platform_timer.h b/repos/os/src/drivers/timer/nova/platform_timer.h index 1558dcc64..36784b5d3 100644 --- a/repos/os/src/drivers/timer/nova/platform_timer.h +++ b/repos/os/src/drivers/timer/nova/platform_timer.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2014-2014 Genode Labs GmbH + * Copyright (C) 2014-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -14,7 +14,9 @@ #ifndef _PLATFORM_TIMER_H_ #define _PLATFORM_TIMER_H_ +/* Genode includes */ #include +#include #include class Platform_timer diff --git a/repos/os/src/test/gpio_drv/gpio_test.h b/repos/os/src/test/gpio_drv/gpio_test.h index 271567ec2..c9613f3b2 100644 --- a/repos/os/src/test/gpio_drv/gpio_test.h +++ b/repos/os/src/test/gpio_drv/gpio_test.h @@ -6,7 +6,7 @@ /* * Copyright (C) 2012 Ksys Labs LLC - * Copyright (C) 2012-2013 Genode Labs GmbH + * Copyright (C) 2012-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -15,10 +15,12 @@ #ifndef _GPIO_TEST_H_ #define _GPIO_TEST_H_ -#include -#include -#include +/* Genode includes */ #include +#include +#include +#include +#include using namespace Genode; @@ -63,7 +65,6 @@ Gpio_test::Gpio_test() { /* initialize GPIO_121 */ _gpio_button.debouncing(31*100); - _gpio_button.irq_sigh(sig_rec.manage(&sig_ctx)); } @@ -102,35 +103,49 @@ bool Gpio_test::irq_test() { printf("---------- IRQ test ----------\n"); - _gpio_button.irq_type(Gpio::Session::FALLING_EDGE); - _gpio_button.irq_enable(true); + { + Genode::Irq_session_client + irq(_gpio_button.irq_session(Gpio::Session::FALLING_EDGE)); + irq.sigh(sig_rec.manage(&sig_ctx)); + /* + * Before any IRQs will be delivered to us, we have to signalize + * that we are ready to handle them by calling 'ack_irq()'. + */ + irq.ack_irq(); - _gpio_led1.write(true); - _gpio_led2.write(false); + _gpio_led1.write(true); + _gpio_led2.write(false); - printf("\nPush and hold button...\n"); + printf("\nPush and hold button...\n"); - wait_for_signal(); - - _gpio_button.irq_enable(false); + wait_for_signal(); + irq.ack_irq(); + } printf("OK\n"); - _gpio_button.irq_type(Gpio::Session::RISING_EDGE); - _gpio_button.irq_enable(true); + { + Genode::Irq_session_client + irq(_gpio_button.irq_session(Gpio::Session::RISING_EDGE)); + irq.sigh(sig_rec.manage(&sig_ctx)); - _gpio_led1.write(false); - _gpio_led2.write(true); + _gpio_led1.write(false); + _gpio_led2.write(true); - printf("\nRelease button...\n"); + printf("\nRelease button...\n"); - wait_for_signal(); - - _gpio_button.irq_enable(false); + wait_for_signal(); + irq.ack_irq(); + } printf("OK\n"); - _gpio_button.irq_type(Gpio::Session::HIGH_LEVEL); + { + Genode::Irq_session_client + irq(_gpio_button.irq_session(Gpio::Session::HIGH_LEVEL)); + irq.sigh(sig_rec.manage(&sig_ctx)); + } + return true; }