diff --git a/arch/x86/driver_static_irq_stubs.S b/arch/x86/driver_static_irq_stubs.S index b5bf2a1430b..246945d82c1 100644 --- a/arch/x86/driver_static_irq_stubs.S +++ b/arch/x86/driver_static_irq_stubs.S @@ -46,30 +46,37 @@ by x86 BSPs. #include #include - /* 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 */ diff --git a/arch/x86/generic_pc/board.h b/arch/x86/generic_pc/board.h index a98ac82cb62..c7a982270c1 100644 --- a/arch/x86/generic_pc/board.h +++ b/arch/x86/generic_pc/board.h @@ -165,15 +165,6 @@ the 'generic_pc' BSP. #define PIT_BASE_ADRS 0x40 #define PIT_REG_ADDR_INTERVAL 1 -#ifndef _ASMLANGUAGE -/* - * The 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 diff --git a/arch/x86/generic_pc/system.c b/arch/x86/generic_pc/system.c index ff142a7f9ce..aa83df96875 100644 --- a/arch/x86/generic_pc/system.c +++ b/arch/x86/generic_pc/system.c @@ -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 /* 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) { diff --git a/arch/x86/quark/board.h b/arch/x86/quark/board.h index 259a5af597f..0034eeab136 100644 --- a/arch/x86/quark/board.h +++ b/arch/x86/quark/board.h @@ -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 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 diff --git a/drivers/interrupt_controller/system_pic.c b/drivers/interrupt_controller/system_pic.c index 58d3c418d5d..534355f2957 100644 --- a/drivers/interrupt_controller/system_pic.c +++ b/drivers/interrupt_controller/system_pic.c @@ -42,10 +42,8 @@ for the pentium4 and minuteia variants of the generic_pc BSP. #include /* 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); +} diff --git a/drivers/timer/hpet.c b/drivers/timer/hpet.c index 002fd6de644..b6cfcfe9349 100644 --- a/drivers/timer/hpet.c +++ b/drivers/timer/hpet.c @@ -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 */ diff --git a/drivers/timer/i8253.c b/drivers/timer/i8253.c index de1e14f0001..f08cb0ffc4d 100644 --- a/drivers/timer/i8253.c +++ b/drivers/timer/i8253.c @@ -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(); diff --git a/drivers/timer/loapic_timer.c b/drivers/timer/loapic_timer.c index 2f9c4be7568..7025137463f 100644 --- a/drivers/timer/loapic_timer.c +++ b/drivers/timer/loapic_timer.c @@ -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(); diff --git a/include/arch/x86/arch.h b/include/arch/x86/arch.h index db60d88e400..47a7586d267 100644 --- a/include/arch/x86/arch.h +++ b/include/arch/x86/arch.h @@ -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 associates IRQ number with priority + * with the interrupt routine , that receives 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 diff --git a/include/drivers/ioapic.h b/include/drivers/ioapic.h index f859fb8ab24..3621df4ca10 100644 --- a/include/drivers/ioapic.h +++ b/include/drivers/ioapic.h @@ -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); diff --git a/include/drivers/loapic.h b/include/drivers/loapic.h index f644f2c0502..9b207e4acbf 100644 --- a/include/drivers/loapic.h +++ b/include/drivers/loapic.h @@ -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); diff --git a/include/drivers/pic.h b/include/drivers/pic.h index 610848a8747..8312c33c0ef 100644 --- a/include/drivers/pic.h +++ b/include/drivers/pic.h @@ -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);