genode/repos/ports-foc/src/lib/l4lx/l4lx_irq.cc
Norman Feske 17c79a9e23 base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.

While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).

To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.

Issue #1987
2016-08-29 17:27:10 +02:00

257 lines
4.8 KiB
C++

/*
* \brief L4lxapi library IRQ functions.
* \author Stefan Kalkowski
* \date 2011-04-11
*/
/*
* Copyright (C) 2011-2013 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.
*/
/* Genode includes */
#include <base/log.h>
#include <base/snprintf.h>
#include <env.h>
#include <l4lx_irq.h>
#include <l4lx_thread.h>
#include <vcpu.h>
namespace Fiasco {
#include <l4/sys/types.h>
#include <l4/sys/kdebug.h>
#include <l4/sys/kip.h>
#include <l4/sys/vcpu.h>
#include <l4/sys/irq.h>
}
using namespace Fiasco;
enum { TIMER_IRQ = 0 };
unsigned int l4lx_irq_max = l4x_nr_irqs();
extern l4_kernel_info_t *l4lx_kinfo;
extern "C" {
FASTCALL l4_cap_idx_t l4x_have_irqcap(int irqnum);
void l4lx_irq_init(void) { }
int l4lx_irq_prio_get(unsigned int irq)
{
NOT_IMPLEMENTED;
return 0;
}
unsigned int l4lx_irq_dev_startup(struct irq_data *data)
{
unsigned irq = data->irq;
struct l4x_irq_desc_private *p =
(struct l4x_irq_desc_private*) irq_get_chip_data(irq);
/* First test whether a capability has been registered with
* this IRQ number */
p->irq_cap = l4x_have_irqcap(irq);
p->cpu = l4x_smp_processor_id();
if (l4_is_invalid_cap(p->irq_cap)) {
Genode::error("invalid irq cap!");
return 0;
}
l4lx_irq_dev_enable(data);
return 1;
}
void l4lx_irq_dev_shutdown(struct irq_data *data)
{
if (data->irq == TIMER_IRQ) {
Genode::warning("timer shutdown not implemented yet");
return;
}
l4lx_irq_dev_disable(data);
}
int l4lx_irq_set_type(struct irq_data *data, unsigned int type)
{
NOT_IMPLEMENTED;
return 0;
}
void l4lx_irq_dev_enable(struct irq_data *data)
{
struct l4x_irq_desc_private *p =
(struct l4x_irq_desc_private*) irq_get_chip_data(data->irq);;
unsigned long flags = 0;
p->enabled = 1;
l4x_irq_save(&flags);
l4_msgtag_t ret = l4_irq_attach(p->irq_cap, data->irq << 2,
l4x_cpu_thread_get_cap(p->cpu));
if (l4_error(ret))
Genode::warning("attach to irq ", Genode::Hex(p->irq_cap), " "
"failed, error=", l4_error(ret));
l4x_irq_restore(flags);
l4lx_irq_dev_eoi(data);
}
void l4lx_irq_dev_disable(struct irq_data *data)
{
struct l4x_irq_desc_private *p =
(struct l4x_irq_desc_private*) irq_get_chip_data(data->irq);;
p->enabled = 0;
Linux::Irq_guard guard;
if (l4_error(l4_irq_detach(p->irq_cap)))
Genode::warning("unable to detach from IRQ ", data->irq);
}
void l4lx_irq_dev_ack(struct irq_data *data) { }
void l4lx_irq_dev_mask(struct irq_data *data)
{
NOT_IMPLEMENTED;
}
void l4lx_irq_dev_mask_ack(struct irq_data *data)
{
// NOT_IMPLEMENTED;
}
void l4lx_irq_dev_unmask(struct irq_data *data)
{
// NOT_IMPLEMENTED;
}
int l4lx_irq_dev_set_affinity(struct irq_data *data,
const struct cpumask *dest, bool force)
{
struct l4x_irq_desc_private *p =
(struct l4x_irq_desc_private*) irq_get_chip_data(data->irq);;
if (!p->irq_cap)
return 0;
unsigned target_cpu = l4x_target_cpu(dest);
if ((int)target_cpu == -1)
return 1;
if (target_cpu == p->cpu)
return 0;
unsigned long flags = 0;
l4x_migrate_lock(&flags);
if (l4_error(l4_irq_detach(p->irq_cap)))
Genode::warning("unable to detach from IRQ ", data->irq);
l4x_cpumask_copy(data, dest);
p->cpu = target_cpu;
Genode::log("switched irq ", data->irq, " to cpu ", target_cpu);
l4_msgtag_t ret = l4_irq_attach(p->irq_cap, data->irq << 2,
l4x_cpu_thread_get_cap(p->cpu));
if (l4_error(ret))
Genode::warning("attach to irq ", p->irq_cap, " failed, error=", l4_error(ret));
if (p->enabled)
l4_irq_unmask(p->irq_cap);
l4x_migrate_unlock(flags);
return 0;
}
void l4lx_irq_dev_eoi(struct irq_data *data)
{
struct l4x_irq_desc_private *p =
(struct l4x_irq_desc_private*) irq_get_chip_data(data->irq);;
Linux::Irq_guard guard;
l4_irq_unmask(p->irq_cap);
}
unsigned int l4lx_irq_timer_startup(struct irq_data *data)
{
NOT_IMPLEMENTED;
return 0;
}
void l4lx_irq_timer_shutdown(struct irq_data *data)
{
NOT_IMPLEMENTED;
}
void l4lx_irq_timer_enable(struct irq_data *data)
{
NOT_IMPLEMENTED;
}
void l4lx_irq_timer_disable(struct irq_data *data)
{
NOT_IMPLEMENTED;
}
void l4lx_irq_timer_ack(struct irq_data *data)
{
NOT_IMPLEMENTED;
}
void l4lx_irq_timer_mask(struct irq_data *data)
{
NOT_IMPLEMENTED;
}
void l4lx_irq_timer_unmask(struct irq_data *data)
{
NOT_IMPLEMENTED;
}
int l4lx_irq_timer_set_affinity(struct irq_data *data, const struct cpumask *dest)
{
NOT_IMPLEMENTED;
return 0;
}
int l4x_alloc_irq_desc_data(int irq)
{
struct l4x_irq_desc_private *p;
Genode::env()->heap()->alloc(sizeof(struct l4x_irq_desc_private), (void**)&p);
if (!p) {
Genode::warning("could not allocate irq descriptor memory!");
return -12; //ENOMEM;
}
return irq_set_chip_data(irq, p);
}
}