mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
eefaa07024
By adding the `irq_type` argument, one can explicitly specify whether to use LEGACY, MSI or MSI-X interrupts. We formerly used the `device_phys_config` to implicitly select MSI, however, with the addition of IOMMU support to the platform driver there is at least one instance where we need an MSI for a non-PCI device. Yet, by adding another session argument to the Irq session, we exceed the character limit for session args. Since not all arguments are relevant for LEGACY interrupts resp. MSI, we can split the Irq_connection constructor to handle the two cases separately and omit unneeded arguments. genodelabs/genode#5002
123 lines
2.8 KiB
C++
123 lines
2.8 KiB
C++
/*
|
|
* \brief IRQ session interface
|
|
* \author Christian Helmuth
|
|
* \author Martin Stein
|
|
* \date 2007-09-13
|
|
*
|
|
* An open IRQ session represents a valid IRQ attachment/association.
|
|
* Initially, the interrupt is masked and will only occur if enabled. This is
|
|
* done by calling ack_irq().
|
|
*
|
|
* Disassociation from an IRQ is done by closing the session.
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2007-2017 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU Affero General Public License version 3.
|
|
*/
|
|
|
|
#ifndef _INCLUDE__IRQ_SESSION__IRQ_SESSION_H_
|
|
#define _INCLUDE__IRQ_SESSION__IRQ_SESSION_H_
|
|
|
|
#include <base/signal.h>
|
|
#include <base/capability.h>
|
|
#include <session/session.h>
|
|
|
|
namespace Genode {
|
|
struct Irq_session;
|
|
}
|
|
|
|
|
|
struct Genode::Irq_session : Session
|
|
{
|
|
struct Info {
|
|
enum Type { INVALID, MSI } type;
|
|
unsigned long address;
|
|
unsigned long value;
|
|
};
|
|
|
|
/**
|
|
* Interrupt trigger
|
|
*/
|
|
enum Trigger { TRIGGER_UNCHANGED = 0, TRIGGER_LEVEL, TRIGGER_EDGE };
|
|
|
|
/**
|
|
* Interrupt trigger polarity
|
|
*/
|
|
enum Polarity { POLARITY_UNCHANGED = 0, POLARITY_HIGH, POLARITY_LOW };
|
|
|
|
/**
|
|
* Interrupt type
|
|
*/
|
|
enum Type { TYPE_LEGACY = 0, TYPE_MSI, TYPE_MSIX };
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~Irq_session() { }
|
|
|
|
/**
|
|
* Acknowledge handling of last interrupt - re-enables interrupt reception
|
|
*/
|
|
virtual void ack_irq() = 0;
|
|
|
|
/**
|
|
* Register irq signal handler
|
|
*/
|
|
virtual void sigh(Genode::Signal_context_capability sigh) = 0;
|
|
|
|
/**
|
|
* Request information about IRQ, e.g. on x86 request MSI address and
|
|
* MSI value to be programmed to device specific PCI registers.
|
|
*/
|
|
virtual Info info() = 0;
|
|
|
|
/*************
|
|
** Session **
|
|
*************/
|
|
|
|
/**
|
|
* \noapi
|
|
*/
|
|
static const char * service_name() { return "IRQ"; }
|
|
|
|
static constexpr unsigned CAP_QUOTA = 3;
|
|
static constexpr size_t RAM_QUOTA = 6*1024;
|
|
|
|
|
|
/*********************
|
|
** RPC declaration **
|
|
*********************/
|
|
|
|
GENODE_RPC(Rpc_ack_irq, void, ack_irq);
|
|
GENODE_RPC(Rpc_sigh, void, sigh, Genode::Signal_context_capability);
|
|
GENODE_RPC(Rpc_info, Info, info);
|
|
GENODE_RPC_INTERFACE(Rpc_ack_irq, Rpc_sigh, Rpc_info);
|
|
};
|
|
|
|
|
|
namespace Genode {
|
|
|
|
static inline void print(Output &out, Irq_session::Trigger value)
|
|
{
|
|
switch (value) {
|
|
case Irq_session::TRIGGER_UNCHANGED: print(out, "UNCHANGED"); break;
|
|
case Irq_session::TRIGGER_LEVEL: print(out, "LEVEL"); break;
|
|
case Irq_session::TRIGGER_EDGE: print(out, "EDGE"); break;
|
|
}
|
|
}
|
|
|
|
static inline void print(Output &out, Irq_session::Polarity value)
|
|
{
|
|
switch (value) {
|
|
case Irq_session::POLARITY_UNCHANGED: print(out, "UNCHANGED"); break;
|
|
case Irq_session::POLARITY_HIGH: print(out, "HIGH"); break;
|
|
case Irq_session::POLARITY_LOW: print(out, "LOW"); break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif /* _INCLUDE__IRQ_SESSION__IRQ_SESSION_H_ */
|