Hi,
AlexHully wrote:I understood that:
One local apic == one core.
Unless there's something like hyper-threading, where one local APIC = one logical CPU (and there's 2 or more logical CPUs in a core).
AlexHully wrote:So, what is the matter ? We can know the cpu speed (cpuid..). Cpus have 4/6 different functional speeds (P-states). So we know how many cycles it can do in, say, one second, since we know its speed.
May a P-state change occur, we can recalibrate the cpu cycles according to the difference.
So why do we need an external source (PIT, whatever) to calibrate the apic timer ?
What did I miss ?
In "roughly chronological" order...
Originally the local APIC was a separate chip (not built into the CPU at all) and its timer ran at bus speed not CPU speed. For these ancient systems (80486) there was no CPUID.
Then (first for Pentium Pro, but then back-ported into later "Pentium with MMX" chips) Intel shifted the local APIC into the same chip as the CPU and changed a few things in the local APIC. The local APIC still ran at bus speed and not CPU speed. These CPUs did have CPUID, but CPUID didn't tell you how fast the CPU is so that doesn't help.
Much later (Pentium 4?), Intel started adding "nominal clock speed" to their CPU brand name strings. Nominal clock speed has nothing to do with actual clock speed and (when a chip is overclocked) the "nominal clock speed" reported doesn't tell you the actual nominal clock speed either. Also; the local APIC still uses bus frequency and not any of the CPU's frequencies, and its insanely difficult to determine bus speed from the CPU speed (if you could know the CPU speed you'd still need the ratio of bus speed to CPU speed).
Even later Intel added "TSC deadline mode" to the local APIC that does use "CPU speed sort of maybe" (in addition to the traditional/older modes that still use bus speed). However; for modern CPUs (e.g. probably all CPUs that are new enough to support TSC deadline mode) the local APIC's TSC deadline mode (and the TSC in general) has nothing to do with CPU's (variable) frequency and is actually a fixed frequency clock (that runs at "faster than nominal clock speed" so that its incremented at least once per CPU cycle even when the CPU is running faster than its nominal clock speed due things like turbo-boost, etc). Also, on some CPUs (Atom) it works differently (to avoid "yet another clock"); and the TSC runs at bus speed and they pretend it runs at a faster frequency by adding a value (e.g. 16) every bus cycle.
Basically; you need to calibrate the local APIC timer (which may mean measuring bus speed or measuring TSC speed), and CPUID won't tell you anything useful regardless of how new/old the CPU is.
Note: For the sake of completeness; with massive quantities of model specific voodoo (lookup tables, etc), for "Intel family 6 and later" CPUs I think it's possible to determine bus speed by combining information from both CPUID and MSRs; but if this is possible it won't work for any overclocked CPU or future CPUs (e.g. until you figure out the model specific bus multiplier and update your tables), and probably won't work for AMD or VIA CPUs either.
Cheers,
Brendan