intrinfo
Information about the interrupt system
The intrinfo area stores information about the interrupt system, and contains the kernel callouts that manipulate the interrupt controller hardware. For 64-bit systems, this area is defined by an array of new_intrinfo data structures; 32-bit systems use the old_intrinfo data structures.
On a multicore system, each interrupt is directed to only one CPU, although it doesn't matter which. How this happens is controlled by the board's Programmable Interrupt Controller chips (PICs). When you initialize the PICs at startup, you can program them to deliver the interrupts to whichever CPU you want; on some PICs you can even get an interrupt to rotate between CPUs each time it is asserted.
Often, QNX startup programs are written so that all interrupts (except those used for interprocessor interrupts) are sent to CPU 0. This allows for the same startup for procnto and procnto-smp. Also, directing all interrupts to one CPU is efficient because it supports better cache usage.
- vector_base
- The base number of the logical interrupt numbers that programs will use (e.g., the interrupt vector passed to InterruptAttach()).
- num_vectors
- The number of vectors starting at vector_base described by this entry.
- cascade_vector
- If this interrupt entry describes a set of interrupts that are cascaded into another interrupt controller, then this member contains the logical interrupt number of the interrupt that this controller cascades into.
- cpu_intr_base
- The association between this set of interrupts and the CPU's view of the interrupt source.
- cpu_intr_stride
- The spacing between interrupt vector entries for interrupt systems that do autovectoring. The default is 0 (no autovectoring).
- flags
- Used by the startup code when generating the kernel's interrupt service
routine (ISR) entry points (see
INTR_* flags
below). - id
- A code snippet that gets copied into the kernel's ISR. This code is used to identify the source of the interrupt, for the case when multiple hardware events can trigger one CPU-visible interrupt. Further modified by the INTR_GENFLAG_* flags, defined below.
- eoi
- A code snippet that gets copied into the kernel's ISR and that provides the End Of Interrupt (EOI) functionality. This code is responsible for telling the controller that the interrupt is done, and for unmasking the interrupt level. For CPU fault-as-an-interrupt handling, eoi identifies the cause of the fault.
- mask
- A callout to mask an interrupt source at the hardware controller level. The numbers passed to this function are the interrupt vector numbers (from 0 to num_vectors - 1).
- unmask
- A callout to unmask an interrupt source at the hardware controller level. Same vector numbers as mask, above.
- config
- Provides configuration information on individual interrupt levels. The function get passed the system page pointer, a pointer to this interrupt info entry, and the zero-based interrupt level. Returns a bitmask (see INTR_CONFIG_FLAG* below).
- patch_data
- Provides information about patched data. This data is passed to the patcher() routine that gets called once for each kernel callout in a startup_intrinfo() structure.
- local_stride
- When local_stride is non-zero, the interrupt is processor-specific.
Each group of kernel callouts (id, eoi, mask, unmask) for each interrupt controller level deals with a set of zero-based interrupt vectors. You must set the kernel callouts for each interrupt level accordingly.
Interrupt vector numbers are passed without offset to the callout routines. The mapping between the zero-based interrupt vectors used by the callouts and the system-wide interrupt vectors is configured in the intrinfo structures, which are found in the init_intrinfo() routine.
INTR_* flags
The flags member takes two sets of flags. One set describes interrupt characteristics, the other set affects interrupt code generation. Both sets are system-independent.
Interrupt characteristics
The first set of flags deals with the characteristics of the interrupts:
- INTR_FLAG_NMI
- Indicates that this is a NonMaskable Interrupt (NMI). An NMI is an interrupt which, unlike normal interrupts, can't be disabled by clearing the CPU's interrupt enable flag. NMIs are typically used to signal events that require immediate action, such as a parity error, a hardware failure, or an imminent loss of power.
- INTR_FLAG_CASCADE_IMPLICIT_EOI
- Indicates that an EOI to the primary interrupt controller is not required when handling a cascaded interrupt, because the EOI is issued automatically. Only used if this entry describes a cascaded controller.
- INTR_FLAG_CPU_FAULT
- Indicates that one or more vectors described by this entry is not connected to a hardware interrupt source, but is generated as a result of a CPU fault (e.g., bus fault, parity error).
Interrupt code generation
The second set of flags deals with code generation:
- INTR_GENFLAG_LOAD_SYSPAGE
- Before the interrupt identification or EOI code sequence is generated, a piece of code
needs to be inserted to fetch the system page pointer into a register so
that it's usable in the identification code sequence. Note:If you use the interrupt_id_dec(), interrupt_id_dec_smp(), or interrupt_eoi_dec() kernel callouts, you must specify the INTR_GENFLAG_LOAD_SYSPAGE flag in the genflags field of the intrinfo_entry structure in the board-specific code.
- INTR_GENFLAG_LOAD_INTRINFO
- Same as INTR_GENFLAG_LOAD_SYSPAGE, except that it loads a pointer to this structure.
- INTR_GENFLAG_LOAD_INTRMASK
- Used only by EOI routines for hardware that doesn't automatically mask at the chip level. When the EOI routine is about to re-enable interrupts, it should re-enable only those interrupts that are actually enabled at the user level (i.e., managed by the functions InterruptMask() and InterruptUnmask()).
- INTR_GENFLAG_NOGLITCH
- Used by the interrupt ID code to trigger a check to see if the interrupt was due to a glitch or to a different controller. If this flag is set, the check is omitted—you're indicating there's no reason (other than the fact that the hardware did generate an interrupt) to be in the ISR. If this flag is not set, the check is made to verify that the suspected hardware really is the source of the interrupt.
- INTR_GENFLAG_LOAD_CPUNUM
- Same as INTR_GENFLAG_LOAD_SYSPAGE, except that it loads a pointer to the number of the CPU this structure uses.
- INTR_GENFLAG_ID_LOOP
- Some interrupt controllers have read-and-clear registers indicating the active interrupts. The first read returns a bitset of the pending interrupts, then immediately zeroes the register.
config() return values
Interrupt controllerin the Kernel Callouts chapter) may return zero or more of the following flags:
- INTR_CONFIG_FLAG_PREATTACH
- Normally, an interrupt is masked (ignored) until a routine attaches to it via
InterruptAttach() or
InterruptAttachEvent(). If CPU fault indications are
routed through to a hardware interrupt (not recommended!), the
interrupt would, by default, be disabled. Setting this flag causes a
dummy
connection to be made to this source, causing this level to become unmasked. - INTR_CONFIG_FLAG_DISALLOWED
- Prevents user code from attaching to this interrupt level. Generally used with INTR_CONFIG_FLAG_PREATTACH, but could be used to prevent user code from attaching to any interrupt in general.
- INTR_CONFIG_FLAG_IPI
- Identifies the vector used as the target of an inter-processor interrupt in an SMP system.
