diff --git a/repos/base-hw/src/core/include/platform.h b/repos/base-hw/src/core/include/platform.h index 6bc889209..bbb0f80a8 100644 --- a/repos/base-hw/src/core/include/platform.h +++ b/repos/base-hw/src/core/include/platform.h @@ -101,6 +101,10 @@ namespace Genode { */ Platform(); + /** + * Return platform IRQ-number for user IRQ-number 'user_irq' + */ + static long irq(long const user_irq); /******************************** ** Platform_generic interface ** diff --git a/repos/base-hw/src/core/irq_session_component.cc b/repos/base-hw/src/core/irq_session_component.cc index 177b4aec6..529a4acad 100644 --- a/repos/base-hw/src/core/irq_session_component.cc +++ b/repos/base-hw/src/core/irq_session_component.cc @@ -1,11 +1,12 @@ /* * \brief Backend for IRQ sessions served by core * \author Martin Stein + * \author Reto Buerki * \date 2012-02-12 */ /* - * 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. @@ -42,7 +43,7 @@ Irq_signal Irq_session_component::signal() { return _signal; } Irq_session_component::~Irq_session_component() { irq_session_ep()->dissolve(this); - _irq_alloc->free((void *)_irq_number); + _irq_alloc->free((void *)(addr_t)_irq_number); } Irq_session_component::Irq_session_component(Cap_session * const cap_session, @@ -58,15 +59,19 @@ Irq_session_component::Irq_session_component(Cap_session * const cap_session throw Root::Invalid_args(); } /* allocate interrupt */ - long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1); - bool error = irq_number < 0 || !_irq_alloc; - error |= _irq_alloc->alloc_addr(1, irq_number).is_error(); + long irq_nr = Arg_string::find_arg(args, "irq_number").long_value(-1); + bool error = irq_nr < 0 || !_irq_alloc; + + /* enable platform specific code to apply mappings */ + long const plat_irq_nr = Platform::irq(irq_nr); + + error |= _irq_alloc->alloc_addr(1, plat_irq_nr).is_error(); if (error) { PERR("unavailable interrupt requested"); throw Root::Invalid_args(); } /* make interrupt accessible */ - _irq_number = (unsigned)irq_number; - _signal = Kernel::User_irq::signal(irq_number); - _cap = Irq_session_capability(irq_session_ep()->manage(this)); + _irq_number = (unsigned)plat_irq_nr; + _signal = Kernel::User_irq::signal(plat_irq_nr); + _cap = Irq_session_capability(irq_session_ep()->manage(this)); } diff --git a/repos/base-hw/src/core/spec/arm/platform_support.cc b/repos/base-hw/src/core/spec/arm/platform_support.cc index 91f34eee6..8666bb000 100644 --- a/repos/base-hw/src/core/spec/arm/platform_support.cc +++ b/repos/base-hw/src/core/spec/arm/platform_support.cc @@ -17,3 +17,6 @@ using namespace Genode; void Platform::_init_io_port_alloc() { }; + + +long Platform::irq(long const user_irq) { return user_irq; } \ No newline at end of file diff --git a/repos/base-hw/src/core/spec/x86/platform_support.cc b/repos/base-hw/src/core/spec/x86/platform_support.cc index 2b9c99cf5..5309fd07c 100644 --- a/repos/base-hw/src/core/spec/x86/platform_support.cc +++ b/repos/base-hw/src/core/spec/x86/platform_support.cc @@ -61,4 +61,12 @@ void Platform::_init_io_port_alloc() } +long Platform::irq(long const user_irq) +{ + /* remap IRQ requests to fit I/O APIC configuration */ + if (user_irq) return user_irq + Board::VECTOR_REMAP_BASE; + return Board::TIMER_VECTOR_USER; +} + + Cpu::User_context::User_context() { }