arm: use gen_isr_tables mechanism for interrupts

This replaces the hard-coded vector table, as well as the
software ISR table created by the linker. Now both are generated
in build via script.

Issue: ZEP-1038, ZEP-1165
Change-Id: Ie6faaf8f7ea3a7a25ecb542f6cf7740836ad7da3
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2017-02-08 17:49:51 -08:00 committed by Anas Nashif
commit e7acd3224c
8 changed files with 33 additions and 177 deletions

View file

@ -1,13 +1,10 @@
ccflags-y += -I$(srctree)/kernel/include ccflags-y += -I$(srctree)/kernel/include
asflags-y := ${ccflags-y} asflags-y := ${ccflags-y}
obj-y = exc_exit.o irq_init.o \ obj-y = exc_exit.o irq_init.o swap.o fault.o irq_manage.o thread.o \
swap.o \ cpu_idle.o fault_s.o fatal.o sys_fatal_error_handler.o thread_abort.o
fault.o \
irq_manage.o thread.o cpu_idle.o \
fault_s.o isr_wrapper.o \
fatal.o sys_fatal_error_handler.o thread_abort.o
obj-$(CONFIG_GEN_SW_ISR_TABLE) += isr_wrapper.o
obj-$(CONFIG_CPLUSPLUS) += __aeabi_atexit.o obj-$(CONFIG_CPLUSPLUS) += __aeabi_atexit.o
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
obj-$(CONFIG_CPU_CORTEX_M) += cortex_m/ obj-$(CONFIG_CPU_CORTEX_M) += cortex_m/

View file

@ -212,45 +212,8 @@ config IRQ_OFFLOAD
run in interrupt context. Adds some overhead to context switching. run in interrupt context. Adds some overhead to context switching.
Mainly useful for test cases. Mainly useful for test cases.
config SW_ISR_TABLE config GEN_ISR_TABLES
bool
prompt "Enable software interrupt handler table"
default y default y
help
Enable an interrupt handler table implemented in software. This
table, unlike ISRs connected directly in the vector table, allow
a parameter to be passed to the interrupt handlers. Also, invoking
the exeception/interrupt exit stub is automatically done.
config IRQ_VECTOR_TABLE_CUSTOM
bool
prompt "Projects provide a custom static IRQ part of vector table"
depends on !SW_ISR_TABLE
default n
help
Projects, not the board, provide the IRQ part of the vector table.
This is the table of interrupt handlers with the best potential
performance, but is the less flexible.
The ISRs are installed directly in the vector table, thus are
directly called by the CPU when an interrupt is taken. This adds
the least overhead when handling an interrupt.
Downsides:
- ISRs cannot have a parameter
- ISRs cannot be connected at runtime
- ISRs must notify the kernel manually by invoking _IntExit() when
then are about to return.
config IRQ_VECTOR_TABLE_SOC
bool
# omit prompt to signify a "hidden" option
depends on SW_ISR_TABLE || !IRQ_VECTOR_TABLE_CUSTOM
default y
help
Not user-selectable, helps build system logic.
config ZERO_LATENCY_IRQS config ZERO_LATENCY_IRQS
bool bool

View file

@ -9,5 +9,3 @@ obj-y = vector_table.o reset.o \
nmi_on_reset.o prep_c.o scs.o scb.o nmi.o \ nmi_on_reset.o prep_c.o scs.o scb.o nmi.o \
exc_manage.o exc_manage.o
obj-$(CONFIG_IRQ_VECTOR_TABLE_SOC) += irq_vector_table.o
obj-$(CONFIG_SW_ISR_TABLE) += sw_isr_table.o

View file

@ -1,44 +0,0 @@
/*
* Copyright (c) 2016 Intel Corporation.
* Copyright (c) 2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief IRQ part of vector table
*
* This file contains the IRQ part of the vector table. It is meant to be used
* for one of two cases:
*
* a) When software-managed ISRs (SW_ISR_TABLE) is enabled, and in that case it
* binds _isr_wrapper() to all the IRQ entries in the vector table.
*
* b) When the platform is written so that device ISRs are installed directly in
* the vector table, they are enumerated here.
*/
#include <toolchain.h>
#include <sections.h>
#include <arch/cpu.h>
extern void _isr_wrapper(void);
typedef void (*vth)(void); /* Vector Table Handler */
#if defined(CONFIG_SW_ISR_TABLE)
vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = {
[0 ...(CONFIG_NUM_IRQS - 1)] = _isr_wrapper,
};
#elif !defined(CONFIG_IRQ_VECTOR_TABLE_CUSTOM)
extern void _irq_spurious(void);
/* placeholders: fill with real ISRs */
vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS] = {
[0 ...(CONFIG_NUM_IRQS - 1)] = _irq_spurious,
};
#endif /* CONFIG_SW_ISR_TABLE */

View file

@ -1,57 +0,0 @@
/*
* Copyright (c) 2015 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief ISR table for static ISR declarations for ARM
*
* Software ISR table for ARM
*/
#include <toolchain.h>
#include <sections.h>
#include <arch/cpu.h>
_ASM_FILE_PROLOGUE
/*
* enable preprocessor features, such
* as %expr - evaluate the expression and use it as a string
*/
.altmacro
/*
* Define an ISR table entry
* Define symbol as weak and give the section .gnu.linkonce
* prefix. This allows linker overload the symbol and the
* whole section by the one defined by a device driver
*/
.macro _isr_table_entry_declare index
WDATA(_isr_irq\index)
.section .gnu.linkonce.isr_irq\index
_isr_irq\index: .word 0xABAD1DEA, _irq_spurious
.endm
/*
* Declare the ISR table
*/
.macro _isr_table_declare from, to
counter = \from
.rept (\to - \from + 1)
_isr_table_entry_declare %counter
counter = counter + 1
.endr
.endm
GTEXT(_irq_spurious)
GDATA(_sw_isr_table)
.section .isr_irq0
.align
_sw_isr_table:
_isr_table_declare 0 CONFIG_NUM_IRQS

View file

@ -62,20 +62,13 @@ extern void _irq_priority_set(unsigned int irq, unsigned int prio,
* *
* All arguments must be computable by the compiler at build time. * All arguments must be computable by the compiler at build time.
* *
* Internally this function does a few things: * _ISR_DECLARE will populate the .intList section with the interrupt's
* parameters, which will then be used by gen_irq_tables.py to create
* the vector table and the software ISR table. This is all done at
* build-time.
* *
* 1. The enum statement has no effect but forces the compiler to only * We additionally set the priority in the interrupt controller at
* accept constant values for the irq_p parameter, very important as the * runtime.
* numerical IRQ line is used to create a named section.
*
* 2. An instance of struct _isr_table_entry is created containing the ISR and
* its parameter. If you look at how _sw_isr_table is created, each entry in
* the array is in its own section named by the IRQ line number. What we are
* doing here is to override one of the default entries (which points to the
* spurious IRQ handler) with what was supplied here.
*
* 3. The priority level for the interrupt is configured by a call to
* _irq_priority_set()
* *
* @param irq_p IRQ line number * @param irq_p IRQ line number
* @param priority_p Interrupt priority * @param priority_p Interrupt priority
@ -87,15 +80,22 @@ extern void _irq_priority_set(unsigned int irq, unsigned int prio,
*/ */
#define _ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \ #define _ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
({ \ ({ \
enum { IRQ = irq_p }; \ _ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
static struct _isr_table_entry _CONCAT(_isr_irq, irq_p) \
__attribute__ ((used)) \
__attribute__ ((section(STRINGIFY(_CONCAT(.gnu.linkonce.isr_irq, irq_p))))) = \
{isr_param_p, isr_p}; \
_irq_priority_set(irq_p, priority_p, flags_p); \ _irq_priority_set(irq_p, priority_p, flags_p); \
irq_p; \ irq_p; \
}) })
/* Spurious interrupt handler. Throws an error if called */
extern void _irq_spurious(void *unused);
#ifdef CONFIG_GEN_SW_ISR_TABLE
/* Architecture-specific common entry point for interrupts from the vector
* table. Most likely implemented in assembly. Looks up the correct handler
* and parameter from the _sw_isr_table and executes it.
*/
extern void _isr_wrapper(void);
#endif
#endif /* _ASMLANGUAGE */ #endif /* _ASMLANGUAGE */
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -63,6 +63,9 @@ MEMORY
SRAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE SRAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE
SYSTEM_CONTROL_SPACE (wx) : ORIGIN = 0xE000E000, LENGTH = 4K SYSTEM_CONTROL_SPACE (wx) : ORIGIN = 0xE000E000, LENGTH = 4K
SYSTEM_CONTROL_PERIPH (wx) : ORIGIN = 0x400FE000, LENGTH = 4K SYSTEM_CONTROL_PERIPH (wx) : ORIGIN = 0x400FE000, LENGTH = 4K
/* Used by and documented in include/linker/intlist.ld */
IDT_LIST (wx) : ORIGIN = (RAM_ADDR + RAM_SIZE), LENGTH = 2K
} }
SECTIONS SECTIONS
@ -84,16 +87,9 @@ SECTIONS
KEEP(*(.kinetis_flash_config)) KEEP(*(.kinetis_flash_config))
KEEP(*(".kinetis_flash_config.*")) KEEP(*(".kinetis_flash_config.*"))
KEEP(*(.isr_irq*)) #ifdef CONFIG_GEN_SW_ISR_TABLE
KEEP(*(SW_ISR_TABLE))
/* sections for IRQ0-9 */ #endif
KEEP(*(SORT(.gnu.linkonce.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.isr_irq[0-9][0-9][0-9])))
_image_text_start = .; _image_text_start = .;
*(.text) *(.text)
@ -236,6 +232,10 @@ SECTIONS
#ifdef CONFIG_CUSTOM_SECTIONS_LD #ifdef CONFIG_CUSTOM_SECTIONS_LD
/* Located in project source directory */ /* Located in project source directory */
#include <custom-sections.ld> #include <custom-sections.ld>
#endif
#ifdef CONFIG_GEN_ISR_TABLES
#include <linker/intlist.ld>
#endif #endif
} }

View file

@ -1,7 +1,6 @@
CONFIG_ZTEST=y CONFIG_ZTEST=y
CONFIG_ZTEST_STACKSIZE=512 CONFIG_ZTEST_STACKSIZE=512
CONFIG_MAIN_STACK_SIZE=512 CONFIG_MAIN_STACK_SIZE=512
CONFIG_SW_ISR_TABLE=n CONFIG_GEN_ISR_TABLES=n
CONFIG_IRQ_VECTOR_TABLE_CUSTOM=y
CONFIG_NUM_IRQS=3 CONFIG_NUM_IRQS=3
CONFIG_COMPILER_OPT="-O0" CONFIG_COMPILER_OPT="-O0"