Hi,
FlashBurn wrote:Brendan wrote:Sounds like a good idea, just don't forget that the same IRQ can be shared by multiple devices (a simple "device_ID = interruptTable[IO_APIC_input_number]" array won't work) and the same device can have multiple interrupts (a simple "IO_APIC_input_number = interruptTable[device_ID]" array won't work either).
Oh, then it could happen, that there are more than 1 entries in the MPS for 1 device?!
As far as I know, for a multi-function device you can have 8 "functions" and each "function" can use one of the PCI bus interrupt lines (so, each of the 4 PCI interrupts lines are used twice). Each "function" can only use one interrupt line. There's also MSI - each of those "functions" can have one (or more?) MSI interrupts too, but normally you'd use the PCI interrupt lines or MSI (and not both at the same time).
That only applies to PCI devices though. For a "master list of interrupts" you also need to consider legacy devices (e.g. some old sound cards use multiple ISA interrupts) and other "non-PCI" devices (e.g. HPET, which often supports 2 IRQs but may support more).
Mostly what I'm thinking is that you need a hierarchical tree of "device structures' which includes a list of interrupts that each device is using (if any); plus a linked list for each possible interrupt vector where each entry in the linked list has a pointer to the "device structure" for the device.
For example, you'd be able to do something like:
Code: Select all
DEVICE_STRUCT *device;
for(interrupt_number = 32; interrupt_number < 256; interrupt_number++) {
device = global_interrupt_list[interrupt_number];
while(device != NULL) {
printf("Int %u = device %s\n", interrupt_number, device->name);
device = device->next;
}
}
FlashBurn wrote:Could you tell me on which addresses are your 2 IO-APICs on the pc that has 2? I´m asking, because I need to know if I could assume that every IO-APIC is at an 4KB address and that 1 IO-APIC "uses" a whole 4KB page.
From memory, I think they are at 0x0FEC00000 and 0x0FEC01000. The actual address of each I/O APIC should be determined from the MP specification tables or the ACPI tables. As far as I know all I/O APICs always consume 4 KiB of space.
geppyfx wrote:Also, ACPI maps each pci device into Global Interrupt Number which is a DWORD. I am not sure how many IOAPICs they intended to cover with this. More than 256? Any clarification?
For 80x86, you can't have more than 256 interrupts. Other architectures may support more interrupts though, and both PCI and ACPI may be used on other architectures that do support more interrupts.
In theory, this is a "per CPU" limit. For example, you can have multiple PCI host controllers where the interrupts for each PCI host controller is sent to a specific CPU (or group of CPUs) and each CPU (or group of CPUs) use different IDTs. In this case you'd have up to 220 IRQs per PCI host controller. With 4 PCI host controllers you'd be able to have about 880 completely independent IRQs. However, ACPI will still only use global interrupt numbers from 32 to 255, and it'd be up to the OS to determine which CPUs receive which IRQs, etc.
FlashBurn wrote:Another problem occured as I was rewriting my code. I do support default configurations of the MPS, but there is anywhere mentioned to which input pin the PCI ints are connected (or did I miss this?). So my above assumption would make my life easier.
For some ancient computers, the PCI interrupts are connected to a "PCI interrupt router" and mapped to ISA interrupts (just like modern computers when they're using the PIC), and (unlike modern computers) only the ISA interrupts are connected to the I/O APIC. For default configurations you can assume this is the case (and that the "global interrupt number" for each PCI device is the same as the "PIC interrupt number" stored in the device's PCI configuration space by the BIOS).
Cheers,
Brendan