PIR$ & IntPin register on PCIe configuration space

Hi all,

Few questions

  1. Are PIR$ table used these days? or are they obsolete?

  2. Each PCI device has IntPin register in their configuration address space. Assuming chipset has IOAPIC, does value in IntPin directly maps to IntPin in IOAPIC or IntPin are steered/redirected to other pin by configuring PIR$ table (if in use?)

Goal: To figure out interrupt vector associated for a given device (PCI) using PCIe configuration address space.

Regards

> Goal: To figure out interrupt vector associated for a given device (PCI) using PCIe configuration

This is not supported in Windows, use the classic PnP IRPs and HW resource lists instead.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Max answered your ultimate question. I'll answer the question that you
asked in passing.

Windows did support $PIR, for machines that are not ACPI compliant. Windows
no longer supports machines that are not ACPI compliant. The same
information supplied by $PIR (and much more) now comes from ACPI.

Jake Oshins
Windows Kernel Team

This post implies no warrantees and confers no rights.

wrote in message news:xxxxx@ntdev...

Hi all,

Few questions

  1. Are PIR$ table used these days? or are they obsolete?

  2. Each PCI device has IntPin register in their configuration address space.
    Assuming chipset has IOAPIC, does value in IntPin directly maps to IntPin in
    IOAPIC or IntPin are steered/redirected to other pin by configuring PIR$
    table (if in use?)

Goal: To figure out interrupt vector associated for a given device (PCI)
using PCIe configuration address space.

Regards

xxxxx@gmail.com wrote:

  1. Each PCI device has IntPin register in their configuration address space. Assuming chipset has IOAPIC, does value in IntPin directly maps to IntPin in IOAPIC or IntPin are steered/redirected to other pin by configuring PIR$ table (if in use?)

Goal: To figure out interrupt vector associated for a given device (PCI) using PCIe configuration address space.

Why? Of what possible use is this information?

You could look up the IOAPIC vector number in the configuration space
(for “legacy” interrupts), but what good does that do? Those do not map
directly to IRQLs in the kernel.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> Why? Of what possible use is this information?

You could look up the IOAPIC vector number in the configuration space (for “legacy” interrupts), but what good does that do? Those do not map directly to IRQLs in the kernel.

For example, I have a device whose configuration space has IntPin value of 1. Now this IntPin will map to some IOAPIC pin (IRQL). From IOAPIC IRQL, I can figure out vector number and from vector number I know which entry needs to be setup in IDT for Interrupt processing.

Am I going completely wrong path here? Or do I have to use some other method of interrupt programming? Even if there is another method, I still would want to know how OS (Windows, for example) maps PCIe device IntPin register to an IRQL? Knowledge is bliss!!!

xxxxx@gmail.com wrote:

For example, I have a device whose configuration space has IntPin value of 1. Now this IntPin will map to some IOAPIC pin (IRQL). From IOAPIC IRQL, I can figure out vector number and from vector number I know which entry needs to be setup in IDT for Interrupt processing.

Am I going completely wrong path here?

Of course you are! Have you done any reading in the sample drivers? If
you have a PCI device, and you are writing a driver for that device, the
operating system will TELL your driver which resources were assigned to
your hardware, including memory, I/O ports, and everything you need to
know to handle the interrupt. YOU do not touch the IDT. YOU do not
touch the APIC. Those things don’t belong to you. You call
IoConnectInterrupt, and the operating system sets up its internal
dispatch tables and programs the IDT. When an interrupt arrives, the
operating system handles the APIC, and then calls your callback.

This is not DOS. You don’t touch the bare metal. There is a kernel in
control of the bare metal, which exposes an abstraction that must be
followed, otherwise things crash. There are many machine architectures
that you know nothing about, where your hacking around is going to
produce incorrect results. Let the operating system abstract that, and
you just follow the rules. Then everyone plays together.

Remember that, in a typical system, there will be many devices sharing a
single IRQ. That cannot happen if drivers try to whack the IDT on their
own.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim

I did read about IoConnectInterrupt and knew before posting this question that it’s the only way to setup interrupts and IDT is never meant to be hacked or touched as OS or Firmware owns that.

However, I was more interested in knowing behind the scenes processes of how PCIe “IntPin register” gets mapped to an IOAPIC pin (IRQL). There must be some sort of pin to pin linking happening at hardware level and I wanted to know what mechanism is doing that.

I was trying to connect dots to gain knowledge of system hardware and it’s working in modern computing.

All I know at this moment is

PCI Device -> Uses PCIe configuration space to configure what interrupt pin it can use using “IntPin” register.

( SOME CONNECTING THING HERE…I DON’T KNOW WHAT)

IOAPIC -> Which has incoming Interrupt pins from PCI device and are mapped to Interrupt vector

LAPIC -> LINT0 or LINT1 configured for ExtInt

IDTR & Interrupt Descriptor table.

So far, all above process is understood but I am missing interrupt routing from PCIe to IOAPIC. This information will help me lot in understanding system at hardware level.

xxxxx@gmail.com wrote:

However, I was more interested in knowing behind the scenes processes of how PCIe “IntPin register” gets mapped to an IOAPIC pin (IRQL). There must be some sort of pin to pin linking happening at hardware level and I wanted to know what mechanism is doing that.

So far, all above process is understood but I am missing interrupt routing from PCIe to IOAPIC. This information will help me lot in understanding system at hardware level.

The situation is rather different from PCI to PCIe. In PCI, there were
four physical wires on the bus that carried interrupt signals, which
meant, naturally, that slots often shared a wire. The PCI controller
would connect those wires to pins on the IOAPIC. When a particular wire
asserted, all you knew is that ONE of the boards on that wire fired.
Each driver for a device sharing that wire had to check to see whether
it’s device fired.

In PCIe, there are no such things as “pins”. It’s all just protocol.
Interrupt requests are just data packets on the PCIe bus. They get sent
to the PCIe root complex, and the root complex decodes them and feeds
the information back up to the IOAPIC.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> So far, all above process is understood but I am missing interrupt routing from PCIe to IOAPIC.

This information will help me lot in understanding system at hardware level.

Well, I guess that, instead of asking questions about it in this NG (where you are more than likely to be told that you don’t need to know it, and most of those who tell you this are unable to answer your questions anyway) it would be much better to look at publicly available OS sources, don’t you think…

Anton Bassov

> to the PCIe root complex, and the root complex decodes them and feeds the information back up to the IOAPIC.

Understood.

Question is, if IntPin register in PCI configuration address space is set to 9, for example, would it mean that IOAPIC pin 9 will be asserted when device issues an interrupt? Is it 1-1 mapping for “IntPin” register to IOAPIC Intr Pin?

> if IntPin register in PCI configuration address space is set to 9

There are only 4 pins in PCI configuration address space. Therefore, the example value in itself is invalid.

would it mean that IOAPIC pin 9 will be asserted when device issues an interrupt?
Is it 1-1 mapping for “IntPin” register to IOAPIC Intr Pin?

Look to the above explanation…

Objectively, they cannot be directly mapped to IOAPIC pins - first, normally there are 24 of them, and, second,
there may be more than one IOAPIC on the motherboard.

If you need a mild introduction to all that you can check MP specifications and see how MP configuration table maps PCI interrupts to IOAPIC pins, including the situation when there are multiple IOAPICs on the target mobo. As I said on another thread already, consulting this table is considered a legacy approach that is not used on ACPI-based systems, but still it will give you some general ideas. If you want to go further you should read ACPI specs. However, I must warn you that this is _significantly_more complex (and longer) document, compared to MP specs…

Anton Bassov

Got this from: http://drdobbs.com/architecture-and-design/232400476


On mainstream components, there are eight PIRQ pins supported by the PCH, named PIRQ[A# :H#]. These route PCI interrupts to IRQs of the 8259 PIC. PIRQ[A#:D#] routing is controlled by PIRQ routing registers 60h?63h (D31:F0:Reg 60- 63h). PIRQ[E#:H#] routing is controlled by PIRQ routing registers 68h?6Bh (D31:F0:Reg 68 ? 6Bh). This arrangement is illustrated in Figure 1. The PCH also connects the eight PIRQ[A#:H#] pins to eight individual I/O Advanced Programmable Interrupt Controller input pins
"

If one needs to bypass ACPI (_PRT), above mentioned 8 registers in intel chipset can be queried for PIRQ[A-H] to IRQ mapping. I know BIOS has already done work for us and is definitely a path to achieve platform-independence, but knowing how it’s done is great leap forward.

Please correct if you think above information is incorrect in anyway

Anton is right on that this NG is generally not a good place to ask this
kind of questions and average windows driver programmers would not know the
answer.

Gluing CPUs, I/O APIC, local APIC and pci devices is a lot of work. I once
have done that for my hobby protected mode kernel to educate myself how
exactly modern PC works. Too bad I don’t remember the details.

Besides the MP spec and ACPI spec Anton recommended, there used to be a
“BIOS writer guide” doc from Intel which contains very useful info about IO
APIC init and PCI interrupt routing. You may also ask your questions in
hobby OS developer forums.

Good luck!
Calvin

On Thu, Mar 29, 2012 at 8:29 PM, wrote:

> Got this from: http://drdobbs.com/architecture-and-design/232400476
> __________________________________________________________
>
> On mainstream components, there are eight PIRQ pins supported by the PCH,
> named PIRQ[A# :H#]. These route PCI interrupts to IRQs of the 8259 PIC.
> PIRQ[A#:D#] routing is controlled by PIRQ routing registers 60h?63h
> (D31:F0:Reg 60- 63h). PIRQ[E#:H#] routing is controlled by PIRQ routing
> registers 68h?6Bh (D31:F0:Reg 68 ? 6Bh). This arrangement is illustrated in
> Figure 1. The PCH also connects the eight PIRQ[A#:H#] pins to eight
> individual I/O Advanced Programmable Interrupt Controller input pins
> "
>
> If one needs to bypass ACPI (_PRT), above mentioned 8 registers in intel
> chipset can be queried for PIRQ[A-H] to IRQ mapping. I know BIOS has
> already done work for us and is definitely a path to achieve
> platform-independence, but knowing how it’s done is great leap forward.
>
> Please correct if you think above information is incorrect in anyway
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

> Am I going completely wrong path here? Or do I have to use some other method of interrupt

programming?

Yes, use the resource descriptor in START IRP, the IOAPIC stuff is done automatically for you.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> I know BIOS has already done work for us and is definitely a path to achieve platform-independence,

exactly…

but knowing how it’s done is great leap forward.

In order to know how it can be done you have to get a datasheet for your target chipset - all this stuff is very specific for a particular chipset…

For example, every PCI device function may signal interrupts via one out of four pins, i.e. INTA# - INTD# , and each of these pins reported to a given PCI device function may be configured to correspond to one out of eight physical pins PIRQA# - PIRQH#. This configuration can be made on per-device level in a way described in a datasheet for a particular chipset. Concerning PIRQ to IOAPIC mapping, again, it depends on chipset
and/or configuration, so that the mappings you have quoted are not universal. For example, the mobo may have more than one IOAPIC; PIRQ[E:H] may be multiplexed with GPIO pins so that interrupts PIRQ[E:H] may not be exposed if they are configured as GPIOs; etc,etc, etc…

Anton Bassov

The IntPin register seems to be confusing you. It’s meaningless. It always
has been. It is just a scratch pad used by the BIOS.

Very early PCI PCs used it to convey the 8295 PIC interrupt assignment.
When that proved insufficient, the $PIR table was created for this purpose.
When that couldn’t convey information about an I/O APIC (and couldn’t be
updated at run time) ACPI was created.

Please use the OS-supplied interfaces. You’re going down a pointless hole.

Jake Oshins
Windows Kernel Team

This message implies no warranties and confers no rights.


wrote in message news:xxxxx@ntdev…

Hi Tim

I did read about IoConnectInterrupt and knew before posting this question
that it’s the only way to setup interrupts and IDT is never meant to be
hacked or touched as OS or Firmware owns that.

However, I was more interested in knowing behind the scenes processes of how
PCIe “IntPin register” gets mapped to an IOAPIC pin (IRQL). There must be
some sort of pin to pin linking happening at hardware level and I wanted to
know what mechanism is doing that.

I was trying to connect dots to gain knowledge of system hardware and it’s
working in modern computing.

All I know at this moment is

PCI Device -> Uses PCIe configuration space to configure what interrupt pin
it can use using “IntPin” register.

( SOME CONNECTING THING HERE…I DON’T KNOW WHAT)

IOAPIC -> Which has incoming Interrupt pins from PCI device and are mapped
to Interrupt vector

LAPIC -> LINT0 or LINT1 configured for ExtInt

IDTR & Interrupt Descriptor table.

So far, all above process is understood but I am missing interrupt routing
from PCIe to IOAPIC. This information will help me lot in understanding
system at hardware level.

Tim, the PCIe protocol is actually semantically equivalent to those four
wires on conventional PCI. From software, there’s no difference.

Jake Oshins
Windows Kernel Team

This message implies no warranties and confers no rights.


“Tim Roberts” wrote in message news:xxxxx@ntdev…

xxxxx@gmail.com wrote:

However, I was more interested in knowing behind the scenes processes of
how PCIe “IntPin register” gets mapped to an IOAPIC pin (IRQL). There must
be some sort of pin to pin linking happening at hardware level and I
wanted to know what mechanism is doing that.

So far, all above process is understood but I am missing interrupt routing
from PCIe to IOAPIC. This information will help me lot in understanding
system at hardware level.

The situation is rather different from PCI to PCIe. In PCI, there were
four physical wires on the bus that carried interrupt signals, which
meant, naturally, that slots often shared a wire. The PCI controller
would connect those wires to pins on the IOAPIC. When a particular wire
asserted, all you knew is that ONE of the boards on that wire fired.
Each driver for a device sharing that wire had to check to see whether
it’s device fired.

In PCIe, there are no such things as “pins”. It’s all just protocol.
Interrupt requests are just data packets on the PCIe bus. They get sent
to the PCIe root complex, and the root complex decodes them and feeds
the information back up to the IOAPIC.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

No, it doesn’t. Let me point out that the IntPin register is only 8 bits
wide. It’s possible to have many more than 256 I/O APIC inputs.

Jake Oshins
Windows Kernel Team

This message implies no warranties and confers no rights.


wrote in message news:xxxxx@ntdev…

to the PCIe root complex, and the root complex decodes them and feeds the
information back up to the IOAPIC.

Understood.

Question is, if IntPin register in PCI configuration address space is set to
9, for example, would it mean that IOAPIC pin 9 will be asserted when device
issues an interrupt? Is it 1-1 mapping for “IntPin” register to IOAPIC Intr
Pin?

Okay. So you probably all figured this out. But, on Monday morning without
having yet had any coffee, I jumped into this thread and confused
“InterruptLine” with “InterruptPin.” Please ignore everything I said about
the IntPin register. I really do know the difference. In my defense, you
are confusing them too, and that threw me off.

The IntPin register tells you only which virtual pin your function triggers.
How that pin maps to an interrupt controller is entirely under the domain of
the chipset maker and the motherboard maker. This information comes to
Windows through ACPI. No device driver needs this.

Jake Oshins
Windows Kernel Team

This message implies no warranties and confers no rights.


“Jake Oshins” wrote in message news:xxxxx@ntdev…

No, it doesn’t. Let me point out that the IntPin register is only 8 bits
wide. It’s possible to have many more than 256 I/O APIC inputs.

Jake Oshins
Windows Kernel Team

This message implies no warranties and confers no rights.


wrote in message news:xxxxx@ntdev…

to the PCIe root complex, and the root complex decodes them and feeds the
information back up to the IOAPIC.

Understood.

Question is, if IntPin register in PCI configuration address space is set to
9, for example, would it mean that IOAPIC pin 9 will be asserted when device
issues an interrupt? Is it 1-1 mapping for “IntPin” register to IOAPIC Intr
Pin?

Okay. So you probably all figured this out. But, on Monday morning without
having yet had any coffee, I jumped into this thread and confused
“InterruptLine” with “InterruptPin.” Please ignore everything I said about
the IntPin register. I really do know the difference. In my defense, you
are confusing them too, and that threw me off.

The IntPin register tells you only which virtual pin your function triggers.
How that pin maps to an interrupt controller is entirely under the domain of
the chipset maker and the motherboard maker. This information comes to
Windows through ACPI. No device driver needs this.

Jake Oshins
Windows Kernel Team

This message implies no warranties and confers no rights.


“Jake Oshins” wrote in message news:xxxxx@ntdev…

No, it doesn’t. Let me point out that the IntPin register is only 8 bits
wide. It’s possible to have many more than 256 I/O APIC inputs.

Jake Oshins
Windows Kernel Team

This message implies no warranties and confers no rights.


wrote in message news:xxxxx@ntdev…

to the PCIe root complex, and the root complex decodes them and feeds the
information back up to the IOAPIC.

Understood.

Question is, if IntPin register in PCI configuration address space is set to
9, for example, would it mean that IOAPIC pin 9 will be asserted when device
issues an interrupt? Is it 1-1 mapping for “IntPin” register to IOAPIC Intr
Pin?