IRQ_CONNECT_STATIC implementation for x86 platform

In order to simplify x86 interrupt stub creation, each interrupt
controller implements an interrupt stub definition macro.

Add IRQ_CONNECT_STATIC() for static interrupt registration, and
construct the interrupt stubs name from device and interrupt
handler names.

Add IRQ_CONFIG() macro for the interrupt controller configuration.
On x86 platform it programs APIC to associate an IRQ number with
the interupt vector.

Add HPET_TIMER0_INT_PRI parameter to Quark platform header to
make it build correctly.

Change-Id: I24ad25e1aa807ffa63733a27ad882877fcad72af
Signed-off-by: Dmitriy Korovkin <dmitriy.korovkin@windriver.com>
This commit is contained in:
Dmitriy Korovkin 2015-06-01 14:14:31 -04:00 committed by Anas Nashif
parent 99b340e2ef
commit 6dd108a263
12 changed files with 150 additions and 132 deletions

View file

@ -46,30 +46,37 @@ by x86 BSPs.
#include <drivers/pic.h>
#include <drivers/system_timer.h>
/* exports (internal APIs) */
#if defined(CONFIG_LOAPIC_TIMER)
GTEXT(_loapic_timer_irq_stub)
#endif
#if defined(CONFIG_HPET_TIMER)
GTEXT(_hpetIntStub)
#endif
#if defined (CONFIG_PIC)
GTEXT(_masterStrayIntStub)
GTEXT(_slaveStrayIntStub)
GTEXT(_pic_master__i8259_boi_master_stub)
GTEXT(_pic_slave__i8259_boi_slave_stub)
#endif
#if defined (CONFIG_PIT)
GTEXT(_i8253_interrupt_stub)
pic_master_mkstub i8253 _timer_int_handler
#endif
#if defined(CONFIG_LOAPIC_TIMER)
loapic_mkstub loapic _timer_int_handler
#endif
#if defined(CONFIG_HPET_TIMER)
ioapic_mkstub hpet _timer_int_handler
#endif
#if defined(CONFIG_BLUETOOTH_UART)
GTEXT(_bluetooth_uart_stub)
#endif /* CONFIG_BLUETOOTH */
#if defined(CONFIG_PIC)
pic_master_mkstub bluetooth bt_uart_isr
#elif defined(CONFIG_IOAPIC)
ioapic_mkstub bluetooth bt_uart_isr
#endif /* CONFIG_PIC */
#endif /* CONFIG_BLUETOOTH_UART */
#if defined(CONFIG_CONSOLE_HANDLER)
GTEXT(_console_uart_stub)
#if defined(CONFIG_PIC)
pic_master_mkstub console uart_console_isr
#elif defined(CONFIG_IOAPIC)
ioapic_mkstub console uart_console_isr
#endif /* CONFIG_PIC */
#endif /* CONFIG_CONSOLE_HANDLER */
/* externs (internal APIs) */
@ -77,28 +84,8 @@ by x86 BSPs.
GTEXT(_IntEnt)
GTEXT(_IntExit)
#if defined(CONFIG_LOAPIC_TIMER)
SECTION_FUNC (TEXT, _loapic_timer_irq_stub)
call _IntEnt /* Inform kernel interrupt has begun */
pushl $0 /* Push dummy parameter */
call _timer_int_handler /* Call actual interrupt handler */
call _loapic_eoi /* Inform loapic interrupt is done */
addl $4, %esp /* Clean-up stack from push above */
jmp _IntExit /* Inform kernel interrupt is done */
#endif /* CONFIG_LOAPIC_TIMER */
#if defined(CONFIG_HPET_TIMER)
SECTION_FUNC(TEXT, _hpetIntStub)
call _IntEnt /* Inform kernel interrupt has begun */
pushl $0 /* Push dummy parameter */
call _timer_int_handler /* Call actual interrupt handler */
call _ioapic_eoi /* Inform ioapic interrupt is done */
addl $4, %esp /* Clean-up stack from push above */
jmp _IntExit /* Inform kernel interrupt is done */
#endif /* CONFIG_HPET_TIMER */
#if defined(CONFIG_PIC)
SECTION_FUNC(TEXT, _masterStrayIntStub)
SECTION_FUNC(TEXT, _pic_master__i8259_boi_master_stub)
/*
* Handle possible spurious (stray) interrupts on IRQ 7. Since on this
* particular BSP, no device is hooked up to IRQ 7, a C level ISR is
@ -118,7 +105,7 @@ SECTION_FUNC(TEXT, _masterStrayIntStub)
* jmp _IntExit /+ Inform kernel interrupt is done +/
*/
SECTION_FUNC(TEXT, _slaveStrayIntStub)
SECTION_FUNC(TEXT, _pic_slave__i8259_boi_slave_stub)
/*
* Handle possible spurious (stray) interrupts on IRQ 15 (slave PIC
* IRQ 7). Since on this particular BSP, no device is hooked up to
@ -140,56 +127,4 @@ SECTION_FUNC(TEXT, _slaveStrayIntStub)
*/
#endif /* CONFIG_PIC */
#if defined(CONFIG_PIT)
SECTION_FUNC(TEXT, _i8253_interrupt_stub)
call _IntEnt /* Inform kernel interrupt has begun */
pushl $0 /* Push dummy parameter */
call _timer_int_handler /* Call actual interrupt handler */
call _i8259_eoi_master /* Inform the PIC interrupt is done */
addl $4, %esp /* Clean-up stack from push above */
jmp _IntExit /* Inform kernel interrupt is done */
#endif /* CONFIG_PIT */
#if defined(CONFIG_BLUETOOTH_UART)
#if defined(CONFIG_PIC)
SECTION_FUNC(TEXT, _bluetooth_uart_stub)
call _IntEnt /* Inform kernel interrupt has begun */
pushl $0 /* Push dummy parameter */
call bt_uart_isr /* Call actual interrupt handler */
call _i8259_eoi_master /* Inform the PIC interrupt is done */
addl $4, %esp /* Clean-up stack from push above */
jmp _IntExit /* Inform kernel interrupt is done */
#elif defined(CONFIG_IOAPIC)
SECTION_FUNC(TEXT, _bluetooth_uart_stub)
call _IntEnt /* Inform kernel interrupt has begun */
pushl $0 /* Push dummy parameter */
call bt_uart_isr /* Call actual interrupt handler */
call _ioapic_eoi /* Inform the PIC interrupt is done */
addl $4, %esp /* Clean-up stack from push above */
jmp _IntExit /* Inform kernel interrupt is done */
#endif /* CONFIG_PIC */
#endif /* CONFIG_BLUETOOTH_UART */
#if defined(CONFIG_CONSOLE_HANDLER)
#if defined(CONFIG_PIC)
SECTION_FUNC(TEXT, _console_uart_stub)
call _IntEnt /* Inform kernel interrupt has begun */
pushl $0 /* Push dummy parameter */
call uart_console_isr /* Call actual interrupt handler */
call _i8259_eoi_master /* Inform the PIC interrupt is done */
addl $4, %esp /* Clean-up stack from push above */
jmp _IntExit /* Inform kernel interrupt is done */
#elif defined(CONFIG_IOAPIC)
SECTION_FUNC(TEXT, _console_uart_stub)
call _IntEnt /* Inform kernel interrupt has begun */
pushl $0 /* Push dummy parameter */
call uart_console_isr /* Call actual interrupt handler */
call _ioapic_eoi /* Inform the PIC interrupt is done */
addl $4, %esp /* Clean-up stack from push above */
jmp _IntExit /* Inform kernel interrupt is done */
#endif /* CONFIG_PIC */
#endif /* CONFIG_CONSOLE_HANDLER */
#endif /* !CONFIG_DYNAMIC_INT_STUBS */

View file

@ -165,15 +165,6 @@ the 'generic_pc' BSP.
#define PIT_BASE_ADRS 0x40
#define PIT_REG_ADDR_INTERVAL 1
#ifndef _ASMLANGUAGE
/*
* The <pri> parameter is deliberately ignored. For this BSP, the macro just has
* to make sure that unique vector numbers are generated.
*/
#define SYS_INT_REGISTER(s, irq, pri) \
NANO_CPU_INT_REGISTER(s, INT_VEC_IRQ0 + (irq), 0)
#endif
#ifndef _ASMLANGUAGE
/*
* Device drivers utilize the macros PLB_BYTE_REG_WRITE() and

View file

@ -105,9 +105,8 @@ static void uartGenericInfoInit(struct uart_init_info *p_info)
#endif /* DO_CONSOLE_INIT */
#if defined(CONFIG_CONSOLE_HANDLER)
extern void *_console_uart_stub;
SYS_INT_REGISTER(_console_uart_stub,
CONFIG_UART_CONSOLE_IRQ, CONFIG_UART_CONSOLE_INT_PRI);
IRQ_CONNECT_STATIC(console, CONFIG_UART_CONSOLE_IRQ,
CONFIG_UART_CONSOLE_INT_PRI, uart_console_isr, 0);
#endif /* CONFIG_CONSOLE_HANDLER */
#if defined(DO_CONSOLE_INIT)
@ -143,10 +142,8 @@ static void consoleInit(void)
#if defined(CONFIG_BLUETOOTH_UART)
#include <bluetooth/uart.h>
/* Interrupt handling */
extern void *_bluetooth_uart_stub;
SYS_INT_REGISTER(_bluetooth_uart_stub,
CONFIG_BLUETOOTH_UART_IRQ,
CONFIG_BLUETOOTH_UART_INT_PRI);
IRQ_CONNECT_STATIC(bluetooth, CONFIG_BLUETOOTH_UART_IRQ,
CONFIG_BLUETOOTH_UART_INT_PRI, bt_uart_isr, 0);
#endif /* CONFIG_BLUETOOTH_UART */
static void bluetooth_init(void)
{

View file

@ -77,6 +77,7 @@ the 'Quark' BSP.
#define HPET_TIMER0_IRQ (20)
#define HPET_TIMER0_VEC (HPET_TIMER0_IRQ + INT_VEC_IRQ0)
#define HPET_TIMER0_INT_PRI (4)
/* HPET uses falling edge triggered interrupt */
#define HPET_IOAPIC_FLAGS (IOAPIC_EDGE | IOAPIC_LOW)
@ -129,15 +130,6 @@ the 'Quark' BSP.
*/
#define LOAPIC_VEC_BASE(x) (x + INT_VEC_IRQ0 + IOAPIC_NUM_RTES)
#ifndef _ASMLANGUAGE
/*
* The <pri> parameter is deliberately ignored. For this BSP, the macro just has
* to make sure that unique vector numbers are generated.
*/
#define SYS_INT_REGISTER(s, irq, pri) \
NANO_CPU_INT_REGISTER(s, INT_VEC_IRQ0 + (irq), 0)
#endif
/* PCI definitions */
#define PCI_BUS_NUMBERS 2

View file

@ -42,10 +42,8 @@ for the pentium4 and minuteia variants of the generic_pc BSP.
#include <drivers/pic.h>
/* Handle possible stray or spurious interrupts on the master and slave PICs */
extern void _masterStrayIntStub(void);
extern void _slaveStrayIntStub(void);
SYS_INT_REGISTER(_masterStrayIntStub, PIC_MASTER_STRAY_INT_LVL, 0);
SYS_INT_REGISTER(_slaveStrayIntStub, PIC_SLAVE_STRAY_INT_LVL, 0);
IRQ_CONNECT_STATIC(pic_master, PIC_MASTER_STRAY_INT_LVL, 0, _i8259_boi_master, 0);
IRQ_CONNECT_STATIC(pic_slave, PIC_SLAVE_STRAY_INT_LVL, 0, _i8259_boi_slave, 0);
/*******************************************************************************
*
@ -148,3 +146,26 @@ int _SysIntVecAlloc(
return vector;
}
/*******************************************************************************
*
* _SysIntVecProgram - program interrupt controller
*
* This BSP provided routine programs the appropriate interrupt controller
* with the given vector based on the given IRQ parameter.
*
* Drivers call this routine instead of irq_connect() when interrupts are
* configured statically.
*
* For PIC-equipped boards this routine does nothing, as PIC does not need
* any additional setup
*
*/
void _SysIntVecProgram(unsigned int vector, /* vector number */
unsigned int irq /* virtualized IRQ */
)
{
ARG_UNUSED(vector);
ARG_UNUSED(irq);
}

View file

@ -195,9 +195,9 @@ extern struct nano_stack _k_command_stack;
#ifdef CONFIG_DYNAMIC_INT_STUBS
static NANO_CPU_INT_STUB_DECL(_hpetIntStub); /* interrupt stub memory */
#else /* !CONFIG_DYNAMIC_INT_STUBS */
extern void *_hpetIntStub(void); /* interrupt stub code */
SYS_INT_REGISTER(_hpetIntStub, HPET_TIMER0_IRQ, HPET_TIMER0_INT_PRI);
#endif /* CONFIG_DYNAMIC_INT_STUBS */
IRQ_CONNECT_STATIC(hpet, HPET_TIMER0_IRQ, HPET_TIMER0_INT_PRI,
_timer_int_handler, 0);
#endif
#ifdef CONFIG_INT_LATENCY_BENCHMARK
static uint32_t main_count_first_irq_value = 0;
@ -626,7 +626,7 @@ void timer_driver(int priority /* priority parameter is ignored by this driver
* has to be programmed into the interrupt controller.
*/
_SysIntVecProgram(HPET_TIMER0_VEC, HPET_TIMER0_IRQ);
IRQ_CONFIG(hpet, HPET_TIMER0_IRQ);
#endif
/* enable the IRQ in the interrupt controller */

View file

@ -116,10 +116,7 @@ extern int32_t _sys_idle_elapsed_ticks;
/* interrupt stub memory for irq_connect() */
#ifndef CONFIG_DYNAMIC_INT_STUBS
extern void *_i8253_interrupt_stub;
SYS_INT_REGISTER(_i8253_interrupt_stub, PIT_INT_LVL, PIT_INT_PRI);
#else
static NANO_CPU_INT_STUB_DECL(_i8253_interrupt_stub);
IRQ_CONNECT_STATIC(i8253, PIT_INT_LVL, PIT_INT_PRI, _timer_int_handler, 0);
#endif
static uint16_t __noinit counterLoadVal; /* computed counter */
@ -497,7 +494,9 @@ void timer_driver(int priority /* priority parameter ignored by this driver */
_i8253CounterPeriodic(counterLoadVal);
#ifdef CONFIG_DYNAMIC_INT_STUBS
#ifndef CONFIG_DYNAMIC_INT_STUBS
IRQ_CONFIG(i8253, PIT_INT_LVL);
#else
/* connect specified routine/parameter to PIT interrupt vector */
(void)irq_connect(PIT_INT_LVL,
@ -505,6 +504,7 @@ void timer_driver(int priority /* priority parameter ignored by this driver */
_timer_int_handler,
0,
_i8253_interrupt_stub);
#endif /* CONFIG_DYNAMIC_INT_STUBS */
_i8253TicklessIdleSkew();

View file

@ -115,9 +115,9 @@ static NANO_CPU_INT_STUB_DECL(
_loapic_timer_irq_stub); /* interrupt stub memory for */
/* irq_connect() */
#else /* !CONFIG_DYNAMIC_INT_STUBS */
extern void *_loapic_timer_irq_stub;
SYS_INT_REGISTER(_loapic_timer_irq_stub, LOAPIC_TIMER_IRQ, LOAPIC_TIMER_INT_PRI);
#endif /* CONFIG_DYNAMIC_INT_STUBS */
IRQ_CONNECT_STATIC(loapic, LOAPIC_TIMER_IRQ, LOAPIC_TIMER_INT_PRI,
_timer_int_handler, 0);
#endif
static uint32_t __noinit counterLoadVal; /* computed counter 0
initial count value */
@ -580,7 +580,7 @@ void timer_driver(int priority /* priority parameter ignored by this driver */
* still
* has to be programmed into the interrupt controller.
*/
_SysIntVecProgram(LOAPIC_TIMER_VEC, LOAPIC_TIMER_IRQ);
IRQ_CONFIG(loapic, LOAPIC_TIMER_IRQ);
#endif /* CONFIG_DYNAMIC_INT_STUBS */
_loApicTimerTicklessIdleSkew();

View file

@ -137,6 +137,41 @@ typedef struct s_isrList {
#define NANO_CPU_INT_STUB_DECL(s) \
_NODATA_SECTION(.intStubSect) NANO_INT_STUB(s)
/*******************************************************************************
*
* IRQ_CONNECT_STATIC - connect a routine to interrupt number
*
* For the device <device> associates IRQ number <irq> with priority
* <priority> with the interrupt routine <isr>, that receives parameter
* <parameter>
*
* RETURNS: N/A
*
*/
#define IRQ_CONNECT_STATIC(device, irq, priority, isr, parameter) \
const uint32_t _##device##_int_vector = INT_VEC_IRQ0 + (irq); \
extern void *_##device##_##isr##_stub; \
NANO_CPU_INT_REGISTER(_##device##_##isr##_stub, INT_VEC_IRQ0 + (irq), priority)
/*******************************************************************************
*
* IRQ_CONFIG - configure interrupt for the device
*
* For the given device do the neccessary configuration steps.
* For x86 platform configure APIC and mark interrupt vector allocated
*
* RETURNS: N/A
*
*/
#define IRQ_CONFIG(device, irq) \
do { \
_SysIntVecProgram(_##device##_int_vector, irq); \
_IntVecMarkAllocated(_##device##_int_vector); \
} while(0)
/*
* A pointer to an "exception stack frame" (ESF) is passed as an argument
* to exception handlers registered via nanoCpuExcConnect(). When an exception

View file

@ -61,7 +61,19 @@ extern "C" {
#define IOAPIC_EXTINT 0x00000700
#ifdef _ASMLANGUAGE
GTEXT(ioapic_eoi)
GTEXT(_ioapic_eoi)
.macro ioapic_mkstub device isr
GTEXT(_\()\device\()_\()\isr\()_stub)
SECTION_FUNC(TEXT, _\()\device\()_\()\isr\()_stub)
call _IntEnt /* Inform kernel interrupt has begun */
pushl $0 /* Push dummy parameter */
call \isr /* Call actual interrupt handler */
call _ioapic_eoi /* Inform ioapic interrupt is done */
addl $4, %esp /* Clean-up stack from push above */
jmp _IntExit /* Inform kernel interrupt is done */
.endm
#else /* _ASMLANGUAGE */
void _ioapic_init(void);
void _ioapic_eoi(unsigned int irq);

View file

@ -70,6 +70,18 @@ extern "C" {
#ifdef _ASMLANGUAGE
GTEXT(_loapic_eoi)
.macro loapic_mkstub device isr
GTEXT(_\()\device\()_\()\isr\()_stub)
SECTION_FUNC(TEXT, _\()\device\()_\()\isr\()_stub)
call _IntEnt /* Inform kernel interrupt has begun */
pushl $0 /* Push dummy parameter */
call \isr /* Call actual interrupt handler */
call _loapic_eoi /* Inform loapic interrupt is done */
addl $4, %esp /* Clean-up stack from push above */
jmp _IntExit /* Inform kernel interrupt is done */
.endm
#else /* _ASMLANGUAGE */
extern void _loapic_init(void);
extern void _loapic_eoi(unsigned int irq);

View file

@ -71,6 +71,29 @@ GTEXT(_i8259_boi_slave)
GTEXT(_i8259_eoi_master)
GTEXT(_i8259_eoi_slave)
.macro pic_master_mkstub device isr
GTEXT(_\()\device\()_\()\isr\()_stub)
SECTION_FUNC(TEXT, _\()\device\()_\()\isr\()_stub)
call _IntEnt /* Inform kernel interrupt has begun */
pushl $0 /* Push dummy parameter */
call \isr /* Call actual interrupt handler */
call _i8259_eoi_master /* Inform PIC interrupt is done */
addl $4, %esp /* Clean-up stack from push above */
jmp _IntExit /* Inform kernel interrupt is done */
.endm
.macro pic_slave_mkstub device isr
GTEXT(_\()\device\()_\()\isr\()_stub)
SECTION_FUNC(TEXT, _\()\device\()_\()\isr\()_stub)
call _IntEnt /* Inform kernel interrupt has begun */
pushl $0 /* Push dummy parameter */
call \isr /* Call actual interrupt handler */
call _i8259_eoi_slave /* Inform PIC interrupt is done */
addl $4, %esp /* Clean-up stack from push above */
jmp _IntExit /* Inform kernel interrupt is done */
.endm
#else /* _ASMLANGUAGE */
extern void _i8259_init(void);