MVIC: handle boards with fixed IRQ to vector mapping

Change-Id: I319bc2a18310a6a6808fced3e142640e225236d2
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
Anas Nashif 2015-07-02 18:59:02 -04:00
commit 7625b098b9

View file

@ -30,6 +30,36 @@
#include <drivers/ioapic.h>
#include <drivers/loapic.h>
#if !defined(LOAPIC_IRQ_BASE) && !defined (LOAPIC_IRQ_COUNT)
/* Default IA32 system APIC definitions with local APIC IRQs after IO APIC. */
#define LOAPIC_IRQ_BASE CONFIG_IOAPIC_NUM_RTES
#define LOAPIC_IRQ_COUNT 6 /* Default to LOAPIC_TIMER to LOAPIC_ERROR */
#define IS_IOAPIC_IRQ(irq) (irq < LOAPIC_IRQ_BASE)
#define HARDWARE_IRQ_LIMIT ((LOAPIC_IRQ_BASE + LOAPIC_IRQ_COUNT) - 1)
#else
/*
Assumption for boards that define LOAPIC_IRQ_BASE & LOAPIC_IRQ_COUNT that
local APIC IRQs are within IOAPIC RTE range.
*/
#define IS_IOAPIC_IRQ(irq) ((irq < LOAPIC_IRQ_BASE) || \
(irq >= (LOAPIC_IRQ_BASE + LOAPIC_IRQ_COUNT)))
#define HARDWARE_IRQ_LIMIT (CONFIG_IOAPIC_NUM_RTES - 1)
#endif
/* forward declarations */
static int __LocalIntVecAlloc(unsigned int irq, unsigned int priority);
/**
*
* @brief Allocate interrupt vector
@ -85,18 +115,11 @@ int _SysIntVecAlloc(
#if defined(CONFIG_LOAPIC_DEBUG)
if ((priority > 15) ||
((irq > (CONFIG_IOAPIC_NUM_RTES + 5)) && (irq != NANO_SOFT_IRQ)))
((irq > HARDWARE_IRQ_LIMIT) && (irq != NANO_SOFT_IRQ)))
return -1;
#endif
/*
* Use the nanokernel utility function _IntVecAlloc(). A value of
* -1 will be returned if there are no free vectors in the requested
* priority.
*/
vector = _IntVecAlloc(priority);
__ASSERT(vector != -1, "No free vectors in the requested priority");
vector = __LocalIntVecAlloc(irq, priority);
/*
* Set up the appropriate interrupt controller to generate the allocated
@ -145,15 +168,13 @@ int _SysIntVecAlloc(
*/
void _SysIntVecProgram(unsigned int vector, unsigned int irq, uint32_t flags)
{
if (irq < CONFIG_IOAPIC_NUM_RTES) {
if (IS_IOAPIC_IRQ(irq)) {
_ioapic_irq_set(irq, vector, flags);
} else {
_loapic_int_vec_set(irq - CONFIG_IOAPIC_NUM_RTES, vector);
_loapic_int_vec_set(irq - LOAPIC_IRQ_BASE, vector);
}
}
/**
*
* @brief Enable an individual interrupt (IRQ)
@ -173,10 +194,10 @@ void _SysIntVecProgram(unsigned int vector, unsigned int irq, uint32_t flags)
*/
void irq_enable(unsigned int irq)
{
if (irq < CONFIG_IOAPIC_NUM_RTES) {
if (IS_IOAPIC_IRQ(irq)) {
_ioapic_irq_enable(irq);
} else {
_loapic_irq_enable(irq - CONFIG_IOAPIC_NUM_RTES);
_loapic_irq_enable(irq - LOAPIC_IRQ_BASE);
}
}
@ -193,9 +214,65 @@ void irq_enable(unsigned int irq)
*/
void irq_disable(unsigned int irq)
{
if (irq < CONFIG_IOAPIC_NUM_RTES) {
if (IS_IOAPIC_IRQ(irq)) {
_ioapic_irq_disable(irq);
} else {
_loapic_irq_disable(irq - CONFIG_IOAPIC_NUM_RTES);
_loapic_irq_disable(irq - LOAPIC_IRQ_BASE);
}
}
#ifdef FIXED_HARDWARE_IRQ_TO_VEC_MAPPING
static inline int handle_fixed_mapping(int irq, int *vector)
{
if (irq != NANO_SOFT_IRQ) {
/*
* On this board Hardware IRQs are fixed and not programmable.
*/
*vector = FIXED_HARDWARE_IRQ_TO_VEC_MAPPING(irq);
/* mark vector as allocated */
_IntVecMarkAllocated(*vector);
return *vector;
}
return 0;
}
#else
static inline int handle_fixed_mapping(int irq, int *vector)
{
ARG_UNUSED(irq);
ARG_UNUSED(vector);
return 0;
}
#endif
/**
*
* @brief Local allocate interrupt vector.
*
* @returns The allocated interrupt vector
*
*/
static int __LocalIntVecAlloc(
unsigned int irq, /* virtualized IRQ */
unsigned int priority /* get vector from <priority> group */
)
{
int vector;
if (handle_fixed_mapping(irq, &vector)) {
return vector;
}
/*
* Use the nanokernel utility function _IntVecAlloc(). A value of
* -1 will be returned if there are no free vectors in the requested
* priority.
*/
vector = _IntVecAlloc(priority);
__ASSERT(vector != -1, "No free vectors in the requested priority");
return vector;
}