mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-22 02:16:44 +00:00
os: use async IRQ and server lib in drivers
Use the new asynchronous IRQ interface in the mostly used drivers, e.g.: * ahci_drv: x86/exynos5 * gpio_drv: imx53/omap4 * input_drv: imx53/dummy * ps2_drv: x86/pl050 * timer_drv Now, the Irq_session is requested from Gpio::Session: From now on we use an asynchronous IRQ interface. To prevent triggering another GPIO IRQ while currently handling the former one, IRQs must now by acknowledged explicitly. While here, we also changed the GPIO session interface regarding IRQ management. The generic GPIO component now wraps the Irq_session managed by the backend instead of using the GPIO backend methods directly. A client using the GPIO session may request the Irq_session_capability by calling 'Gpio::Session::irq_session()' and can use this capability when using a local Irq_session_client. Issue #1456.
This commit is contained in:
parent
bfb47cfd4e
commit
85599c072f
@ -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<Gpio::Session>
|
||||
{
|
||||
private:
|
||||
|
||||
struct Irq_session_component : public Genode::Rpc_object<Genode::Irq_session>
|
||||
{
|
||||
Driver &_driver;
|
||||
unsigned long _pin;
|
||||
Genode::Signal_context_capability _sigh;
|
||||
|
||||
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<Gpio::Session>
|
||||
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,6 +112,7 @@ class Gpio::Root : public Genode::Root_component<Gpio::Session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Rpc_entrypoint &_ep;
|
||||
Driver &_driver;
|
||||
|
||||
protected:
|
||||
@ -114,7 +133,7 @@ class Gpio::Root : public Genode::Root_component<Gpio::Session_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<Gpio::Session_component>
|
||||
Root(Genode::Rpc_entrypoint *session_ep,
|
||||
Genode::Allocator *md_alloc, Driver &driver)
|
||||
: Genode::Root_component<Gpio::Session_component>(session_ep, md_alloc),
|
||||
_driver(driver) { }
|
||||
_ep(*session_ep), _driver(driver) { }
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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.
|
||||
@ -31,11 +31,9 @@ struct Gpio::Session_client : Genode::Rpc_client<Session>
|
||||
void write(bool level) override { call<Rpc_write>(level); }
|
||||
bool read() override { return call<Rpc_read>(); }
|
||||
void debouncing(unsigned int us) override { call<Rpc_debouncing>(us); }
|
||||
void irq_type(Irq_type it) override { call<Rpc_irq_type>(it); }
|
||||
void irq_enable(bool enable) override { call<Rpc_irq_enable>(enable); }
|
||||
|
||||
void irq_sigh(Genode::Signal_context_capability cap) override {
|
||||
call<Rpc_irq_sigh>(cap); }
|
||||
Genode::Irq_session_capability irq_session(Irq_type type) override {
|
||||
return call<Rpc_irq_session>(type); }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__GPIO_SESSION_H__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.
|
||||
@ -19,6 +19,7 @@
|
||||
#include <base/signal.h>
|
||||
#include <dataspace/capability.h>
|
||||
#include <session/session.h>
|
||||
#include <irq_session/capability.h>
|
||||
|
||||
namespace Gpio { struct Session; }
|
||||
|
||||
@ -62,25 +63,11 @@ 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;
|
||||
|
||||
|
||||
/*******************
|
||||
@ -91,13 +78,11 @@ struct Gpio::Session : Genode::Session
|
||||
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_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_ */
|
||||
|
@ -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
|
||||
|
@ -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<P0ci>(1 << tag);
|
||||
p0_irq.wait_for_irq();
|
||||
p0_irq_rec.wait_for_signal();
|
||||
if (!read<Is::Ips>()) {
|
||||
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<Is::Ips>(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<Is::Ips>(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<Is::Ips>(1);
|
||||
p0_irq.ack_irq();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1668,7 +1676,7 @@ struct Sata_ahci : Attached_mmio
|
||||
/* issue command and wait for completion */
|
||||
write<P0sact>(1 << tag);
|
||||
write<P0ci>(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<Is::Ips>(1);
|
||||
p0_irq.ack_irq();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -114,6 +114,18 @@ class I2c_interface : public Attached_mmio
|
||||
};
|
||||
|
||||
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>(con);
|
||||
Stat::Busy::set(stat, 1);
|
||||
write<Stat>(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>(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<Con::Irq_pending>(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<Ds>();
|
||||
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<Fp_3d::Value>(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<Phy_con_0::Pwr_off>(0);
|
||||
if (i2c_hdmi()->stop_hdmi_phy()) return -1;
|
||||
if (_i2c_hdmi.stop_hdmi_phy()) return -1;
|
||||
write<Phy_rstout::Reset>(1);
|
||||
delayer()->usleep(10000);
|
||||
write<Phy_rstout::Reset>(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<Core_rstout::Reset>(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;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
#include <base/printf.h>
|
||||
#include <os/server.h>
|
||||
|
||||
namespace Framebuffer
|
||||
{
|
||||
|
@ -11,9 +11,6 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* local includes */
|
||||
#include <driver.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <framebuffer_session/framebuffer_session.h>
|
||||
#include <cap_session/connection.h>
|
||||
@ -22,6 +19,10 @@
|
||||
#include <base/sleep.h>
|
||||
#include <os/config.h>
|
||||
#include <os/static_root.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include <driver.h>
|
||||
|
||||
namespace Framebuffer
|
||||
{
|
||||
@ -111,10 +112,13 @@ class Framebuffer::Session_component
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Program entrypoint
|
||||
*/
|
||||
int main(int, char **)
|
||||
struct Main
|
||||
{
|
||||
Server::Entrypoint &ep;
|
||||
Framebuffer::Driver driver;
|
||||
|
||||
Main(Server::Entrypoint &ep)
|
||||
: ep(ep), driver()
|
||||
{
|
||||
using namespace Framebuffer;
|
||||
|
||||
@ -125,7 +129,7 @@ int main(int, char **)
|
||||
|
||||
/* try to read custom user config */
|
||||
try {
|
||||
char out[5] = { };
|
||||
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);
|
||||
@ -137,21 +141,23 @@ int main(int, char **)
|
||||
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<Framebuffer::Session> fb_root(ep.manage(&fb_session));
|
||||
static Static_root<Framebuffer::Session> fb_root(ep.manage(fb_session));
|
||||
|
||||
/* announce service and relax */
|
||||
env()->parent()->announce(ep.manage(&fb_root));
|
||||
sleep_forever();
|
||||
return 0;
|
||||
env()->parent()->announce(ep.manage(fb_root));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
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); }
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <gpio/driver.h>
|
||||
#include <irq_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* 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<Gpio_reg::Int_stat>();
|
||||
|
||||
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;
|
||||
Genode::Signal_rpc_member<Irq_handler> _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<Gpio_reg::Int_stat>(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>(Gpio_reg::Int_conf::LOW_LEVEL, j);
|
||||
regs->write<Gpio_reg::Int_mask>(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<Gpio_reg::Dir>(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<Gpio_reg::Data>(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_reg::Pad_stat>(_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>(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>(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>(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>(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<Gpio_reg::Int_stat>();
|
||||
|
||||
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<Gpio_reg::Int_stat>(0xffffffff);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _DRIVER_H_ */
|
||||
|
@ -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 <cap_session/connection.h>
|
||||
#include <gpio/component.h>
|
||||
#include <gpio/config.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include <driver.h>
|
||||
|
||||
|
||||
int main(int, char **)
|
||||
struct Main
|
||||
{
|
||||
Server::Entrypoint &ep;
|
||||
Genode::Sliced_heap sliced_heap;
|
||||
Imx53_driver &driver;
|
||||
Gpio::Root root;
|
||||
|
||||
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;
|
||||
|
||||
printf("--- i.MX53 gpio driver ---\n");
|
||||
|
||||
Imx53_driver &driver = Imx53_driver::factory();
|
||||
Gpio::process_config(driver);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* Announce service
|
||||
*/
|
||||
env()->parent()->announce(ep.manage(&gpio_root));
|
||||
|
||||
Genode::sleep_forever();
|
||||
return 0;
|
||||
env()->parent()->announce(ep.manage(root));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
** 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); }
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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_rpc_member<Gpio_bank> _dispatcher;
|
||||
Genode::Signal_context_capability _sig_cap[MAX_PINS];
|
||||
bool _irq_enabled[MAX_PINS];
|
||||
|
||||
public:
|
||||
|
||||
Gpio_bank(Genode::addr_t base, Genode::size_t size,
|
||||
unsigned irq)
|
||||
: Genode::Thread<4096>("irq handler"),
|
||||
_reg(base, size), _irq(irq)
|
||||
void _handle(unsigned)
|
||||
{
|
||||
for (unsigned i = 0; i < MAX_PINS; i++)
|
||||
_irq_enabled[i] = false;
|
||||
start();
|
||||
}
|
||||
|
||||
void entry()
|
||||
{
|
||||
unsigned long status;
|
||||
|
||||
while (true) {
|
||||
_reg.write<Gpio_reg::Irqstatus_0>(0xffffffff);
|
||||
|
||||
_irq.wait_for_irq();
|
||||
|
||||
status = _reg.read<Gpio_reg::Irqstatus_0>();
|
||||
unsigned long status = _reg.read<Gpio_reg::Irqstatus_0>();
|
||||
|
||||
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(Server::Entrypoint &ep,
|
||||
Genode::addr_t base, Genode::size_t size,
|
||||
unsigned irq)
|
||||
: _reg(base, size), _irq(irq),
|
||||
_dispatcher(ep, *this, &Gpio_bank::_handle)
|
||||
{
|
||||
for (unsigned i = 0; i < MAX_PINS; i++)
|
||||
_irq_enabled[i] = false;
|
||||
|
||||
_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<Gpio_reg::Ctrl>());
|
||||
i+1, _gpio_bank(i << PIN_SHIFT)->regs()->read<Gpio_reg::Ctrl>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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<Gpio_reg::Oe>(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<Gpio_reg::Setdataout>(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_reg::Datain>(_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<Gpio_reg::Debounceenable>(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<Gpio_reg::Debouncingtime::Time>(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<Gpio_reg::Leveldetect0> (0, _gpio_index(gpio));
|
||||
gpio_reg->write<Gpio_reg::Leveldetect1> (0, _gpio_index(gpio));
|
||||
gpio_reg->write<Gpio_reg::Fallingdetect>(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<Gpio_reg::Leveldetect0> (0, _gpio_index(gpio));
|
||||
gpio_reg->write<Gpio_reg::Leveldetect1> (0, _gpio_index(gpio));
|
||||
gpio_reg->write<Gpio_reg::Fallingdetect>(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<Gpio_reg::Leveldetect0> (0, _gpio_index(gpio));
|
||||
gpio_reg->write<Gpio_reg::Leveldetect1> (1, _gpio_index(gpio));
|
||||
gpio_reg->write<Gpio_reg::Fallingdetect>(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<Gpio_reg::Leveldetect0> (1, _gpio_index(gpio));
|
||||
gpio_reg->write<Gpio_reg::Leveldetect1> (0, _gpio_index(gpio));
|
||||
gpio_reg->write<Gpio_reg::Fallingdetect>(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;
|
||||
}
|
||||
|
||||
|
@ -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 <cap_session/connection.h>
|
||||
#include <gpio/component.h>
|
||||
#include <gpio/config.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include <driver.h>
|
||||
|
||||
|
||||
int main(int, char **)
|
||||
struct Main
|
||||
{
|
||||
Server::Entrypoint &ep;
|
||||
Genode::Sliced_heap sliced_heap;
|
||||
Omap4_driver &driver;
|
||||
Gpio::Root root;
|
||||
|
||||
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;
|
||||
|
||||
printf("--- omap4 gpio driver ---\n");
|
||||
|
||||
Omap4_driver &driver = Omap4_driver::factory();
|
||||
Gpio::process_config(driver);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* Announce service
|
||||
*/
|
||||
env()->parent()->announce(ep.manage(&gpio_root));
|
||||
|
||||
Genode::sleep_forever();
|
||||
return 0;
|
||||
env()->parent()->announce(ep.manage(root));
|
||||
}
|
||||
};
|
||||
|
||||
/************
|
||||
** 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); }
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 <input_session/input_session.h>
|
||||
#include <input/event.h>
|
||||
#include <base/printf.h>
|
||||
#include <os/server.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
@ -71,28 +72,33 @@ namespace Input {
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
struct Main
|
||||
{
|
||||
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");
|
||||
return 1;
|
||||
throw Genode::Exception();
|
||||
}
|
||||
|
||||
/* 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());
|
||||
|
||||
/* tell parent about the service */
|
||||
env()->parent()->announce(ep.manage(&input_root));
|
||||
|
||||
/* main's done - go to sleep */
|
||||
|
||||
sleep_forever();
|
||||
return 0;
|
||||
env()->parent()->announce(ep.manage(root));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
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); }
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = dummy_input_drv
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
LIBS = base server
|
||||
|
@ -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 <base/env.h>
|
||||
#include <base/thread.h>
|
||||
#include <base/signal.h>
|
||||
#include <gpio_session/connection.h>
|
||||
|
||||
@ -29,7 +28,7 @@ namespace Input {
|
||||
}
|
||||
|
||||
|
||||
class Input::Tablet_driver : Genode::Thread<8192>
|
||||
class Input::Tablet_driver
|
||||
{
|
||||
private:
|
||||
|
||||
@ -41,66 +40,63 @@ class Input::Tablet_driver : Genode::Thread<8192>
|
||||
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;
|
||||
Genode::Irq_session_client _irq_ts;
|
||||
Genode::Irq_session_client _irq_bt;
|
||||
Genode::Signal_rpc_member<Tablet_driver> _ts_dispatcher;
|
||||
Genode::Signal_rpc_member<Tablet_driver> _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);
|
||||
_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;
|
||||
_touchscreen.event(_ev_queue);
|
||||
_irq_ts.ack_irq();
|
||||
}
|
||||
|
||||
Genode::Signal_context_capability _init_bt_gpio()
|
||||
void _handle_bt(unsigned)
|
||||
{
|
||||
Genode::Signal_context_capability ret = _receiver.manage(&_bt_rx);
|
||||
_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;
|
||||
_buttons.event(_ev_queue);
|
||||
_irq_bt.ack_irq();
|
||||
}
|
||||
|
||||
Tablet_driver(Event_queue &ev_queue)
|
||||
: Thread("touchscreen_signal_handler"),
|
||||
Tablet_driver(Server::Entrypoint &ep, Event_queue &ev_queue)
|
||||
:
|
||||
_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_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);
|
||||
|
||||
_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);
|
||||
|
||||
_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;
|
||||
}
|
||||
|
||||
|
@ -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,10 +44,13 @@ class Input::Touchscreen {
|
||||
|
||||
public:
|
||||
|
||||
Touchscreen() : _i2c_ds(Genode::Board_base::I2C_3_BASE,
|
||||
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<void>(),
|
||||
Genode::Board_base::I2C_3_IRQ),
|
||||
_irq_handler),
|
||||
_state(RELEASED)
|
||||
{
|
||||
/* ask for touchscreen firmware version */
|
||||
|
@ -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 <util/mmio.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <irq_session/connection.h>
|
||||
|
||||
/* 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;
|
||||
Irq_handler &_irq_handler;
|
||||
|
||||
void _busy() { while (!read<Status::Busy>()); }
|
||||
|
||||
@ -101,15 +102,19 @@ class I2c::I2c : Genode::Mmio
|
||||
{
|
||||
write<Data>(value);
|
||||
|
||||
_irq.wait_for_irq();
|
||||
if (!read<Status::Irq>()) throw No_irq();
|
||||
do { _irq_handler.wait(); }
|
||||
while (!read<Status::Irq>());
|
||||
|
||||
write<Status::Irq>(0);
|
||||
if (read<Status::Rcv_ack>()) 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<Control>(0);
|
||||
write<Status>(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<Status::Irq>()) throw No_irq();
|
||||
do { _irq_handler.wait(); }
|
||||
while (!read<Status::Irq>());
|
||||
|
||||
write<Status::Irq>(0);
|
||||
|
||||
if (i == num-1) {
|
||||
@ -167,8 +171,7 @@ class I2c::I2c : Genode::Mmio
|
||||
|
||||
_stop();
|
||||
return;
|
||||
} catch(No_irq) {
|
||||
}
|
||||
} catch(No_ack) { }
|
||||
_stop();
|
||||
}
|
||||
}
|
||||
|
48
repos/os/src/drivers/input/imx53/irq_handler.h
Normal file
48
repos/os/src/drivers/input/imx53/irq_handler.h
Normal file
@ -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 <irq_session/connection.h>
|
||||
#include <os/server.h>
|
||||
|
||||
class Irq_handler
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Irq_connection _irq;
|
||||
Genode::Signal_receiver _sig_rec;
|
||||
Genode::Signal_dispatcher<Irq_handler> _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_ */
|
@ -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 <input/component.h>
|
||||
#include <input/root.h>
|
||||
#include <base/printf.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include <driver.h>
|
||||
|
||||
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;
|
||||
|
||||
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(session.event_queue());
|
||||
Input::Tablet_driver::factory(ep, session.event_queue());
|
||||
break;
|
||||
default:
|
||||
PWRN("No input driver available for this board");
|
||||
}
|
||||
|
||||
/* entry point serving input root interface */
|
||||
static Input::Root_component root(ep, session);
|
||||
|
||||
/* tell parent about the service */
|
||||
env()->parent()->announce(ep.manage(&root));
|
||||
|
||||
/* main's done - go to sleep */
|
||||
sleep_forever();
|
||||
return 0;
|
||||
env()->parent()->announce(ep.manage(root));
|
||||
}
|
||||
};
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
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); }
|
||||
}
|
||||
|
@ -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<void>(),
|
||||
Genode::Board_base::I2C_2_IRQ),
|
||||
_irq_handler),
|
||||
_state(0)
|
||||
{
|
||||
static Genode::uint8_t init_cmd[][2] = {
|
||||
|
@ -1,5 +1,5 @@
|
||||
TARGET = input_drv
|
||||
REQUIRES = imx53
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
LIBS = base server
|
||||
INC_DIR += $(PRG_DIR)
|
@ -14,37 +14,43 @@
|
||||
#ifndef _IRQ_HANDLER_H_
|
||||
#define _IRQ_HANDLER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <irq_session/connection.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include "input_driver.h"
|
||||
|
||||
class Irq_handler : Genode::Thread<4096>
|
||||
class Irq_handler
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Irq_connection _irq;
|
||||
Genode::Signal_rpc_member<Irq_handler> _dispatcher;
|
||||
Input_driver &_input_driver;
|
||||
|
||||
public:
|
||||
|
||||
Irq_handler(int irq_number, Input_driver &input_driver)
|
||||
:
|
||||
Thread("irq_handler"),
|
||||
_irq(irq_number),
|
||||
_input_driver(input_driver)
|
||||
void _handle(unsigned)
|
||||
{
|
||||
start();
|
||||
}
|
||||
_irq.ack_irq();
|
||||
|
||||
void entry()
|
||||
{
|
||||
while (1) {
|
||||
_irq.wait_for_irq();
|
||||
while (_input_driver.event_pending())
|
||||
_input_driver.handle_event();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Irq_handler(Server::Entrypoint &ep,
|
||||
int irq_number, Input_driver &input_driver)
|
||||
:
|
||||
_irq(irq_number),
|
||||
_dispatcher(ep, *this, &Irq_handler::_handle),
|
||||
_input_driver(input_driver)
|
||||
{
|
||||
_irq.sigh(_dispatcher);
|
||||
_irq.ack_irq();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif /* _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,36 +15,25 @@
|
||||
#define _IRQ_HANDLER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <irq_session/connection.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include "input_driver.h"
|
||||
#include "serial_interface.h"
|
||||
|
||||
class Irq_handler : Genode::Thread<4096>
|
||||
class Irq_handler
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Irq_connection _irq;
|
||||
Genode::Signal_rpc_member<Irq_handler> _dispatcher;
|
||||
Serial_interface *_channel;
|
||||
Input_driver &_input_driver;
|
||||
|
||||
public:
|
||||
|
||||
Irq_handler(int irq_number, Serial_interface *channel, Input_driver &input_driver)
|
||||
:
|
||||
Thread("irq_handler"),
|
||||
_irq(irq_number),
|
||||
_channel(channel),
|
||||
_input_driver(input_driver)
|
||||
void _handle(unsigned)
|
||||
{
|
||||
start();
|
||||
}
|
||||
|
||||
void entry()
|
||||
{
|
||||
while (1) {
|
||||
_irq.ack_irq();
|
||||
|
||||
#ifdef __CODEZERO__
|
||||
/*
|
||||
@ -57,10 +46,21 @@ class Irq_handler : Genode::Thread<4096>
|
||||
/* 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();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Irq_handler(Server::Entrypoint &ep,
|
||||
int irq_number, Serial_interface *channel,
|
||||
Input_driver &input_driver)
|
||||
:
|
||||
_irq(irq_number),
|
||||
_dispatcher(ep, *this, &Irq_handler::_handle),
|
||||
_channel(channel),
|
||||
_input_driver(input_driver)
|
||||
{
|
||||
_irq.sigh(_dispatcher);
|
||||
_irq.ack_irq();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <input/component.h>
|
||||
#include <input/root.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include "ps2_keyboard.h"
|
||||
@ -28,34 +29,38 @@
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
struct Main
|
||||
{
|
||||
Server::Entrypoint &ep;
|
||||
|
||||
Pl050 pl050;
|
||||
Input::Session_component session;
|
||||
Input::Root_component root;
|
||||
|
||||
Serial_interface *kbd = pl050.kbd_interface();
|
||||
Serial_interface *aux = pl050.aux_interface();
|
||||
Ps2_mouse ps2_mouse;
|
||||
Ps2_keyboard ps2_keybd;
|
||||
|
||||
/*
|
||||
* Initialize server entry point
|
||||
*/
|
||||
enum { STACK_SIZE = 4096 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "ps2_ep");
|
||||
Irq_handler ps2_mouse_irq;
|
||||
Irq_handler ps2_keybd_irq;
|
||||
|
||||
static Input::Session_component session;
|
||||
static Input::Root_component root(ep, session);
|
||||
|
||||
Ps2_mouse ps2_mouse(*aux, session.event_queue());
|
||||
Ps2_keyboard ps2_keybd(*kbd, session.event_queue(), true);
|
||||
|
||||
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));
|
||||
|
||||
Genode::sleep_forever();
|
||||
return 0;
|
||||
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));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
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); }
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
TARGET = ps2_drv
|
||||
REQUIRES = pl050
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
LIBS = base server
|
||||
|
||||
INC_DIR += $(PRG_DIR) $(PRG_DIR)/..
|
||||
|
@ -11,13 +11,16 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <input/component.h>
|
||||
#include <input/root.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* 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
|
||||
{
|
||||
Server::Entrypoint &ep;
|
||||
|
||||
I8042 i8042;
|
||||
Input::Session_component session;
|
||||
Input::Root_component root;
|
||||
|
||||
Serial_interface *kbd = i8042.kbd_interface();
|
||||
Serial_interface *aux = i8042.aux_interface();
|
||||
Ps2_mouse ps2_mouse;
|
||||
Ps2_keyboard ps2_keybd;
|
||||
|
||||
/*
|
||||
* Initialize server entry point
|
||||
*/
|
||||
enum { STACK_SIZE = 4096 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "ps2_ep");
|
||||
Irq_handler ps2_mouse_irq;
|
||||
Irq_handler ps2_keybd_irq;
|
||||
|
||||
static Input::Session_component session;
|
||||
static Input::Root_component root(ep, session);
|
||||
|
||||
Ps2_mouse ps2_mouse(*aux, session.event_queue());
|
||||
Ps2_keyboard ps2_keybd(*kbd, session.event_queue(), i8042.kbd_xlate());
|
||||
|
||||
Irq_handler ps2_mouse_irq(12, ps2_mouse);
|
||||
Irq_handler ps2_keybd_irq( 1, ps2_keybd);
|
||||
|
||||
env()->parent()->announce(ep.manage(&root));
|
||||
|
||||
Genode::sleep_forever();
|
||||
return 0;
|
||||
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));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
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); }
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
TARGET = ps2_drv
|
||||
REQUIRES = x86 ps2
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
LIBS = base server
|
||||
|
||||
INC_DIR = $(PRG_DIR)/..
|
||||
|
@ -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 <base/printf.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <block/component.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include <dwmmc.h>
|
||||
@ -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<void>(),
|
||||
_controller(ep, (addr_t)_mmio.local_addr<void>(),
|
||||
_delayer, use_dma),
|
||||
_use_dma(use_dma)
|
||||
{
|
||||
|
@ -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.
|
||||
@ -319,6 +319,8 @@ struct Exynos5_msh_controller : private Dwmmc, Sd_card::Host_controller
|
||||
Sd_card::Card_info _card_info;
|
||||
|
||||
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<Rintsts::Data_transfer_over>()) {
|
||||
write<Rintsts>(~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)
|
||||
{
|
||||
|
@ -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");
|
||||
|
@ -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 <base/printf.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <os/attached_ram_dataspace.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include <driver.h>
|
||||
@ -86,7 +87,9 @@ static void run_benchmark(Block::Driver &driver,
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
struct Main
|
||||
{
|
||||
Main(Server::Entrypoint &ep)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
@ -161,6 +164,16 @@ int main(int argc, char **argv)
|
||||
request_sizes[i], write_operation);
|
||||
|
||||
printf("\n--- i.MX53 SD card benchmark finished ---\n");
|
||||
sleep_forever();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
** 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); }
|
||||
}
|
||||
|
@ -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)/../..
|
||||
|
@ -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 <timer_session/connection.h>
|
||||
#include <block/component.h>
|
||||
#include <drivers/board_base.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include <esdhcv2.h>
|
||||
|
@ -415,6 +415,8 @@ struct Esdhcv2_controller : private Esdhcv2, public Sd_card::Host_controller
|
||||
};
|
||||
|
||||
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;
|
||||
@ -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>() != 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<Irqstat>();
|
||||
|
||||
/*
|
||||
@ -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); }
|
||||
|
||||
|
||||
/****************************************
|
||||
|
@ -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); }
|
||||
}
|
||||
|
||||
|
@ -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,7 +77,9 @@ static void run_benchmark(Block::Driver &driver,
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
struct Main
|
||||
{
|
||||
Main(Server::Entrypoint &ep)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
@ -151,6 +153,16 @@ int main(int argc, char **argv)
|
||||
request_sizes[i], write_operation);
|
||||
|
||||
printf("\n--- OMAP4 SD card benchmark finished ---\n");
|
||||
sleep_forever();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
** 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); }
|
||||
}
|
||||
|
@ -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)/../..
|
||||
|
@ -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 <base/printf.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <block/component.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include <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.
|
||||
@ -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); }
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
@ -501,6 +501,8 @@ struct Omap4_hsmmc_controller : private Mmchs, public Sd_card::Host_controller
|
||||
Genode::addr_t const _adma_desc_phys;
|
||||
|
||||
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<Stat::Tc>() == 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::access_t>()),
|
||||
_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); }
|
||||
|
||||
|
||||
/****************************************
|
||||
|
19
repos/os/src/drivers/timer/hw/platform_timer.h
Executable file → Normal file
19
repos/os/src/drivers/timer/hw/platform_timer.h
Executable file → Normal file
@ -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 <irq_session/connection.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* Local includes */
|
||||
#include <platform_timer_base.h>
|
||||
@ -35,6 +36,9 @@ class Platform_timer : public Platform_timer_base,
|
||||
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_ */
|
||||
|
@ -14,12 +14,15 @@
|
||||
#ifndef _TIMER_ROOT_H_
|
||||
#define _TIMER_ROOT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/arg_string.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/heap.h>
|
||||
#include <root/component.h>
|
||||
#include <cap_session/cap_session.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include "timer_session_component.h"
|
||||
|
||||
|
||||
@ -56,12 +59,12 @@ class Timer::Root_component : public Genode::Root_component<Session_component>
|
||||
* The 'cap' argument is not used by the single-threaded server
|
||||
* variant.
|
||||
*/
|
||||
Root_component(Genode::Rpc_entrypoint *session_ep,
|
||||
Root_component(Server::Entrypoint &ep,
|
||||
Genode::Allocator *md_alloc,
|
||||
Genode::Cap_session *cap)
|
||||
:
|
||||
Genode::Root_component<Session_component>(session_ep, md_alloc),
|
||||
_timeout_scheduler(&_platform_timer, session_ep)
|
||||
Genode::Root_component<Session_component>(&ep.rpc_ep(), md_alloc),
|
||||
_timeout_scheduler(&_platform_timer, &ep.rpc_ep())
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -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 <base/thread.h>
|
||||
#include <os/server.h>
|
||||
|
||||
|
||||
class Platform_timer
|
||||
|
@ -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 <io_port_session/connection.h>
|
||||
#include <irq_session/connection.h>
|
||||
#include <os/server.h>
|
||||
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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 <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/heap.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* 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");
|
||||
|
||||
/*
|
||||
* Use sliced heap to allocate each session component at a separate
|
||||
* dataspace.
|
||||
*/
|
||||
static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session());
|
||||
|
||||
/*
|
||||
* Create root interface for timer service
|
||||
*/
|
||||
static Timer::Root_component timer_root(&ep, &sliced_heap, &cap);
|
||||
Server::Entrypoint &ep;
|
||||
Sliced_heap sliced_heap;
|
||||
Timer::Root_component root;
|
||||
|
||||
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(&timer_root));
|
||||
|
||||
sleep_forever();
|
||||
return 0;
|
||||
env()->parent()->announce(ep.manage(root));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
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); }
|
||||
}
|
||||
|
@ -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 <os/attached_rom_dataspace.h>
|
||||
#include <os/server.h>
|
||||
#include <trace/timestamp.h>
|
||||
|
||||
class Platform_timer
|
||||
|
@ -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 <gpio_session/connection.h>
|
||||
#include <base/signal.h>
|
||||
#include <util/mmio.h>
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <base/signal.h>
|
||||
#include <gpio_session/connection.h>
|
||||
#include <irq_session/client.h>
|
||||
#include <util/mmio.h>
|
||||
|
||||
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,8 +103,15 @@ 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);
|
||||
@ -111,13 +119,15 @@ bool Gpio_test::irq_test()
|
||||
printf("\nPush and hold button...\n");
|
||||
|
||||
wait_for_signal();
|
||||
|
||||
_gpio_button.irq_enable(false);
|
||||
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);
|
||||
@ -125,12 +135,17 @@ bool Gpio_test::irq_test()
|
||||
printf("\nRelease button...\n");
|
||||
|
||||
wait_for_signal();
|
||||
|
||||
_gpio_button.irq_enable(false);
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user