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:
parent
1927b3d020
commit
e7acd3224c
8 changed files with 33 additions and 177 deletions
|
@ -1,13 +1,10 @@
|
|||
ccflags-y += -I$(srctree)/kernel/include
|
||||
asflags-y := ${ccflags-y}
|
||||
|
||||
obj-y = exc_exit.o irq_init.o \
|
||||
swap.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-y = exc_exit.o irq_init.o swap.o fault.o irq_manage.o thread.o \
|
||||
cpu_idle.o fault_s.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_IRQ_OFFLOAD) += irq_offload.o
|
||||
obj-$(CONFIG_CPU_CORTEX_M) += cortex_m/
|
||||
|
|
|
@ -212,45 +212,8 @@ config IRQ_OFFLOAD
|
|||
run in interrupt context. Adds some overhead to context switching.
|
||||
Mainly useful for test cases.
|
||||
|
||||
config SW_ISR_TABLE
|
||||
bool
|
||||
prompt "Enable software interrupt handler table"
|
||||
config GEN_ISR_TABLES
|
||||
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
|
||||
bool
|
||||
|
|
|
@ -9,5 +9,3 @@ obj-y = vector_table.o reset.o \
|
|||
nmi_on_reset.o prep_c.o scs.o scb.o nmi.o \
|
||||
exc_manage.o
|
||||
|
||||
obj-$(CONFIG_IRQ_VECTOR_TABLE_SOC) += irq_vector_table.o
|
||||
obj-$(CONFIG_SW_ISR_TABLE) += sw_isr_table.o
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
*
|
||||
* 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
|
||||
* accept constant values for the irq_p parameter, very important as the
|
||||
* 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()
|
||||
* We additionally set the priority in the interrupt controller at
|
||||
* runtime.
|
||||
*
|
||||
* @param irq_p IRQ line number
|
||||
* @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) \
|
||||
({ \
|
||||
enum { IRQ = irq_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}; \
|
||||
_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
|
||||
_irq_priority_set(irq_p, priority_p, flags_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 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -63,6 +63,9 @@ MEMORY
|
|||
SRAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE
|
||||
SYSTEM_CONTROL_SPACE (wx) : ORIGIN = 0xE000E000, 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
|
||||
|
@ -84,16 +87,9 @@ SECTIONS
|
|||
KEEP(*(.kinetis_flash_config))
|
||||
KEEP(*(".kinetis_flash_config.*"))
|
||||
|
||||
KEEP(*(.isr_irq*))
|
||||
|
||||
/* sections for IRQ0-9 */
|
||||
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])))
|
||||
#ifdef CONFIG_GEN_SW_ISR_TABLE
|
||||
KEEP(*(SW_ISR_TABLE))
|
||||
#endif
|
||||
|
||||
_image_text_start = .;
|
||||
*(.text)
|
||||
|
@ -236,6 +232,10 @@ SECTIONS
|
|||
#ifdef CONFIG_CUSTOM_SECTIONS_LD
|
||||
/* Located in project source directory */
|
||||
#include <custom-sections.ld>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GEN_ISR_TABLES
|
||||
#include <linker/intlist.ld>
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_ZTEST_STACKSIZE=512
|
||||
CONFIG_MAIN_STACK_SIZE=512
|
||||
CONFIG_SW_ISR_TABLE=n
|
||||
CONFIG_IRQ_VECTOR_TABLE_CUSTOM=y
|
||||
CONFIG_GEN_ISR_TABLES=n
|
||||
CONFIG_NUM_IRQS=3
|
||||
CONFIG_COMPILER_OPT="-O0"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue