From 35fcb2736c5588774d4ed8bf0f5a020ca58ff319 Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Mon, 13 Feb 2017 09:36:32 -0800 Subject: [PATCH] arc: enable gen_isr_tables mechanism Change-Id: I5897e110f554377796bfe38dd5c0f8652c29e5be Signed-off-by: Andrew Boie --- arch/arc/Kconfig | 46 ++++------------------------ arch/arc/core/Makefile | 2 -- arch/arc/core/fast_irq.S | 2 +- arch/arc/core/irq_vector_table.c | 43 -------------------------- arch/arc/core/isr_wrapper.S | 10 +++--- arch/arc/core/sw_isr_table.S | 52 -------------------------------- doc/porting/arch.rst | 2 +- include/arch/arc/arch.h | 49 ------------------------------ include/arch/arc/v2/irq.h | 35 +++++++++++++++++++++ include/arch/arc/v2/linker.ld | 27 +++++------------ 10 files changed, 56 insertions(+), 212 deletions(-) delete mode 100644 arch/arc/core/irq_vector_table.c delete mode 100644 arch/arc/core/sw_isr_table.S diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 4811bf483fe..8f2a62ef1e8 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -144,6 +144,12 @@ config XIP default n if NSIM default y +config GEN_ISR_TABLES + default y + +config GEN_IRQ_START_VECTOR + default 16 + config HARVARD prompt "Harvard Architecture" bool @@ -208,46 +214,6 @@ config FLASH_BASE_ADDRESS normally set by the board's defconfig file and the user should generally avoid modifying it via the menu configuration. -config SW_ISR_TABLE - bool - prompt "Enable software interrupt handler table" - 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 BSP, 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 _ExcExit() when - then are about to return. - -config IRQ_VECTOR_TABLE_BSP - 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 CACHE_LINE_SIZE_DETECT bool prompt "Detect d-cache line size at runtime" diff --git a/arch/arc/core/Makefile b/arch/arc/core/Makefile index bc16184b0ba..2afcdabf1ed 100644 --- a/arch/arc/core/Makefile +++ b/arch/arc/core/Makefile @@ -16,5 +16,3 @@ obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o # Some ARC cores like the EM4 lack the atomic LLOCK/SCOND and # can't use these. obj-$(CONFIG_ATOMIC_OPERATIONS_CUSTOM) += atomic.o -obj-$(CONFIG_IRQ_VECTOR_TABLE_BSP) += irq_vector_table.o -obj-$(CONFIG_SW_ISR_TABLE) += sw_isr_table.o diff --git a/arch/arc/core/fast_irq.S b/arch/arc/core/fast_irq.S index 01b44f6fafa..e5acb6f43fc 100644 --- a/arch/arc/core/fast_irq.S +++ b/arch/arc/core/fast_irq.S @@ -72,7 +72,7 @@ SECTION_FUNC(TEXT, _firq_enter) * If CONFIG_RGF_NUM_BANKS>1, firq uses a 2nd register bank so GPRs do * not need to be saved. * If CONFIG_RGF_NUM_BANKS==1, firq must use the stack to save registers. - * This has already been done by _isr_enter. + * This has already been done by _isr_wrapper. */ #ifdef CONFIG_ARC_STACK_CHECKING diff --git a/arch/arc/core/irq_vector_table.c b/arch/arc/core/irq_vector_table.c deleted file mode 100644 index d06c630203b..00000000000 --- a/arch/arc/core/irq_vector_table.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2014 Wind River Systems, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @brief IRQ part of vector table for Quark SE Sensor Subsystem - * - * 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 _IsrWrapper() to all the IRQ entries in the vector table. - * - * b) When the BSP is written so that device ISRs are installed directly in the - * vector table, they are enumerated here. - * - */ - -#include -#include - -extern void _isr_enter(void); -typedef void (*vth)(void); /* Vector Table Handler */ - -#if defined(CONFIG_SW_ISR_TABLE) - -vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS - 16] = { - [0 ...(CONFIG_NUM_IRQS - 17)] = _isr_enter -}; - -#elif !defined(CONFIG_IRQ_VECTOR_TABLE_CUSTOM) - -extern void _SpuriousIRQ(void); - -/* placeholders: fill with real ISRs */ - -vth __irq_vector_table _irq_vector_table[CONFIG_NUM_IRQS - 16] = { - [0 ...(CONFIG_NUM_IRQS - 17)] = _SpuriousIRQ -}; - -#endif /* CONFIG_SW_ISR_TABLE */ diff --git a/arch/arc/core/isr_wrapper.S b/arch/arc/core/isr_wrapper.S index 035add0526c..c48ba5556ba 100644 --- a/arch/arc/core/isr_wrapper.S +++ b/arch/arc/core/isr_wrapper.S @@ -20,7 +20,7 @@ #include #include -GTEXT(_isr_enter) +GTEXT(_isr_wrapper) GTEXT(_isr_demux) #if CONFIG_RGF_NUM_BANKS == 1 @@ -41,9 +41,9 @@ _rirq_enter/_firq_enter: they are jump points. The flow is the following: -ISR -> _isr_enter -- + -> _rirq_enter -> _isr_demux -> ISR -> _rirq_exit - | - + -> _firq_enter -> _isr_demux -> ISR -> _firq_exit +ISR -> _isr_wrapper -- + -> _rirq_enter -> _isr_demux -> ISR -> _rirq_exit + | + + -> _firq_enter -> _isr_demux -> ISR -> _firq_exit Context switch explanation: @@ -216,7 +216,7 @@ From RIRQ: interrupt. */ -SECTION_FUNC(TEXT, _isr_enter) +SECTION_FUNC(TEXT, _isr_wrapper) #if CONFIG_RGF_NUM_BANKS == 1 st r0,[saved_r0] #endif diff --git a/arch/arc/core/sw_isr_table.S b/arch/arc/core/sw_isr_table.S deleted file mode 100644 index 868bd72b9e7..00000000000 --- a/arch/arc/core/sw_isr_table.S +++ /dev/null @@ -1,52 +0,0 @@ -/* sw_isr_table.S - ISR table for static ISR declarations for ARC */ - -/* - * Copyright (c) 2015 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -/* - * 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) - _isr_table_entry_declare %counter - counter = counter + 1 - .endr -.endm - -GTEXT(_irq_spurious) -GDATA(_sw_isr_table) - -.section .isr_irq16 -.align -_sw_isr_table: - -/*In ARC architecture, IRQ 0-15 are reserved for the system and are not -assignable by the user, for that reason the isr table linker section -start at IRQ 16*/ -_isr_table_declare 16 CONFIG_NUM_IRQS diff --git a/doc/porting/arch.rst b/doc/porting/arch.rst index f7072c42f29..e0a122711f2 100644 --- a/doc/porting/arch.rst +++ b/doc/porting/arch.rst @@ -134,7 +134,7 @@ parameter. executing. A common interrupt handler demuxer is installed for all entries of the real interrupt vector table, which then fetches the device's ISR and parameter from the separate table. This approach is commonly used in the ARC - and ARM architectures via the :option:`CONFIG_SW_ISR_TABLE` implementation. + and ARM architectures via the :option:`CONFIG_GEN_ISR_TABLES` implementation. You can find examples of the stubs by looking at :code:`_interrupt_enter()` in x86, :code:`_IntExit()` in ARM, :code:`_isr_wrapper()` in ARM, or the full implementation description for ARC in :file:`arch/arc/core/isr_wrapper.S`. diff --git a/include/arch/arc/arch.h b/include/arch/arc/arch.h index 6ed34e62c86..f9b492e6776 100644 --- a/include/arch/arc/arch.h +++ b/include/arch/arc/arch.h @@ -43,53 +43,4 @@ extern "C" { #ifdef __cplusplus } #endif - -#ifndef _ASMLANGUAGE -#include - -/* internal routine documented in C file, needed by IRQ_CONNECT() macro */ -extern void _irq_priority_set(unsigned int irq, unsigned int prio, - uint32_t flags); - -/** - * Configure a static interrupt. - * - * All arguments must be computable by the compiler at build time. - * - * Internally this function does a few things: - * - * 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() - * - * @param irq_p IRQ line number - * @param priority_p Interrupt priority, in range 0-13 - * @param isr_p Interrupt service routine - * @param isr_param_p ISR parameter - * @param flags_p IRQ options (ignored for now) - * - * @return The vector assigned to this interrupt - */ -#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}; \ - _irq_priority_set(irq_p, priority_p, flags_p); \ - irq_p; \ -}) - -#endif - #endif /* _ARC_ARCH__H_ */ diff --git a/include/arch/arc/v2/irq.h b/include/arch/arc/v2/irq.h index 038ee3c4078..850fe43261b 100644 --- a/include/arch/arc/v2/irq.h +++ b/include/arch/arc/v2/irq.h @@ -18,6 +18,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -33,6 +34,40 @@ extern void _arch_irq_enable(unsigned int irq); extern void _arch_irq_disable(unsigned int irq); extern void _irq_exit(void); +extern void _irq_priority_set(unsigned int irq, unsigned int prio, + uint32_t flags); +extern void _isr_wrapper(void); +extern void _irq_spurious(void *unused); + +/** + * Configure a static interrupt. + * + * All arguments must be computable by the compiler at build time. + * + * _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. + * + * We additionally set the priority in the interrupt controller at + * runtime. + * + * @param irq_p IRQ line number + * @param priority_p Interrupt priority + * @param isr_p Interrupt service routine + * @param isr_param_p ISR parameter + * @param flags_p IRQ options + * + * @return The vector assigned to this interrupt + */ +#define _ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \ +({ \ + _ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \ + _irq_priority_set(irq_p, priority_p, flags_p); \ + irq_p; \ +}) + + /** * diff --git a/include/arch/arc/v2/linker.ld b/include/arch/arc/v2/linker.ld index 8ca50de3fd3..e42eeb5607f 100644 --- a/include/arch/arc/v2/linker.ld +++ b/include/arch/arc/v2/linker.ld @@ -57,6 +57,8 @@ MEMORY { #ifdef DCCM_START DCCM (rw) : ORIGIN = DCCM_START, LENGTH = DCCM_SIZE*1k #endif + /* Used by and documented in include/linker/intlist.ld */ + IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K } SECTIONS { @@ -72,25 +74,9 @@ SECTIONS { KEEP(*(".exc_vector_table.*")) KEEP(*(IRQ_VECTOR_TABLE)) - KEEP(*(.isr_irq*)) - - /* - * The following sections maps the location of the different - * rows for the _sw_isr_table. Each row maps to an IRQ entry - * (handler, argument). - * - * In ARC architecture, IRQ 0-15 are reserved for the system - * and are not * assignable by the user, for that reason the - * linker sections start on IRQ 16 - */ - - /* sections for IRQ16-19 */ - KEEP(*(SORT(.gnu.linkonce.isr_irq[1][6-9]))) - /* sections for IRQ20-99 */ - KEEP(*(SORT(.gnu.linkonce.isr_irq[2-9][0-9]))) - /* sections for IRQ100-999 */ - KEEP(*(SORT(.gnu.linkonce.isr_irq[1-9][0-9][0-9]))) - +#ifdef CONFIG_GEN_SW_ISR_TABLE + KEEP(*(SW_ISR_TABLE)) +#endif *(.text) *(".text.*") *(.gnu.linkonce.t.*) @@ -189,4 +175,7 @@ SECTIONS { #include #endif +#ifdef CONFIG_GEN_ISR_TABLES +#include +#endif }