From 2a1ae3f4361bf84a683c517c6cb022b080519524 Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Wed, 20 Jan 2016 15:13:38 -0800 Subject: [PATCH] ARM: ARC: put sw_isr_table in ROM by default We can save a great deal of RAM this way, it only needs to be in RAM if dynamic interrupts are in use. At some point this config option broke, probably when static interrupts were introduced into the system. To induce build (instead of runtime) errors when irq_connect_dynamic() is used without putting the table in RAM, the dynamic interrupt functions are now conditionally compiled. Change-Id: I4860508746fd375d189390163876c59b6c544c9a Signed-off-by: Andrew Boie --- arch/arc/Kconfig | 4 +- arch/arc/core/irq_manage.c | 52 ++++++++++--------- arch/arm/core/cortex_m/Kconfig | 4 +- arch/arm/core/irq_manage.c | 43 ++++++++------- .../nanokernel/nanokernel_interrupts.rst | 3 ++ include/arch/arc/v2/linker.cmd | 18 +++++++ include/arch/arm/cortex_m/scripts/linker.cmd | 17 +++++- include/section_tags.h | 6 --- include/sections.h | 12 ----- .../test/test_task_irq/prj_arm.conf | 2 +- 10 files changed, 93 insertions(+), 68 deletions(-) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 88b94bd5efa..f04247ee179 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -182,9 +182,9 @@ config SW_ISR_TABLE_DYNAMIC bool prompt "Allow installing interrupt handlers at runtime" depends on SW_ISR_TABLE - default y + default n help - This option enables nanoCpuIntConnect(). It moves the ISR table to + This option enables irq_connect_dynamic(). It moves the ISR table to SRAM so that it is writable. This has the side-effect of removing write-protection on the ISR table. diff --git a/arch/arc/core/irq_manage.c b/arch/arc/core/irq_manage.c index 99e2254d265..0503e640310 100644 --- a/arch/arc/core/irq_manage.c +++ b/arch/arc/core/irq_manage.c @@ -37,30 +37,6 @@ #include #include -/* - * @internal - * - * @brief Replace an interrupt handler by another - * - * An interrupt's ISR can be replaced at runtime. - * - * @return N/A - */ - -void _irq_handler_set( - unsigned int irq, - void (*new)(void *arg), - void *arg -) -{ - int key = irq_lock(); - int index = irq - 16; - - _sw_isr_table[index].isr = new; - _sw_isr_table[index].arg = arg; - - irq_unlock(key); -} /* * @brief Enable an interrupt line @@ -142,6 +118,32 @@ void _irq_spurious(void *unused) ; } +#if CONFIG_SW_ISR_TABLE_DYNAMIC +/* + * @internal + * + * @brief Replace an interrupt handler by another + * + * An interrupt's ISR can be replaced at runtime. + * + * @return N/A + */ + +void _irq_handler_set( + unsigned int irq, + void (*new)(void *arg), + void *arg +) +{ + int key = irq_lock(); + int index = irq - 16; + + _sw_isr_table[index].isr = new; + _sw_isr_table[index].arg = arg; + + irq_unlock(key); +} + /* * @brief Connect an ISR to an interrupt line * @@ -185,3 +187,5 @@ void _irq_disconnect(unsigned int irq) { _irq_handler_set(irq, _irq_spurious, NULL); } + +#endif /* CONFIG_SW_ISR_TABLE_DYNAMIC */ diff --git a/arch/arm/core/cortex_m/Kconfig b/arch/arm/core/cortex_m/Kconfig index 5a992dd0073..72f4d678bdf 100644 --- a/arch/arm/core/cortex_m/Kconfig +++ b/arch/arm/core/cortex_m/Kconfig @@ -154,9 +154,9 @@ config SW_ISR_TABLE_DYNAMIC bool prompt "Allow installing interrupt handlers at runtime" depends on SW_ISR_TABLE - default y + default n help - This option enables irq_connect(). It moves the ISR table to + This option enables irq_connect_dynamic(). It moves the ISR table to SRAM so that it is writable. This has the side-effect of removing write-protection on the ISR table. diff --git a/arch/arm/core/irq_manage.c b/arch/arm/core/irq_manage.c index f10e37f0a7c..a4797a910d5 100644 --- a/arch/arm/core/irq_manage.c +++ b/arch/arm/core/irq_manage.c @@ -33,26 +33,6 @@ extern void __reserved(void); -/** - * @internal - * - * @brief Replace an interrupt handler by another - * - * An interrupt's ISR can be replaced at runtime. - * - * @return N/A - */ -void _irq_handler_set(unsigned int irq, - void (*new)(void *arg), - void *arg) -{ - int key = irq_lock(); - - _sw_isr_table[irq].isr = new; - _sw_isr_table[irq].arg = arg; - - irq_unlock(key); -} /** * @@ -124,6 +104,28 @@ void _irq_spurious(void *unused) __reserved(); } +#if CONFIG_SW_ISR_TABLE_DYNAMIC +/** + * @internal + * + * @brief Replace an interrupt handler by another + * + * An interrupt's ISR can be replaced at runtime. + * + * @return N/A + */ +void _irq_handler_set(unsigned int irq, + void (*new)(void *arg), + void *arg) +{ + int key = irq_lock(); + + _sw_isr_table[irq].isr = new; + _sw_isr_table[irq].arg = arg; + + irq_unlock(key); +} + /** * * @brief Connect an ISR to an interrupt line @@ -164,3 +166,4 @@ void _irq_disconnect(unsigned int irq) { _irq_handler_set(irq, _irq_spurious, NULL); } +#endif /* CONFIG_SW_ISR_TABLE_DYNAMIC */ diff --git a/doc/kernel/nanokernel/nanokernel_interrupts.rst b/doc/kernel/nanokernel/nanokernel_interrupts.rst index 92f2f8769d1..8f6bcccbd00 100644 --- a/doc/kernel/nanokernel/nanokernel_interrupts.rst +++ b/doc/kernel/nanokernel/nanokernel_interrupts.rst @@ -127,6 +127,9 @@ Prerequisites * (x86 only) Set the :option:`NUM_DYNAMIC_STUBS` configuration option to specify the maximum number of dynamic ISRs allowed in the project. +* (ARC & ARM only) Enable the :option:`SW_ISR_TABLE_DYNAMIC` so that + interrupts may be connected at runtime. + Example ------- diff --git a/include/arch/arc/v2/linker.cmd b/include/arch/arc/v2/linker.cmd index 4b81d611ec5..ea60bdb841b 100644 --- a/include/arch/arc/v2/linker.cmd +++ b/include/arch/arc/v2/linker.cmd @@ -68,6 +68,21 @@ SECTIONS { KEEP(*(.irq_vector_table)) KEEP(*(".irq_vector_table.*")) +#ifndef CONFIG_SW_ISR_TABLE_DYNAMIC + 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]))) +#endif *(.text) *(".text.*") @@ -123,6 +138,8 @@ SECTIONS { __data_ram_start = .; *(.data) *(".data.*") + +#if CONFIG_SW_ISR_TABLE_DYNAMIC KEEP(*(.isr_irq*)) /*The following sections maps the location of the different rows for @@ -136,6 +153,7 @@ SECTIONS { 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]))) +#endif } GROUP_LINK_IN(RAMABLE_REGION) SECTION_PROLOGUE(initlevel, (OPTIONAL),) diff --git a/include/arch/arm/cortex_m/scripts/linker.cmd b/include/arch/arm/cortex_m/scripts/linker.cmd index 91f707c429e..d4ba52fd0a5 100644 --- a/include/arch/arm/cortex_m/scripts/linker.cmd +++ b/include/arch/arm/cortex_m/scripts/linker.cmd @@ -85,8 +85,20 @@ SECTIONS KEEP(*(.security_frdm_k64f)) KEEP(*(".security_frdm_k64f.*")) - _image_text_start = .; +#ifndef CONFIG_SW_ISR_TABLE_DYNAMIC + 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]))) +#endif + + _image_text_start = .; *(.text) *(".text.*") } GROUP_LINK_IN(ROMABLE_REGION) @@ -139,6 +151,8 @@ SECTIONS __data_ram_start = .; *(.data) *(".data.*") + +#if CONFIG_SW_ISR_TABLE_DYNAMIC KEEP(*(.isr_irq*)) /* sections for IRQ0-9 */ @@ -149,6 +163,7 @@ SECTIONS /* sections for IRQ100-999 */ KEEP(*(SORT(.gnu.linkonce.isr_irq[0-9][0-9][0-9]))) +#endif } GROUP_LINK_IN(RAMABLE_REGION) SECTION_PROLOGUE (initlevel, (OPTIONAL),) diff --git a/include/section_tags.h b/include/section_tags.h index be608c57fe3..e1228bcaeca 100644 --- a/include/section_tags.h +++ b/include/section_tags.h @@ -32,9 +32,6 @@ #define __scs_section __in_section(SCS_SECTION, _FILE_PATH_HASH, __COUNTER__) #define __scp_section __in_section(SCP_SECTION, _FILE_PATH_HASH, __COUNTER__) -#define __isr_table_section __in_section(ISR_TABLE_SECTION, _FILE_PATH_HASH, \ - __COUNTER__) - #define __irq_vector_table __in_section(IRQ_VECTOR_TABLE, _FILE_PATH_HASH, \ __COUNTER__) @@ -51,9 +48,6 @@ #define __irq_vector_table \ __in_section(IRQ_VECTOR_TABLE, _FILE_PATH_HASH, __COUNTER__) - #define __isr_table_section \ - __in_section(ISR_TABLE_SECTION, _FILE_PATH_HASH, __COUNTER__) - #endif /* CONFIG_ARC */ #endif /* !_ASMLANGUAGE */ diff --git a/include/sections.h b/include/sections.h index 0136408d9f6..09a6be88819 100644 --- a/include/sections.h +++ b/include/sections.h @@ -53,12 +53,6 @@ #define SCS_SECTION scs #define SCP_SECTION scp -#ifdef CONFIG_SW_ISR_TABLE_DYNAMIC -#define ISR_TABLE_SECTION DATA -#else /* !CONFIG_SW_ISR_TABLE_DYNAMIC */ -#define ISR_TABLE_SECTION RODATA -#endif /* CONFIG_SW_ISR_TABLE_DYNAMIC */ - #define SECURITY_FRDM_K64F security_frdm_k64f #define IRQ_VECTOR_TABLE irq_vector_table @@ -68,12 +62,6 @@ #elif defined(CONFIG_ARC) - #ifdef CONFIG_SW_ISR_TABLE_DYNAMIC - #define ISR_TABLE_SECTION DATA - #else - #define ISR_TABLE_SECTION RODATA - #endif - #define IRQ_VECTOR_TABLE irq_vector_table #endif diff --git a/samples/microkernel/test/test_task_irq/prj_arm.conf b/samples/microkernel/test/test_task_irq/prj_arm.conf index 8effee1b06a..4b0a8064ab3 100644 --- a/samples/microkernel/test/test_task_irq/prj_arm.conf +++ b/samples/microkernel/test/test_task_irq/prj_arm.conf @@ -1,6 +1,6 @@ # Let stack canaries use non-random number generator. # This option is NOT to be used in production code. CONFIG_TEST_RANDOM_GENERATOR=y - +CONFIG_SW_ISR_TABLE_DYNAMIC=y CONFIG_MAX_NUM_TASK_IRQS=5 CONFIG_NUM_IRQS=4