CPUID: Difference between revisions

108 bytes added ,  29 days ago
m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
m (→‎Checking CPUID availability: The are -> There are)
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(2 intermediate revisions by 2 users not shown)
Line 9:
This assembly routine checks if CPUID is supported:
 
<sourcesyntaxhighlight lang="asm">
pushfd ;Save EFLAGS
pushfd ;Store EFLAGS
Line 20:
and eax,0x00200000 ;eax = zero if ID bit can't be changed, else non-zero
ret
</syntaxhighlight>
</source>
 
Note 1: There are some old CPUs where CPUID is supported but the ID bit in EFLAGS is not (NexGen). There are also CPUs that support CPUID if and only if it has to be enabled first (Cyrix M1).
Line 29:
The idea of the CPUID instruction is that you can call it with different values in EAX, and it will return different information about the processor. For example, if we want the Vendor ID String (see below), we should code something like that:
 
<sourcesyntaxhighlight lang="asm">
mov eax, 0x0
cpuid
</syntaxhighlight>
</source>
 
There are differences between AMD and Intel. According to the Intel CPUID application note, we should first check the Vendor ID String for "GenuineIntel" before taking out information, such as the Processor Signature, Processor Feature Flags, etc.
Line 40:
When called with EAX = 0, CPUID returns the vendor ID string in EBX, EDX and ECX. Writing these to memory in this order results in a 12-character string. These can be tested against known Vendor ID strings:
 
<sourcesyntaxhighlight lang="c">
// Vendor strings from CPUs.
#define CPUID_VENDOR_AMD "AuthenticAMD"
Line 73:
#define CPUID_VENDOR_BHYVE "bhyve bhyve "
#define CPUID_VENDOR_QNX " QNXQVMBSQG "
</syntaxhighlight>
</source>
You already know that the Vendor ID String is returned in EBX, ECX, EDX. Let us take an Intel processor. It should return "GenuineIntel". Look at the following text to see how the string is placed in the registers:
Line 94:
Recent processors also use ECX for features (which form a different set), with which you should be very careful as some old CPUs return bogus information in this register.
 
<sourcesyntaxhighlight lang="c">
enum {
CPUID_FEAT_ECX_SSE3 = 1 << 0,
Line 159:
CPUID_FEAT_EDX_PBE = 1 << 31
};
</syntaxhighlight>
</source>
 
== Using CPUID from GCC ==
Line 165:
Alternatively, one can use the __get_cpuid function that comes with GCC. To use this function, include <cpuid.h>.
 
<sourcesyntaxhighlight lang="c">
#include <cpuid.h>
 
Line 180:
{
unsigned int eax, unused, edx;
__get_cpuid(1, &eax, &unused, &unused, %&edx);
return edx & CPUID_FEAT_EDX_APIC;
}
 
</syntaxhighlight>
</source>
 
{{Disputed}}
Line 190:
CPUID can be invoked with various request codes (in eax) and will return values in general registers (much as a built-in service interrupt). The following code is made Public Domain out of Clicker's x86/cpu.h
 
<sourcesyntaxhighlight lang="c">
/* DEPRECATED: You should use the <cpuid.h> header that comes with GCC instead. */
 
Line 221:
return (int)where[0];
}
</syntaxhighlight>
</source>
 
== See Also ==