CPUID: Difference between revisions

Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content deleted Content added
→‎CPU Features: Updated features list
Chase (talk | contribs)
m Add syntax highlighting
Line 6: Line 6:
An Assembly-routine that checks whether CPUID is supported looks like the following:
An Assembly-routine that checks whether CPUID is supported looks like the following:


<source lang="asm">
<pre>
; returns zero if CPUID is not supported. returns 1 otherwise.
; returns zero if CPUID is not supported. returns 1 otherwise.
pushfd
pushfd
Line 21: Line 21:
shr eax, 21
shr eax, 21
ret
ret
</pre>
</source>


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:
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:


<source lang="asm">
<pre>
mov eax, 0x0
mov eax, 0x0
cpuid
cpuid
</pre>
</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.
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 36: Line 36:
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:
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:


<source lang="c">
<pre>
/* Vendor-strings. */
/* Vendor-strings. */
#define CPUID_VENDOR_OLDAMD "AMDisbetter!" //early engineering samples of AMD K5 processor
#define CPUID_VENDOR_OLDAMD "AMDisbetter!" //early engineering samples of AMD K5 processor
Line 51: Line 51:
#define CPUID_VENDOR_NSC "Geode by NSC"
#define CPUID_VENDOR_NSC "Geode by NSC"
#define CPUID_VENDOR_RISE "RiseRiseRise"
#define CPUID_VENDOR_RISE "RiseRiseRise"
</pre>
</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:
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 72: Line 72:
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.
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.


<source lang="c">
<pre>
enum {
enum {
CPUID_FEAT_ECX_SSE3 = 1 << 0,
CPUID_FEAT_ECX_SSE3 = 1 << 0,
Line 130: Line 130:
CPUID_FEAT_EDX_PBE = 1 << 31
CPUID_FEAT_EDX_PBE = 1 << 31
};
};
</pre>
</source>


== Using CPUID from GCC ==
== Using CPUID from GCC ==
Line 136: Line 136:
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
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


<source lang="c">
<pre>
enum cpuid_requests {
enum cpuid_requests {
CPUID_GETVENDORSTRING,
CPUID_GETVENDORSTRING,
Line 166: Line 166:
return highest;
return highest;
}
}
</pre>
</source>


== See Also ==
== See Also ==