Hi u all,
i read a few research papers, which explain the apic's timer present in intel processors from the p6 and up to be far more exact, and much better to use for example 1gbit networking where every 10 useconds a package ahs to be send.
I only want to use the apics timer. No I/O apic ect at the moment,
From the intel documentation is thougth to do the following:
1. IA32_APIC_BASE[11] should be set to 1
2. Spurious-Interrupt Vector Register (SVR) : 0xFEE000F0H
set first byte to 1 to softwae enable the apic.
3. divide configuration register : 0xFEE003E0, bits 0,1 ,3 to set a divider
4. initial-count register register : 0xFEE00380 to some value
5. LVT timer register register : 0xFEE00320H
mask bit is bit 16,
bit 17 to select one-time or periodic counting
and first byt is the vector to which the cpu will jump at interrupt table.
So i did this all. I even checked CPUID to check if my proc has an apic. (mobility p4 3,2 ghz). I'm testing this software in VMWare which states to use the same underlying processor.
The problem is, i set the IDT able. It works, because i can use the normal pic. I also have a keyboard ahnged to it ect. But i never get an interrupt of the APIC timer. So am i not doing something? At the moment, my handler ( like all other working handlers) are in asm, and call a C function, which jus prints to screen that an interrupt accurred from the apic's timer. O course i registered the richt index in the IDT, the vector used in the LVT register.
Does someone have an idea?
Thanks in advance!
APIC TIMER
Re:APIC TIMER
Have you tried it on a real machine? It could be that VMWare isn't emulating the APIC properly (or at all). Very high resolution timers don't tend to like being emulated.
Re:APIC TIMER
Hi, thanks for the reply,
Well, the VMWare spec say that the emulate the exact same processor as the underlying machine. So i gues it would work. But is indeed did not try it on a real machine. I'll check that tomorow and post the results,
Gr
Well, the VMWare spec say that the emulate the exact same processor as the underlying machine. So i gues it would work. But is indeed did not try it on a real machine. I'll check that tomorow and post the results,
Gr
Re:APIC TIMER
VMWare does not emulate the underlying machine... it can't because it doesn't have emulation routines for all expansion cards, floppy types, harddrives or what ever.
Re:APIC TIMER
Well, i did not mean that VMWare emulates the whle machine.
It does not. It emulates a soundblaster type soundcard, a network adapter of AMD ect...
But, according to the specs, the exact same cpu is emulated as the physycal one. SO the APIC should work.
I have no exess to a machine with floppy. My machine is a laptop without floppy, and i have no hdd driver writen yet. Also, i would not ecen do that since i will not play with my hdd, to important data. So i have to wat for another machine, or someones help here on the forum on how exactly to use the APIC's timer.
It does not. It emulates a soundblaster type soundcard, a network adapter of AMD ect...
But, according to the specs, the exact same cpu is emulated as the physycal one. SO the APIC should work.
I have no exess to a machine with floppy. My machine is a laptop without floppy, and i have no hdd driver writen yet. Also, i would not ecen do that since i will not play with my hdd, to important data. So i have to wat for another machine, or someones help here on the forum on how exactly to use the APIC's timer.
Re:APIC TIMER
Hi,
I would also assume that this does not extend to hardware outside of the CPU and hardware that is conceptually outside of the CPU (but is actually inside the CPU). This would include the local APIC (which was once an external chip), and for modern AMD CPUs the hyper-transport link (or memory controller).
Despite this, the virtualized local APIC timer in VMware should work fine as both Windows and Linux will use it if it's present.
Some notes...
In most CPUs IA32_APIC_BASE[11] is "sticky" - once it's cleared it can't be set again without resetting the CPU, and even in CPUs where this bit isn't sticky I wouldn't recommend setting it (the BIOS probably disabled it for a reason). Given this, it's enough for an OS to completely ignore IA32_APIC_BASE[11] and check to see if the local APIC is present and enabled in IA32_APIC_BASE[11] by using CPUID (if IA32_APIC_BASE[11] is cleared by the BIOS, then CPUID feature flags will tell the OS that the local APIC isn't supported).
For the spurious interrupt bit 8 must be set (and I'd recommend setting a spurious interrupt vector at the same time). Changing the first byte to 1 won't enable the local APIC.
You should also make sure that the "task priority register" (0xFEE00080) is set to zero - if the value in the task priority register is higher than the interrupt vector you're using for the timer then you won't get an IRQ.
To start the timer running, I'd clear the local APIC count then set the LVT timer register, and then set a proper count. I'm not sure if this is necessary or not, but it's a good idea anyway IMHO.
Lastly, all local APIC registers MUST be accessed as 32 bit dwords - if you try to transfer a word or a byte then the local APIC will ignore the transfer. Also, if you're using C don't trust your optimizer - AFAIK something like "variable |= 1" could be optimized into "or byte [variable],1" even if "variable" is a volatile 32 bit integer.
Cheers,
Brendan
I would assume that VMware uses dynamic translation for privileged code (where things like CR0, CR4, IF, MTRRs, MSRs, etc are virtualized), and directly executes unprivileged code (including CPUID, FPU/MMX/SSE, the arithmetic flags in the eflags register, etc). In this case it is impossible for the guest CPU to be different from the host CPU, as most instructions aren't virtualized.MTermi wrote:But, according to the specs, the exact same cpu is emulated as the physycal one. SO the APIC should work.
I would also assume that this does not extend to hardware outside of the CPU and hardware that is conceptually outside of the CPU (but is actually inside the CPU). This would include the local APIC (which was once an external chip), and for modern AMD CPUs the hyper-transport link (or memory controller).
Despite this, the virtualized local APIC timer in VMware should work fine as both Windows and Linux will use it if it's present.
Some notes...
In most CPUs IA32_APIC_BASE[11] is "sticky" - once it's cleared it can't be set again without resetting the CPU, and even in CPUs where this bit isn't sticky I wouldn't recommend setting it (the BIOS probably disabled it for a reason). Given this, it's enough for an OS to completely ignore IA32_APIC_BASE[11] and check to see if the local APIC is present and enabled in IA32_APIC_BASE[11] by using CPUID (if IA32_APIC_BASE[11] is cleared by the BIOS, then CPUID feature flags will tell the OS that the local APIC isn't supported).
For the spurious interrupt bit 8 must be set (and I'd recommend setting a spurious interrupt vector at the same time). Changing the first byte to 1 won't enable the local APIC.
You should also make sure that the "task priority register" (0xFEE00080) is set to zero - if the value in the task priority register is higher than the interrupt vector you're using for the timer then you won't get an IRQ.
To start the timer running, I'd clear the local APIC count then set the LVT timer register, and then set a proper count. I'm not sure if this is necessary or not, but it's a good idea anyway IMHO.
Lastly, all local APIC registers MUST be accessed as 32 bit dwords - if you try to transfer a word or a byte then the local APIC will ignore the transfer. Also, if you're using C don't trust your optimizer - AFAIK something like "variable |= 1" could be optimized into "or byte [variable],1" even if "variable" is a volatile 32 bit integer.
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.