Hi,
nooooooooos wrote:(a)Must I only change the settings of the LINT0 and LINT1? Or are there other Registers necessary? (I dont want to use the apic-timer)
(b)And what settings I have to change? It's logical to clear the mask bit...but what else?
(c)Which value for the vector is needed? Must I set the vectors of both, the LINT0 and the LINT1, onto different values? (I have already redirected the ioapics to 0x20-0x37). I don't catch on why to use a second vector.
For initializing the local APIC, you'd want to clear the disable bit, setup LINT0 and LINT1, setup the spurious interrupt and install a spurious interrupt handler, set the "task priority register" and setup the "destination format register" (not necessarily in this order).
You should parse either ACPI tables or Intel's Multiprocessor tables to determine how each local APIC input and each I/O APIC input should be programmed. This information includes which PCI devices are connected where, if each input is level triggered or edge triggered, what type of interrupt (SMI, NMI, extINT, etc). Typically (but not necessarily always) these tables will tell you that one of the local APIC inputs (on each CPU) is used for NMI and the other input (on each CPU) is used for INTR. Please note that for SMI, NMI and INTR the interrupt vector is not used by the APIC (and should be set to zero IIRC).
For the other local APIC interrupts (timer, error interrupt, thermal monitoring interrupt, etc), your OS can either use them or disable them. They won't be listed in the ACPI tables or MPS tables as they're entirely inside the CPU (they're more like exceptions than IRQs IMHO).
I/O APICs should be configured dynamically based on what the ACPI or MPS tables say. Some systems have more than one I/O APIC (e.g. my server has 2 of them with 16 inputs per I/O APIC, but I've seen specs for larger servers with four I/O APICs). The highest 4 bits of the interrupt vector used for each IRQ determines that IRQ's priority, so it's usually best to spread the interrupt vectors out (e.g. int 0x22 for the PIT timer, int 0xF0 for the floppy controller, int 0x30 for the network card, etc).
Bunching them all together (e.g. from 0x20 to 0x37) means that you're only using 2 priorities - IRQs from 0x20 to 0x2F using one priority, and IRQs from 0x30 to 0x37 using another priority. Depending on your OS this can be a bad idea. For example, if a floppy drive IRQ and an ethernet card IRQ happen at the same time, then normally you'd want the ethernet card's IRQ to have higher priority to reduce it's latency (so that the ethernet card's IRQ doesn't wait until after you've finished servicing the floppy drive's IRQ).
The way I do it is have interrupt handlers for all possible interrupts. During boot I setup the first 32 interrupts for exceptions, then use 0x20 for the kernel API, 0x21 to 0x23 for IPIs and 0xFF for the local APIC's spurious IRQ. I install dummy IRQ handlers for interrupts 0x24 to 0xFE. Then I use the desired IRQ priority to search for the "best" free interrupt vector when each IRQ handler is installed. In this way a network card driver might tell the OS to use "priority 3" for it's IRQ, while a floppy driver might tell the OS to use "priority 10" for it's IRQ.
The other thing to consider is which CPU/s each IRQ is delivered to. In a NUMA machine you might want to deliver IRQs to CPUs that are "close" to the devices generating that IRQ to reduce bus traffic. In an SMP computer you might want to spread IRQs around, so that you don't have one CPU handling all/most IRQs (unbalanced CPU load). You might also want to send IRQs to CPUs that aren't in some sort of power management state. For example, if a CPU is in a sleep state then it's probably better to send the IRQ to a different CPU than to bring that CPU out of the sleep state; and if a CPU is hot (operating at reduced performance due to thermal throttling) then you might want to send the IRQs elsewhere to help bring that CPU back to a normal temperature. Lastly, if an IRQ occurs frequently then you might want to send it to the same CPU all the time, in the hope that the IRQ handler and it's data is still in that CPU's cache.
Cheers,
Brendan