Attaching and detaching interrupts

In order to install an ISR, the software must tell the OS that it wishes to associate the ISR with a particular source of interrupts, which can be a hardware Interrupt Request line (IRQ) or one of several software interrupts.

The actual number of interrupts depends on the hardware configuration supplied by the board's manufacturer. For the interrupt assignments for specific boards, see the buildfile in that board's BSP.

In any case, a thread specifies which interrupt source it wants to associate with which ISR, using the InterruptAttach() or InterruptAttachEvent() function calls; when the software wishes to dissociate the ISR from the interrupt source, it can call InterruptDetach(). For example:

#define IRQ3 3

/*  A forward reference for the handler */
extern const sigevent *serint (void *, int);
…

/*
 *  Associate the interrupt handler, serint,
 *  with IRQ 3, the 2nd PC serial port
 */

id = InterruptAttach (IRQ3, serint, NULL, 0, 0);
…

/*  Perform some processing. */
…

/*  Done; detach the interrupt source. */
InterruptDetach (id);
Note: The startup code is responsible for making sure that all interrupt sources are masked during system initialization. When the first call to InterruptAttach() or InterruptAttachEvent() is done for an interrupt vector, the kernel unmasks it. Similarly, when the last InterruptDetach() is done for an interrupt vector, the kernel remasks the level.

Because the interrupt handler can potentially gain control of the machine, we don't let just anybody associate an interrupt with ISR code. The process must have the PROCMGR_AID_INTERRUPT ability enabled. For more information, see procmgr_ability() in the C Library Reference.

Attaching an ISR superlocks the process's memory (see Locking memory in the “Process Manager” chapter of the System Architecture guide). This helps to reduce latency; we don't want to be handling page faults in an ISR.