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
|
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/
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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.
|
* 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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue