Hi,
I have issues with moving from PIC to IOAPIC for handling keyboard irq (and probably other interrupts aswell).
I do;
Disable PIC, Mask of all in PIC
Enable APIC (works well, also uses apic timer)
Enable IOAPIC redirection entry inin1 to handle my keyboard.
Bochs says:
[IOAP ] vector 0x21 stuck???
I guess it have something with the ACKnowledge of the interrupt or something?? Im really stuck...
My isr for keyboard is at 0x21 so that seems to be correct. It might be my destination id, destination mode etc beeing wrong, since i pretty sure edgemode, active high etc is correct.
This is my ioapic and apic when kernel is just started:
Anyone got a tip or a good guess?
-
Thomas
IOAPIC redirection entries
Re: IOAPIC redirection entries
I fixed it. Was the destination that was not right. Added 0xFF000000 (broadcast) to destiation instead of 0x00000000. Now it works
CORRECTION:
It does not work. The isr fire on keypress and seems to work, but bochs still tells [IOAP ] vector 0x21 stuck??. It also seems that after a while it crashes and burns. Probably due to some error not beeing handled correctly... So i guess i fixed the delivery, but not completely.
Is anyone able to dump their apic and ioapic values for me so i can see if there is some major differences in setup?
Thanks!
-
Thomas
CORRECTION:
It does not work. The isr fire on keypress and seems to work, but bochs still tells [IOAP ] vector 0x21 stuck??. It also seems that after a while it crashes and burns. Probably due to some error not beeing handled correctly... So i guess i fixed the delivery, but not completely.
Is anyone able to dump their apic and ioapic values for me so i can see if there is some major differences in setup?
Thanks!
-
Thomas
Last edited by mutex on Sat Mar 20, 2010 7:29 am, edited 1 time in total.
Re: IOAPIC redirection entries
Hi,
You don't want to broadcast the IRQ to all CPUs (and have all CPUs execute the keyboard IRQ handler at the same time). You want to send the IRQ to one (and only one) CPU - either a specific CPU, or the lowest priority CPU, or the lowest priority CPU within a specific group of CPUs.
Cheers,
Brendan
I'm glad you're making progress, but...thomasnilsen wrote:I fixed it. Was the destination that was not right. Added 0xFF000000 (broadcast) to destiation instead of 0x00000000. Now it works
You don't want to broadcast the IRQ to all CPUs (and have all CPUs execute the keyboard IRQ handler at the same time). You want to send the IRQ to one (and only one) CPU - either a specific CPU, or the lowest priority CPU, or the lowest priority CPU within a specific group of CPUs.
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: IOAPIC redirection entries
Hi,
You are most definetly right. I was thinking to use the PPR and TPR to tell interrupt system what priority each cpu currently has.
Well i have setup the destination mode to 0b001 (lowest priority mode) so with broadcast i guess it that only lowest priority one will handle or am i wrong?
-
Thomas
You are most definetly right. I was thinking to use the PPR and TPR to tell interrupt system what priority each cpu currently has.
Well i have setup the destination mode to 0b001 (lowest priority mode) so with broadcast i guess it that only lowest priority one will handle or am i wrong?
-
Thomas
Re: IOAPIC redirection entries
Hi,
Ok - first I should say it's 5:30 in the morning here (I'm tired) and the following is from memory - it'd be a good idea to double check anything I've said before you rely on it, just in case...
Because interrupts range from 0x20 to 0xFF (where 0x20 is the lowest priority interrupt), any TPR value below 0x20 will allow all interrupts but still effect the "lowest priority delivery". Because of this, I'd only use TPR values below 0x20. For example:
Also note that you can combine this with "logical destination mode", to send the IRQ to the lowest priority CPU within a specific group of CPUs. For example, you might have an IRQ that occurs very often and you might want that IRQ to be handled by CPUs that happen to share the same L2/L3 cache (to avoid cache-line bouncing); or you might have a NUMA system and want all IRQs that originate from an I/O hub to be handled by CPUs that are "close" to that I/O hub (to avoid extra latency/hops when the IRQ handler/device driver accesses the devices). The main trick here is how you setup the "logical destination register" (e.g. you could set bit 7 in the logical destination register for all CPUs that are "close" to an I/O hub, then use logical destination mode to send an IRQ to the lowest priority CPU that has bit 7 set in it's logical destination register; and set bit 6 in the logical destination register for some CPUs that share L2/L3 caches).
For x2APIC most of this is mostly the same, except you have no control over the contents of the logical destination register - the highest 16-bits are used to select the NUMA domain and the lowest 16 bits are used to select between 1 and 16 CPUs within that NUMA domain, and therefore you can only send an interrupt to CPUs within one specific NUMA domain using logical delivery mode.
Cheers,
Brendan
Ok - first I should say it's 5:30 in the morning here (I'm tired) and the following is from memory - it'd be a good idea to double check anything I've said before you rely on it, just in case...
The lowest priority delivery mode is a little tricky. The processor's priority is determined by the highest value in the TPR register, the IRR register and the ISR register (where the lowest 4 bits of the IRR and ISR are ignored); and any interrupt that is lower priority than the processor's priority won't be accepted (e.g. if all CPUs have their TPR set to 0xFF then no interrupts will be accepted by any CPU). If you don't change the TPR then all IRQs will go to the same CPU every time, unless that CPU happens to be servicing a different IRQ. How this is done is up to you.thomasnilsen wrote:Well i have setup the destination mode to 0b001 (lowest priority mode) so with broadcast i guess it that only lowest priority one will handle or am i wrong?
Because interrupts range from 0x20 to 0xFF (where 0x20 is the lowest priority interrupt), any TPR value below 0x20 will allow all interrupts but still effect the "lowest priority delivery". Because of this, I'd only use TPR values below 0x20. For example:
- 0x18 to 0x1F = used when the CPU is in different sleep states, where the value depends on the latency of leaving the sleep state
0x10 to 0x17 = used when the CPU has acquired different kernel locks, where the value depends on which kernel lock
0x00 to 0x0F = used in all other cases, where the value depends on the current thread's priority
Also note that you can combine this with "logical destination mode", to send the IRQ to the lowest priority CPU within a specific group of CPUs. For example, you might have an IRQ that occurs very often and you might want that IRQ to be handled by CPUs that happen to share the same L2/L3 cache (to avoid cache-line bouncing); or you might have a NUMA system and want all IRQs that originate from an I/O hub to be handled by CPUs that are "close" to that I/O hub (to avoid extra latency/hops when the IRQ handler/device driver accesses the devices). The main trick here is how you setup the "logical destination register" (e.g. you could set bit 7 in the logical destination register for all CPUs that are "close" to an I/O hub, then use logical destination mode to send an IRQ to the lowest priority CPU that has bit 7 set in it's logical destination register; and set bit 6 in the logical destination register for some CPUs that share L2/L3 caches).
For x2APIC most of this is mostly the same, except you have no control over the contents of the logical destination register - the highest 16-bits are used to select the NUMA domain and the lowest 16 bits are used to select between 1 and 16 CPUs within that NUMA domain, and therefore you can only send an interrupt to CPUs within one specific NUMA domain using logical delivery mode.
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: IOAPIC redirection entries
Hi Brendan,
Thanks for your comprehensive reply. Not bad at 0530 in the morning
I think the Intel Manual is a little bit unclear in how the IOAPIC and LOAPIC should be programmed to work together.
The prioritization in an important role as you describe especially when considering systems with NUMA architecture where a miss in the selection process for handling interrupts and events might have severe impact on performance because of each cpus memory access.
Its clear to me how the LOAPIC work from the Intel Manuals, but i still think the docs for the IOAPIC and are missing some info that i sure would like to have atleast where im at now with things not working... The only thing i have found is a "preliminary paper" for it and i miss something around the communication with the loapic.. Atleast now when i have problems that i think is related to how the APIC is communicating and ACKing the IOAPIC delivered interrupts probably due to some misinterpretation of how things should work...
Note to self;
Need to find out how this prioritized selection process and how the LOAPIC is telling each other who took the interrupt for delivery to cpu.. The issue with [IOAP ] vector 0x21 stuck?? is probably related to the LOAPIC not telling the IOAPIC that its ACKing the interrupt so the IOAPIC constantly retries.. Unsure...
-
Thomas
Thanks for your comprehensive reply. Not bad at 0530 in the morning
I think the Intel Manual is a little bit unclear in how the IOAPIC and LOAPIC should be programmed to work together.
The prioritization in an important role as you describe especially when considering systems with NUMA architecture where a miss in the selection process for handling interrupts and events might have severe impact on performance because of each cpus memory access.
Its clear to me how the LOAPIC work from the Intel Manuals, but i still think the docs for the IOAPIC and are missing some info that i sure would like to have atleast where im at now with things not working... The only thing i have found is a "preliminary paper" for it and i miss something around the communication with the loapic.. Atleast now when i have problems that i think is related to how the APIC is communicating and ACKing the IOAPIC delivered interrupts probably due to some misinterpretation of how things should work...
Note to self;
Need to find out how this prioritized selection process and how the LOAPIC is telling each other who took the interrupt for delivery to cpu.. The issue with [IOAP ] vector 0x21 stuck?? is probably related to the LOAPIC not telling the IOAPIC that its ACKing the interrupt so the IOAPIC constantly retries.. Unsure...
-
Thomas