PCI IRQ routing from Chipsets
PCI IRQ routing from Chipsets
Hi,
I've been posting in a few threads recently where the issue of using ACPI to determine PCI IRQ routings has come up.
Brendan has suggested that it's a totally viable option to perform manual probing by having each pci device trigger an interrupt and then monitor for it.
I quite like this idea, but I was wondering if it wouldn't be possible to directly obtain this information from the chipset?
PIIX4 (which I believe is what bochs/qemu etc all emulate) .. or HM77 (my laptop) etc..
If I were assuming Sandy Bridge+ support only there aren't that many chipsets, and I suspect many would share similar configuration space information.
http://www.intel.co.uk/content/dam/www/ ... asheet.pdf Page 407
and
http://www.intel.com/Assets/PDF/datasheet/290562.pdf Page 59
I've been posting in a few threads recently where the issue of using ACPI to determine PCI IRQ routings has come up.
Brendan has suggested that it's a totally viable option to perform manual probing by having each pci device trigger an interrupt and then monitor for it.
I quite like this idea, but I was wondering if it wouldn't be possible to directly obtain this information from the chipset?
PIIX4 (which I believe is what bochs/qemu etc all emulate) .. or HM77 (my laptop) etc..
If I were assuming Sandy Bridge+ support only there aren't that many chipsets, and I suspect many would share similar configuration space information.
http://www.intel.co.uk/content/dam/www/ ... asheet.pdf Page 407
and
http://www.intel.com/Assets/PDF/datasheet/290562.pdf Page 59
Re: PCI IRQ routing from Chipsets
Hi,
Some things inside the chipset depend on how it has been used, including how it's been connected to other things (e.g. see section "2.27 Pin Straps" in the Platform Controller Hub datasheet you linked to; which lists all the signals that effect the chip's configuration at boot), how the firmware initialises it and what the firmware's SMM code does.
For IRQs alone (and not "everything ACPI's AML does"); you may or may not be able to get by with a chipset driver alone (I really don't know - you'd have to analyse all the chipsets one at a time).
However; a chipset driver would only solve some problems (e.g. determining IRQs) and eventually you will want more (e.g. things like power management); so it wouldn't be adequate in the long term. Instead; you could have a native "motherboard driver" that does everything ACPI's AML does (and more).
Also note that it's likely that Intel/AMD/Nvidia/VIA will make more chipsets in future. What this means is that "Sandy Bridge+ support only there aren't that many chipsets" is a little misleading (it'd probably be more accurate to say there will be a thousands of Sandy Bridge or later chipsets, where most of them haven't been released yet). Also; when a new chipset is released your OS won't support it for several months until you buy one for testing and develop the chipset driver.
Basically what I'm saying here is that what you really want is a series of options, where the OS tries each option until it finds something that works, where those options might be (in order of best to worst):
Cheers,
Brendan
johnsa wrote:I quite like this idea, but I was wondering if it wouldn't be possible to directly obtain this information from the chipset?
PIIX4 (which I believe is what bochs/qemu etc all emulate) .. or HM77 (my laptop) etc..
If I were assuming Sandy Bridge+ support only there aren't that many chipsets, and I suspect many would share similar configuration space information.
Some things inside the chipset depend on how it has been used, including how it's been connected to other things (e.g. see section "2.27 Pin Straps" in the Platform Controller Hub datasheet you linked to; which lists all the signals that effect the chip's configuration at boot), how the firmware initialises it and what the firmware's SMM code does.
For IRQs alone (and not "everything ACPI's AML does"); you may or may not be able to get by with a chipset driver alone (I really don't know - you'd have to analyse all the chipsets one at a time).
However; a chipset driver would only solve some problems (e.g. determining IRQs) and eventually you will want more (e.g. things like power management); so it wouldn't be adequate in the long term. Instead; you could have a native "motherboard driver" that does everything ACPI's AML does (and more).
Also note that it's likely that Intel/AMD/Nvidia/VIA will make more chipsets in future. What this means is that "Sandy Bridge+ support only there aren't that many chipsets" is a little misleading (it'd probably be more accurate to say there will be a thousands of Sandy Bridge or later chipsets, where most of them haven't been released yet). Also; when a new chipset is released your OS won't support it for several months until you buy one for testing and develop the chipset driver.
Basically what I'm saying here is that what you really want is a series of options, where the OS tries each option until it finds something that works, where those options might be (in order of best to worst):
- Motherboard driver
- Generic motherboard driver (using ACPI's AML)
- Chipset driver
- Auto-detection
- Manual configuration by end user (e.g. MS-DOS "config.sys")
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: PCI IRQ routing from Chipsets
After spending some more time reading through the docs and thinking I'm not sure even having a chipset driver would solve the IRQ routing.
The chipset specification yields that you can obtain two sets of information:
1.) (For 8259a PIC operation)
The LPC controller (Bus 0: Device 31: Function 0) has PCI configuration space registers 0x60-0x63 and 0x68-0x6b (page 467 for intel series 7 chipset).
bit 7: Interrupt Routing Enable (IRQEN) — R/W.
[ 0 = The corresponding PIRQ is routed to one of the ISA-compatible interrupts specified in bits[3:0]. / 1 = The PIRQ is not routed to the 8259 ]
NOTE: BIOS must program this bit to 0 during POST for any of the PIRQs that are being used. The value of this bit may subsequently be changed by the OS when setting up for I/O APIC interrupt delivery mode.
6:4 Reserved
3:0 IRQ Routing — R/W. (ISA compatible.)
Value IRQ
0000b Reserved
1000b Reserved
1001b IRQ9
1010b IRQ10
0001b Reserved
0010b Reserved
0011b IRQ3
0100b IRQ4
0101b IRQ5
0110b IRQ6
0111b IRQ7
1011b IRQ11
1100b IRQ12
1101b Reserved
1110b IRQ14
1111b IRQ15
This seems only useful for PIC operation apart from bit 7 which we might still need/want to set ourselves to correctly enable IOAPIC delivery (more so than just masking the PIC and enabling IOAPIC).
2.) (For APIC operation)
The LPC controller supplies you with
(RCBA) Root Complex Base Address in the same configuration space as above with registers 0xF0–0xF3
(Page 402)
Using this base +
3100h–3103h through to 128h–312bh (will tell you which device is assigned which INT# pin) .. Assuming the firmware configures the system this might not be necessary to look at as the values should be the same in each devices pci config space?
(Page 407) - the part I thought was of interest:
3140h–3141h through to 3160h–3161h (supply you the INT# to PIRQ routing).. My first thought was that this would be sufficient.. but is this not the same information that is provided in the device configuration space
as interrupt line? (that in theory should supply an IRQ number in the ISA range 0-15) whereas these PIRQ# are numbered A-H
Assuming these values are not the same as the device's PCI config space interrupt line field they still only get you part of the way. You still need to know which GSI (interrupt on which I/O APIC if there is more than one) corresponds to PIRQA,B .. etc. One would "assume" they start at GSI 16 -> 24.. but that might be a fatal mistake. In addition if there are two PCI busses each with their own LPC controller, you're still only going to know which PIRQ (limited to 8 ) again.
The ACPI AML _PRT information returns back a direct GSI (so with ioapic max redir entry and ioapic count you know exactly which input to configure).
So as interesting as that all was.. I don't think it actually tells you anything of use in configuring the IOAPIC / PCI routing!
It would seem that the AML is the single and only source of this information in the entire system.
The chipset specification yields that you can obtain two sets of information:
1.) (For 8259a PIC operation)
The LPC controller (Bus 0: Device 31: Function 0) has PCI configuration space registers 0x60-0x63 and 0x68-0x6b (page 467 for intel series 7 chipset).
bit 7: Interrupt Routing Enable (IRQEN) — R/W.
[ 0 = The corresponding PIRQ is routed to one of the ISA-compatible interrupts specified in bits[3:0]. / 1 = The PIRQ is not routed to the 8259 ]
NOTE: BIOS must program this bit to 0 during POST for any of the PIRQs that are being used. The value of this bit may subsequently be changed by the OS when setting up for I/O APIC interrupt delivery mode.
6:4 Reserved
3:0 IRQ Routing — R/W. (ISA compatible.)
Value IRQ
0000b Reserved
1000b Reserved
1001b IRQ9
1010b IRQ10
0001b Reserved
0010b Reserved
0011b IRQ3
0100b IRQ4
0101b IRQ5
0110b IRQ6
0111b IRQ7
1011b IRQ11
1100b IRQ12
1101b Reserved
1110b IRQ14
1111b IRQ15
This seems only useful for PIC operation apart from bit 7 which we might still need/want to set ourselves to correctly enable IOAPIC delivery (more so than just masking the PIC and enabling IOAPIC).
2.) (For APIC operation)
The LPC controller supplies you with
(RCBA) Root Complex Base Address in the same configuration space as above with registers 0xF0–0xF3
(Page 402)
Using this base +
3100h–3103h through to 128h–312bh (will tell you which device is assigned which INT# pin) .. Assuming the firmware configures the system this might not be necessary to look at as the values should be the same in each devices pci config space?
(Page 407) - the part I thought was of interest:
3140h–3141h through to 3160h–3161h (supply you the INT# to PIRQ routing).. My first thought was that this would be sufficient.. but is this not the same information that is provided in the device configuration space
as interrupt line? (that in theory should supply an IRQ number in the ISA range 0-15) whereas these PIRQ# are numbered A-H
Assuming these values are not the same as the device's PCI config space interrupt line field they still only get you part of the way. You still need to know which GSI (interrupt on which I/O APIC if there is more than one) corresponds to PIRQA,B .. etc. One would "assume" they start at GSI 16 -> 24.. but that might be a fatal mistake. In addition if there are two PCI busses each with their own LPC controller, you're still only going to know which PIRQ (limited to 8 ) again.
The ACPI AML _PRT information returns back a direct GSI (so with ioapic max redir entry and ioapic count you know exactly which input to configure).
So as interesting as that all was.. I don't think it actually tells you anything of use in configuring the IOAPIC / PCI routing!
It would seem that the AML is the single and only source of this information in the entire system.
Re: PCI IRQ routing from Chipsets
Hi,
For PCI Express, it mostly tries to emulate "conventional PCI" (even though it's completely different - e.g. using links and not a bus). Because it's not using a bus, how the "interrupt line at slot" is mapped to "interrupt line at host bridge" doesn't depend on how the bus was wired (on the motherboard) but instead depends on the internals of the root port for the slot.
For devices built into that specific chipset, it looks like registers 0x3100 to 0x312B of the root complex determine "which interrupt line at the device", and registers 0x3140 to 0x3161 determine how "interrupt line at the device" is mapped to "interrupt line at the host bridge".
For devices plugged into PCI slots; it's mostly similar. How the card's hard-wired interrupt lines (indicated by the card's "interrupt line" fields) are mapped to "interrupt line at the root port" is determined by registers 0x3100 to 0x312B of the root complex; and registers 0x3140 to 0x3161 determine how "interrupt line at the root port" is mapped to "interrupt line at the host bridge".
What this means is that for devices built into the chipset you can determine everything from the chipset (which interrupt line at the slot, how it's mapped to an interrupt line at the host bridge, and which IO APIC input/GSI that is); and for card's plugged into PCI slots you can determine everything from the device's/card's "interrupt line" and the chipset (which interrupt line at the card, how it's mapped to an interrupt at the root port, how that is mapped to an interrupt at the host bridge, and which IO APIC input/GSI that is).
However; don't forget that all of this is PCI Express, and MSI is mandatory for PCI Express. In other words, you could probably forget about all of the above and just use MSI for everything. Also note that I'd expect this to be the case for all "Sandy Bridge or later" systems.
Cheers,
Brendan
Either you are using PIC and can use the "Interrupt Line" register from the device's PCI configuration space to determine which PIC interrupt it uses (and don't need a chipset driver for that); or you're using IO APIC (or MSI) anyway and don't care about PIC.johnsa wrote:After spending some more time reading through the docs and thinking I'm not sure even having a chipset driver would solve the IRQ routing.
The chipset specification yields that you can obtain two sets of information:
1.) (For 8259a PIC operation)
Some brief revision (just in case). For normal/older "conventional PCI" cards (e.g. plugged into PCI slots) the "Interrupt Pin" register is hardwired and indicates which interrupt line the device uses at the slot (but for single-function devices it's typically always "interrupt line A"); then the motherboard connects "interrupt line at the slot/device" to "interrupt line at the host bridge" in a non-obvious way (e.g. "line A at slot 1" might become "line B at host", "line A at slot 2" might become "line C at host", "line A at slot 3" might become "line D at host", etc). The idea of that is to spread the interrupts around.johnsa wrote:2.) (For APIC operation)
For PCI Express, it mostly tries to emulate "conventional PCI" (even though it's completely different - e.g. using links and not a bus). Because it's not using a bus, how the "interrupt line at slot" is mapped to "interrupt line at host bridge" doesn't depend on how the bus was wired (on the motherboard) but instead depends on the internals of the root port for the slot.
For devices built into that specific chipset, it looks like registers 0x3100 to 0x312B of the root complex determine "which interrupt line at the device", and registers 0x3140 to 0x3161 determine how "interrupt line at the device" is mapped to "interrupt line at the host bridge".
For devices plugged into PCI slots; it's mostly similar. How the card's hard-wired interrupt lines (indicated by the card's "interrupt line" fields) are mapped to "interrupt line at the root port" is determined by registers 0x3100 to 0x312B of the root complex; and registers 0x3140 to 0x3161 determine how "interrupt line at the root port" is mapped to "interrupt line at the host bridge".
How "interrupt line at the host bridge" is mapped to IO APIC inputs is described in the section "5.9.2 Interrupt Mapping" on page 161.johnsa wrote:You still need to know which GSI (interrupt on which I/O APIC if there is more than one) corresponds to PIRQA,B .. etc. One would "assume" they start at GSI 16 -> 24.. but that might be a fatal mistake. In addition if there are two PCI busses each with their own LPC controller, you're still only going to know which PIRQ (limited to 8 ) again.
The ACPI AML _PRT information returns back a direct GSI (so with ioapic max redir entry and ioapic count you know exactly which input to configure).
What this means is that for devices built into the chipset you can determine everything from the chipset (which interrupt line at the slot, how it's mapped to an interrupt line at the host bridge, and which IO APIC input/GSI that is); and for card's plugged into PCI slots you can determine everything from the device's/card's "interrupt line" and the chipset (which interrupt line at the card, how it's mapped to an interrupt at the root port, how that is mapped to an interrupt at the host bridge, and which IO APIC input/GSI that is).
However; don't forget that all of this is PCI Express, and MSI is mandatory for PCI Express. In other words, you could probably forget about all of the above and just use MSI for everything. Also note that I'd expect this to be the case for all "Sandy Bridge or later" systems.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: PCI IRQ routing from Chipsets
5.9.2 (pg 161) what a brilliant find!
That solves the last piece of the puzzle then for what I'm trying to achieve.
I've checked 6,7,8,9 series specs and x79 and x99 .. and the ioapic routing there is identical, so I can happily assume that for every chipset i'd support this would be the case, (of course it still makes good sense to have a chipset driver for each with these items laid out in case they do decide to change or provide more than 24 irqs at some point).
The odds are that in the end i'd probably go MSI for everything (it's cleaner, faster etc) but to start with it would be great to have the IOAPIC routings in place too and correctly working (just in case MSI for all devices causes me to run out of vectors).
But this does provide a different angle to solving the issue of having to either use ACPI _PRT vs. probing (as long as you know which chip-sets your supporting/running on).
I'd start with the list below and use these ids to determine the chipset:
That solves the last piece of the puzzle then for what I'm trying to achieve.
I've checked 6,7,8,9 series specs and x79 and x99 .. and the ioapic routing there is identical, so I can happily assume that for every chipset i'd support this would be the case, (of course it still makes good sense to have a chipset driver for each with these items laid out in case they do decide to change or provide more than 24 irqs at some point).
The odds are that in the end i'd probably go MSI for everything (it's cleaner, faster etc) but to start with it would be great to have the IOAPIC routings in place too and correctly working (just in case MSI for all devices causes me to run out of vectors).
But this does provide a different angle to solving the issue of having to either use ACPI _PRT vs. probing (as long as you know which chip-sets your supporting/running on).
I'd start with the list below and use these ids to determine the chipset:
Code: Select all
X99 chipset
bus 0: device 31 : function 0
8086:8D44h
8086:8D47h ; 05h Intel® X99 Chipset (HEDT)
X79 chipset
8086:1D40h ; 05h PCH
8086:1D41h ; 05h PCH Production
9 series chipset
bus 0: device 31: funciton 0
8086:8CC2h ; 00h LPC Controller (Full Featured Engineering Sample).
8086:8CC4h ; 00h LPC Controller (Z97 SKU).
8086:8CC6h ; 00h LPC Controller (H97 SKU).
8 series chipset
bus 0: device 31: funciton 0
8086:8C41h ; 04h LPC Controller (Mobile Full Featured Engineering Sample).
8086:8C42h ; 04h LPC Controller (Desktop Full Featured Engineering Sample).
8086:8C44h ; 04h LPC Controller (Z87 SKU).
8086:8C46h ; 04h LPC Controller (Z85 SKU).
8086:8C49h ; 04h LPC Controller (HM86 SKU).
8086:8C4Ah ; 04h LPC Controller (H87 SKU).
8086:8C4Bh ; 04h LPC Controller (HM87 SKU).
8086:8C4Ch ; 04h LPC Controller (Q85 SKU).
8086:8C4Eh ; 04h LPC Controller (Q87 SKU).
8086:8C4Fh ; 04h LPC Controller (QM87 SKU).
8086:8C50h ; 04h LPC Controller (B85 SKU).
8086:8C52h ; 04h LPC Controller (C222 SKU).
8086:8C54h ; 04h LPC Controller (C224 SKU).
8086:8C56h ; 04h LPC Controller (C226 SKU).
8086:8C5Ch ; 04h LPC Controller (H81 SKU).
7 series chipset
bus 0: device 31: funciton 0
8086:1E47h ; 04h Intel® Q77 Express Chipset
8086:1E48h ; 04h Intel® Q75 Express Chipset
8086:1E47h ; 04h Intel® Q77 Express Chipset
8086:1E48h ; 04h Intel® Q75 Express Chipset
8086:1E49h ; 04h Intel® B75 Express Chipset
8086:1E44h ; 04h Intel® Z77 Express Chipset
8086:1E46h ; 04h Intel® Z75 Express Chipset
8086:1E4Ah ; 04h Intel® H77 Express Chipset
8086:1E53h ; 04h Intel® C216 Chipset
8086:1E55h ; 04h Mobile Intel® QM77 Express Chipset
8086:1E55h ; 04h Mobile Intel® QM77 Express Chipset
8086:1E58h ; 04h Mobile Intel® UM77 Express Chipset
8086:1E57h ; 04h Mobile Intel® HM77 Express Chipset
8086:1E59h ; 04h Mobile Intel® HM76 Express Chipset
8086:1E5Dh ; 04h Mobile Intel® HM75 Express Chipset
8086:1E5Eh ; 04h Mobile Intel® HM70 Express Chipset
8086:1E56h ; 04h Mobile Intel® QS77 Express Chipset
8086:1E5Fh ; 04h Mobile Intel® NM70 Express Chipset
8086:1E5Eh ; 04h Mobile Intel® HM70 Express Chipset
8086:1E56h ; 04h Mobile Intel® QS77 Express Chipset
-
- Member
- Posts: 170
- Joined: Wed Jul 18, 2007 5:51 am
Re: PCI IRQ routing from Chipsets
This is another example of where Intel FAILED to design a system properly.
Intel invented the PCI standard, and IRQ mapping should have been properly standardised as part of the specification.
The original PCI connector has 4 pins for IRQ. That was a bad design because almost all PCI device makers ended up using INTA.
Intel should of designed PCI so there was only ONE INT pin on the connector. Intel should have required that the motherboard chipset has an individual pin for each PCI slot.
When a PCI interrupt occurs the chipset knows exactly what slot it came from and can work out which CPU Interrupt Vector to call.
If Intel designed PCI properly, the BIOS / OS would only need to set the Interrupt Line value. Everything else is done by hardware.
No stupid ACPI lookups required.
Intel invented the PCI standard, and IRQ mapping should have been properly standardised as part of the specification.
The original PCI connector has 4 pins for IRQ. That was a bad design because almost all PCI device makers ended up using INTA.
Intel should of designed PCI so there was only ONE INT pin on the connector. Intel should have required that the motherboard chipset has an individual pin for each PCI slot.
When a PCI interrupt occurs the chipset knows exactly what slot it came from and can work out which CPU Interrupt Vector to call.
If Intel designed PCI properly, the BIOS / OS would only need to set the Interrupt Line value. Everything else is done by hardware.
No stupid ACPI lookups required.
Re: PCI IRQ routing from Chipsets
If things had been designed properly.. there would be no real mode, no SMM, no legacy BIOS, no real mode, definitely no ACPI, I'd know which device I booted off.. there would be a standard simple way to reboot.. there would be a better solution like zones or ranges instead of paging... in fact in general most things would be 1/50th of the complexity that they've landed up becoming.
If I had unlimited financial resources I would design a completely new system from scratch.. but unless I win the Euro lottery (about 4 times over) it's unlikely to happen
So.. instead I'll bash on with things the way there are... I think the key rationale behind building any sort of OS now is to hide the filth of the platform from yourself forget about end users.. As we speak I am writing an AML interpreter, in truth it's actually not that bad, the only real let-down is that the specification is very lacking so a lot i'm inferring by manually traversing aml in a hex-editor alongside it's asl.
I've setup an opcode table, method execution stubs, a runtime stack/heap and symbol tables .. so in the next few days I should have a fully populated linked-list/symbol table of the acpi name space including operationregions, packages, names, scopes, devices, methods. buffers and resourcetemplates.. this evening I'm busy implementing a name parser which walks the symbol table using scope entries (parent pointers) to interpret things like
"\" , "\NAME.SUBNAME' and "^^" so that each name resolves to a qualified path through the scope tree with a terminal 4char name element, once that's done i can expose the helper methods like
find_device_by_hid,
find_device_by_cid,
find_device_by_addr
acpi_symbol_exists
and so on..
Although I have no real desire to be doing this and even if i don't implement it fully it does at least form a more sound basis to obtain _S5, _PRT and to be able to execute _PIC _PTS _GTS for now. It's 100% fasm, entirely position independent and the only dependency is that you have the following functions: malloc,free,print string,byte,word,dword,qword,allocateLock,aquireLock,releaseLock... so with a very quick find and replace the file should plug in for anyone.
If I had unlimited financial resources I would design a completely new system from scratch.. but unless I win the Euro lottery (about 4 times over) it's unlikely to happen
So.. instead I'll bash on with things the way there are... I think the key rationale behind building any sort of OS now is to hide the filth of the platform from yourself forget about end users.. As we speak I am writing an AML interpreter, in truth it's actually not that bad, the only real let-down is that the specification is very lacking so a lot i'm inferring by manually traversing aml in a hex-editor alongside it's asl.
I've setup an opcode table, method execution stubs, a runtime stack/heap and symbol tables .. so in the next few days I should have a fully populated linked-list/symbol table of the acpi name space including operationregions, packages, names, scopes, devices, methods. buffers and resourcetemplates.. this evening I'm busy implementing a name parser which walks the symbol table using scope entries (parent pointers) to interpret things like
"\" , "\NAME.SUBNAME' and "^^" so that each name resolves to a qualified path through the scope tree with a terminal 4char name element, once that's done i can expose the helper methods like
find_device_by_hid,
find_device_by_cid,
find_device_by_addr
acpi_symbol_exists
and so on..
Although I have no real desire to be doing this and even if i don't implement it fully it does at least form a more sound basis to obtain _S5, _PRT and to be able to execute _PIC _PTS _GTS for now. It's 100% fasm, entirely position independent and the only dependency is that you have the following functions: malloc,free,print string,byte,word,dword,qword,allocateLock,aquireLock,releaseLock... so with a very quick find and replace the file should plug in for anyone.
Re: PCI IRQ routing from Chipsets
Do you have any arguments against ACPICA? Could you tell about them?
I hope that "I want it to be in pure FASM" isn't the only one.
I hope that "I want it to be in pure FASM" isn't the only one.
Re: PCI IRQ routing from Chipsets
Hi,
They could have used a single interrupt (at the CPU) with some sort of "PCI interrupt source register" (e.g. where that register has 1 bit per function per PCI slot), but that's a lot of bits, it wouldn't work for PCI bridges, and it'd make any IRQ priority scheme (implemented at the CPU) impossible.
Then IO APICs got invented. At the same time Intel also created the Multi-Processor Specification, which made it easy for an OS to determine which PCI device/function is connected to which IO APIC input. It still wasn't a problem at all.
Then ACPI got invented. Instead of doing the right thing (and standardising the hardware such that everything can be described via. static tables); they designed an extremely flexible scheme (AML) and watched as everything turned into an over-complicated nightmare (not just PCI interrupts). This had very little to do with Intel or PCI_SIG. This is mostly Microsoft's fault.
Cheers,
Brendan
Devices were supposed to use INTA for its first function (and INTB for its second function, etc); where the motherboard's wiring makes it very likely that they're spread evenly across the bus' 4 interrupt lines. If devices just did whatever they felt like the chance of interrupt sharing would've been much higher (and you also wouldn't have been able to shift cards from one PCI slot to another to fix it).tom9876543 wrote:This is another example of where Intel FAILED to design a system properly.
Intel invented the PCI standard, and IRQ mapping should have been properly standardised as part of the specification. The original PCI connector has 4 pins for IRQ. That was a bad design because almost all PCI device makers ended up using INTA.
There are multi-function devices, where (e.g.) you'll have a video device and a sound device on the same card. It's also possible to have a PCI bridge on a card (e.g. imagine a board that plugs into a PCI slot, that has 5 more PCI slots). For both of these reasons you need more than one INT pin on the connector.tom9876543 wrote:Intel should of designed PCI so there was only ONE INT pin on the connector.
When PCI was first released, IO APICs didn't exist yet and 80x86 computers used PIC chips. Of the 15 possible IRQs, most were already reserved by legacy/ISA devices.tom9876543 wrote:Intel should have required that the motherboard chipset has an individual pin for each PCI slot.
They could have used a single interrupt (at the CPU) with some sort of "PCI interrupt source register" (e.g. where that register has 1 bit per function per PCI slot), but that's a lot of bits, it wouldn't work for PCI bridges, and it'd make any IRQ priority scheme (implemented at the CPU) impossible.
Originally, the "Interrupt Line" field in PCI configuration space told the OS exactly which IRQ the device/function used, so it wasn't a problem at all.tom9876543 wrote:When a PCI interrupt occurs the chipset knows exactly what slot it came from and can work out which CPU Interrupt Vector to call.
If Intel designed PCI properly, the BIOS / OS would only need to set the Interrupt Line value. Everything else is done by hardware.
No stupid ACPI lookups required.
Then IO APICs got invented. At the same time Intel also created the Multi-Processor Specification, which made it easy for an OS to determine which PCI device/function is connected to which IO APIC input. It still wasn't a problem at all.
Then ACPI got invented. Instead of doing the right thing (and standardising the hardware such that everything can be described via. static tables); they designed an extremely flexible scheme (AML) and watched as everything turned into an over-complicated nightmare (not just PCI interrupts). This had very little to do with Intel or PCI_SIG. This is mostly Microsoft's fault.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
-
- Member
- Posts: 170
- Joined: Wed Jul 18, 2007 5:51 am
Re: PCI IRQ routing from Chipsets
Hi Brendan,
Thank you for critique of my proposed simplified PCI IRQ routing design.
It is true that one device can have function A and function B. PCI was always designed to allow interrupt sharing, so they can simply share the same interrupt.
Based on my proposal, the motherboard chipset knows exactly what PCI slot each IRQ originated from.
In x86 world, when PCI configuration header Interrupt Line is set, the motherboard chipset could automatically route the IRQ to legacy 8259 or to IO APIC. For legacy 8259, the IRQ number has to be 0 - 15. So the default powerup value of Interrupt Line would be 0xFF - Disabled.
The BSD web page http://people.freebsd.org/~jhb/papers/b ... node5.html provides interesting info:
Its true I didn't think about PCI bridges.
In my proposed simplified design, a PCI Bridge has one pin to connected to the motherboard chipset.
One solution could be to have the interrupt pins of the downstream slots mapped to a standard location in PCI Bridge Configuration space e.g. DOWNSTREAM_IRQ_MAP.
This could be 32 bits wide allowing maximum of 32 slots behind the bridge.
When motherboard chipset gets IRQ from PCI Bridge, it automatically does PCI Config Read of DOWNSTREAM_IRQ_MAP to see what bits are set, and then fires the IRQs for the downstream devices as required.
Thank you for critique of my proposed simplified PCI IRQ routing design.
It is true that one device can have function A and function B. PCI was always designed to allow interrupt sharing, so they can simply share the same interrupt.
Based on my proposal, the motherboard chipset knows exactly what PCI slot each IRQ originated from.
In x86 world, when PCI configuration header Interrupt Line is set, the motherboard chipset could automatically route the IRQ to legacy 8259 or to IO APIC. For legacy 8259, the IRQ number has to be 0 - 15. So the default powerup value of Interrupt Line would be 0xFF - Disabled.
The BSD web page http://people.freebsd.org/~jhb/papers/b ... node5.html provides interesting info:
-> Intel FAILED in their design of PCI, it should of included PCI IRQ routing in the spec.Most PCI interrupt routing information is platform-specific
Its true I didn't think about PCI bridges.
In my proposed simplified design, a PCI Bridge has one pin to connected to the motherboard chipset.
One solution could be to have the interrupt pins of the downstream slots mapped to a standard location in PCI Bridge Configuration space e.g. DOWNSTREAM_IRQ_MAP.
This could be 32 bits wide allowing maximum of 32 slots behind the bridge.
When motherboard chipset gets IRQ from PCI Bridge, it automatically does PCI Config Read of DOWNSTREAM_IRQ_MAP to see what bits are set, and then fires the IRQs for the downstream devices as required.
Re: PCI IRQ routing from Chipsets
Nothing in particular nope, I just like doing things myself from scratch the long way around (re-inventing the wheel and all). If this wasn't the case there wouldn't be much point in building a hobby OS for meNable wrote:Do you have any arguments against ACPICA? Could you tell about them?
I hope that "I want it to be in pure FASM" isn't the only one.
Re: PCI IRQ routing from Chipsets
my aml parsing journey continues.. i can now honestly echo Linus sentiments in regard to it.
1.) the IASL compiler is in fact NOT a compiler.. it's just a translator
2.) ASL allows forward referencing completely breaking the notion of an interpreter
3.) The entire run-time model has to be a nasty hybrid of compiler/interpreter with multiple passes to resolve forward references
the entire thing would have been a lot easier if they had defined a proper VM style bytecode and the asl compiler generated bytecode that mapped to a simple instruction set with virtual flags and registers....sigh
expressions are not evaluated by the compiler, not even simplified in any way..just dumped out in prefix format..
1.) the IASL compiler is in fact NOT a compiler.. it's just a translator
2.) ASL allows forward referencing completely breaking the notion of an interpreter
3.) The entire run-time model has to be a nasty hybrid of compiler/interpreter with multiple passes to resolve forward references
the entire thing would have been a lot easier if they had defined a proper VM style bytecode and the asl compiler generated bytecode that mapped to a simple instruction set with virtual flags and registers....sigh
expressions are not evaluated by the compiler, not even simplified in any way..just dumped out in prefix format..