local apic & timer interrupt

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
Kicer
Posts: 13
Joined: Sat Apr 01, 2006 12:00 am

local apic & timer interrupt

Post by Kicer »

hi

I'm configuring local apic and i tried to set up timer interrupt
i wrote:

Code: Select all

mov eax,0x20050
    mov [gs: esi + 0x320],eax           ;set apic timer interrupt

    mov eax,256
    mov [gs:esi + 0380H],eax            ;timer
but even i set that this interrupt should be periodic it's being rised only once
in bochs log could be found:

Code: Select all

00002180135-d-[APIC0] CPU 0: read from APIC address fee000f0 = 000000ff
00002180140-d-[APIC0] CPU 0: write 0x000001ff to APIC address fee000f0
00002180140-d-[APIC0] write 000001ff to spurious interrupt register
00002180140-d-[APIC0] CPU 0: write 0x00020050 to APIC address fee00320
00002180140-d-[APIC0] CPU 0: write 0x00000100 to APIC address fee00380
00002180140-d-[APIC0] APIC: Initial Timer Count Register = 256

00002180396-d-[APIC0] Local apic on CPU 0: trigger interrupt vector=0x50
00002180396-d-[APIC0] triggered vector 0x50
00002180396-d-[APIC0] service_local_apic(): setting INTR=1 for vector 0x50
00002180396-d-[APIC0] CPU 0: local apic timer (periodic) triggered int, reset counter to 0x00000100
00002180400-d-[APIC0] CPU 0: acknowledge_int returning vector 0x50
00002180652-d-[APIC0] Local apic on CPU 0: trigger interrupt vector=0x50
00002180652-d-[APIC0] triggered vector 0x50
00002180652-d-[APIC0] local apic (CPU 0): not delivering int50 because int50 is in service
00002180652-d-[APIC0] CPU 0: local apic timer (periodic) triggered int, reset counter to 0x00000100
00002180908-d-[APIC0] Local apic on CPU 0: trigger interrupt vector=0x50
00002180908-d-[APIC0] triggered vector 0x50
00002180908-d-[APIC0] triggered vector 0x50 not accepted
00002180908-d-[APIC0] CPU 0: local apic timer (periodic) triggered int, reset counter to 0x00000100
00002181164-d-[APIC0] Local apic on CPU 0: trigger interrupt vector=0x50
00002181164-d-[APIC0] triggered vector 0x50
00002181164-d-[APIC0] triggered vector 0x50 not accepted
as i guess i should clear INTR for this interrupt vector
but i've no idea how (i was trying to find answer in intel doc but i couldn't)

thank You in advance for answers
Last edited by Kicer on Sun Apr 23, 2006 11:00 pm, edited 2 times in total.
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: local apic & timer interrupt

Post by xenos »

You need to send an EOI by writing 0 into the EOI register (apic base + 0xB0) and the end of your interrupt routine. Then it should work.
yaocong
Posts: 22
Joined: Fri Sep 09, 2005 11:00 pm
Location: China
Contact:

Re: local apic & timer interrupt

Post by yaocong »

I always do not know what is relationship between the IO APIC and the Local APIC?
I like the Dream of the Red Chamber.
Kicer
Posts: 13
Joined: Sat Apr 01, 2006 12:00 am

Re: local apic & timer interrupt

Post by Kicer »

yaocong wrote:I always do not know what is relationship between the IO APIC and the Local APIC?
IO APIC is used only in MP system and is forwarding irqs to cpus (You are selecting the target cpu for each irq except fpu (14 as i remember))
each cpu has local apic, and it has a lot of functions. generally its used to comunicate one cpu with others and in uniprocessor it can be usefull becouse of its timer interrupt that can be triggered as often as You wish.


Now I have another problem:
this trick with resetting EOI register works (thx XenOS)
but i've run it at M$ virtual machine and at my PC and intrrupt isn't trigerred even once. i've checked it and after i put any value to 0x380 register, the value of 0x390 is still the some (it's not decreasing)
any reasons of this situation ?
User avatar
gaf
Member
Member
Posts: 349
Joined: Thu Oct 21, 2004 11:00 pm
Location: Munich, Germany

Re: local apic & timer interrupt

Post by gaf »

Hello,
did you actually check whether the local Apic is enabled on your computer ? To do so you should first execute a cpuid with eax being 1. Then check whether bit 11 of the edx register, which contains the results of the cpuid instruction, is set. If not the local apic on your computer was disabled by the BIOS. There's some work-around in the linux code that might allow you to reactivate it.

regards,
gaf
Kicer
Posts: 13
Joined: Sat Apr 01, 2006 12:00 am

Re: local apic & timer interrupt

Post by Kicer »

0000 0011 1000 0011 1111 1011 1111 1111 <-this is how my edx looks like after cpuid with eax=1
as You can see 11 bit is set so apic should be enabled
User avatar
gaf
Member
Member
Posts: 349
Joined: Thu Oct 21, 2004 11:00 pm
Location: Munich, Germany

Re: local apic & timer interrupt

Post by gaf »

Hello,
It's also possible that the BIOS has relocated your local APIC's registers. You should be able to get the correct base address from the IA32_APIC_BASE MSR (0x1B).
Apart from that you should make sure that all registers involved in the timer logic are initialized, and that the APIC is also software (as opposed to hardware..) enabled. To activate the APIC you have to set bit 8 in the spurious interrupt register, which is located at address 0xF0.
You might also try to read the physical APIC ID, so that you at least know whether you're accessing the correct memory range..

regards,
gaf

btw: Just noticed that it's actually bit 9 and not 11 of the cpuid return value that must be set if an local APIC is present. There's also a bit 11 APIC enable flag, but that's in the MSR and not the cpuid return code..
Kicer
Posts: 13
Joined: Sat Apr 01, 2006 12:00 am

Re: local apic & timer interrupt

Post by Kicer »

that seems to be reason
in bochs i have fee00900 in eax and in m$ virtual pc is 0
thx for ideas
User avatar
gaf
Member
Member
Posts: 349
Joined: Thu Oct 21, 2004 11:00 pm
Location: Munich, Germany

Re: local apic & timer interrupt

Post by gaf »

Hello Kicer,
that actually looks as if the lapic was either disabled or simply isn't emulated by Virtual PC. Provided that your real computer has an apic, you might be able to reactivate it by setting bit 11 of IA32_APIC_BASE MSR. After the apic was enabled you should be able to get the base address from the MSR. The linux code I mentioned can also be browsed online and might help you to write your apic code.

regards,
gaf
Kicer
Posts: 13
Joined: Sat Apr 01, 2006 12:00 am

Re: local apic & timer interrupt

Post by Kicer »

yes, You are right, virtual pc does no support lapic (i've checked cpuid).
i didn't suppose it won't. but on my real pc i've configured msr and it work :)
in intels docs is written that there are two ways to turn on lapic and i thought it enought to use one of them so i only set up one bit in spurious register.
Kicer
Posts: 13
Joined: Sat Apr 01, 2006 12:00 am

Re: local apic & timer interrupt

Post by Kicer »

Another problem now:
i've set irq 0 -> standard interval - 18,2 times per second
and local apic's timer interrupt -> i put value 256 to counter
on virtual pc's (bochs for example) works normally
on my PC i've momentaly after booting exception number 13 with 0x13b error value
that means my pc was trying to use 7th irq but i've not set in ldt
Once i had almost the same problem -> my keyboard irq procedure was too long and irq0 was repating so fast (100 times per second) that pic could cooperate with this situation so he generated this strange irq.
now i'm not sure if reason is the same
i've change value i put to counter -> 65536 and after several seconds i've the same exception. (in this time timer irq is being triggered 0x3000 - 0xf000 times it depends but i don't know what on)
both, irq0 and timer procedures are very short (only inc one byte on screen)
any possible reasons of this situation ?
Post Reply