Page 1 of 1

CPUID on AMD and Intel

Posted: Mon May 07, 2007 2:19 am
by crackers
Is this instruction returning values in the same format for both AMD and Intel - I mean meaning of functions and returned values ? If not than is there any documentation for this instruction for AMD processors ?

Posted: Mon May 07, 2007 3:10 am
by Combuster
In concept, yes.
However, the instruction contains enough bugs and pitfalls that parsing them cpu-dependent is the best option if you want anything more than the brand and the first 32 bits of cpu capabilities.

The AMD doc you are looking for: http://www.amd.com/us-en/assets/content ... /25481.pdf

Posted: Mon May 07, 2007 4:07 am
by TomTom
Even for reading the brand you need to check for certain CPUs (iirc some early Pentium CPUs didn't support that)

Re: CPUID on AMD and Intel

Posted: Mon May 07, 2007 6:44 am
by Brendan
Hi,
crackers wrote:Is this instruction returning values in the same format for both AMD and Intel - I mean meaning of functions and returned values ? If not than is there any documentation for this instruction for AMD processors ?
A quick list of differences between AMD and Intel (ignoring bugs):
  • Cache details - these are reported using entirely different methods. Intel was using arbitrary numerical codes (eax = 0x00000002) which forces software to use a conversion table, but switched to a better method (eax = 0x00000004) that doesn't require a conversion table and returns a little more information (how many logical CPUs share the cache, etc). AMD doesn't support either of these methods but uses it's own version (eax = 0x80000005 for L1 caches and eax = 0x80000006 for L1 caches). I don't know how AMD returns information about L3 caches or information about which caches are shared between different cores (AFAIK this information can't be obtained at all for AMD CPUs).

    Power Management - Intel uses eax = 0x00000006 while AMD use eax = 0x80000007. Both manufacturers do power management in different ways.

    Multi-core - AMD uses eax = 0x80000008 for the number of cores on the chip while Intel uses eax = 0x00000004.

    Feature Flags - in general there's 2 functions for this, eax = 0x00000001 for Intel defined features and eax = 0x80000001 for AMD defined features. Because AMD implements a lot of Intel features and Intel implements some AMD features, you need to use both functions to get a complete list of supported features. Also, Centaur/VIA has some interesting features (e.g. an encryption engine) that are detected using eax = 0xC0000001 (if and only if the CPU vendor string is "CentaurHauls").

    Some features (SYSENTER and SYSCALL) are supported in some modes (e.g. protected mode or long mode) but not others, but there's only one flag to determine if it's supported or not. For example an Intel CPU that supports SYSCALL in long mode will leave the SYSCALL feature flag clear because SYSCALL isn't support in protected mode (unlike AMD). An AMD CPU that supports SYSENTER in protected mode will set the SYSENTER flag even though it doesn't support SYSENTER in long mode (unlike Intel).
On top of this there's CPU bugs where some CPUs say they support features when they don't. For example, Intel Pentium 4 model 3 says it supports CMPXCHG16B when it doesn't, Pentium Pro model 3 stepping 3 says it supports SYSENTER when it doesn't, AMD K5 model 0 says it doesn't support PGE when it does, lots of older CPUs support CMPXCHG8B but don't report it.

Then there's other CPU bugs that can be avoided. For an example there's some Pentium II overdrive chips that support PAT but the upper 4 PAT entries don't work if PSE or PAE is enabled. In this case I just clear the PAE feature flag (in the OS's version of the feature flags) so the OS never uses PAE on these CPUs.

Because of all these problems I parse CPUID information during boot and build (consistent and correct) OS specific information that's used by everything after that. This also means that I can also other methods of detecting information about a CPU and the rest of my software still works the same. Examples of this include building a "brand string" for CPUs that don't support CPUID eax=0x80000002 to CPUID eax=0x80000004; using vendor, family and stepping information to determine cache details; or using I/O ports to get CPU information for older Cyrix CPUs.

Lastly, my OS's code goes even further than this, and builds a set of "errata flags" and a set of "flaw flags". Errata flags are used to tell the OS to use evasive action (i.e. implement some sort of work-around). For example, the CPUID code might set the "has F00F bug" flag, and the OS would handle this by making sure the IDT isn't cached (so the OS won't lock up if malicious code executes the F00F instruction). Because flaw flags are fixed by work-arounds in the OS the user doesn't need to care about them. Errata flags are for things that can cause erratic behavior or reduced stability that have no sane work-around - my CPUID code keeps track of these so they can be reported to system administrators.

@TomTom: Some early Pentium CPUs return the family, model and stepping in EAX for "CPUID eax = 0x00000000" (instead of returning the highest standard function number supported). These CPUs don't return a vendor string, feature flags, or any other information. For these CPUs my code detects them and sets the family, model and stepping to what was reported, then sets the vendor string to "GenuineIntel" and feature flags (FPU, VME, DE, PSE, TSC, MSR, MCE and CX8). Then it uses the family, model and stepping to find a brand string (probably "Pentium (P5)"). Lastly it decides the CPU has the F00F bug (that the OS fixes) and some FPU problems (that the OS can't fix).


Cheers,

Brendan

Posted: Wed May 09, 2007 12:41 am
by crackers
Wow, thats a lot of infos big thx, but in meantime I've found some other thinkgs that troubles me.

1. In Intel docs for cpuid instruction I've found few brand ID's with the same meaning for example
17h - Mobile Intel Celeron
0Fh - Mobile Intel Celeron
12h - Intel Celeron M
(btw is there a diffrence between those Processors with 'M' and ones with 'mobile' in name). Does it mean that I've to check all three values to determine if processor is celeron mobile or normal celeron ?

2. How can I tell the diffrence between Pentium D and Pentium 4 Extreme edition ?

3. Is there a way to tell if processors is Pentium 75 or for example Pentium 166 since they have the same model number ?

Posted: Wed May 09, 2007 4:33 am
by Brendan
Hi,
crackers wrote:1. In Intel docs for cpuid instruction I've found few brand ID's with the same meaning for example
17h - Mobile Intel Celeron
0Fh - Mobile Intel Celeron
12h - Intel Celeron M
(btw is there a diffrence between those Processors with 'M' and ones with 'mobile' in name). Does it mean that I've to check all three values to determine if processor is celeron mobile or normal celeron ?
Brand IDs (and the brand string, if supported) are mostly meaningless marketting names that are only useful for displaying to the user so they feel good. To determine the differences between CPUs, use the vendor, family, model, stepping, feature flags and cache details (and never use the brand string or brand ID to determine differences between CPUs).

It's possible for completely different CPUs to have the same or very similar brand names (the words "celeron", "xeon" and "mobile" are used for a variety of Pentium II to Pentium 4 CPUs). It's also possible for almost identical CPUs to have completely different brand names (e.g. the only difference between a "family 6 celeron" and a "family 6 Pentium III" may be cache size).

Also note that for some CPUs you need to use the cache size to determine the correct brand string (same brand ID, family, model and steppings), and for some CPUs it's impossible to tell the difference from software (same brand ID, family, model, stepping and cache sizes).
crackers wrote:2. How can I tell the diffrence between Pentium D and Pentium 4 Extreme edition ?
IIRC Pentium D is single core with hyper-threading (2 logical CPUs), and Pentium 4 EE is dual core with hyper-threading (4 logical CPUs). These CPUs should support the brand string - use CPUID eax=0x80000002 to CPUID eax=0x80000004 to tell the user what it is.
crackers wrote:3. Is there a way to tell if processors is Pentium 75 or for example Pentium 166 since they have the same model number ?
No - it's possible that the only difference is the details painted on top of the CPU.

Imagine you make 100000 Pentium CPUs and then test them to see how fast each one can run. Some are broken and get thrown away, some can run at 75 MHz and no faster, some can run at 100 MHz, some at 150 MHz, and some can run at 166 MHz. For each one you put different markings on the outside and sell it at a difference price. In the end, the only difference between these CPUs is how fast they could run, and the jumper settings for the clock multiplier on the motherboard....

The same applies to other CPUs, and (for later CPUs) to caches - i.e. test the CPU's caches and if there's a problem somewhere, disable part of the cache and call it a Celeron. :)


Cheers,

Brendan