parent
6dd9d349fc
commit
a58bc84d3e
|
@ -18,6 +18,7 @@
|
||||||
#include <regulator/consts.h>
|
#include <regulator/consts.h>
|
||||||
#include <regulator_session/connection.h>
|
#include <regulator_session/connection.h>
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
|
#include <irq_session/connection.h>
|
||||||
#include <util/mmio.h>
|
#include <util/mmio.h>
|
||||||
|
|
||||||
/* Emulation */
|
/* Emulation */
|
||||||
|
@ -363,3 +364,15 @@ void platform_hcd_init(Services *services)
|
||||||
if (services->xhci)
|
if (services->xhci)
|
||||||
xhci_setup(services);
|
xhci_setup(services);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Genode::Irq_session_capability platform_irq_activate(int irq)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Genode::Irq_connection conn(irq);
|
||||||
|
conn.on_destruction(Genode::Irq_connection::KEEP_OPEN);
|
||||||
|
return conn;
|
||||||
|
} catch (...) { }
|
||||||
|
|
||||||
|
return Genode::Irq_session_capability();
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <drivers/board_base.h>
|
#include <drivers/board_base.h>
|
||||||
#include <gpio_session/connection.h>
|
#include <gpio_session/connection.h>
|
||||||
#include <io_mem_session/connection.h>
|
#include <io_mem_session/connection.h>
|
||||||
|
#include <irq_session/connection.h>
|
||||||
#include <util/mmio.h>
|
#include <util/mmio.h>
|
||||||
|
|
||||||
#include <extern_c_begin.h>
|
#include <extern_c_begin.h>
|
||||||
|
@ -320,3 +321,14 @@ void platform_hcd_init(Services *services)
|
||||||
platform_device_register(pdev);
|
platform_device_register(pdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Genode::Irq_session_capability platform_irq_activate(int irq)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Genode::Irq_connection conn(irq);
|
||||||
|
conn.on_destruction(Genode::Irq_connection::KEEP_OPEN);
|
||||||
|
return conn;
|
||||||
|
} catch (...) { }
|
||||||
|
|
||||||
|
return Genode::Irq_session_capability();
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <io_mem_session/connection.h>
|
#include <io_mem_session/connection.h>
|
||||||
|
#include <irq_session/connection.h>
|
||||||
#include <util/mmio.h>
|
#include <util/mmio.h>
|
||||||
#include <platform_session/connection.h>
|
#include <platform_session/connection.h>
|
||||||
|
|
||||||
|
@ -228,3 +229,15 @@ void platform_hcd_init(Services *services)
|
||||||
|
|
||||||
platform_device_register(pdev);
|
platform_device_register(pdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Genode::Irq_session_capability platform_irq_activate(int irq)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Genode::Irq_connection conn(irq);
|
||||||
|
conn.on_destruction(Genode::Irq_connection::KEEP_OPEN);
|
||||||
|
return conn;
|
||||||
|
} catch (...) { }
|
||||||
|
|
||||||
|
return Genode::Irq_session_capability();
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#include <base/printf.h>
|
#include <base/printf.h>
|
||||||
#include <os/config.h>
|
#include <os/config.h>
|
||||||
#include <util/xml_node.h>
|
#include <util/xml_node.h>
|
||||||
|
#include <os/signal_rpc_dispatcher.h>
|
||||||
|
#include <irq_session/capability.h>
|
||||||
|
|
||||||
struct Services
|
struct Services
|
||||||
{
|
{
|
||||||
|
@ -111,5 +113,6 @@ struct Services
|
||||||
};
|
};
|
||||||
|
|
||||||
void platform_hcd_init(Services *services);
|
void platform_hcd_init(Services *services);
|
||||||
|
Genode::Irq_session_capability platform_irq_activate(int irq);
|
||||||
|
|
||||||
#endif /* _PLATFORM_H_ */
|
#endif /* _PLATFORM_H_ */
|
||||||
|
|
|
@ -11,9 +11,13 @@
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode inludes */
|
/* Genode base includes */
|
||||||
#include <ram_session/client.h>
|
#include <ram_session/client.h>
|
||||||
#include <base/object_pool.h>
|
#include <base/object_pool.h>
|
||||||
|
#include <irq_session/connection.h>
|
||||||
|
|
||||||
|
/* Genode os includes */
|
||||||
|
#include <os/server.h>
|
||||||
#include <pci_session/connection.h>
|
#include <pci_session/connection.h>
|
||||||
#include <pci_device/client.h>
|
#include <pci_device/client.h>
|
||||||
|
|
||||||
|
@ -29,7 +33,7 @@ struct bus_type pci_bus_type;
|
||||||
/**
|
/**
|
||||||
* Scan PCI bus and probe for HCDs
|
* Scan PCI bus and probe for HCDs
|
||||||
*/
|
*/
|
||||||
class Pci_driver
|
class Pci_driver : public Genode::List<Pci_driver>::Element
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -53,9 +57,12 @@ class Pci_driver
|
||||||
{
|
{
|
||||||
using namespace Pci;
|
using namespace Pci;
|
||||||
|
|
||||||
_dev = new (Genode::env()->heap()) pci_dev;
|
|
||||||
Device_client client(_cap);
|
Device_client client(_cap);
|
||||||
|
uint8_t bus, dev, func;
|
||||||
|
client.bus_address(&bus, &dev, &func);
|
||||||
|
|
||||||
|
_dev = new (Genode::env()->heap()) pci_dev;
|
||||||
|
_dev->devfn = ((uint16_t)bus << 8) | (0xff & PCI_DEVFN(dev, func));
|
||||||
_dev->vendor = client.vendor_id();
|
_dev->vendor = client.vendor_id();
|
||||||
_dev->device = client.device_id();
|
_dev->device = client.device_id();
|
||||||
_dev->class_ = client.class_code();
|
_dev->class_ = client.class_code();
|
||||||
|
@ -105,6 +112,8 @@ class Pci_driver
|
||||||
/* enable bus master */
|
/* enable bus master */
|
||||||
cmd |= 0x4;
|
cmd |= 0x4;
|
||||||
client.config_write(CMD, cmd, Device::ACCESS_16BIT);
|
client.config_write(CMD, cmd, Device::ACCESS_16BIT);
|
||||||
|
|
||||||
|
_drivers().insert(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -135,6 +144,12 @@ class Pci_driver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Genode::List<Pci_driver> & _drivers()
|
||||||
|
{
|
||||||
|
static Genode::List<Pci_driver> _list;
|
||||||
|
return _list;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Pci_driver(pci_driver *drv, Pci::Device_capability cap,
|
Pci_driver(pci_driver *drv, Pci::Device_capability cap,
|
||||||
|
@ -157,6 +172,8 @@ class Pci_driver
|
||||||
dde_kit_release_io(r->start, (r->end - r->start) + 1);
|
dde_kit_release_io(r->start, (r->end - r->start) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_drivers().remove(this);
|
||||||
|
|
||||||
destroy(Genode::env()->heap(), _dev);
|
destroy(Genode::env()->heap(), _dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,8 +193,20 @@ class Pci_driver
|
||||||
Pci::Device_client client(_cap);
|
Pci::Device_client client(_cap);
|
||||||
client.config_write(devfn, val, _access_size(val));
|
client.config_write(devfn, val, _access_size(val));
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
static Genode::Irq_session_capability irq_cap(unsigned irq)
|
||||||
|
{
|
||||||
|
for (Pci_driver *d = _drivers().first(); d; d = d->next()) {
|
||||||
|
if (d->_dev && d->_dev->irq != irq)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Pci::Device_client client(d->_cap);
|
||||||
|
return client.irq(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Genode::Irq_session_capability();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/********************************
|
/********************************
|
||||||
** Backend memory definitions **
|
** Backend memory definitions **
|
||||||
|
@ -401,3 +430,13 @@ void Backend_memory::free(Genode::Ram_dataspace_capability cap)
|
||||||
memory_pool.remove_locked(o);
|
memory_pool.remove_locked(o);
|
||||||
destroy(env()->heap(), o);
|
destroy(env()->heap(), o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************
|
||||||
|
** Platform specific irq cap discovery **
|
||||||
|
*****************************************/
|
||||||
|
|
||||||
|
Genode::Irq_session_capability platform_irq_activate(int irq)
|
||||||
|
{
|
||||||
|
return Pci_driver::irq_cap(irq);
|
||||||
|
}
|
||||||
|
|
|
@ -12,19 +12,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <irq_session/client.h>
|
||||||
|
|
||||||
#include <extern_c_begin.h>
|
#include <extern_c_begin.h>
|
||||||
#include <lx_emul.h>
|
#include <lx_emul.h>
|
||||||
#include <extern_c_end.h>
|
#include <extern_c_end.h>
|
||||||
|
|
||||||
extern "C" {
|
#include <platform.h>
|
||||||
#include <dde_kit/interrupt.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#include<timer_session/connection.h>
|
|
||||||
/* our local incarnation of sender and receiver */
|
/* our local incarnation of sender and receiver */
|
||||||
static Signal_helper *_signal = 0;
|
static Signal_helper *_signal = 0;
|
||||||
static Genode::Lock _irq_sync(Genode::Lock::LOCKED);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This contains the Linux-driver handlers
|
* This contains the Linux-driver handlers
|
||||||
|
@ -52,6 +50,8 @@ class Irq_context : public Genode::List<Irq_context>::Element
|
||||||
unsigned int _irq; /* IRQ number */
|
unsigned int _irq; /* IRQ number */
|
||||||
Genode::List<Irq_handler> _handler_list; /* List of registered handlers */
|
Genode::List<Irq_handler> _handler_list; /* List of registered handlers */
|
||||||
Genode::Signal_rpc_member<Irq_context> _dispatcher;
|
Genode::Signal_rpc_member<Irq_context> _dispatcher;
|
||||||
|
Genode::Irq_session_capability _irq_cap;
|
||||||
|
Genode::Irq_session_client _irq_client;
|
||||||
|
|
||||||
static Genode::List<Irq_context> *_list()
|
static Genode::List<Irq_context> *_list()
|
||||||
{
|
{
|
||||||
|
@ -72,26 +72,6 @@ class Irq_context : public Genode::List<Irq_context>::Element
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called by the DDE kit upon IRQ */
|
|
||||||
static void _dde_handler(void *irq)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Make sure there is only one interrupt handled at a time, since dde_kit
|
|
||||||
* will use one thread per IRQ
|
|
||||||
*/
|
|
||||||
static Genode::Lock handler_lock;
|
|
||||||
Genode::Lock::Guard guard(handler_lock);
|
|
||||||
|
|
||||||
Irq_context *ctx = static_cast<Irq_context *>(irq);
|
|
||||||
|
|
||||||
/* set context & submit signal */
|
|
||||||
_signal->sender().context(ctx->_dispatcher);
|
|
||||||
_signal->sender().submit();
|
|
||||||
|
|
||||||
/* wait for interrupt to get acked at device side */
|
|
||||||
_irq_sync.lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call one IRQ handler
|
* Call one IRQ handler
|
||||||
*/
|
*/
|
||||||
|
@ -129,8 +109,8 @@ class Irq_context : public Genode::List<Irq_context>::Element
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* interrupt should be acked at device now */
|
/* ack interrupt */
|
||||||
_irq_sync.unlock();
|
_irq_client.ack_irq();
|
||||||
|
|
||||||
if (handled)
|
if (handled)
|
||||||
Routine::schedule_all();
|
Routine::schedule_all();
|
||||||
|
@ -144,14 +124,18 @@ class Irq_context : public Genode::List<Irq_context>::Element
|
||||||
|
|
||||||
Irq_context(unsigned int irq)
|
Irq_context(unsigned int irq)
|
||||||
: _irq(irq),
|
: _irq(irq),
|
||||||
_dispatcher(_signal->ep(), *this, &Irq_context::_handle)
|
_dispatcher(_signal->ep(), *this, &Irq_context::_handle),
|
||||||
|
_irq_cap(platform_irq_activate(_irq)),
|
||||||
|
_irq_client(_irq_cap)
|
||||||
{
|
{
|
||||||
/* register at DDE (shared) */
|
if (!_irq_cap.valid()) {
|
||||||
int ret = dde_kit_interrupt_attach(_irq, 0, 0, _dde_handler, this);
|
PERR("Interrupt %d attach failed", irq);
|
||||||
if (ret)
|
return;
|
||||||
PERR("Interrupt attach return %d for IRQ %u", ret, irq);
|
}
|
||||||
|
|
||||||
|
_irq_client.sigh(_dispatcher);
|
||||||
|
_irq_client.ack_irq();
|
||||||
|
|
||||||
dde_kit_interrupt_enable(_irq);
|
|
||||||
_list()->insert(this);
|
_list()->insert(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue