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; }