Hi,
JulienDarc wrote:Section 6.3.1, from intel dev guide vol3 :
The I/O APIC determines the vector number of the interrupt and sends this number to the local APIC
How does it determine the vector number ? Is it at the stage where we parse the DSDT that we assign a number to every peripheral ? (I didn't do that step myself)
For IO APIC; there's a register for each IO APIC input, and software sets the interrupt vector for an IO APIC input to whatever it likes. The problem is determining which device's IRQs are connected to which IO APIC inputs.
Devices can be split into one of 2 categories: legacy and PCI. For legacy devices (e.g. PIT, CMOS, etc), the IO APIC input they're connected to is fixed and you can use the ACPI MADT/APIC table to determine which IO APIC input. For PCI devices the IO APIC input they're connected to is not fixed (e.g. things like hot-plug PCI mean they can change and therefore can't be described by a table generated by firmware during boot), and you need to interpret the firmware's AML (e.g. with something like ACPICA) to determine which IO APIC input they use.
Alternatively, for old computers (and mostly only if ACPI doesn't exist) you can use the MultiProcessor Specification tables. This will give you the information for both legacy and PCI devices in a fixed table (and can't work for things like hot-plug PCI). Sadly the MultiProcessor Specification tables are deprecated and can't be relied on for newer computers.
There are also 2 other alternatives for determining which IO APIC input is used by which PCI device/s - you can have a native motherboard driver for each different motherboard (e.g. using PCI device and vendor ID for the root bridge and "LPC to PCI bridge" to determine the chipset, and using the chipset and SMBIOS to determine the motherboard and which motherboard driver) where the native motherboard driver knows how PCI devices are mapped to IO APIC inputs; or you can use a clever "auto-detection" scheme.
Alternatively, for newer computers the device/s may provide something called MSI (Message Signalled Interrupt). In this case the device itself sends a message when it wants an IRQ, and you can tell the device what to put in that message (which interrupt vector) without caring about the IO APIC or ACPI or MultiProcessor Specification. MSI was optional for "PCI conventional" but became mandatory for PCI-E.
Also note that for all cases (either IO APIC or MSI) software determines which interrupt vectors to use; and "which interrupt vector" determines the priority of the interrupt. This implies that you'll need something to manage interrupt vectors, so you can allocate interrupt vector/s with a certain priority (and free them).
Finally; none of it depends on the device itself - you can have generic code that figures out which interrupt vector/s a device uses and reserve the interrupt vector/s for the device, and then enable the interrupt/s when a device driver is started. The device driver itself needn't be involved in determining which interrupt the device uses; and the device driver needn't know or care if you're using PIC or IO APIC or MSI. For "very advanced", the OS can abstract interrupts completely (e.g. telling the device driver that its device may have generated an IRQ) where the device driver doesn't know which interrupt vector; which allows the OS to dynamically adjust the interrupt vector/s that devices use whenever it likes without telling the device driver/s that interrupt vectors were changed.
Cheers,
Brendan