Interrupt priority levels

Serge Vakulenko edited this page Jun 1, 2014 · 15 revisions

(from The Book, chapter 4.3)

When the top half of the kernel accesses resources that are shared with the bottom half of the kernel, it must prevent the bottom half from running while it is using the resource. Although interrupt priorities are machine dependent, most implementations of 4.4BSD order them according to the table:

Name Blocks PIC32 C0_Status register IPL
spl0() nothing (normal operating mode) 0-0 0000 00-- ---- ---1 0
splsoftclock() low-priority clock processing 0-0 0000 01-- ---- ---1 1
splnet() network protocol processing 0-0 0000 10-- ---- ---1 2
splbio() disk controllers 0-0 0000 11-- ---- ---1 3
splimp() network device controllers 0-0 0001 00-- ---- ---1 4
spltty() terminal multiplexers 0-0 0001 01-- ---- ---1 5
splclock() high-priority clock processing 0-0 0001 10-- ---- ---1 6
splhigh() all interrupt activity --- ---- ---- ---- ---0 ---

To block interrupt routines at and below a certain priority level, a critical section must make an appropriate set-priority-level call. All the set-priority-level calls return the previous priority level. When the critical section is done, the priority is returned to its previous level using splx(). For example, when a process needs to manipulate a terminal's data queue, the code that accesses the queue is written in the following style:

s = spltty();        /* raise priority to block tty processing */
 ...                 /* manipulate tty */
splx(s);             /* reset priority level to previous value */

On PIC32 microcontroller, bits 18,16..10 of COP0 Status register contain the current IPL. An interrupt will be signalled only if the requested IPL is higher than this value. Requested IPL values for specific interrupts are programmed via fields IP0..IP3 of IPCx registers.

Bit 0 of COP0 Status register contains a global Interrupt Enable flag. When 0, all interrupts are disabled.