base: factor out irq parsing into helper header

to be used by sel4 in the next commit

Issue #2044
This commit is contained in:
Alexander Boettcher 2016-07-26 11:34:29 +02:00 committed by Christian Helmuth
parent 464181b01d
commit cb675a12d8
3 changed files with 93 additions and 84 deletions

View File

@ -20,6 +20,7 @@
/* core includes */
#include <irq_root.h>
#include <irq_args.h>
#include <irq_session_component.h>
#include <platform.h>
#include <util.h>
@ -185,60 +186,26 @@ Irq_session_component::Irq_session_component(Range_allocator *irq_alloc,
:
_irq_number(~0U), _irq_alloc(irq_alloc)
{
long irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
Irq_args const irq_args(args);
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);
if (msi_alloc.get(irq_args.irq_number(), 1)) {
PERR("Unavailable MSI %ld requested.", irq_args.irq_number());
throw Root::Unavailable();
}
msi_alloc.set(irq_number, 1);
msi_alloc.set(irq_args.irq_number(), 1);
} else {
if (!irq_alloc || irq_alloc->alloc_addr(1, irq_number).error()) {
PERR("Unavailable IRQ %ld requested.", irq_number);
if (!irq_alloc || irq_alloc->alloc_addr(1, irq_args.irq_number()).error()) {
PERR("Unavailable IRQ %ld requested.", irq_args.irq_number());
throw Root::Unavailable();
}
}
_irq_number = irq_number;
_irq_number = irq_args.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);
Irq_session::Trigger irq_trigger;
Irq_session::Polarity irq_polarity;
switch(irq_t) {
case -1:
case Irq_session::TRIGGER_UNCHANGED:
irq_trigger = Irq_session::TRIGGER_UNCHANGED;
break;
case Irq_session::TRIGGER_EDGE:
irq_trigger = Irq_session::TRIGGER_EDGE;
break;
case Irq_session::TRIGGER_LEVEL:
irq_trigger = Irq_session::TRIGGER_LEVEL;
break;
default:
throw Root::Unavailable();
}
switch(irq_p) {
case -1:
case POLARITY_UNCHANGED:
irq_polarity = POLARITY_UNCHANGED;
break;
case POLARITY_HIGH:
irq_polarity = POLARITY_HIGH;
break;
case POLARITY_LOW:
irq_polarity = POLARITY_LOW;
break;
default:
throw Root::Unavailable();
}
_irq_object.associate(_irq_number, msi, irq_trigger, irq_polarity);
_irq_object.associate(_irq_number, msi, irq_args.trigger(),
irq_args.polarity());
}

View File

@ -18,6 +18,7 @@
/* core includes */
#include <kernel/irq.h>
#include <irq_root.h>
#include <irq_args.h>
#include <core_env.h>
/* base-internal includes */
@ -89,45 +90,7 @@ Irq_session_component::Irq_session_component(Range_allocator * const irq_alloc,
throw Root::Invalid_args();
}
long irq_trg = Arg_string::find_arg(args, "irq_trigger").long_value(-1);
long irq_pol = Arg_string::find_arg(args, "irq_polarity").long_value(-1);
Irq_args const irq_args(args);
Irq_session::Trigger irq_trigger;
Irq_session::Polarity irq_polarity;
switch(irq_trg) {
case -1:
case Irq_session::TRIGGER_UNCHANGED:
irq_trigger = Irq_session::TRIGGER_UNCHANGED;
break;
case Irq_session::TRIGGER_EDGE:
irq_trigger = Irq_session::TRIGGER_EDGE;
break;
case Irq_session::TRIGGER_LEVEL:
irq_trigger = Irq_session::TRIGGER_LEVEL;
break;
default:
PERR("invalid trigger mode %ld specified for IRQ %u", irq_trg,
_irq_number);
throw Root::Unavailable();
}
switch(irq_pol) {
case -1:
case POLARITY_UNCHANGED:
irq_polarity = POLARITY_UNCHANGED;
break;
case POLARITY_HIGH:
irq_polarity = POLARITY_HIGH;
break;
case POLARITY_LOW:
irq_polarity = POLARITY_LOW;
break;
default:
PERR("invalid polarity %ld specified for IRQ %u", irq_pol,
_irq_number);
throw Root::Unavailable();
}
Platform::setup_irq_mode(_irq_number, irq_trigger, irq_polarity);
Platform::setup_irq_mode(_irq_number, irq_args.trigger(), irq_args.polarity());
}

View File

@ -0,0 +1,79 @@
/*
* \brief Utility to parse IRQ session arguments
* \author Alexander Boettcher
* \date 2016-07-20
*/
/*
* Copyright (C) 2016 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_ARGS_H_
#define _CORE__INCLUDE__IRQ_ARGS_H_
#include <base/log.h>
#include <util/arg_string.h>
#include <irq_session/irq_session.h>
namespace Genode { class Irq_args; }
class Genode::Irq_args
{
private:
Irq_session::Trigger _irq_trigger;
Irq_session::Polarity _irq_polarity;
long _irq_number;
public:
Irq_args(const char * args)
{
_irq_number = Arg_string::find_arg(args, "irq_number").long_value(-1);
long irq_trg = Arg_string::find_arg(args, "irq_trigger").long_value(-1);
long irq_pol = Arg_string::find_arg(args, "irq_polarity").long_value(-1);
switch (irq_trg) {
case -1:
case Irq_session::TRIGGER_UNCHANGED:
_irq_trigger = Irq_session::TRIGGER_UNCHANGED;
break;
case Irq_session::TRIGGER_EDGE:
_irq_trigger = Irq_session::TRIGGER_EDGE;
break;
case Irq_session::TRIGGER_LEVEL:
_irq_trigger = Irq_session::TRIGGER_LEVEL;
break;
default:
error("invalid trigger mode ", irq_trg, " specified for IRQ ",
_irq_number);
throw Root::Unavailable();
}
switch (irq_pol) {
case -1:
case Irq_session::POLARITY_UNCHANGED:
_irq_polarity = Irq_session::POLARITY_UNCHANGED;
break;
case Irq_session::POLARITY_HIGH:
_irq_polarity = Irq_session::POLARITY_HIGH;
break;
case Irq_session::POLARITY_LOW:
_irq_polarity = Irq_session::POLARITY_LOW;
break;
default:
error("invalid polarity ", irq_pol, " specified for IRQ ",
_irq_number);
throw Root::Unavailable();
}
}
long irq_number() const { return _irq_number; }
Irq_session::Trigger trigger() const { return _irq_trigger; }
Irq_session::Polarity polarity() const { return _irq_polarity; }
};
#endif /* _CORE__INCLUDE__IRQ_ARGS_H_ */