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
257 lines
4.8 KiB
C++
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);
|
|
}
|
|
|
|
}
|