Hello,
I have some basic questions about IO-APIC. In the boot-up message, I can see this:
IO-APIC[ 0]: pins 23 PIN[ 0m]: vector=20, del=0, dm=physical, dest=0 (high, edge) PIN[ 1m]: vector=21, del=0, dm=physical, dest=0 (high, edge) PIN[ 2m]: vector=22, del=0, dm=physical, dest=0 (high, edge)
I understand this info is from IO-APIC redirection table. My question is what does vector means? Is that the interrupt number CPU is going to see when an interrupt request is sent from a pin? Or it's an irq number assigned to an IO-APIC pin?
Thanks.
Best, Chen
On Fri, 27 Jul 2012 16:34:12 -0800 Chen Tian (CT) wrote:
CT> I have some basic questions about IO-APIC. In the boot-up message, I can CT> see this: CT> CT> IO-APIC[ 0]: pins 23 CT> PIN[ 0m]: vector=20, del=0, dm=physical, dest=0 (high, edge) CT> PIN[ 1m]: vector=21, del=0, dm=physical, dest=0 (high, edge) CT> PIN[ 2m]: vector=22, del=0, dm=physical, dest=0 (high, edge) CT> CT> I understand this info is from IO-APIC redirection table. My question is CT> what does vector means? Is that the interrupt number CPU is going to see CT> when an interrupt request is sent from a pin? Or it's an irq number CT> assigned to an IO-APIC pin?
It is the interrupt vector that the IOAPIC will send to the CPU when there is interrupt activity on the respective pin. The vector is then used as an index into the IDT, which tells the CPU where the interrupt handler can be found. Which is why it starts at 0x20, because vectors 0x0-0x1f are reserved for exceptions.
Cheers, Udo
Thanks for the reply. Then what is the irq number that is assigned to an io-apic pin? When writing a driver for a PCi device, how can I use the value in pci irq field to find the right irq no. for this device so I can call attach function in driver?
Chen On Jul 28, 2012 10:24 AM, "Udo Steinberg" udo@hypervisor.org wrote:
On Fri, 27 Jul 2012 16:34:12 -0800 Chen Tian (CT) wrote:
CT> I have some basic questions about IO-APIC. In the boot-up message, I can CT> see this: CT> CT> IO-APIC[ 0]: pins 23 CT> PIN[ 0m]: vector=20, del=0, dm=physical, dest=0 (high, edge) CT> PIN[ 1m]: vector=21, del=0, dm=physical, dest=0 (high, edge) CT> PIN[ 2m]: vector=22, del=0, dm=physical, dest=0 (high, edge) CT> CT> I understand this info is from IO-APIC redirection table. My question is CT> what does vector means? Is that the interrupt number CPU is going to see CT> when an interrupt request is sent from a pin? Or it's an irq number CT> assigned to an IO-APIC pin?
It is the interrupt vector that the IOAPIC will send to the CPU when there is interrupt activity on the respective pin. The vector is then used as an index into the IDT, which tells the CPU where the interrupt handler can be found. Which is why it starts at 0x20, because vectors 0x0-0x1f are reserved for exceptions.
Cheers, Udo
l4-hackers mailing list l4-hackers@os.inf.tu-dresden.de http://os.inf.tu-dresden.de/mailman/listinfo/l4-hackers
On Sat, 28 Jul 2012 07:44:10 -0700 Chen Tian (CT) wrote:
CT> Thanks for the reply. Then what is the irq number that is assigned to an CT> io-apic pin? When writing a driver for a PCi device, how can I use the CT> value in pci irq field to find the right irq no. for this device so I can CT> call attach function in driver?
I assume you mean the value in the PCI interrupt line field at offset 0x3c in the configuration space? That value has no meaning when the IOAPIC is used.
What you need to do instead is parse _PRT blocks of the ACPI DSDT table to figure out which IOAPIC pin each device is connected to. Here's an example:
Name (AH02, Package (0x04) { Package (0x04) { 0xFFFF, // PCI address of the device 0x00, // PCI LINK A 0x00, 0x1D // IOAPIC GSI 29 },
Package (0x04) { 0xFFFF, 0x01, // PCI LINK B 0x00, 0x29 // IOAPIC GSI 41 },
Package (0x04) { 0xFFFF, 0x02, // PCI LINK C 0x00, 0x28 // IOAPIC GSI 40 },
Package (0x04) { 0xFFFF, 0x03, // PCI LINK D 0x00, 0x2A // IOAPIC GSI 42 } })
Depending on which of the PCI interrupt lines (A-D) the device is configured to use, it will either generate GSI 29, 41, 40, or 42. In this case the machine has multiple IOAPICs, each with 24 pins, so for example GSI 29 would be the 6th pin on the second IOAPIC.
Cheers, Udo
So I should use the interrupt pin field at offset 0x3c to find out which PCI link the device uses. Can I use this value directly to search IO-APIC GSI in _PRT blocks? I read some article that says this value may be local to PCI device, and it may be remapped by motherboard to another PCI link number through something like daisy chain type of mapping. For example, PCI slot 1's INTA# uses INTA#, while PCI slot 2's INTA# actually uses INTB#. Is this true? If so, I think I need to handle this mapping before search _PRT blocks, right?
For GSI number, I assume it is the irq number I am looking for. But I still have some questions. First, is it always fixed for each pin of each IO-APIC? For example, first pin of first IO-APIC has GSI 0, second pin has 1, ..., and the first pin of second IO-APIC has GSI 24, second pin has 25, ...? If so, then irq number will range from 0 to 47 on a two-io-apic machine. But Linux runs on the same machine can report irq 53 for some device, which is very confusing to me.
Second, some document says GSI number can be overridden. When booting Fiasco.OC, I can see a line like ovr[0] 2->0. Does that mean GSI 2 eventually become irq 0? I am not sure when and why a GSI number needs to be overridden, but can the overriding happen to the device I am interested? If so, how should I deal with it in my device driver, i.e., should I use the original GSI number as my device's irq or use the one after overriding?
Look forward to your reply. I am so eager to know the answers. Thanks.
Best, Chen
On Sat, Jul 28, 2012 at 7:11 AM, Udo Steinberg udo@hypervisor.org wrote:
On Sat, 28 Jul 2012 07:44:10 -0700 Chen Tian (CT) wrote:
CT> Thanks for the reply. Then what is the irq number that is assigned to an CT> io-apic pin? When writing a driver for a PCi device, how can I use the CT> value in pci irq field to find the right irq no. for this device so I can CT> call attach function in driver?
I assume you mean the value in the PCI interrupt line field at offset 0x3c in the configuration space? That value has no meaning when the IOAPIC is used.
What you need to do instead is parse _PRT blocks of the ACPI DSDT table to figure out which IOAPIC pin each device is connected to. Here's an example:
Name (AH02, Package (0x04) { Package (0x04) { 0xFFFF, // PCI address of the device 0x00, // PCI LINK A 0x00, 0x1D // IOAPIC GSI 29 }, Package (0x04) { 0xFFFF, 0x01, // PCI LINK B 0x00, 0x29 // IOAPIC GSI 41 }, Package (0x04) { 0xFFFF, 0x02, // PCI LINK C 0x00, 0x28 // IOAPIC GSI 40 }, Package (0x04) { 0xFFFF, 0x03, // PCI LINK D 0x00, 0x2A // IOAPIC GSI 42 } })
Depending on which of the PCI interrupt lines (A-D) the device is configured to use, it will either generate GSI 29, 41, 40, or 42. In this case the machine has multiple IOAPICs, each with 24 pins, so for example GSI 29 would be the 6th pin on the second IOAPIC.
Cheers, Udo
l4-hackers mailing list l4-hackers@os.inf.tu-dresden.de http://os.inf.tu-dresden.de/mailman/listinfo/l4-hackers
On Sat, 28 Jul 2012 08:29:31 -0800 Chen Tian (CT) wrote:
CT> So I should use the interrupt pin field at offset 0x3c to find out which CT> PCI link the device uses.
Yes, but the offset of the interrupt pin ix 0x3d.
CT> Can I use this value directly to search IO-APIC CT> GSI in _PRT blocks? I read some article that says this value may be local CT> to PCI device, and it may be remapped by motherboard to another PCI link CT> number through something like daisy chain type of mapping. For example, PCI CT> slot 1's INTA# uses INTA#, while PCI slot 2's INTA# actually uses INTB#. CT> Is this true? If so, I think I need to handle this mapping before search CT> _PRT blocks, right?
The _PRT method is defined in the ACPI specification as follows:
Field Type Description Address DWORD The address of the device (uses the same format as _ADR). Pin BYTE The PCI pin number of the device (0INTA, 1INTB, 2INTC, 3INTD). Source NamePath Name of the device that allocates the interrupt to which the above pin is Or connected. The name can be a fully qualified path, a relative path, or a simple BYTE name segment that utilizes the namespace search rules. Note: This field is a NamePath and not a String literal, meaning that it should not be surrounded by quotes. If this field is the integer constant Zero (or a BYTE value of 0), then the interrupt is allocated from the global interrupt pool. Source DWORD Index that indicates which resource descriptor in the resource template of the Index device pointed to in the Source field this interrupt is allocated from. If the Source field is the BYTE value zero, then this field is the global system interrupt number to which the pin is connected.
Once you've found the PCI device in the ACPI namespace, you need to look at the "Source" field to see which upstream device a PCI pin is connected to and "Source Index" tells you where it is connected. You then need to do the same for the upstream device, and so forth. For example, you may find that INTA is connected to INTC upstream, and INTC is connected to INTB even further upstream. Once you find that the "Source" field is 0, the "Source Index" is the GSI number that you are looking for.
CT> For GSI number, I assume it is the irq number I am looking for. But I still CT> have some questions. First, is it always fixed for each pin of each CT> IO-APIC? For example, first pin of first IO-APIC has GSI 0, second pin has CT> 1, ..., and the first pin of second IO-APIC has GSI 24, second pin has 25, CT> ...? If so, then irq number will range from 0 to 47 on a two-io-apic CT> machine. But Linux runs on the same machine can report irq 53 for some CT> device, which is very confusing to me.
The ACPI MADT table lists all the IOAPICs in the system. Each IOAPIC has a certain number of pins, which you can read out from the IOAPIC itself. The first IOAPIC serves GSI 0 through X-1, where X is the number of pins. The second IOAPIC then serves pins X through X + (Y-1), where Y is the number of pins of the second IOAPIC and so forth.
CT> Second, some document says GSI number can be overridden. When booting CT> Fiasco.OC, I can see a line like ovr[0] 2->0. Does that mean GSI 2 CT> eventually become irq 0? I am not sure when and why a GSI number needs to CT> be overridden, but can the overriding happen to the device I am CT> interested? If so, how should I deal with it in my device driver, i.e., CT> should I use the original GSI number as my device's irq or use the one CT> after overriding?
The legacy IRQs are also connected to the IOAPIC, typically in a 1:1 fashion. This means IRQx is connected to GSIx, except where overrides are used. This is only relevant if you want to drive a non-PCI legacy device, such as the PIT, which uses IRQ0, which is typically connected to GSI2.
Cheers, Udo
l4-hackers@os.inf.tu-dresden.de