mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-11 05:12:05 +00:00
parent
6dd9d349fc
commit
a58bc84d3e
@ -18,6 +18,7 @@
|
||||
#include <regulator/consts.h>
|
||||
#include <regulator_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <irq_session/connection.h>
|
||||
#include <util/mmio.h>
|
||||
|
||||
/* Emulation */
|
||||
@ -363,3 +364,15 @@ void platform_hcd_init(Services *services)
|
||||
if (services->xhci)
|
||||
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 <gpio_session/connection.h>
|
||||
#include <io_mem_session/connection.h>
|
||||
#include <irq_session/connection.h>
|
||||
#include <util/mmio.h>
|
||||
|
||||
#include <extern_c_begin.h>
|
||||
@ -320,3 +321,14 @@ void platform_hcd_init(Services *services)
|
||||
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 */
|
||||
#include <io_mem_session/connection.h>
|
||||
#include <irq_session/connection.h>
|
||||
#include <util/mmio.h>
|
||||
#include <platform_session/connection.h>
|
||||
|
||||
@ -228,3 +229,15 @@ void platform_hcd_init(Services *services)
|
||||
|
||||
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 <os/config.h>
|
||||
#include <util/xml_node.h>
|
||||
#include <os/signal_rpc_dispatcher.h>
|
||||
#include <irq_session/capability.h>
|
||||
|
||||
struct Services
|
||||
{
|
||||
@ -111,5 +113,6 @@ struct Services
|
||||
};
|
||||
|
||||
void platform_hcd_init(Services *services);
|
||||
Genode::Irq_session_capability platform_irq_activate(int irq);
|
||||
|
||||
#endif /* _PLATFORM_H_ */
|
||||
|
@ -11,9 +11,13 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode inludes */
|
||||
/* Genode base includes */
|
||||
#include <ram_session/client.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_device/client.h>
|
||||
|
||||
@ -29,7 +33,7 @@ struct bus_type pci_bus_type;
|
||||
/**
|
||||
* Scan PCI bus and probe for HCDs
|
||||
*/
|
||||
class Pci_driver
|
||||
class Pci_driver : public Genode::List<Pci_driver>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
@ -53,9 +57,12 @@ class Pci_driver
|
||||
{
|
||||
using namespace Pci;
|
||||
|
||||
_dev = new (Genode::env()->heap()) pci_dev;
|
||||
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->device = client.device_id();
|
||||
_dev->class_ = client.class_code();
|
||||
@ -105,6 +112,8 @@ class Pci_driver
|
||||
/* enable bus master */
|
||||
cmd |= 0x4;
|
||||
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:
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
_drivers().remove(this);
|
||||
|
||||
destroy(Genode::env()->heap(), _dev);
|
||||
}
|
||||
|
||||
@ -176,8 +193,20 @@ class Pci_driver
|
||||
Pci::Device_client client(_cap);
|
||||
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 **
|
||||
@ -401,3 +430,13 @@ void Backend_memory::free(Genode::Ram_dataspace_capability cap)
|
||||
memory_pool.remove_locked(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 <irq_session/client.h>
|
||||
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <extern_c_end.h>
|
||||
|
||||
extern "C" {
|
||||
#include <dde_kit/interrupt.h>
|
||||
}
|
||||
#include <platform.h>
|
||||
|
||||
|
||||
#include<timer_session/connection.h>
|
||||
/* our local incarnation of sender and receiver */
|
||||
static Signal_helper *_signal = 0;
|
||||
static Genode::Lock _irq_sync(Genode::Lock::LOCKED);
|
||||
|
||||
/**
|
||||
* This contains the Linux-driver handlers
|
||||
@ -52,6 +50,8 @@ class Irq_context : public Genode::List<Irq_context>::Element
|
||||
unsigned int _irq; /* IRQ number */
|
||||
Genode::List<Irq_handler> _handler_list; /* List of registered handlers */
|
||||
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()
|
||||
{
|
||||
@ -72,26 +72,6 @@ class Irq_context : public Genode::List<Irq_context>::Element
|
||||
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
|
||||
*/
|
||||
@ -129,8 +109,8 @@ class Irq_context : public Genode::List<Irq_context>::Element
|
||||
break;
|
||||
}
|
||||
|
||||
/* interrupt should be acked at device now */
|
||||
_irq_sync.unlock();
|
||||
/* ack interrupt */
|
||||
_irq_client.ack_irq();
|
||||
|
||||
if (handled)
|
||||
Routine::schedule_all();
|
||||
@ -144,14 +124,18 @@ class Irq_context : public Genode::List<Irq_context>::Element
|
||||
|
||||
Irq_context(unsigned int 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) */
|
||||
int ret = dde_kit_interrupt_attach(_irq, 0, 0, _dde_handler, this);
|
||||
if (ret)
|
||||
PERR("Interrupt attach return %d for IRQ %u", ret, irq);
|
||||
if (!_irq_cap.valid()) {
|
||||
PERR("Interrupt %d attach failed", irq);
|
||||
return;
|
||||
}
|
||||
|
||||
_irq_client.sigh(_dispatcher);
|
||||
_irq_client.ack_irq();
|
||||
|
||||
dde_kit_interrupt_enable(_irq);
|
||||
_list()->insert(this);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user