2012-05-30 20:13:09 +02:00
|
|
|
/*
|
2013-10-30 13:56:57 +01:00
|
|
|
* \brief Backend for IRQ sessions served by core
|
2012-05-30 20:13:09 +02:00
|
|
|
* \author Martin Stein
|
|
|
|
* \date 2012-02-12
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 21:44:47 +01:00
|
|
|
* Copyright (C) 2012-2013 Genode Labs GmbH
|
2012-05-30 20:13:09 +02:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
2013-11-14 17:29:34 +01:00
|
|
|
/* base-hw includes */
|
|
|
|
#include <kernel/interface.h>
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
/* core includes */
|
2013-10-30 13:56:57 +01:00
|
|
|
#include <kernel/irq.h>
|
2012-05-30 20:13:09 +02:00
|
|
|
#include <irq_root.h>
|
2013-10-30 13:56:57 +01:00
|
|
|
#include <core_env.h>
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
using namespace Genode;
|
|
|
|
|
2013-10-30 13:56:57 +01:00
|
|
|
/**
|
|
|
|
* On other platforms, every IRQ session component creates its entrypoint.
|
|
|
|
* However, on base-hw this isn't necessary as users can wait for their
|
|
|
|
* interrupts directly. Instead of replacing cores generic irq_root.h and
|
|
|
|
* main.cc with base-hw specific versions, we simply use a local singleton.h
|
|
|
|
*/
|
|
|
|
static Rpc_entrypoint * irq_session_ep()
|
|
|
|
{
|
|
|
|
enum { STACK_SIZE = 2048 };
|
|
|
|
static Rpc_entrypoint
|
|
|
|
_ep(core_env()->cap_session(), STACK_SIZE, "irq_session_ep");
|
|
|
|
return &_ep;
|
|
|
|
}
|
2012-05-30 20:13:09 +02:00
|
|
|
|
2013-10-30 13:56:57 +01:00
|
|
|
void Irq_session_component::wait_for_irq() { PERR("not implemented"); }
|
2012-05-30 20:13:09 +02:00
|
|
|
|
2013-10-30 13:56:57 +01:00
|
|
|
Irq_signal Irq_session_component::signal() { return _signal; }
|
2012-05-30 20:13:09 +02:00
|
|
|
|
2013-10-30 13:56:57 +01:00
|
|
|
Irq_session_component::~Irq_session_component() { PERR("not implemented"); }
|
2012-05-30 20:13:09 +02:00
|
|
|
|
|
|
|
|
2013-10-30 13:56:57 +01:00
|
|
|
Irq_session_component::Irq_session_component(Cap_session * const cap_session,
|
|
|
|
Range_allocator * const irq_alloc,
|
|
|
|
const char * const args)
|
2012-05-30 20:13:09 +02:00
|
|
|
:
|
2013-10-30 13:56:57 +01:00
|
|
|
_irq_alloc(irq_alloc)
|
2012-05-30 20:13:09 +02:00
|
|
|
{
|
|
|
|
/* check arguments */
|
|
|
|
bool shared = Arg_string::find_arg(args, "irq_shared").bool_value(false);
|
|
|
|
if (shared) {
|
2013-10-30 13:56:57 +01:00
|
|
|
PERR("shared interrupts not supported");
|
2012-05-30 20:13:09 +02:00
|
|
|
throw Root::Invalid_args();
|
|
|
|
}
|
2013-10-30 13:56:57 +01:00
|
|
|
/* allocate interrupt */
|
2012-05-30 20:13:09 +02:00
|
|
|
long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
|
2013-10-30 13:56:57 +01:00
|
|
|
bool error = irq_number < 0 || !_irq_alloc;
|
|
|
|
error |= _irq_alloc->alloc_addr(1, irq_number).is_error();
|
|
|
|
if (error) {
|
|
|
|
PERR("unavailable interrupt requested");
|
2012-05-30 20:13:09 +02:00
|
|
|
throw Root::Invalid_args();
|
|
|
|
}
|
2013-10-30 13:56:57 +01:00
|
|
|
/* make interrupt accessible */
|
|
|
|
_signal = Irq::signal(irq_number);
|
|
|
|
_cap = Irq_session_capability(irq_session_ep()->manage(this));
|
2012-05-30 20:13:09 +02:00
|
|
|
}
|