APIC and the ISR+IRR

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

APIC and the ISR+IRR

Post by durand »

I was wondering if someone could explain how to read the ISR and IRR registers of the local APIC to me. The documentation I'm reading doesn't add up to what I'm seeing so I think I'm a little confused.

The docs say the ISR is a 256 bit register located at 0xFEE00100 and ranges up to 0xFEE00170 which is 112 bytes. I've tried printing out the values of this ISR but they don't look correct and don't match the interrupt I'm expecting.

I'm expecting the local APIC timer interrupt on occasion. Am I correct to expect the interrupt to be registered in the IRR and ISR?


Durand.
User avatar
gaf
Member
Member
Posts: 349
Joined: Thu Oct 21, 2004 11:00 pm
Location: Munich, Germany

Re:APIC and the ISR+IRR

Post by gaf »

Hey Durand
durand wrote:The docs say the ISR is a 256 bit register located at 0xFEE00100 and ranges up to 0xFEE00170 which is 112 bytes.


Keep in mind that you're accessing the registers of a device, and not just ordinary memory. A range from 0xFEE00100 to 0xFEE00170 simply means that there are 8 registers (32bit each -> 256bits) that can be accessed by reading/writing the "even" (16bit aligned) addresses: 0xFEE00100, 0xFEE00110, ... 0xFEE00170.
durand wrote:I'm expecting the local APIC timer interrupt on occasion. Am I correct to expect the interrupt to be registered in the IRR and ISR?
It should be in the ISR, the IRR holds interrupts that are pending as they can't yet be delivered due to a higher priority interrupt blocking the CPU.

Detecting the interrupt number by reading out the ISR is however prohibitively expensive as the binary logorithm of the 256bit register would have to be calculated. I would thus recommend you to rather use a more elabarated GDT design that assigns an exclusive stub to each interrupt. Using this technique it's trivial to get the interrupt number, as it just has to be stored somewhere in the stub-code..

regards,
gaf
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

Re:APIC and the ISR+IRR

Post by durand »

Thanks gaf! I didn't find that information but I saw something like that when I was trying to read the apic source from bochs. Now it makes sense. :)

By the way, do you know the effect of setting the initial count of the APIC Timer to zero while it's already busy counting down a one-shot interval set earlier?
ti_mo_n

Re:APIC and the ISR+IRR

Post by ti_mo_n »

If during the count-down process the initial-count register is set, counting will restart,
using the new initial-count value.
and
After the timer
reaches zero, an timer interrupt is generated and the timer remains at its 0 value until reprogrammed.
So it should fire an interrupt.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:APIC and the ISR+IRR

Post by Brendan »

Hi,
gaf wrote:Detecting the interrupt number by reading out the ISR is however prohibitively expensive as the binary logorithm of the 256bit register would have to be calculated. I would thus recommend you to rather use a more elabarated GDT design that assigns an exclusive stub to each interrupt. Using this technique it's trivial to get the interrupt number, as it just has to be stored somewhere in the stub-code..
You are of course correct (GDT stub-code would be faster), but it doesn't sound prohibitively expensive:

Code: Select all

    mov ebx,0xFEE00170
.nextDword:
    bsr ecx,[ebx]
    jne .found
    sub ebx,16
    cmp ebx,0xFEE00100
    jae .nextDword
    jmp .errorNoneSet

.foundDword:
    add bl,bl
    or cl,bl            ;ecx = interrupt number
Because the local APIC is built into the CPU there won't be any cache miss penalties or anything. Of course in C there's no way to generate a "bsr" instruction (and I'd be very surprised if any optimizer can convert any manual loop into a bsr or bsf instruction).

Doing the same thing for the PIC chips (if your OS supports either) would be much slower (delays caused by I/O port accesses to the "PCI to IPC bridge").
durand wrote:By the way, do you know the effect of setting the initial count of the APIC Timer to zero while it's already busy counting down a one-shot interval set earlier?
The Intel manual says "after the timer reaches zero, an timer interrupt is generated". The word "after" could mean that the interrupt is generated when the counter tries to go from zero to "-1". In this case setting the initial count to zero would generate an IRQ after N bus cycles (where N depends on the divide configuration register).

The AMD manual says "when the count reaches 0, a timer interrupt is generated". This would imply that the interrupt is generated when the count goes from 1 to zero. In this case setting the initial count to zero would mean you either won't get any IRQ or you'd get an IRQ immediately.

I really do wish the manuals were more descriptive. For e.g. would an initial count of 1 mean 2*N bus cycles (interrupt on overflow) or would an initial count of 1 mean 1*N bus cycles (interrupt as soon as zero is reached)?

I'd also like to know how long it takes before the count is first decreased. For e.g. when the divide configuration register is set to "divide by 128" and you set the initial count register, is the count first decreased 128 bus clocks after the count is set, or could it be anywhere from 1 to 128 bus clocks before the count is first decreased? If the latter case is true then reducing the "divide by" value and increasing the count would improve timing accuracy.

I would assume that setting a count of zero would mean you won't get any IRQ, and that the delay you get for a non-zero count is between "(count - 1) * divider + 1" and "count * divider" bus cycles. For e.g. with "divide by 128", for a count of 1 the delay would be between 1 and 128 bus cycles, and for a count of 2 the delay would be between 129 and 256 bus cycles.

Assumptions suck though... ;)


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.
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

Re:APIC and the ISR+IRR

Post by durand »

Yeah. Assumptions do suck and I think I'm having to deal with a few of my APIC assumptions at the moment. :)

But thanks for the help guys. It really has helped me out. I'll do some testing on the APIC behaviour later on tonight and post what I find out.
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

Re:APIC and the ISR+IRR

Post by durand »

Apparently, the correct behaviour of the APIC when the Initial Count register is set to zero is to cancel the current count down and not send an interrupt.

If interrupts are disabled and the timer event occurs, the interrupt is registered in the IRR. If the APIC timer is masked, no event registers anywhere.

That's all I see and have found.
Post Reply