There are actually a couple more layers of indirection. The BIOS PCI
IRT tells you which input on the IRQ router a particular PCI slot is
connected to. The BIOS, and then the OS, program the router so that
specific outputs on the router are connected to specific inputs on the
interrupt controller. The BIOS, and then the OS, then program IDT
addresses into the interrupt controller.
So in a machine using the PCI IRT (and there are damn few left in the
world, which I’ll get into in a moment) the IRT tells you, for instance,
that your plug-in NIC that’s in PCI slot 4 is connected to input PIRB$
on the router. You can then program PIRB$ to IRQ 11. You can then put
a base of 0x38 into the slave PIC and you’ll get an IDT entry of 0x3b
for your NIC.
The PCI IRT doesn’t work for machines that might hot-plug PCI slots or
buses, like a laptop in a docking station. So all of that function has
been replaced by ACPI, which gives you something similar. The
difference is that ACPI is capable of changing at runtime in response to
hardware and software events.
Furthermore, the PCI IRT only covers the machine while it’s running in
8259-PIC mode. Dave was talking about a machine running HALMPS, which
implies APIC mode. In machines running HALMPS, there is a table that’s
similar to the PCI IRT, except that it only tells where the PCI devices
are attached at the interrupt controllers. If there is a router, it’s
not described to the OS. The BIOS programs it once and that’s the end
of it. Again, this doesn’t work in machines that need to hot-plug PCI
stuff. But that’s only an issue for a small subset of the world.
MPS has also be obsoleted by ACPI, which makes it possible do hot-plug.
One final note. The IDT entries for machine with an 8259-PIC are mostly
static, since there is only one base register in a PIC. The other IDT
entries are consecutive, starting with that base. (There is another one
in the slave PIC, but that doesn’t change the story much.) In an APIC
machine, every single input on the interrupt controller has a separate
IDT entry register. So they may be assigned very differently.
-----Original Message-----
Subject: RE: Distributing Interrupts over different vectors
From: “Moreira, Alberto”
Date: Mon, 28 Jan 2002 12:00:10 -0500
X-Message-Number: 30
Hi, Jake,
It’s been a while since I last did Bios work, but I had the impression
that
IDT slots were a direct consequence of the PCI Interrupt Routing Table
in
the Bios. If I understand you correctly, you map IDT slots to interrupt
lines based on those two algorithms you state. So, am I correct if I say
that the Bios IRT is ignored ?
Alberto.
-----Original Message-----
From: Jake Oshins [mailto:xxxxx@windows.microsoft.com]
Sent: Sunday, January 27, 2002 12:47 AM
To: NT Developers Interest List
Subject: [ntdev] RE: Distributing Interrupts over different vectors
From what you write, I think that you’re confused about a bunch of
things. Let me do some explaining:
First, IRQL is different from IRQ. IRQL is the priority level at which
your interrupt is delivered. Many different vectors may map to the same
IRQL. This doesn’t mean that you’re sharing interrupts. It just means
that some interrupts will be masked (on one of the processors) while a
device is servicing it’s interrupt. In practice this doesn’t mean much.
Don’t pay much attention to IRQL, as it doesn’t tell you what you think
it tells you. (You also use the word “vector” below. That’s something
completely separate, which I won’t cover here.)
Second, IRQ is a representation of which interrupt line will be
triggered.
The PCI spec says that each device interrupts by driving a line called
INTA# (or perhaps INTB#, INTC# or INTD#, but the differences are
meaningless here) to ground. The guy who designed HALMPS (my former
boss) decided to encode the “IRQ” of a PCI device as (DeviceNumber << 2
| (IntPin - 1)). This means that, for instance, a device with a PCI
device number of 6 that triggers INTA# (which yeilds and Interrupt Pin
Number of 1) would get encoded as (6 << 2 | 0), or 24. This means that
there is exactly one IRQ 24 on every PCI bus, using HALMPS. If there
are two PCI buses, and both of them have a device number 6, then you’ll
get two IRQ 24s, even if they aren’t sharing.
Furthermore, you might have two different PCI devices that are sharing.
The motherboard may wire them together. With HALMPS, you’ll never see
the same IRQ for them, since they’ll have different PCI Device numbers.
These two things make it completely impossible to tell if PCI devices
are sharing interrupts using HALMPS. There is no user interface that
will tell you. (You can find out with the debugger. Just type either
“!arbiter 4” or “!idt”. These will make it clear.) If your hardware
guy insisted that the devices aren’t sharing, then he’s probably right.
They aren’t.
That’s one of the reasons why, when I designed HALACPI, HALAACPI and
HALMACPI, I changed the representation of IRQ for those HALs. For them,
IRQ is the number of the input on the interrupt controller. If you’re
using an 8259 PIC interrupt controller (and consequently HALACPI) then
you’ll see the same IRQ representation you saw in DOS. If you’re using
APIC interrupt controllers (and consequently either HALAACPI or
HALMACPI) then the representation of IRQ starts with the primary I/O
APIC, which frequently has 20 inputs. The first 16 get mapped to IRQ
0-15, which are the ISA inputs. The next four usually get used for PCI
interrupts. If you’re lucky enough to have multiple I/O APICs, you may
see much higher IRQ numbers. (There were a few major simplifications in
this description. If anybody wants to go into greater detail, post
specific questions to this list.)
With these HALs, it’s quite easy to see if you’re sharing interrupts.
If the IRQ is the same, then your devices are plugged into the same
input on the interrupt controller, and they are sharing.
- Jake
-----Original Message-----
Subject: Distributing Interrupts over different vectors
From: “Dave Harvey”
Date: Sat, 26 Jan 2002 21:25:48 -0500
X-Message-Number: 16
I have a new piece of hardware running NT-E, with 6 PCI busses.
This is a Dual P4 running HalMps. I have 10 high interrupt devices,
and I’d like to avoid interrupt sharing for performance reasons.
Bus 0 has 4 devices, and the other busses have 2 devices each.
I’m getting something like 4 IRQL 16, 4 IRQL 17, and 1 each IRQL 24 and
25, i.e., the IRQL
starts back at 16 on each bus. (The IRQL is as reported by
Administrative Tools\Windows NT Diagnostics).
I’ve look through the HAL source, and have a very rough idea how it
assigns the vectors.
The hardware guys insist that the hardware can avoid interrupt sharing,
and that is also my understanding of the APIC.
Questions:
- Is this IRQL as reported 1:1 with the APIC Vector, and therefore I’m
really getting interrupt sharing?
- Given I can change the HAL and BIOS, is it feasible to avoid interrupt
sharing?
- Is there a description of how I’d avoid interrupt sharing some where?
- Would I need to modify the HAL, or is this a BIOS problem?
- I ended up in the HAL at some configuration files that look like they
turn into data tables inside the HAL. Is that the place
I should be looking? Is there a description somewhere?
Thanks,
-DH
—
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com