diff --git a/repos/base-codezero/src/core/irq_session_component.cc b/repos/base-codezero/src/core/irq_session_component.cc
index 326076e2f..30b892ff3 100644
--- a/repos/base-codezero/src/core/irq_session_component.cc
+++ b/repos/base-codezero/src/core/irq_session_component.cc
@@ -13,7 +13,6 @@
/* Genode includes */
#include
-#include
/* core includes */
#include
@@ -22,128 +21,109 @@
#include
-namespace Genode {
- typedef Irq_proxy > Irq_proxy_base;
- class Irq_proxy_component;
-}
-
using namespace Genode;
-/**
- * Platform-specific proxy code
- */
-class Genode::Irq_proxy_component : public Irq_proxy_base
+bool Irq_object::_associate() { return true; }
+
+
+void Irq_object::_wait_for_irq()
{
- private:
+ using namespace Codezero;
- bool _irq_attached;
-
- protected:
-
- bool _associate() { return true; }
-
- void _wait_for_irq()
- {
- using namespace Codezero;
-
- /* attach thread to IRQ when first called */
- if (!_irq_attached) {
- int ret = l4_irq_control(IRQ_CONTROL_REGISTER, 0, _irq_number);
- if (ret < 0) {
- PERR("l4_irq_control(IRQ_CONTROL_REGISTER) returned %d", ret);
- sleep_forever();
- }
- _irq_attached = true;
- }
-
- /* block for IRQ */
- int ret = l4_irq_control(IRQ_CONTROL_WAIT, 0, _irq_number);
- if (ret < 0)
- PWRN("l4_irq_control(IRQ_CONTROL_WAIT) returned %d", ret);
- }
-
- void _ack_irq() { }
-
- public:
-
- Irq_proxy_component(long irq_number)
- :
- Irq_proxy(irq_number),
- _irq_attached(false)
- {
- _start();
- }
-};
+ /* block for IRQ */
+ int ret = l4_irq_control(IRQ_CONTROL_WAIT, 0, _irq);
+ if (ret < 0)
+ PWRN("l4_irq_control(IRQ_CONTROL_WAIT) returned %d", ret);
+}
-/***************************
- ** IRQ session component **
- ***************************/
-
-
-void Irq_session_component::ack_irq()
+void Irq_object::start()
{
- if (!_proxy) {
- PERR("Expected to find IRQ proxy for IRQ %02x", _irq_number);
+ ::Thread_base::start();
+ _sync_bootup.lock();
+}
+
+
+void Irq_object::entry()
+{
+ if (!_associate()) {
+ PERR("Could not associate with IRQ 0x%x", _irq);
return;
}
- _proxy->ack_irq();
+ /* thread is up and ready */
+ _sync_bootup.unlock();
+
+ /* wait for first ack_irq */
+ _sync_ack.lock();
+
+ using namespace Codezero;
+
+ /* attach thread to IRQ when first called */
+ int ret = l4_irq_control(IRQ_CONTROL_REGISTER, 0, _irq);
+ if (ret < 0) {
+ PERR("l4_irq_control(IRQ_CONTROL_REGISTER) returned %d", ret);
+ return;
+ }
+
+ while (true) {
+
+ _wait_for_irq();
+
+ if (!_sig_cap.valid())
+ continue;
+
+ Genode::Signal_transmitter(_sig_cap).submit(1);
+
+ _sync_ack.lock();
+ }
}
+Irq_object::Irq_object(unsigned irq)
+:
+ Thread<4096>("irq"),
+ _sync_ack(Lock::LOCKED), _sync_bootup(Lock::LOCKED),
+ _irq(irq)
+{ }
+
+
Irq_session_component::Irq_session_component(Range_allocator *irq_alloc,
const char *args)
:
- _irq_alloc(irq_alloc)
+ _irq_number(Arg_string::find_arg(args, "irq_number").long_value(-1)),
+ _irq_alloc(irq_alloc),
+ _irq_object(_irq_number)
{
- long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
- if (irq_number == -1) {
- PERR("invalid IRQ number requested");
- throw Root::Unavailable();
- }
-
long msi = Arg_string::find_arg(args, "device_config_phys").long_value(0);
if (msi)
throw Root::Unavailable();
- /* check if IRQ thread was started before */
- _proxy = Irq_proxy_component::get_irq_proxy(irq_number, irq_alloc);
- if (!_proxy) {
- PERR("unavailable IRQ %lx requested", irq_number);
+ if (!irq_alloc || irq_alloc->alloc_addr(1, _irq_number).is_error()) {
+ PERR("Unavailable IRQ 0x%x requested", _irq_number);
throw Root::Unavailable();
}
- _irq_number = irq_number;
+ _irq_object.start();
}
Irq_session_component::~Irq_session_component()
{
- if (!_proxy) return;
-
- if (_irq_sigh.valid())
- _proxy->remove_sharer(&_irq_sigh);
+ PERR("Not yet implemented.");
}
-void Irq_session_component::sigh(Genode::Signal_context_capability sigh)
+void Irq_session_component::ack_irq()
{
- if (!_proxy) {
- PERR("signal handler got not registered - irq thread unavailable");
- return;
- }
+ _irq_object.ack_irq();
+}
- Genode::Signal_context_capability old = _irq_sigh;
- if (old.valid() && !sigh.valid())
- _proxy->remove_sharer(&_irq_sigh);
-
- _irq_sigh = sigh;
-
- if (!old.valid() && sigh.valid())
- _proxy->add_sharer(&_irq_sigh);
+void Irq_session_component::sigh(Genode::Signal_context_capability cap)
+{
+ _irq_object.sigh(cap);
}
diff --git a/repos/base-fiasco/src/core/irq_session_component.cc b/repos/base-fiasco/src/core/irq_session_component.cc
index 0578f6b00..cce0929ad 100644
--- a/repos/base-fiasco/src/core/irq_session_component.cc
+++ b/repos/base-fiasco/src/core/irq_session_component.cc
@@ -2,12 +2,10 @@
* \brief Core implementation of IRQ sessions
* \author Christian Helmuth
* \date 2007-09-13
- *
- * FIXME ram quota missing
*/
/*
- * 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.
@@ -18,7 +16,6 @@
#include
/* core includes */
-#include
#include
#include
@@ -29,155 +26,136 @@ namespace Fiasco {
#include
}
-namespace Genode {
- typedef Irq_proxy > Irq_proxy_base;
- class Irq_proxy_component;
+using namespace Genode;
+
+bool Irq_object::_associate()
+{
+ using namespace Fiasco;
+
+ int err;
+ l4_threadid_t irq_tid;
+ l4_umword_t dw0, dw1;
+ l4_msgdope_t result;
+
+ l4_make_taskid_from_irq(_irq, &irq_tid);
+
+ /* boost thread to IRQ priority */
+ enum { IRQ_PRIORITY = 0xC0 };
+
+ l4_sched_param_t param = {sp:{prio:IRQ_PRIORITY, small:0, state:0, time_exp:0, time_man:0}};
+ l4_threadid_t ext_preempter = L4_INVALID_ID;
+ l4_threadid_t partner = L4_INVALID_ID;
+ l4_sched_param_t old_param;
+ l4_thread_schedule(l4_myself(), param, &ext_preempter, &partner, &old_param);
+
+ err = l4_ipc_receive(irq_tid,
+ L4_IPC_SHORT_MSG, &dw0, &dw1,
+ L4_IPC_BOTH_TIMEOUT_0, &result);
+
+ if (err != L4_IPC_RETIMEOUT) PERR("IRQ association failed");
+
+ return (err == L4_IPC_RETIMEOUT);
}
-using namespace Genode;
-
-
-/**
- * Platform-specific proxy code
- */
-
-class Genode::Irq_proxy_component : public Irq_proxy_base
+void Irq_object::_wait_for_irq()
{
- protected:
+ using namespace Fiasco;
- bool _associate()
- {
- using namespace Fiasco;
+ l4_threadid_t irq_tid;
+ l4_umword_t dw0=0, dw1=0;
+ l4_msgdope_t result;
- int err;
- l4_threadid_t irq_tid;
- l4_umword_t dw0, dw1;
- l4_msgdope_t result;
+ l4_make_taskid_from_irq(_irq, &irq_tid);
- l4_make_taskid_from_irq(_irq_number, &irq_tid);
+ do {
+ l4_ipc_call(irq_tid,
+ L4_IPC_SHORT_MSG, 0, 0,
+ L4_IPC_SHORT_MSG, &dw0, &dw1,
+ L4_IPC_NEVER, &result);
- /* boost thread to IRQ priority */
- enum { IRQ_PRIORITY = 0xC0 };
-
- l4_sched_param_t param = {sp:{prio:IRQ_PRIORITY, small:0, state:0,
- time_exp:0, time_man:0}};
- l4_threadid_t ext_preempter = L4_INVALID_ID;
- l4_threadid_t partner = L4_INVALID_ID;
- l4_sched_param_t old_param;
- l4_thread_schedule(l4_myself(), param, &ext_preempter, &partner,
- &old_param);
-
- err = l4_ipc_receive(irq_tid,
- L4_IPC_SHORT_MSG, &dw0, &dw1,
- L4_IPC_BOTH_TIMEOUT_0, &result);
-
- if (err != L4_IPC_RETIMEOUT) PERR("IRQ association failed");
-
- return (err == L4_IPC_RETIMEOUT);
- }
-
- void _wait_for_irq()
- {
- using namespace Fiasco;
-
- l4_threadid_t irq_tid;
- l4_umword_t dw0=0, dw1=0;
- l4_msgdope_t result;
-
- l4_make_taskid_from_irq(_irq_number, &irq_tid);
-
- do {
- l4_ipc_call(irq_tid,
- L4_IPC_SHORT_MSG, 0, 0,
- L4_IPC_SHORT_MSG, &dw0, &dw1,
- L4_IPC_NEVER, &result);
-
- if (L4_IPC_IS_ERROR(result))
- PERR("Ipc error %lx", L4_IPC_ERROR(result));
- } while (L4_IPC_IS_ERROR(result));
- }
-
- void _ack_irq() { }
-
- public:
-
- Irq_proxy_component(long irq_number)
- :
- Irq_proxy(irq_number)
- {
- _start();
- }
-};
+ if (L4_IPC_IS_ERROR(result)) PERR("Ipc error %lx", L4_IPC_ERROR(result));
+ } while (L4_IPC_IS_ERROR(result));
+}
-/***************************
- ** IRQ session component **
- ***************************/
-
-
-void Irq_session_component::ack_irq()
+void Irq_object::start()
{
- if (!_proxy) {
- PERR("Expected to find IRQ proxy for IRQ %02x", _irq_number);
+ ::Thread_base::start();
+ _sync_bootup.lock();
+}
+
+
+void Irq_object::entry()
+{
+ if (!_associate()) {
+ PERR("Could not associate with IRQ 0x%x", _irq);
return;
}
- _proxy->ack_irq();
+ /* thread is up and ready */
+ _sync_bootup.unlock();
+
+ /* wait for first ack_irq */
+ _sync_ack.lock();
+
+ while (true) {
+
+ _wait_for_irq();
+
+ if (!_sig_cap.valid())
+ continue;
+
+ Genode::Signal_transmitter(_sig_cap).submit(1);
+
+ _sync_ack.lock();
+ }
}
+Irq_object::Irq_object(unsigned irq)
+:
+ Thread<4096>("irq"),
+ _sync_ack(Lock::LOCKED), _sync_bootup(Lock::LOCKED),
+ _irq(irq)
+{ }
+
+
Irq_session_component::Irq_session_component(Range_allocator *irq_alloc,
const char *args)
:
- _irq_alloc(irq_alloc)
+ _irq_number(Arg_string::find_arg(args, "irq_number").long_value(-1)),
+ _irq_alloc(irq_alloc),
+ _irq_object(_irq_number)
{
- long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
- if (irq_number == -1) {
- PERR("invalid IRQ number requested");
- throw Root::Unavailable();
- }
-
long msi = Arg_string::find_arg(args, "device_config_phys").long_value(0);
if (msi)
throw Root::Unavailable();
- /* check if IRQ thread was started before */
- _proxy = Irq_proxy_component::get_irq_proxy(irq_number, irq_alloc);
- if (!_proxy) {
- PERR("unavailable IRQ %lx requested", irq_number);
+ if (!irq_alloc || irq_alloc->alloc_addr(1, _irq_number).is_error()) {
+ PERR("Unavailable IRQ 0x%x requested", _irq_number);
throw Root::Unavailable();
}
- _irq_number = irq_number;
+ _irq_object.start();
}
Irq_session_component::~Irq_session_component()
{
- if (!_proxy) return;
-
- if (_irq_sigh.valid())
- _proxy->remove_sharer(&_irq_sigh);
+ PERR("Not yet implemented.");
}
-void Irq_session_component::sigh(Genode::Signal_context_capability sigh)
+void Irq_session_component::ack_irq()
{
- if (!_proxy) {
- PERR("signal handler got not registered - irq thread unavailable");
- return;
- }
+ _irq_object.ack_irq();
+}
- Genode::Signal_context_capability old = _irq_sigh;
- if (old.valid() && !sigh.valid())
- _proxy->remove_sharer(&_irq_sigh);
-
- _irq_sigh = sigh;
-
- if (!old.valid() && sigh.valid())
- _proxy->add_sharer(&_irq_sigh);
+void Irq_session_component::sigh(Genode::Signal_context_capability cap)
+{
+ _irq_object.sigh(cap);
}
diff --git a/repos/base-foc/src/core/include/irq_object.h b/repos/base-foc/src/core/include/irq_object.h
new file mode 100644
index 000000000..774539159
--- /dev/null
+++ b/repos/base-foc/src/core/include/irq_object.h
@@ -0,0 +1,59 @@
+/*
+ * \brief Fiasco.OC-specific core implementation of IRQ sessions
+ * \author Christian Helmuth
+ * \author Stefan Kalkowski
+ * \author Sebastian Sumpf
+ * \date 2007-09-13
+ */
+
+/*
+ * 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.
+ */
+
+#pragma once
+
+/* Genode includes */
+#include
+#include
+#include
+
+namespace Genode { class Irq_object; }
+
+
+class Genode::Irq_object
+{
+ private:
+
+ Cap_index *_cap;
+ Irq_session::Trigger _trigger; /* interrupt trigger */
+ Irq_session::Polarity _polarity; /* interrupt polarity */
+
+ unsigned _irq;
+ Genode::addr_t _msi_addr;
+ Genode::addr_t _msi_data;
+
+ Signal_context_capability _sig_cap;
+
+ Native_thread _capability() const { return _cap->kcap(); }
+
+ public:
+
+ Irq_object();
+ ~Irq_object();
+
+ Irq_session::Trigger trigger() const { return _trigger; }
+ Irq_session::Polarity polarity() const { return _polarity; }
+
+ Genode::addr_t msi_address() const { return _msi_addr; }
+ Genode::addr_t msi_value() const { return _msi_data; }
+
+ void sigh(Genode::Signal_context_capability cap) { _sig_cap = cap; }
+ void notify() { Genode::Signal_transmitter(_sig_cap).submit(1); }
+
+ bool associate(unsigned irq, bool msi, Irq_session::Trigger,
+ Irq_session::Polarity);
+ void ack_irq();
+};
diff --git a/repos/base-foc/src/core/irq_session_component.cc b/repos/base-foc/src/core/irq_session_component.cc
index 111954385..bd016bd38 100644
--- a/repos/base-foc/src/core/irq_session_component.cc
+++ b/repos/base-foc/src/core/irq_session_component.cc
@@ -4,12 +4,10 @@
* \author Stefan Kalkowski
* \author Sebastian Sumpf
* \date 2007-09-13
- *
- * FIXME ram quota missing
*/
/*
- * 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.
@@ -18,6 +16,7 @@
/* Genode includes */
#include
#include
+#include
/* core includes */
#include
@@ -33,14 +32,14 @@ namespace Fiasco {
#include
}
-using namespace Genode;
-
namespace Genode {
class Interrupt_handler;
- class Irq_proxy_component;
- typedef Irq_proxy > Irq_proxy_base;
}
+
+using namespace Genode;
+
+
/**
* Dispatches interrupts from kernel
*/
@@ -59,126 +58,121 @@ class Genode::Interrupt_handler : public Thread<4096>
static Interrupt_handler handler;
return handler._thread_cap.dst();
}
+
};
-/**
- * Irq_proxy interface implementation
- */
-class Genode::Irq_proxy_component : public Irq_proxy_base
+enum { MAX_MSIS = 256 };
+static class Msi_allocator : public Genode::Bit_array
{
- private:
-
- Cap_index *_cap;
- Semaphore _sem;
- Irq_session::Trigger _trigger; /* interrupt trigger */
- Irq_session::Polarity _polarity; /* interrupt polarity */
-
- bool _running;
- Genode::addr_t _msi_addr;
- Genode::addr_t _msi_data;
-
- Native_thread _capability() const { return _cap->kcap(); }
-
- protected:
-
- bool _associate()
- {
- using namespace Fiasco;
- if (l4_error(l4_factory_create_irq(L4_BASE_FACTORY_CAP,
- _capability()))) {
- PERR("l4_factory_create_irq failed!");
- return false;
- }
-
- unsigned long gsi = _irq_number;
- if (_msi_addr)
- gsi |= L4_ICU_FLAG_MSI;
-
- if (l4_error(l4_icu_bind(L4_BASE_ICU_CAP, gsi, _capability()))) {
- PERR("Binding IRQ%ld to the ICU failed", _irq_number);
- return false;
- }
-
- if (!_msi_addr)
- /* set interrupt mode */
- Platform::setup_irq_mode(gsi, _trigger, _polarity);
-
- if (l4_error(l4_irq_attach(_capability(), _irq_number,
- Interrupt_handler::handler_cap()))) {
- PERR("Error attaching to IRQ %ld", _irq_number);
- return false;
- }
-
- if (_msi_addr && l4_error(l4_icu_msi_info(L4_BASE_ICU_CAP, gsi,
- &_msi_data))) {
- PERR("Error getting MSI info");
- return false;
- }
-
- return true;
- }
-
- void _wait_for_irq()
- {
- using namespace Fiasco;
-
- int err;
- l4_msgtag_t tag = l4_irq_unmask(_capability());
- if ((err = l4_ipc_error(tag, l4_utcb())))
- PERR("IRQ unmask: %d\n", err);
-
- _sem.down();
- }
-
- void _ack_irq() { }
-
public:
- Irq_proxy_component(long irq_number)
- :
- Irq_proxy_base(irq_number),
- _cap(cap_map()->insert(platform_specific()->cap_id_alloc()->alloc())),
- _sem(), _trigger(Irq_session::TRIGGER_UNCHANGED),
- _polarity(Irq_session::POLARITY_UNCHANGED),
- _running(false), _msi_addr(0), _msi_data(0)
- { }
+ Msi_allocator() {
+ using namespace Fiasco;
- Semaphore *semaphore() { return &_sem; }
+ l4_icu_info_t info { .features = 0 };
+ l4_msgtag_t res = l4_icu_info(Fiasco::L4_BASE_ICU_CAP, &info);
- Irq_session::Trigger trigger() const { return _trigger; }
- Irq_session::Polarity polarity() const { return _polarity; }
-
- void setup_irq_mode(Irq_session::Trigger t, Irq_session::Polarity p)
- {
- _trigger = t;
- _polarity = p;
-
- /* set interrupt mode */
- Platform::setup_irq_mode(_irq_number, _trigger, _polarity);
+ if (l4_error(res) || !(info.features & L4_ICU_FLAG_MSI))
+ set(0, MAX_MSIS);
+ else
+ if (info.nr_msis < MAX_MSIS)
+ set(info.nr_msis, MAX_MSIS - info.nr_msis);
}
+} msi_alloc;
- Genode::addr_t msi_address() const { return _msi_addr; }
- Genode::addr_t msi_value() const { return _msi_data; }
+bool Genode::Irq_object::associate(unsigned irq, bool msi,
+ Irq_session::Trigger trigger,
+ Irq_session::Polarity polarity)
+{
+ if (msi)
+ /*
+ * Local APIC address, See Intel x86 Spec - Section MSI 10.11.
+ *
+ * XXX local Apic ID encoding missing - address is constructed
+ * assuming that local APIC id of boot CPU is 0 XXX
+ */
+ _msi_addr = 0xfee00000UL;
- void enable(bool msi)
- {
- if (_running)
- return;
+ _irq = irq;
+ _trigger = trigger;
+ _polarity = polarity;
- if (msi)
- /*
- * Local APIC address, See Intel x86 Spec - Section MSI 10.11.
- *
- * XXX local Apic ID encoding missing - address is constructed
- * assuming that local APIC id of boot CPU is 0 XXX
- */
- _msi_addr = 0xfee00000UL;
+ using namespace Fiasco;
+ if (l4_error(l4_factory_create_irq(L4_BASE_FACTORY_CAP,
+ _capability()))) {
+ PERR("l4_factory_create_irq failed!");
+ return false;
+ }
- _running = true;
- _start();
- }
-};
+ unsigned long gsi = _irq;
+ if (_msi_addr)
+ gsi |= L4_ICU_FLAG_MSI;
+
+ if (l4_error(l4_icu_bind(L4_BASE_ICU_CAP, gsi, _capability()))) {
+ PERR("Binding IRQ %u to the ICU failed", _irq);
+ return false;
+ }
+
+ if (!_msi_addr)
+ /* set interrupt mode */
+ Platform::setup_irq_mode(gsi, _trigger, _polarity);
+
+ if (l4_error(l4_irq_attach(_capability(), reinterpret_cast(this),
+ Interrupt_handler::handler_cap()))) {
+ PERR("Error attaching to IRQ %u", _irq);
+ return false;
+ }
+
+ if (_msi_addr && l4_error(l4_icu_msi_info(L4_BASE_ICU_CAP, gsi,
+ &_msi_data))) {
+ PERR("Error getting MSI info");
+ return false;
+ }
+
+ return true;
+}
+
+
+void Genode::Irq_object::ack_irq()
+{
+ using namespace Fiasco;
+
+ int err;
+ l4_msgtag_t tag = l4_irq_unmask(_capability());
+ if ((err = l4_ipc_error(tag, l4_utcb())))
+ PERR("IRQ unmask: %d\n", err);
+}
+
+
+Genode::Irq_object::Irq_object()
+:
+ _cap(cap_map()->insert(platform_specific()->cap_id_alloc()->alloc())),
+ _trigger(Irq_session::TRIGGER_UNCHANGED),
+ _polarity(Irq_session::POLARITY_UNCHANGED),
+ _irq(~0U), _msi_addr(0), _msi_data(0)
+{ }
+
+
+Genode::Irq_object::~Irq_object()
+{
+ if (_irq == ~0U)
+ return;
+
+ using namespace Fiasco;
+
+ unsigned long gsi = _irq;
+ if (_msi_addr)
+ gsi |= L4_ICU_FLAG_MSI;
+
+ if (l4_error(l4_irq_detach(_capability())))
+ PERR("Error detaching IRQ");
+
+ if (l4_error(l4_icu_unbind(L4_BASE_ICU_CAP, gsi, _capability())))
+ PERR("Error unbinding IRQ");
+
+ cap_map()->remove(_cap);
+}
/***************************
@@ -186,26 +180,28 @@ class Genode::Irq_proxy_component : public Irq_proxy_base
***************************/
-void Irq_session_component::ack_irq()
-{
- if (!_proxy) {
- PERR("Expected to find IRQ proxy for IRQ %02x", _irq_number);
- return;
- }
-
- _proxy->ack_irq();
-}
-
-
Irq_session_component::Irq_session_component(Range_allocator *irq_alloc,
const char *args)
+:
+ _irq_number(~0U), _irq_alloc(irq_alloc)
{
long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
- if (irq_number < 0) {
- PERR("invalid IRQ number requested %ld", irq_number);
- throw Root::Unavailable();
+ long msi = Arg_string::find_arg(args, "device_config_phys").long_value(0);
+ if (msi) {
+ if (msi_alloc.get(irq_number, 1)) {
+ PERR("Unavailable MSI %ld requested.", irq_number);
+ throw Root::Unavailable();
+ }
+ msi_alloc.set(irq_number, 1);
+ } else {
+ if (!irq_alloc || irq_alloc->alloc_addr(1, irq_number).is_error()) {
+ PERR("Unavailable IRQ %ld requested.", irq_number);
+ throw Root::Unavailable();
+ }
}
+ _irq_number = irq_number;
+
long irq_t = Arg_string::find_arg(args, "irq_trigger").long_value(-1);
long irq_p = Arg_string::find_arg(args, "irq_polarity").long_value(-1);
@@ -242,114 +238,49 @@ Irq_session_component::Irq_session_component(Range_allocator *irq_alloc,
throw Root::Unavailable();
}
- long msi = Arg_string::find_arg(args, "device_config_phys").long_value(0);
- if (msi) {
- using namespace Fiasco;
-
- l4_icu_info_t info { .features = 0 };
- l4_msgtag_t res = l4_icu_info(Fiasco::L4_BASE_ICU_CAP, &info);
- if (l4_error(res) || !(info.features & L4_ICU_FLAG_MSI))
- throw Root::Unavailable();
-
- /**
- * irq_alloc range [0, max)
- *
- * legacy irq [0, max_legacy)
- * msi [max_legacy, info.nr_msis)
- * unused [info.nr_msis, max)
- *
- * max - is currently set to 256 in base-foc platform.cc
- * max_legacy - is info.nr_irqs, defined by hardware/kernel
- */
- irq_number = info.nr_msis - 1 - irq_number;
- }
-
- /* check if IRQ thread was started before */
- _proxy = Irq_proxy_component::get_irq_proxy(irq_number, irq_alloc);
- if (!_proxy) {
- PERR("unavailable IRQ %lx requested", irq_number);
- throw Root::Unavailable();
- }
-
- bool setup = false;
- bool fail = false;
- /* sanity check */
- if (irq_trigger != TRIGGER_UNCHANGED && _proxy->trigger() != irq_trigger) {
- if (_proxy->trigger() == TRIGGER_UNCHANGED)
- setup = true;
- else
- fail = true;
- }
-
- if (irq_polarity != POLARITY_UNCHANGED && _proxy->polarity() != irq_polarity) {
- if (_proxy->polarity() == POLARITY_UNCHANGED)
- setup = true;
- else
- fail = true;
- }
-
- if (fail) {
- PERR("Interrupt mode mismatch: IRQ %ld current mode: t: %d p: %d "
- "request mode: trg: %d p: %d",
- irq_number, _proxy->trigger(), _proxy->polarity(),
- irq_trigger, irq_polarity);
- throw Root::Unavailable();
- }
-
- if (setup)
- /* set interrupt mode */
- _proxy->setup_irq_mode(irq_trigger, irq_polarity);
-
- _irq_number = irq_number;
-
- _proxy->enable(msi);
+ _irq_object.associate(_irq_number, msi, irq_trigger, irq_polarity);
}
Irq_session_component::~Irq_session_component()
{
- if (!_proxy) return;
+ if (_irq_number == ~0U)
+ return;
- if (_irq_sigh.valid())
- _proxy->remove_sharer(&_irq_sigh);
+ if (_irq_object.msi_address()) {
+ msi_alloc.clear(_irq_number, 1);
+ } else {
+ Genode::addr_t free_irq = _irq_number;
+ _irq_alloc->free((void *)free_irq);
+ }
}
-void Irq_session_component::sigh(Genode::Signal_context_capability sigh)
+void Irq_session_component::ack_irq() { _irq_object.ack_irq(); }
+
+
+void Irq_session_component::sigh(Genode::Signal_context_capability cap)
{
- if (!_proxy) {
- PERR("signal handler got not registered - irq thread unavailable");
- return;
- }
-
- Genode::Signal_context_capability old = _irq_sigh;
-
- if (old.valid() && !sigh.valid())
- _proxy->remove_sharer(&_irq_sigh);
-
- _irq_sigh = sigh;
-
- if (!old.valid() && sigh.valid())
- _proxy->add_sharer(&_irq_sigh);
+ _irq_object.sigh(cap);
}
Genode::Irq_session::Info Irq_session_component::info()
{
- if (!_proxy || !_proxy->msi_address() || !_proxy->msi_value())
+ if (!_irq_object.msi_address() || !_irq_object.msi_value())
return { .type = Genode::Irq_session::Info::Type::INVALID };
return {
.type = Genode::Irq_session::Info::Type::MSI,
- .address = _proxy->msi_address(),
- .value = _proxy->msi_value()
+ .address = _irq_object.msi_address(),
+ .value = _irq_object.msi_value()
};
}
-/***************************************
- ** Interrupt handler implemtentation **
- ***************************************/
+/**************************************
+ ** Interrupt handler implementation **
+ **************************************/
/* Build with frame pointer to make GDB backtraces work. See issue #1061. */
__attribute__((optimize("-fno-omit-frame-pointer")))
@@ -367,11 +298,8 @@ void Interrupt_handler::entry()
if ((err = l4_ipc_error(tag, l4_utcb())))
PERR("IRQ receive: %d\n", err);
else {
- Irq_proxy_component *proxy;
- proxy = Irq_proxy_component::get_irq_proxy(label);
-
- if (proxy)
- proxy->semaphore()->up();
+ Irq_object * irq_object = reinterpret_cast(label);
+ irq_object->notify();
}
}
}
diff --git a/repos/base-foc/src/core/platform.cc b/repos/base-foc/src/core/platform.cc
index c091816cc..4a562e283 100644
--- a/repos/base-foc/src/core/platform.cc
+++ b/repos/base-foc/src/core/platform.cc
@@ -30,6 +30,7 @@
/* Fiasco includes */
namespace Fiasco {
#include
+#include
#include
#include
#include
@@ -333,7 +334,17 @@ void Platform::_setup_mem_alloc()
}
-void Platform::_setup_irq_alloc() { _irq_alloc.add_range(0, 0x100); }
+void Platform::_setup_irq_alloc()
+{
+ using namespace Fiasco;
+
+ l4_icu_info_t info { .features = 0 };
+ l4_msgtag_t res = l4_icu_info(Fiasco::L4_BASE_ICU_CAP, &info);
+ if (l4_error(res))
+ panic("could not determine number of IRQs");
+
+ _irq_alloc.add_range(0, info.nr_irqs);
+}
void Platform::_setup_basics()
diff --git a/repos/base-hw/src/core/irq_session_component.cc b/repos/base-hw/src/core/irq_session_component.cc
index f50105d43..e99297216 100644
--- a/repos/base-hw/src/core/irq_session_component.cc
+++ b/repos/base-hw/src/core/irq_session_component.cc
@@ -69,6 +69,10 @@ Irq_session_component::Irq_session_component(Range_allocator * const irq_alloc,
_irq_number(Platform::irq(_find_irq_number(args))),
_irq_alloc(irq_alloc)
{
+ long const msi = Arg_string::find_arg(args, "device_config_phys").long_value(0);
+ if (msi)
+ throw Root::Unavailable();
+
/* allocate interrupt */
if (_irq_alloc->alloc_addr(1, _irq_number).is_error()) {
PERR("unavailable interrupt requested");
diff --git a/repos/base-nova/src/core/include/irq_object.h b/repos/base-nova/src/core/include/irq_object.h
new file mode 100644
index 000000000..057696cb1
--- /dev/null
+++ b/repos/base-nova/src/core/include/irq_object.h
@@ -0,0 +1,54 @@
+/*
+ * \brief Nova-specific instance of the IRQ object
+ * \author Alexander Boettcher
+ */
+
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include
+
+namespace Genode { class Irq_object; }
+
+class Genode::Irq_object : public Thread<4096> {
+
+ private:
+
+ Signal_context_capability _sig_cap;
+ Lock _sync_ack;
+ Lock _sync_life;
+
+ Genode::addr_t _kernel_caps;
+ Genode::addr_t _msi_addr;
+ Genode::addr_t _msi_data;
+ enum { UNDEFINED, SHUTDOWN } volatile _state;
+
+ void entry() override;
+
+ enum { KERNEL_CAP_COUNT_LOG2 = 1 };
+
+ Genode::addr_t const irq_sel() { return _kernel_caps; }
+ Genode::addr_t const sc_sel() { return _kernel_caps + 1; }
+
+ public:
+
+ Irq_object();
+ ~Irq_object();
+
+ Genode::addr_t msi_address() const { return _msi_addr; }
+ Genode::addr_t msi_value() const { return _msi_data; }
+
+ void sigh(Signal_context_capability cap) { _sig_cap = cap; }
+ void notify() { Genode::Signal_transmitter(_sig_cap).submit(1); }
+
+ void ack_irq() { _sync_ack.unlock(); }
+
+ void start() override;
+ void start(unsigned irq, Genode::addr_t);
+};
diff --git a/repos/base-nova/src/core/irq_session_component.cc b/repos/base-nova/src/core/irq_session_component.cc
index 6bdc406c8..bb3ee2d8c 100644
--- a/repos/base-nova/src/core/irq_session_component.cc
+++ b/repos/base-nova/src/core/irq_session_component.cc
@@ -2,11 +2,12 @@
* \brief Implementation of IRQ session component
* \author Norman Feske
* \author Sebastian Sumpf
+ * \author Alexander Boettcher
* \date 2009-10-02
*/
/*
- * 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.
@@ -18,7 +19,6 @@
/* core includes */
#include
-#include
#include
#include
@@ -29,201 +29,214 @@
using namespace Genode;
-namespace Genode {
- class Irq_proxy_component;
+
+static void thread_start()
+{
+ Thread_base::myself()->entry();
+ sleep_forever();
+}
+
+
+static bool associate(unsigned irq, Genode::addr_t irq_sel,
+ Genode::addr_t &msi_addr, Genode::addr_t &msi_data,
+ Genode::addr_t virt_addr = 0)
+{
+ /* map IRQ SM cap from kernel to core at irq_sel selector */
+ using Nova::Obj_crd;
+
+ Obj_crd src(platform_specific()->gsi_base_sel() + irq, 0);
+ Obj_crd dst(irq_sel, 0);
+ enum { MAP_FROM_KERNEL_TO_CORE = true };
+
+ int ret = map_local((Nova::Utcb *)Thread_base::myself()->utcb(),
+ src, dst, MAP_FROM_KERNEL_TO_CORE);
+ if (ret) {
+ PERR("Could not map IRQ %u", irq);
+ return false;
+ }
+
+ /* assign IRQ to CPU && request msi data to be used by driver */
+ uint8_t res = Nova::assign_gsi(irq_sel, virt_addr, boot_cpu(),
+ msi_addr, msi_data);
+
+ if (virt_addr && res != Nova::NOVA_OK) {
+ PERR("setting up MSI %u failed - error %u", irq, res);
+ return false;
+ }
+
+ /* nova syscall interface specifies msi addr/data to be 32bit */
+ msi_addr = msi_addr & ~0U;
+ msi_data = msi_data & ~0U;
+
+ return true;
+}
+
+
+static bool msi(unsigned irq, Genode::addr_t irq_sel, Genode::addr_t phys_mem,
+ Genode::addr_t &msi_addr, Genode::addr_t &msi_data)
+{
+ void * virt = 0;
+ if (platform()->region_alloc()->alloc_aligned(4096, &virt, 12).is_error())
+ return false;
+
+ Genode::addr_t virt_addr = reinterpret_cast(virt);
+ if (!virt_addr)
+ return false;
+
+ using Nova::Rights;
+ using Nova::Utcb;
+
+ Nova::Mem_crd phys_crd(phys_mem >> 12, 0, Rights(true, false, false));
+ Nova::Mem_crd virt_crd(virt_addr >> 12, 0, Rights(true, false, false));
+ Utcb * utcb = reinterpret_cast(Thread_base::myself()->utcb());
+
+ if (map_local_phys_to_virt(utcb, phys_crd, virt_crd)) {
+ platform()->region_alloc()->free(virt, 4096);
+ return false;
+ }
+
+ /* try to assign MSI to device */
+ bool res = associate(irq, irq_sel, msi_addr, msi_data, virt_addr);
+
+ unmap_local(Nova::Mem_crd(virt_addr >> 12, 0, Rights(true, true, true)));
+ platform()->region_alloc()->free(virt, 4096);
+
+ return res;
+}
+
+
+void Irq_object::start()
+{
+ PERR("wrong start method called");
+ throw Root::Unavailable();
}
/**
- * Global worker (i.e. thread with SC)
+ * Create global EC, associate it to SC
*/
-class Irq_thread : public Thread_base
+void Irq_object::start(unsigned irq, Genode::addr_t const device_phys)
{
- private:
+ /* associate GSI or MSI to device belonging to device_phys */
+ bool ok = false;
+ if (device_phys)
+ ok = msi(irq, irq_sel(), device_phys, _msi_addr, _msi_data);
+ else
+ ok = associate(irq, irq_sel(), _msi_addr, _msi_data);
- enum { STACK_SIZE = 1024 * sizeof(addr_t) };
- enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT };
+ if (!ok)
+ throw Root::Unavailable();
- static void _thread_start()
- {
- Thread_base::myself()->entry();
- sleep_forever();
- }
+ /* start thread having a SC */
+ using namespace Nova;
+ addr_t pd_sel = Platform_pd::pd_core_sel();
+ addr_t utcb = reinterpret_cast(&_context->utcb);
- public:
+ /* put IP on stack, it will be read from core pager in platform.cc */
+ addr_t *sp = reinterpret_cast(_context->stack_top() - sizeof(addr_t));
+ *sp = reinterpret_cast(thread_start);
- Irq_thread(char const *name) : Thread_base(WEIGHT, name, STACK_SIZE)
- { }
+ /* create global EC */
+ enum { GLOBAL = true };
+ uint8_t res = create_ec(_tid.ec_sel, pd_sel, boot_cpu(),
+ utcb, (mword_t)sp, _tid.exc_pt_sel, GLOBAL);
+ if (res != NOVA_OK) {
+ PERR("%p - create_ec returned %d", this, res);
+ throw Root::Unavailable();
+ }
- /**
- * Create global EC, associate it to SC
- */
- void start()
- {
- using namespace Nova;
- addr_t pd_sel = Platform_pd::pd_core_sel();
- addr_t utcb = reinterpret_cast(&_context->utcb);
+ /* remap startup portal from main thread */
+ if (map_local((Utcb *)Thread_base::myself()->utcb(),
+ Obj_crd(PT_SEL_STARTUP, 0),
+ Obj_crd(_tid.exc_pt_sel + PT_SEL_STARTUP, 0))) {
+ PERR("could not create startup portal");
+ throw Root::Unavailable();
+ }
- /*
- * Put IP on stack, it will be read from core pager in platform.cc
- */
- addr_t *sp = reinterpret_cast(_context->stack_top() - sizeof(addr_t));
- *sp = reinterpret_cast(_thread_start);
+ /* remap debugging page fault portal for core threads */
+ if (map_local((Utcb *)Thread_base::myself()->utcb(),
+ Obj_crd(PT_SEL_PAGE_FAULT, 0),
+ Obj_crd(_tid.exc_pt_sel + PT_SEL_PAGE_FAULT, 0))) {
+ PERR("could not create page fault portal");
+ throw Root::Unavailable();
+ }
- /* create global EC */
- enum { GLOBAL = true };
- uint8_t res = create_ec(_tid.ec_sel, pd_sel, boot_cpu(),
- utcb, (mword_t)sp, _tid.exc_pt_sel, GLOBAL);
- if (res != NOVA_OK) {
- PERR("%p - create_ec returned %d", this, res);
- throw Cpu_session::Thread_creation_failed();
- }
+ /* default: we don't accept any mappings or translations */
+ Utcb * utcb_obj = reinterpret_cast(Thread_base::utcb());
+ utcb_obj->crd_rcv = Obj_crd();
+ utcb_obj->crd_xlt = Obj_crd();
- /* remap startup portal from main thread */
- if (map_local((Utcb *)Thread_base::myself()->utcb(),
- Obj_crd(PT_SEL_STARTUP, 0),
- Obj_crd(_tid.exc_pt_sel + PT_SEL_STARTUP, 0))) {
- PERR("could not create startup portal");
- throw Cpu_session::Thread_creation_failed();
- }
+ /* create SC */
+ Qpd qpd(Qpd::DEFAULT_QUANTUM, Qpd::DEFAULT_PRIORITY + 1);
+ res = create_sc(sc_sel(), pd_sel, _tid.ec_sel, qpd);
+ if (res != NOVA_OK) {
+ PERR("%p - create_sc returned returned %d", this, res);
+ throw Root::Unavailable();
+ }
- /* remap debugging page fault portal for core threads */
- if (map_local((Utcb *)Thread_base::myself()->utcb(),
- Obj_crd(PT_SEL_PAGE_FAULT, 0),
- Obj_crd(_tid.exc_pt_sel + PT_SEL_PAGE_FAULT, 0))) {
- PERR("could not create page fault portal");
- throw Cpu_session::Thread_creation_failed();
- }
-
- /* default: we don't accept any mappings or translations */
- Utcb * utcb_obj = reinterpret_cast(Thread_base::utcb());
- utcb_obj->crd_rcv = Obj_crd();
- utcb_obj->crd_xlt = Obj_crd();
-
- /* create SC */
- unsigned sc_sel = cap_map()->insert();
- res = create_sc(sc_sel, pd_sel, _tid.ec_sel, Qpd(Qpd::DEFAULT_QUANTUM, Qpd::DEFAULT_PRIORITY + 1));
- if (res != NOVA_OK) {
- PERR("%p - create_sc returned returned %d", this, res);
- throw Cpu_session::Thread_creation_failed();
- }
- }
-};
+ _sync_life.lock();
+}
-/**
- * Irq_proxy interface implementation
- */
-class Genode::Irq_proxy_component : public Irq_proxy
+void Irq_object::entry()
{
- private:
+ /* signal that thread is up and ready */
+ _sync_life.unlock();
- Genode::addr_t _irq_sel; /* IRQ cap selector */
- Genode::addr_t _dev_mem; /* used when MSI or HPET is used */
- bool _ready; /* flag to signal that IRQ SM can be used */
+ /* wait for first ack_irq */
+ _sync_ack.lock();
- Genode::addr_t _msi_addr;
- Genode::addr_t _msi_data;
+ while (true) {
- protected:
+ if (Nova::NOVA_OK != Nova::sm_ctrl(irq_sel(), Nova::SEMAPHORE_DOWN))
+ PERR("Error: blocking for irq_sel 0x%lx failed", irq_sel());
- bool _associate()
- {
- /* assign IRQ to CPU && request msi data to be used by driver */
- uint8_t res = Nova::assign_gsi(_irq_sel, _dev_mem, boot_cpu(),
- _msi_addr, _msi_data);
-
- _ready = res == Nova::NOVA_OK;
-
- /*
- * Return ever success so that the IRQ proxy thread gets started.
- * For MSIs or HPET a separate associate() call with a valid
- * dev_mem address is required.
- */
- if (_dev_mem && !_ready)
- PERR("setting up MSI 0x%lx failed - error %u", _irq_number, res);
-
- return _dev_mem ? _ready : true;
+ if (_state == SHUTDOWN) {
+ /* signal end of life to entrypoint thread */
+ _sync_life.unlock();
+ while (1) nova_die();
}
- void _wait_for_irq()
- {
- if (!_ready)
- PERR("Error: assign_gsi failed for IRQ %ld", _irq_number);
+ if (!_sig_cap.valid())
+ continue;
- if (Nova::NOVA_OK != Nova::sm_ctrl(_irq_sel, Nova::SEMAPHORE_DOWN))
- PERR("Error: blocking for irq %ld failed", _irq_number);
- }
+ notify();
- void _ack_irq() { }
+ _sync_ack.lock();
+ }
+}
- public:
- Irq_proxy_component(long irq_number)
- :
- /* since we run in APIC mode translate IRQ 0 (PIT) to 2 */
- Irq_proxy(irq_number ? irq_number : 2),
- _irq_sel(cap_map()->insert()),
- _dev_mem(0),
- _ready(false),
- _msi_addr(0),
- _msi_data(0)
- {
- /* map IRQ SM cap from kernel to core at _irq_sel selector */
- using Nova::Obj_crd;
+Irq_object::Irq_object()
+:
+ Thread<4096>("irq"),
+ _sync_ack(Lock::LOCKED), _sync_life(Lock::LOCKED),
+ _kernel_caps(cap_map()->insert(KERNEL_CAP_COUNT_LOG2)),
+ _msi_addr(0UL), _msi_data(0UL), _state(UNDEFINED)
+{ }
- Obj_crd src(platform_specific()->gsi_base_sel() + _irq_number, 0);
- Obj_crd dst(_irq_sel, 0);
- enum { MAP_FROM_KERNEL_TO_CORE = true };
- int ret = map_local((Nova::Utcb *)Thread_base::myself()->utcb(),
- src, dst, MAP_FROM_KERNEL_TO_CORE);
- if (ret) {
- PERR("Could not map IRQ %ld", _irq_number);
- throw Root::Unavailable();
- }
+Irq_object::~Irq_object()
+{
+ /* tell interrupt thread to get in a defined dead state */
+ _state = SHUTDOWN;
+ /* send ack - thread maybe got not the first ack */
+ _sync_ack.unlock();
+ /* unblock thread if it is waiting for interrupts */
+ Nova::sm_ctrl(irq_sel(), Nova::SEMAPHORE_UP);
+ /* wait until thread signals end of life */
+ _sync_life.lock();
- /* let thread run */
- _start();
- }
+ /* revoke SC and SM of interrupt source */
+ Nova::revoke(Nova::Obj_crd(_kernel_caps, KERNEL_CAP_COUNT_LOG2));
+ enum { NO_REVOKE_REQUIRED = false };
+ cap_map()->remove(_kernel_caps, KERNEL_CAP_COUNT_LOG2, NO_REVOKE_REQUIRED);
+}
- void associate(Genode::addr_t phys_mem)
- {
- void * v = 0;
- if (platform()->region_alloc()->alloc_aligned(4096,
- &v, 12).is_error())
- return;
- Genode::addr_t virt_addr = reinterpret_cast(v);
-
- if (!virt_addr)
- return;
-
- using Nova::Mem_crd;
- using Nova::Rights;
-
- if (map_local_phys_to_virt(reinterpret_cast(Thread_base::myself()->utcb()),
- Mem_crd(phys_mem >> 12, 0, Rights(true, false, false)),
- Mem_crd(virt_addr >> 12, 0, Rights(true, false, false)))) {
- platform()->region_alloc()->free(v, 4096);
- return;
- }
-
- /* local attached pci config extended io mem of device */
- _dev_mem = virt_addr;
- /* try to assign MSI to device */
- _associate();
-
- /* revert local mapping */
- _dev_mem = 0;
- unmap_local(Mem_crd(virt_addr >> 12, 0, Rights(true, true, true)));
- platform()->region_alloc()->free(v, 4096);
- }
-
- bool ready() const { return _ready; }
- Genode::addr_t msi_address() const { return _msi_addr; }
- Genode::addr_t msi_value() const { return _msi_data; }
-};
+/***************************
+ ** IRQ session component **
+ ***************************/
static Nova::Hip * kernel_hip()
@@ -237,35 +250,15 @@ static Nova::Hip * kernel_hip()
}
-/***************************
- ** IRQ session component **
- ***************************/
-
-
-void Irq_session_component::ack_irq()
-{
- if (!_proxy) {
- PERR("Expected to find IRQ proxy for IRQ %02x", _irq_number);
- return;
- }
-
- _proxy->ack_irq();
-}
-
-
Irq_session_component::Irq_session_component(Range_allocator *irq_alloc,
const char *args)
+:
+ _irq_number(~0U), _irq_alloc(irq_alloc)
{
- typedef Irq_proxy Proxy;
-
long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
- if (irq_number < 0) {
- PERR("invalid IRQ number requested");
- throw Root::Unavailable();
- }
-
long device_phys = Arg_string::find_arg(args, "device_config_phys").long_value(0);
if (device_phys) {
+
if (irq_number >= kernel_hip()->sel_gsi)
throw Root::Unavailable();
@@ -275,58 +268,47 @@ Irq_session_component::Irq_session_component(Range_allocator *irq_alloc,
throw Root::Unavailable();
}
- /* check if IRQ thread was started before */
- _proxy = Proxy::get_irq_proxy(irq_number, irq_alloc);
- if (!_proxy) {
- PERR("unavailable IRQ %lx requested", irq_number);
+ if (!irq_alloc || irq_alloc->alloc_addr(1, irq_number).is_error()) {
+ PERR("Unavailable IRQ 0x%lx requested", irq_number);
throw Root::Unavailable();
}
- if (device_phys)
- _proxy->associate(device_phys);
-
_irq_number = irq_number;
+
+ _irq_object.start(_irq_number, device_phys);
}
Irq_session_component::~Irq_session_component()
{
- if (!_proxy)
+ if (_irq_number == ~0U)
return;
- if (_irq_sigh.valid())
- _proxy->remove_sharer(&_irq_sigh);
+ Genode::addr_t free_irq = _irq_number;
+ _irq_alloc->free((void *)free_irq);
}
-void Irq_session_component::sigh(Genode::Signal_context_capability sigh)
+void Irq_session_component::ack_irq()
{
- if (!_proxy) {
- PERR("signal handler got not registered - irq thread unavailable");
- return;
- }
+ _irq_object.ack_irq();
+}
- Genode::Signal_context_capability old = _irq_sigh;
- if (old.valid() && !sigh.valid())
- _proxy->remove_sharer(&_irq_sigh);
-
- _irq_sigh = sigh;
-
- if (!old.valid() && sigh.valid())
- _proxy->add_sharer(&_irq_sigh);
+void Irq_session_component::sigh(Genode::Signal_context_capability cap)
+{
+ _irq_object.sigh(cap);
}
Genode::Irq_session::Info Irq_session_component::info()
{
- if (!_proxy || !_proxy->ready() || !_proxy->msi_address() ||
- !_proxy->msi_value())
+ if (!_irq_object.msi_address() || !_irq_object.msi_value())
return { .type = Genode::Irq_session::Info::Type::INVALID };
return {
.type = Genode::Irq_session::Info::Type::MSI,
- .address = _proxy->msi_address(),
- .value = _proxy->msi_value()
+ .address = _irq_object.msi_address(),
+ .value = _irq_object.msi_value()
};
}
diff --git a/repos/base-okl4/src/core/irq_session_component.cc b/repos/base-okl4/src/core/irq_session_component.cc
index 90fb96f3f..840901a42 100644
--- a/repos/base-okl4/src/core/irq_session_component.cc
+++ b/repos/base-okl4/src/core/irq_session_component.cc
@@ -17,6 +17,7 @@
#include
/* core includes */
+#include
#include
/* OKL4 includes */
@@ -32,6 +33,10 @@ using namespace Okl4;
using namespace Genode;
+/* bit to use for IRQ notifications */
+enum { IRQ_NOTIFY_BIT = 13 };
+
+
/* XXX move this functionality to a central place instead of duplicating it */
static inline Okl4::L4_ThreadId_t thread_get_my_global_id()
{
@@ -40,72 +45,87 @@ static inline Okl4::L4_ThreadId_t thread_get_my_global_id()
return myself;
}
-namespace Genode {
- typedef Irq_proxy > Irq_proxy_base;
- class Irq_proxy_component;
+
+bool Irq_object::_associate()
+{
+ /* allow roottask (ourself) to handle the interrupt */
+ L4_LoadMR(0, _irq);
+ int ret = L4_AllowInterruptControl(L4_rootspace);
+ if (ret != 1) {
+ PERR("L4_AllowInterruptControl returned %d, error code=%ld\n",
+ ret, L4_ErrorCode());
+ return false;
+ }
+
+ /*
+ * Note: 'L4_Myself()' does not work for the thread argument of
+ * 'L4_RegisterInterrupt'. We have to specify our global ID.
+ */
+ L4_LoadMR(0, _irq);
+ ret = L4_RegisterInterrupt(thread_get_my_global_id(), IRQ_NOTIFY_BIT, 0, 0);
+ if (ret != 1) {
+ PERR("L4_RegisterInterrupt returned %d, error code=%ld\n",
+ ret, L4_ErrorCode());
+ return false;
+ }
+
+ return true;
}
-/**
- * Platform-specific proxy code
- */
-class Genode::Irq_proxy_component : public Irq_proxy_base
+
+void Irq_object::_wait_for_irq()
{
- protected:
+ /* prepare ourself to receive asynchronous IRQ notifications */
+ L4_Set_NotifyMask(1 << IRQ_NOTIFY_BIT);
+ L4_Accept(L4_NotifyMsgAcceptor);
- bool _associate()
- {
- /* allow roottask (ourself) to handle the interrupt */
- L4_LoadMR(0, _irq_number);
- int ret = L4_AllowInterruptControl(L4_rootspace);
- if (ret != 1) {
- PERR("L4_AllowInterruptControl returned %d, error code=%ld\n",
- ret, L4_ErrorCode());
- return false;
- }
+ /* wait for asynchronous interrupt notification */
+ L4_ThreadId_t partner = L4_nilthread;
+ L4_ReplyWait(partner, &partner);
+}
- /* bit to use for IRQ notifications */
- enum { IRQ_NOTIFY_BIT = 13 };
- /*
- * Note: 'L4_Myself()' does not work for the thread argument of
- * 'L4_RegisterInterrupt'. We have to specify our global ID.
- */
- L4_LoadMR(0, _irq_number);
- ret = L4_RegisterInterrupt(thread_get_my_global_id(), IRQ_NOTIFY_BIT, 0, 0);
- if (ret != 1) {
- PERR("L4_RegisterInterrupt returned %d, error code=%ld\n",
- ret, L4_ErrorCode());
- return false;
- }
+void Irq_object::start()
+{
+ ::Thread_base::start();
+ _sync_bootup.lock();
+}
- /* prepare ourself to receive asynchronous IRQ notifications */
- L4_Set_NotifyMask(1 << IRQ_NOTIFY_BIT);
- return true;
- }
+void Irq_object::entry()
+{
+ if (!_associate())
+ PERR("Could not associate with IRQ 0x%x", _irq);
- void _wait_for_irq()
- {
- L4_Accept(L4_NotifyMsgAcceptor);
+ /* thread is up and ready */
+ _sync_bootup.unlock();
- /* wait for asynchronous interrupt notification */
- L4_ThreadId_t partner = L4_nilthread;
- L4_ReplyWait(partner, &partner);
- }
+ /* wait for first ack_irq */
+ _sync_ack.lock();
- void _ack_irq()
- {
- L4_LoadMR(0, _irq_number);
- L4_AcknowledgeInterrupt(0, 0);
- }
+ while (true) {
- public:
+ L4_LoadMR(0, _irq);
+ L4_AcknowledgeInterrupt(0, 0);
- Irq_proxy_component(long irq_number) : Irq_proxy(irq_number)
- {
- _start();
- }
-};
+ _wait_for_irq();
+
+ if (!_sig_cap.valid())
+ continue;
+
+ Genode::Signal_transmitter(_sig_cap).submit(1);
+
+ _sync_ack.lock();
+ }
+}
+
+
+Irq_object::Irq_object(unsigned irq)
+:
+ Thread<4096>("irq"),
+ _sync_ack(Lock::LOCKED), _sync_bootup(Lock::LOCKED),
+ _irq(irq)
+{ }
/***************************
@@ -113,74 +133,41 @@ class Genode::Irq_proxy_component : public Irq_proxy_base
***************************/
-void Irq_session_component::ack_irq()
-{
- /* block at interrupt proxy */
- if (!_proxy) {
- PERR("Expected to find IRQ proxy for IRQ %02x", _irq_number);
- return;
- }
-
- _proxy->ack_irq();
-}
-
-
Irq_session_component::Irq_session_component(Range_allocator *irq_alloc,
const char *args)
:
- _irq_alloc(irq_alloc)
+ _irq_number(Arg_string::find_arg(args, "irq_number").long_value(-1)),
+ _irq_alloc(irq_alloc),
+ _irq_object(_irq_number)
{
- /*
- * XXX Removed irq_shared argument as this is the default now. If we need
- * exclusive later on, we should add this as new argument.
- */
-
- long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
- if (irq_number == -1) {
- PERR("invalid IRQ number requested");
- throw Root::Unavailable();
- }
-
long msi = Arg_string::find_arg(args, "device_config_phys").long_value(0);
if (msi)
throw Root::Unavailable();
- /* check if IRQ thread was started before */
- _proxy = Irq_proxy_component::get_irq_proxy(irq_number, irq_alloc);
- if (!_proxy) {
- PERR("unavailable IRQ %lx requested", irq_number);
+ if (!irq_alloc || irq_alloc->alloc_addr(1, _irq_number).is_error()) {
+ PERR("Unavailable IRQ 0x%x requested", _irq_number);
throw Root::Unavailable();
}
- _irq_number = irq_number;
+ _irq_object.start();
}
Irq_session_component::~Irq_session_component()
{
- if (!_proxy) return;
-
- if (_irq_sigh.valid())
- _proxy->remove_sharer(&_irq_sigh);
+ PDBG("Not yet implemented!");
}
-void Irq_session_component::sigh(Genode::Signal_context_capability sigh)
+void Irq_session_component::ack_irq()
{
- if (!_proxy) {
- PERR("signal handler got not registered - irq thread unavailable");
- return;
- }
+ _irq_object.ack_irq();
+}
- Genode::Signal_context_capability old = _irq_sigh;
- if (old.valid() && !sigh.valid())
- _proxy->remove_sharer(&_irq_sigh);
-
- _irq_sigh = sigh;
-
- if (!old.valid() && sigh.valid())
- _proxy->add_sharer(&_irq_sigh);
+void Irq_session_component::sigh(Genode::Signal_context_capability cap)
+{
+ _irq_object.sigh(cap);
}
diff --git a/repos/base-pistachio/src/core/irq_session_component.cc b/repos/base-pistachio/src/core/irq_session_component.cc
index 8cdc5bf2e..e4e40e200 100644
--- a/repos/base-pistachio/src/core/irq_session_component.cc
+++ b/repos/base-pistachio/src/core/irq_session_component.cc
@@ -2,12 +2,10 @@
* \brief Pistachio-specific implementation of IRQ sessions
* \author Julian Stecklina
* \date 2008-02-21
- *
- * FIXME ram quota missing
*/
/*
- * Copyright (C) 2008-2013 Genode Labs GmbH
+ * Copyright (C) 2008-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.
@@ -18,7 +16,6 @@
#include
/* core includes */
-#include
#include
#include
@@ -40,97 +37,88 @@ static inline L4_ThreadId_t irqno_to_threadid(unsigned int irqno)
}
-namespace Genode {
- typedef Irq_proxy > Irq_proxy_base;
- class Irq_proxy_component;
+bool Irq_object::_associate()
+{
+ L4_ThreadId_t const irq_thread = irqno_to_threadid(_irq);
+
+ return L4_AssociateInterrupt(irq_thread, L4_Myself());
}
-/**
- * Platform-specific proxy code
- */
-
-class Genode::Irq_proxy_component : public Irq_proxy_base
+void Irq_object::_wait_for_irq()
{
- private:
+ L4_ThreadId_t const irq_thread = irqno_to_threadid(_irq);
- /*
- * On Pistachio, an IRQ is unmasked right after attaching.
- * Hence, the kernel may send an IRQ IPC when the IRQ hander is
- * not explicitly waiting for an IRQ but when it is waiting for
- * a client's 'wait_for_irq' RPC call. To avoid this conflict, we
- * lazily associate to the IRQ when calling the 'wait_for_irq'
- * function for the first time. We use the '_irq_attached' flag
- * for detecting the first call.
- */
- bool _irq_attached; /* true if IRQ is already attached */
+ /* send unmask message and wait for new IRQ */
+ L4_Set_MsgTag(L4_Niltag);
+ L4_MsgTag_t res = L4_Call(irq_thread);
- protected:
+ if (L4_IpcFailed(res))
+ PERR("ipc error while waiting for interrupt.");
+}
- bool _associate() { return true; }
- void _wait_for_irq()
- {
- L4_ThreadId_t irq_thread = irqno_to_threadid(_irq_number);
+void Irq_object::start()
+{
+ ::Thread_base::start();
+ _sync_bootup.lock();
+}
- /* attach to IRQ when called for the first time */
- L4_MsgTag_t res;
- if (!_irq_attached) {
- if (L4_AssociateInterrupt(irq_thread, L4_Myself()) != true) {
- PERR("L4_AssociateInterrupt failed");
- return;
- }
+void Irq_object::entry()
+{
+ if (!_associate()) {
+ PERR("Could not associate with IRQ 0x%x", _irq);
+ return;
+ }
- /*
- * Right after associating with an interrupt, the interrupt is
- * unmasked. Hence, we do not need to send an unmask message
- * to the IRQ thread but just wait for the IRQ.
- */
- L4_Set_MsgTag(L4_Niltag);
- res = L4_Receive(irq_thread);
+ /* thread is up and ready */
+ _sync_bootup.unlock();
- /*
- * Now, the IRQ is masked. To receive the next IRQ we have to send
- * an unmask message to the IRQ thread first.
- */
- _irq_attached = true;
+ /* wait for first ack_irq */
+ _sync_ack.lock();
- /* receive subsequent interrupt */
- } else {
+ /*
+ * Right after associating with an interrupt, the interrupt is
+ * unmasked. Hence, we do not need to send an unmask message
+ * to the IRQ thread but just wait for the IRQ.
+ */
+ L4_ThreadId_t const irq_thread = irqno_to_threadid(_irq);
+ L4_Set_MsgTag(L4_Niltag);
+ L4_MsgTag_t res = L4_Receive(irq_thread);
- /* send unmask message and wait for new IRQ */
- L4_Set_MsgTag(L4_Niltag);
- res = L4_Call(irq_thread);
- }
+ if (L4_IpcFailed(res))
+ PERR("ipc error while attaching to interrupt.");
- if (L4_IpcFailed(res)) {
- PERR("ipc error while waiting for interrupt.");
- return;
- }
- }
+ /*
+ * Now, the IRQ is masked. To receive the next IRQ we have to send
+ * an unmask message to the IRQ thread first.
+ */
+ if (_sig_cap.valid()) {
+ Genode::Signal_transmitter(_sig_cap).submit(1);
+ _sync_ack.lock();
+ }
- void _ack_irq() { }
+ while (true) {
- public:
+ _wait_for_irq();
- Irq_proxy_component(long irq_number)
- :
- Irq_proxy(irq_number),
- _irq_attached(false)
- {
- _start();
- }
+ if (!_sig_cap.valid())
+ continue;
- ~Irq_proxy_component()
- {
- L4_ThreadId_t const thread_id = irqno_to_threadid(_irq_number);
- L4_Word_t const res = L4_DeassociateInterrupt(thread_id);
+ Genode::Signal_transmitter(_sig_cap).submit(1);
- if (res != 1)
- PERR("L4_DeassociateInterrupt failed");
- }
-};
+ _sync_ack.lock();
+ }
+}
+
+
+Irq_object::Irq_object(unsigned irq)
+:
+ Thread<4096>("irq"),
+ _sync_ack(Lock::LOCKED), _sync_bootup(Lock::LOCKED),
+ _irq(irq)
+{ }
/***************************
@@ -138,68 +126,44 @@ class Genode::Irq_proxy_component : public Irq_proxy_base
***************************/
-void Irq_session_component::ack_irq()
-{
- if (!_proxy) {
- PERR("Expected to find IRQ proxy for IRQ %02x", _irq_number);
- return;
- }
-
- _proxy->ack_irq();
-}
-
-
Irq_session_component::Irq_session_component(Range_allocator *irq_alloc,
const char *args)
:
- _irq_alloc(irq_alloc)
+ _irq_number(Arg_string::find_arg(args, "irq_number").long_value(-1)),
+ _irq_alloc(irq_alloc),
+ _irq_object(_irq_number)
{
- long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
- if (irq_number == -1) {
- PERR("invalid IRQ number requested");
- throw Root::Unavailable();
- }
-
long msi = Arg_string::find_arg(args, "device_config_phys").long_value(0);
if (msi)
throw Root::Unavailable();
- /* check if IRQ thread was started before */
- _proxy = Irq_proxy_component::get_irq_proxy(irq_number, irq_alloc);
- if (!_proxy) {
- PERR("unavailable IRQ %lx requested", irq_number);
+ if (!irq_alloc || irq_alloc->alloc_addr(1, _irq_number).is_error()) {
+ PERR("Unavailable IRQ 0x%x requested", _irq_number);
throw Root::Unavailable();
}
- _irq_number = irq_number;
+ _irq_object.start();
}
Irq_session_component::~Irq_session_component()
{
- if (!_proxy) return;
+ L4_Word_t res = L4_DeassociateInterrupt(irqno_to_threadid(_irq_number));
- if (_irq_sigh.valid())
- _proxy->remove_sharer(&_irq_sigh);
+ if (res != 1)
+ PERR("L4_DeassociateInterrupt failed");
}
-void Irq_session_component::sigh(Genode::Signal_context_capability sigh)
+void Irq_session_component::ack_irq()
{
- if (!_proxy) {
- PERR("signal handler got not registered - irq thread unavailable");
- return;
- }
+ _irq_object.ack_irq();
+}
- Genode::Signal_context_capability old = _irq_sigh;
- if (old.valid() && !sigh.valid())
- _proxy->remove_sharer(&_irq_sigh);
-
- _irq_sigh = sigh;
-
- if (!old.valid() && sigh.valid())
- _proxy->add_sharer(&_irq_sigh);
+void Irq_session_component::sigh(Genode::Signal_context_capability cap)
+{
+ _irq_object.sigh(cap);
}
diff --git a/repos/base/src/core/include/irq_object.h b/repos/base/src/core/include/irq_object.h
new file mode 100644
index 000000000..02733c126
--- /dev/null
+++ b/repos/base/src/core/include/irq_object.h
@@ -0,0 +1,42 @@
+/*
+ * \brief Core-specific instance of the IRQ session interface
+ * \author Christian Helmuth
+ * \date 2007-09-13
+ */
+
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include
+
+namespace Genode { class Irq_object; }
+
+class Genode::Irq_object : public Thread<4096> {
+
+ private:
+
+ Signal_context_capability _sig_cap;
+ Lock _sync_ack;
+ Lock _sync_bootup;
+ unsigned _irq;
+
+ bool _associate();
+ void _wait_for_irq();
+
+ void entry() override;
+
+ public:
+
+ Irq_object(unsigned irq);
+
+ void sigh(Signal_context_capability cap) { _sig_cap = cap; }
+ void ack_irq() { _sync_ack.unlock(); }
+
+ void start() override;
+};
diff --git a/repos/base/src/core/include/irq_proxy.h b/repos/base/src/core/include/irq_proxy.h
deleted file mode 100644
index 463957948..000000000
--- a/repos/base/src/core/include/irq_proxy.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/**
- * \brief Shared-interrupt support
- * \author Christian Helmuth
- * \author Sebastian Sumpf
- * \date 2009-12-15
- */
-
-#ifndef _CORE__INCLUDE__IRQ_PROXY_H_
-#define _CORE__INCLUDE__IRQ_PROXY_H_
-
-#include
-
-
-namespace Genode {
- class Irq_sigh;
- template class Irq_proxy;
-}
-
-
-class Genode::Irq_sigh : public Genode::Signal_context_capability,
- public Genode::List::Element
-{
- public:
-
- inline Irq_sigh * operator= (const Signal_context_capability &cap)
- {
- Signal_context_capability::operator=(cap);
- return this;
- }
-
- Irq_sigh() { }
-
- void notify() { Genode::Signal_transmitter(*this).submit(1); }
-};
-
-
-/*
- * Proxy thread that associates to the interrupt and unblocks waiting irqctrl
- * threads.
- *
- * XXX resources are not accounted as the interrupt is shared
- */
-template
-class Genode::Irq_proxy : public THREAD,
- public Genode::List >::Element
-{
- protected:
-
- char _name[32];
- Lock _startup_lock;
-
- long _irq_number;
-
- Lock _mutex; /* protects this object */
- int _num_sharers; /* number of clients sharing this IRQ */
- Semaphore _sleep; /* wake me up if aspired blockers return */
- List _sigh_list;
- int _num_acknowledgers; /* number of currently blocked clients */
- bool _woken_up; /* client decided to wake me up -
- this prevents multiple wakeups
- to happen during initialization */
-
-
- /***************
- ** Interface **
- ***************/
-
- /**
- * Request interrupt
- *
- * \return true on success
- */
- virtual bool _associate() = 0;
-
- /**
- * Wait for associated interrupt
- */
- virtual void _wait_for_irq() = 0;
-
- /**
- * Acknowledge interrupt
- */
- virtual void _ack_irq() = 0;
-
- /********************
- ** Implementation **
- ********************/
-
- const char *_construct_name(long irq_number)
- {
- snprintf(_name, sizeof(_name), "irqproxy%02lx", irq_number);
- return _name;
- }
-
- void _loop()
- {
- /* wait for first blocker */
- _sleep.down();
-
- while (1) {
- _wait_for_irq();
-
- /* notify all */
- notify_about_irq(1);
-
- /*
- * We must wait for all clients to ack their interrupt,
- * otherwise level-triggered interrupts will occur immediately
- * after acknowledgement. That's an inherent security problem
- * with shared IRQs and induces problems with dynamic driver
- * load and unload.
- */
- _sleep.down();
-
- /* acknowledge previous interrupt */
- _ack_irq();
- }
- }
-
- /**
- * Start this thread, should be called externally from derived class
- */
- virtual void _start()
- {
- THREAD::start();
- _startup_lock.lock();
- }
-
- public:
-
- Irq_proxy(long irq_number)
- :
- THREAD(_construct_name(irq_number)),
- _startup_lock(Lock::LOCKED), _irq_number(irq_number),
- _mutex(Lock::UNLOCKED), _num_sharers(0), _num_acknowledgers(0), _woken_up(false)
-
- { }
-
- /**
- * Thread interface
- */
- void entry()
- {
- bool const associate_suceeded = _associate();
-
- _startup_lock.unlock();
-
- if (associate_suceeded)
- _loop();
- }
-
- /**
- * Acknowledgements of clients
- */
- virtual bool ack_irq()
- {
- Lock::Guard lock_guard(_mutex);
-
- _num_acknowledgers++;
-
- /*
- * The proxy thread has to be woken up if no client woke it up
- * before and this client is the last aspired acknowledger.
- */
- if (!_woken_up && _num_acknowledgers == _num_sharers) {
- _sleep.up();
- _woken_up = true;
- }
-
- return _woken_up;
- }
-
- /**
- * Notify all clients about irq
- */
- void notify_about_irq(unsigned)
- {
- Lock::Guard lock_guard(_mutex);
-
- /* reset acknowledger state */
- _num_acknowledgers = 0;
- _woken_up = false;
-
- /* inform blocked clients */
- for (Irq_sigh * s = _sigh_list.first(); s ; s = s->next())
- s->notify();
- }
-
- long irq_number() const { return _irq_number; }
-
- virtual bool add_sharer(Irq_sigh *s)
- {
- Lock::Guard lock_guard(_mutex);
-
- ++_num_sharers;
- _sigh_list.insert(s);
-
- return true;
- }
-
- virtual void remove_sharer(Irq_sigh *s)
- {
- Lock::Guard lock_guard(_mutex);
-
- _sigh_list.remove(s);
- --_num_sharers;
-
- if (_woken_up)
- return;
-
- if (_num_acknowledgers == _num_sharers) {
- _sleep.up();
- _woken_up = true;
- }
- }
-
- template
- static PROXY *get_irq_proxy(long irq_number, Range_allocator *irq_alloc = 0)
- {
- static List proxies;
- static Lock proxies_lock;
-
- Lock::Guard lock_guard(proxies_lock);
-
- /* lookup proxy in database */
- for (Irq_proxy *p = proxies.first(); p; p = p->next())
- if (p->irq_number() == irq_number)
- return static_cast(p);
-
- /* try to create proxy */
- if (!irq_alloc || irq_alloc->alloc_addr(1, irq_number).is_error())
- return 0;
-
- PROXY *new_proxy = new (env()->heap()) PROXY(irq_number);
- proxies.insert(new_proxy);
- return new_proxy;
- }
-};
-
-#endif /* _CORE__INCLUDE__IRQ_PROXY_H_ */
diff --git a/repos/base/src/core/include/irq_session_component.h b/repos/base/src/core/include/irq_session_component.h
index f65024832..a69d2e0a7 100644
--- a/repos/base/src/core/include/irq_session_component.h
+++ b/repos/base/src/core/include/irq_session_component.h
@@ -5,37 +5,33 @@
*/
/*
- * 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.
*/
-#ifndef _CORE__INCLUDE__IRQ_SESSION_COMPONENT_H_
-#define _CORE__INCLUDE__IRQ_SESSION_COMPONENT_H_
+#pragma once
+#include
#include
#include
#include
#include
#include
-#include
-namespace Genode {
- class Irq_proxy_component;
- class Irq_session_component;
-}
+#include
+
+namespace Genode { class Irq_session_component; }
class Genode::Irq_session_component : public Rpc_object,
public List::Element
{
private:
- unsigned _irq_number;
- Range_allocator *_irq_alloc;
- Irq_proxy_component *_proxy;
-
- Irq_sigh _irq_sigh;
+ unsigned _irq_number;
+ Range_allocator *_irq_alloc;
+ Irq_object _irq_object;
public:
@@ -45,14 +41,14 @@ class Genode::Irq_session_component : public Rpc_object,
* \param irq_alloc platform-dependent IRQ allocator
* \param args session construction arguments
*/
- Irq_session_component(Range_allocator *irq_alloc,
- const char *args);
+ Irq_session_component(Range_allocator *irq_alloc, const char *args);
/**
* Destructor
*/
~Irq_session_component();
+
/***************************
** Irq session interface **
***************************/
@@ -61,5 +57,3 @@ class Genode::Irq_session_component : public Rpc_object,
void sigh(Signal_context_capability) override;
Info info() override;
};
-
-#endif /* _CORE__INCLUDE__IRQ_SESSION_COMPONENT_H_ */