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:
parent
00c4d32d42
commit
7625b098b9
1 changed files with 94 additions and 17 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue