nanokernel: deprecate dynamic IRQs

We have not found any use-cases for dynamic IRQs where a static
IRQ did not also suffice. Deprecate so that we can eventually
remove from Zephyr and nontrivially decrease the complexity of
the kernel.

Change-Id: I509655371773aeaca7d01134dd850eb4cd95f387
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2016-03-28 14:49:37 -07:00 committed by Benjamin Walsh
commit 15800ce78a
14 changed files with 26 additions and 112 deletions

View file

@ -277,7 +277,7 @@ For example, if 3 bits are implemented, use 1, 2, and 3,
not 0x20h, 0x40h, and 0x60h. not 0x20h, 0x40h, and 0x60h.
Interrupt priority is set using the *prio* parameter of Interrupt priority is set using the *prio* parameter of
:c:macro:`IRQ_CONNECT()` or :c:func:`irq_connect_dynamic()`. :c:macro:`IRQ_CONNECT()`.
The range of available priorities is different if using Zero Latency Interrupts The range of available priorities is different if using Zero Latency Interrupts
(ZLI) or not. (ZLI) or not.

View file

@ -25,9 +25,6 @@ Each ISR has the following properties:
An :abbr:`IDT (Interrupt Descriptor Table)` is used to associate a given interrupt An :abbr:`IDT (Interrupt Descriptor Table)` is used to associate a given interrupt
source with a given ISR. source with a given ISR.
Only a single ISR can be associated with a specific IRQ at any given time. Only a single ISR can be associated with a specific IRQ at any given time.
An ISR can be incorporated into the IDT when the Zephyr project is built
(a "static ISR") or bound to the IDT when the system is up and running
(a "dynamic ISR").
Multiple ISRs can utilize the same function to process interrupts, Multiple ISRs can utilize the same function to process interrupts,
allowing a single function to service a device that generates allowing a single function to service a device that generates
@ -66,27 +63,10 @@ response, and which can be done quickly and without blocking.
Installing an ISR Installing an ISR
***************** *****************
Use one of the following procedures to install an ISR: It's important to note that IRQ_CONNECT() is not a C function and does
some inline assembly magic behind the scenes. All its arguments must be known
* `Installing a Static ISR`_ at build time. Drivers that have multiple instances may need to define
* `Installing a Dynamic ISR`_ per-instance config functions to configure the interrupt for that instance.
Installing a Static ISR
=======================
Use a static ISR to register an interrupt handler when the interrupt
parameters are known during the build time and the device is always
present in the system.
.. note::
There is no API method to uninstall a static ISR; however, it is
possible to replace it by installing a dynamic ISR.
Prerequisites
-------------
* Ensure that the platform used by the project supports static ISRs.
Example Example
------- -------
@ -112,51 +92,6 @@ Example
... ...
} }
Installing a Dynamic ISR
========================
Use a dynamic ISR to register an interrupt handler when the interrupt
parameters can be found out only at runtime, or when a device is not always
present in the system.
Prerequisites
-------------
* Ensure that the platform used by the project supports dynamic ISRs.
* (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
-------
This is an example of a dynamic interrupt for x86:
.. code-block:: c
#define MY_DEV_IRQ 24 /* device uses IRQ 24 */
#define MY_DEV_PRIO 2 /* device uses interrupt priority 2 */
#define MY_ISR_ARG 17 /* argument passed to my_isr() */
/* IRQ flags. Interrupt is triggered by low level signal */
#define MY_IRQ_FLAGS (IOAPIC_LEVEL | IOAPIC_LOW)
void my_isr(void *arg)
{
... /* ISR code */
}
void my_isr_installer(void)
{
...
irq_connect_dynamic(MY_DEV_IRQ, MY_DEV_PRIO, my_isr, MY_ISR_ARG,
MY_IRQ_FLAGS);
...
irq_enable(MY_DEV_IRQ);
...
}
Working with Interrupts Working with Interrupts
*********************** ***********************
@ -221,22 +156,11 @@ Additional intermediate context switches may be required
to execute any currently executing fiber or any higher-priority tasks to execute any currently executing fiber or any higher-priority tasks
that are scheduled to run. that are scheduled to run.
IDT Security
============
Ideally, the IDT memory area should be protected against accidental
modification, in the same way that text and read-only data areas
are protected. If no dynamic interrupts are in use, i.e.
:option:`NUM_DYNAMIC_STUBS` is 0, the IDT will be located in ROM.
APIs APIs
**** ****
These are the interrupt-related Application Program Interfaces. These are the interrupt-related Application Program Interfaces.
:c:func:`irq_connect_dynamic()`
Registers a dynamic ISR with the IDT and interrupt controller.
:c:func:`irq_enable()` :c:func:`irq_enable()`
Enables interrupts from a specific IRQ. Enables interrupts from a specific IRQ.

View file

@ -24,6 +24,11 @@
/* Pull in the arch-specific implementations */ /* Pull in the arch-specific implementations */
#include <arch/cpu.h> #include <arch/cpu.h>
#ifndef _ASMLANGUAGE
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* Configure a static interrupt. * Configure a static interrupt.
* *
@ -52,9 +57,18 @@
* *
* @return The vector assigned to this interrupt * @return The vector assigned to this interrupt
*/ */
#define irq_connect_dynamic(irq_p, priority_p, isr_p, isr_param_p, flags_p) \ extern int _arch_irq_connect_dynamic(unsigned int irq, unsigned int priority,
_arch_irq_connect_dynamic(irq_p, priority_p, isr_p, isr_param_p, \ void (*routine)(void *parameter), void *parameter,
flags_p) uint32_t flags);
static inline int __attribute__((deprecated))
irq_connect_dynamic(unsigned int irq, unsigned int priority,
void (*routine)(void *parameter), void *parameter,
uint32_t flags)
{
return _arch_irq_connect_dynamic(irq, priority, routine, parameter, flags);
}
/** /**
@ -122,5 +136,9 @@
*/ */
#define irq_disable(irq) _arch_irq_disable(irq) #define irq_disable(irq) _arch_irq_disable(irq)
#ifdef __cplusplus
}
#endif
#endif /* ASMLANGUAGE */
#endif /* _IRQ_H_ */ #endif /* _IRQ_H_ */

View file

@ -11,4 +11,3 @@ CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096
CONFIG_SYS_POWER_MANAGEMENT=y CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_NUM_IRQS=43 CONFIG_NUM_IRQS=43
CONFIG_SW_ISR_TABLE_DYNAMIC=y

View file

@ -9,4 +9,3 @@ CONFIG_NUM_TIMER_PACKETS=16
CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096 CONFIG_MICROKERNEL_SERVER_STACK_SIZE=4096
CONFIG_SYS_POWER_MANAGEMENT=y CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_NUM_IRQS=43 CONFIG_NUM_IRQS=43
CONFIG_SW_ISR_TABLE_DYNAMIC=y

View file

@ -117,10 +117,6 @@ void dummyIsr(void *unused)
*/ */
void fgTaskEntry(void) void fgTaskEntry(void)
{ {
#ifdef TEST_max
/* dynamically link in dummy ISR */
irq_connect_dynamic(IRQ_LINE, IRQ_PRIORITY, dummyIsr, (void *) 0, 0);
#endif /* TEST_max */
#ifdef TEST_reg #ifdef TEST_reg
IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0); IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0);
#endif #endif

View file

@ -1,3 +1,2 @@
CONFIG_SERIAL=n CONFIG_SERIAL=n
CONFIG_IPM=n CONFIG_IPM=n
CONFIG_SW_ISR_TABLE_DYNAMIC=y

View file

@ -2,4 +2,3 @@ CONFIG_PRINTK=y
CONFIG_STDOUT_CONSOLE=y CONFIG_STDOUT_CONSOLE=y
CONFIG_NUM_IRQS=43 CONFIG_NUM_IRQS=43
CONFIG_FAULT_DUMP=2 CONFIG_FAULT_DUMP=2
CONFIG_SW_ISR_TABLE_DYNAMIC=y

View file

@ -1,4 +1,3 @@
CONFIG_PRINTK=y CONFIG_PRINTK=y
CONFIG_STDOUT_CONSOLE=y CONFIG_STDOUT_CONSOLE=y
CONFIG_IDT_NUM_VECTORS=256 CONFIG_IDT_NUM_VECTORS=256
CONFIG_NUM_DYNAMIC_STUBS=2

View file

@ -120,11 +120,6 @@ static void fiberEntry(int message, int arg1)
void main(void) void main(void)
{ {
#ifdef TEST_max
/* dynamically link in dummy ISR */
irq_connect_dynamic(IRQ_LINE, IRQ_PRIORITY, dummyIsr,
(void *) 0, 0);
#endif /* TEST_max */
#ifdef TEST_reg #ifdef TEST_reg
IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0); IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0);
#endif #endif

View file

@ -51,7 +51,3 @@ config STATIC_ISR
bool "static isr" bool "static isr"
default y default y
config DYNAMIC_ISR
bool "dynamic isr"
default n

View file

@ -14,7 +14,5 @@ CONFIG_OBJECTS_LIFO=y
CONFIG_OBJECTS_FIFO=y CONFIG_OBJECTS_FIFO=y
CONFIG_OBJECTS_STACK=y CONFIG_OBJECTS_STACK=y
CONFIG_STATIC_ISR=n CONFIG_STATIC_ISR=n
CONFIG_DYNAMIC_ISR=y
CONFIG_NUM_DYNAMIC_STUBS=2
#CONFIG_TOOLCHAIN_VARIANT="iamcu" #CONFIG_TOOLCHAIN_VARIANT="iamcu"
CONFIG_KERNEL_BIN_NAME="prj10" CONFIG_KERNEL_BIN_NAME="prj10"

View file

@ -14,7 +14,5 @@ CONFIG_OBJECTS_LIFO=y
CONFIG_OBJECTS_FIFO=y CONFIG_OBJECTS_FIFO=y
CONFIG_OBJECTS_STACK=y CONFIG_OBJECTS_STACK=y
CONFIG_STATIC_ISR=n CONFIG_STATIC_ISR=n
CONFIG_DYNAMIC_ISR=y
CONFIG_NUM_DYNAMIC_STUBS=2
CONFIG_NANO_TIMEOUTS=y CONFIG_NANO_TIMEOUTS=y
CONFIG_KERNEL_BIN_NAME="prj11" CONFIG_KERNEL_BIN_NAME="prj11"

View file

@ -115,12 +115,6 @@ void main(void)
IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0); IRQ_CONNECT(IRQ_LINE, IRQ_PRIORITY, dummyIsr, NULL, 0);
#endif #endif
#ifdef CONFIG_DYNAMIC_ISR
/* dynamically link in dummy ISR */
irq_connect_dynamic(IRQ_LINE, IRQ_PRIORITY, dummyIsr,
(void *) 0, 0);
#endif
#ifdef CONFIG_OBJECTS_FIBER #ifdef CONFIG_OBJECTS_FIBER
/* start a trivial fiber */ /* start a trivial fiber */
task_fiber_start(pStack, FIBER_STACK_SIZE, fiberEntry, (int) MESSAGE, task_fiber_start(pStack, FIBER_STACK_SIZE, fiberEntry, (int) MESSAGE,