Sun Java Solaris Communities My SDN Account Join SDN
 
Documentation

Interrupts

Device drivers use ddi_add_intr(9F) to add an interrupt handler to the system. The interrupt number, inumber, determines with which interrupt level the handler is associated. The system passes inumber to the PCI nexus driver to determine the interrupt level for a device based upon the value of the "interrupts" or "interrupt-priorities" properties.

The "interrupt-priorities" property is set in the device driver's .conf file, and the "interrupts" property is an OpenBoot property created by the device's parent node. If both the "interrupt-priorities" property and "interrupts" property are present, the system uses the "interrupt-priorities" property. The system uses inumber as an index to the array of values in the "interrupt-priorities" property to get the interrupt level.

If the "interrupt-priorities" property is not present in the driver .conf file, the system gets the values of the "interrupt" property and uses inumber to index to the array to get the interrupt value. If the interrupt value is one of 1, 2, 3, and 4 ($INTA, $INTB, $INTC, and $INTD), the interrupt level is determined from the base_class bits of the "class-code" property of the device.

For example, the following table shows the setting of the interrupt level for different base classes of a PCI device in Solaris 2.5.1.

Base Class Description Interrupt Level
00H Backward Compatible 1
01H Mass Storage Controller 4
02H Network Controller 6
03H Display Controller 9
04H Multimedia Controller 10
05H Memory Controller 10
06H Bridge Controller 10
07H Communications Controller 1
08H Peripheral Controller 1
09H Input Devices 1
0AH Docking Stations 1
0BH Processors 1
0CH Serial Bus Controller 1

The value of the "class-code" property of a device is 0x00030000. The base class of the device is 0x3, which is a display controller. Based on the information in the previous table, the system assigns interrupt level 9 to the device.

For the on-board PCI devices such as glm (SCSI), hme (network), and ebus, a different scheme is used to determine the interrupt level. The lower 6 bits of the "interrupt" property is the INO. Device drivers use the INO to index into a built-in table to get the interrupt level.

The IDU is responsible for fielding interrupts from external PCI devices, building the interrupt packet, and sending the interrupt packet to the appropriate CPU. The packet is 64 bytes long and contains the INO and target CPU. The INO is a fixed value and is specific to each interrupt source. The INO allows software to uniquely identify the source of the interrupt without having to poll all interrupt sources, thus reducing overhead in processing interrupts.

When a PCI interrupt occurs, the system calls the PCI nexus driver's interrupt handler, pci_intr_wrapper(). pci_intr_wrapper() is a wrapper around the child's interrupt handlers to avoid having multiple child interrupt handlers access the HPB interrupt register at the same time. pci_intr_wrapper() invokes the associated interrupt handler of the child node and clears the corresponding interrupt through the HPB's clear-interrupt register after the return from the child's interrupt handler.

Usually, the system creates a separate thread to handle the interrupt service to maximize thread concurrence. However, if the interrupt level is above the clock interrupt level, the system can't hold mutex to create a separate interrupt thread to service the interrupt. The interrupt handler runs in the same thread as the interrupted process. In such a case, the driver must not try to hold any mutex locks in its interrupt handler to avoid system panic on recursive mutex calls. Device drivers should always call ddi_intr_hilevel(9F) to check if its interrupt level is above the clock interrupt level before it registers the interrupt handler.

For a detailed discussion on the use of DDI interrupt functions and how to handle high-level interrupts, refer to Handling High-Level Interrupts in Writing Device Drivers.

<< Previous |  Contents |  Next>>