[linux-audio-user] APIC
Clemens Ladisch
clemens at ladisch.de
Tue Jan 20 05:05:27 EST 2004
Yesterday, I wrote:
> Mark Knecht wrote:
> > Also, the first link says 'For APICs, when two interrupts are present
> > when interrupts are enabled, the one with the highest interrupt vector
> > number will be taken first' and 'So, the last PCI interrupt source in the
> > MPS table will be the highest priority'.
> >
> > However the second link says 'The local APIC unit will handle interrupts
> > depending on vector, with lowest being highest priority. Here is a sample
> > table with NR being the IRQ e.g. 0 = 31;'
> >
> > For me this wording seems contradictory,
>
> I think the first is simply wrong
I've looked into the Intel documentation, and it turns out I thought
wrong, i.e., the first quoted link is right. (But it was for an older
Linux version which assigned vector numbers consecutively.)
Section 8.3.3 of the "IA-32 Intel(R) Architecture Software Developer's
Manual, Volume 3: System Programming Guide" says:
| For interrupts that are delivered to the processor through the local
| APIC, each interrupt has an implied priority based on its vector
| number. The local APIC uses this priority to determine when to
| service the interrupt relative to the other activities of the
| processor, including the servicing of other interrupts.
|
| For interrupts vectors in the range of 16 to 255, the interrupt
| priority is determined using the following relationship:
|
| priority = vector / 16
|
| Here the quotient is rounded down to the nearest integer value to
| determine the priority, with 1 being the lowest priority and 15 is
| the highest. Because vectors 0 through 31 are reserved for
| dedicated uses by the IA-32 architecture, the priorities of user
| defined interrupts range from 2 to 15.
|
| Each interrupt priority level (sometimes interpreted by software as
| an interrupt priority class) encompasses 16 vectors. Prioritizing
| interrupts within a priority level is determined by the vector
| number. The higher the vector number, the higher the priority
| within that priority level. In determining the priority of a vector
| and ranking of vectors within a priority group, the vector number is
| often divided into two parts, with the high 4 bits of the vector
| indicating its priority and the low 4 bit indicating its ranking
| within the priority group.
So, if Intel's explanation is correct, higher vector numbers have
higer priority.
> The table shown by Zwane is output into the system log when booting.
For example, on my P4P800, dmesg says:
.... IRQ redirection table:
NR Log Phy Mask Trig IRR Pol Stat Dest Deli Vect:
00 000 00 1 0 0 0 0 0 0 00
01 003 03 0 0 0 0 0 1 1 39
02 003 03 0 0 0 0 0 1 1 31
03 003 03 0 0 0 0 0 1 1 41
04 003 03 0 0 0 0 0 1 1 49
05 003 03 0 0 0 0 0 1 1 51
06 003 03 0 0 0 0 0 1 1 59
07 003 03 0 0 0 0 0 1 1 61
08 003 03 0 0 0 0 0 1 1 69
09 003 03 0 1 0 0 0 1 1 71
0a 003 03 0 0 0 0 0 1 1 79
0b 003 03 0 0 0 0 0 1 1 81
0c 003 03 0 0 0 0 0 1 1 89
0d 003 03 0 0 0 0 0 1 1 91
0e 003 03 0 0 0 0 0 1 1 99
0f 003 03 0 0 0 0 0 1 1 A1
10 003 03 1 1 0 1 0 1 1 B9
11 003 03 1 1 0 1 0 1 1 B1
12 003 03 1 1 0 1 0 1 1 A9
13 003 03 1 1 0 1 0 1 1 C1
14 003 03 1 1 0 1 0 1 1 D1
15 003 03 1 1 0 1 0 1 1 D9
16 003 03 1 1 0 1 0 1 1 E1
17 003 03 1 1 0 1 0 1 1 C9
So, interrupt 22 (0x16) has the highest priority (vector 0xE1),
followed by interrupts 21 and 20, etc. (On the P4P800, these
interrupts are assigned to the onboard 3C940 and PCI slots 5 and 4,
respectively.)
It would be possible to assign a different vector number to a specific
interrupt by patching the assign_irq_vector function in
arch/i386/kernel/io_apic.c
> > One other piece of interesting information was that you can supposedly
> > control the ordering of the interrupt table using some kernel type software.
> > This would be quite cool since you could then insert your sound card
> > anywhere into the list and give it the very best servicing that your machine
> > can provide.
>
> The "Task Priority Register" register mentioned there lets you assign
> a priority to each CPU, so that an interrupt can interrupt the
> lowest-priority task in a multi-CPU system.
This explanation is slightly wrong, too. The processor priority isn't
determined by the TPR but by the PPR (Processor Priority Register),
which is computed as follows:
| [T]he processor priority is set to either to the highest priority
| pending interrupt [...] or to the current task priority, whichever
| is higher.
The TPR is used to suppress interrupts which have a lower priority
than the current task priority.
Regards,
Clemens
More information about the Linux-audio-user
mailing list