CPUID: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
(Ported CPUID page, reorganized it)
 
(updated to use code templates)
Line 9: Line 9:
When called with EAX = 0, CPUID returns the brand name in EBX, EDX and ECX. Writing these to memory in this order results in a 12-character string. These can be tested against known brands:
When called with EAX = 0, CPUID returns the brand name in EBX, EDX and ECX. Writing these to memory in this order results in a 12-character string. These can be tested against known brands:


/* Vendor-strings. */
{{code|CPUID Vendor Strings|
<pre>
#define CPUID_VENDOR_AMD "AuthenticAMD"
/* Vendor-strings. */
#define CPUID_VENDOR_INTEL "GenuineIntel"
#define CPUID_VENDOR_VIA "CentaurHauls"
#define CPUID_VENDOR_AMD "AuthenticAMD"
#define CPUID_VENDOR_INTEL "GenuineIntel"
#define CPUID_VENDOR_TRANSMETA "GenuineTMx86"
#define CPUID_VENDOR_VIA "CentaurHauls"
#define CPUID_VENDOR_CYRIX "CyrixInstead"
#define CPUID_VENDOR_CENTAUR "CentaurHauls"
#define CPUID_VENDOR_TRANSMETA "GenuineTMx86"
#define CPUID_VENDOR_NEXGEN "NexGenDriven"
#define CPUID_VENDOR_CYRIX "CyrixInstead"
#define CPUID_VENDOR_CENTAUR "CentaurHauls"
#define CPUID_VENDOR_UMC "UMC UMC UMC " /* FIXME - Is the space right? */
#define CPUID_VENDOR_SIS "SiS SiS SiS " /* FIXME - Same. */
#define CPUID_VENDOR_NEXGEN "NexGenDriven"
#define CPUID_VENDOR_NSC "Geode by NSC"
#define CPUID_VENDOR_UMC "UMC UMC UMC " /* FIXME - Is the space right? */
#define CPUID_VENDOR_SIS "SiS SiS SiS " /* FIXME - Same. */
#define CPUID_VENDOR_RISE "RiseRiseRise"
#define CPUID_VENDOR_NSC "Geode by NSC"
#define CPUID_VENDOR_RISE "RiseRiseRise"
</pre>
}}


Also, EAX is set to the maximum EAX value supported for CPUID calls, as not all queries are supported on all processors
Also, EAX is set to the maximum EAX value supported for CPUID calls, as not all queries are supported on all processors
Line 29: Line 33:
Note that different brands of CPUs may have given different meanings to these.
Note that different brands of CPUs may have given different meanings to these.
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.

{{code|CPUID flags|
/* Flags. */
<pre>
#define CPUID_FLAG_FPU 0x1 /* Floating Point Unit. */
/* Flags. */
#define CPUID_FLAG_VME 0x2 /* Virtual Mode Extensions. */
#define CPUID_FLAG_DE 0x4 /* Debugging Extensions. */
#define CPUID_FLAG_FPU 0x1 /* Floating Point Unit. */
#define CPUID_FLAG_PSE 0x8 /* Page Size Extensions. */
#define CPUID_FLAG_VME 0x2 /* Virtual Mode Extensions. */
#define CPUID_FLAG_TSC 0x10 /* Time Stamp Counter. */
#define CPUID_FLAG_DE 0x4 /* Debugging Extensions. */
#define CPUID_FLAG_MSR 0x20 /* Model-specific registers. */
#define CPUID_FLAG_PSE 0x8 /* Page Size Extensions. */
#define CPUID_FLAG_PAE 0x40 /* Physical Address Extensions. */
#define CPUID_FLAG_TSC 0x10 /* Time Stamp Counter. */
#define CPUID_FLAG_MCE 0x80 /* Machine Check Exceptions. */
#define CPUID_FLAG_MSR 0x20 /* Model-specific registers. */
#define CPUID_FLAG_CXCHG8 0x100 /* Compare and exchange 8-byte. */
#define CPUID_FLAG_PAE 0x40 /* Physical Address Extensions. */
#define CPUID_FLAG_APIC 0x200 /* On-chip APIC. */
#define CPUID_FLAG_MCE 0x80 /* Machine Check Exceptions. */
#define CPUID_FLAG_SEP 0x800 /* Fast System Calls. */
#define CPUID_FLAG_CXCHG8 0x100 /* Compare and exchange 8-byte. */
#define CPUID_FLAG_MTRR 0x1000 /* Memory Type Range Registers. */
#define CPUID_FLAG_APIC 0x200 /* On-chip APIC. */
#define CPUID_FLAG_PGE 0x2000 /* Page Global Enable. */
#define CPUID_FLAG_SEP 0x800 /* Fast System Calls. */
#define CPUID_FLAG_MCA 0x4000 /* Machine Check Architecture. */
#define CPUID_FLAG_MTRR 0x1000 /* Memory Type Range Registers.
#define CPUID_FLAG_CMOV 0x8000 /* Conditional move-instruction. */
#define CPUID_FLAG_PGE 0x2000 /* Page Global Enable.
#define CPUID_FLAG_PAT 0x10000 /* Page Attribute Table. */
#define CPUID_FLAG_MCA 0x4000 /* Machine Check Architecture. */
#define CPUID_FLAG_PSE36 0x20000 /* 36-bit Page Size Extensions. */
#define CPUID_FLAG_CMOV 0x8000 /* Conditional move-instruction. */
#define CPUID_FLAG_PSN 0x40000 /* Processor Serial Number. */
#define CPUID_FLAG_PAT 0x10000 /* Page Attribute Table. */
#define CPUID_FLAG_CLFL 0x80000 /* CLFLUSH - fixme? */
#define CPUID_FLAG_PSE36 0x20000 /* 36-bit Page Size Extensions. */
#define CPUID_FLAG_DTES 0x200000 /* Debug Trace and EMON Store MSRs. */
#define CPUID_FLAG_PSN 0x40000 /* Processor Serial Number. */
#define CPUID_FLAG_ACPI 0x400000 /* Thermal Cotrol MSR. */
#define CPUID_FLAG_CLFL 0x80000 /* CLFLUSH - fixme? */
#define CPUID_FLAG_MMX 0x800000 /* MMX instruction set. */
#define CPUID_FLAG_DTES 0x200000 /* Debug Trace and EMON Store MSRs. */
#define CPUID_FLAG_FXSR 0x1000000 /* Fast floating point save/restore. */
#define CPUID_FLAG_ACPI 0x400000 /* Thermal Cotrol MSR. */
#define CPUID_FLAG_SSE 0x2000000 /* SSE (Streaming SIMD Extensions) */
#define CPUID_FLAG_MMX 0x800000 /* MMX instruction set. */
#define CPUID_FLAG_SSE2 0x4000000 /* SSE2 (Streaming SIMD Extensions - #2) */
#define CPUID_FLAG_FXSR 0x1000000 /* Fast floating point save/restore. */
#define CPUID_FLAG_SS 0x8000000 /* Selfsnoop. */
#define CPUID_FLAG_SSE 0x2000000 /* SSE (Streaming SIMD Extensions) */
#define CPUID_FLAG_HTT 0x10000000 /* Hyper-Threading Technology. */
#define CPUID_FLAG_SSE2 0x4000000 /* SSE2 (Streaming SIMD Extensions - #2) */
#define CPUID_FLAG_TM1 0x20000000 /* Thermal Interrupts, Status MSRs. */
#define CPUID_FLAG_SS 0x8000000 /* Selfsnoop. */
#define CPUID_FLAG_IA64 0x40000000 /* IA-64 (64-bit Intel CPU) */
#define CPUID_FLAG_HTT 0x10000000 /* Hyper-Threading Technology. */
#define CPUID_FLAG_PBE 0x80000000 /* Pending Break Event. */
#define CPUID_FLAG_TM1 0x20000000 /* Thermal Interrupts, Status MSRs. */
#define CPUID_FLAG_IA64 0x40000000 /* IA-64 (64-bit Intel CPU) */
#define CPUID_FLAG_PBE 0x80000000 /* Pending Break Event. */
</pre>
}}


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


{{code|CPUID in GCC|
enum cpuid_requests {
<pre>
CPUID_GETVENDORSTRING,
enum cpuid_requests {
CPUID_GETFEATURES,
CPUID_GETVENDORSTRING,
CPUID_GETTLB,
CPUID_GETFEATURES,
CPUID_GETSERIAL,
CPUID_GETTLB,
CPUID_GETSERIAL,
CPUID_INTELEXTENDED=0x80000000,
CPUID_INTELFEATURES,
CPUID_INTELBRANDSTRING,
CPUID_INTELBRANDSTRINGMORE,
CPUID_INTELBRANDSTRINGEND,
};
/** issue a single request to CPUID. Fits 'intel features', for instance
CPUID_INTELEXTENDED=0x80000000,
* note that even if only "eax" and "edx" are of interrest, other registers
CPUID_INTELFEATURES,
* will be modified by the operation, so we need to tell the compiler about it.
CPUID_INTELBRANDSTRING,
*/
CPUID_INTELBRANDSTRINGMORE,
static inline void cpuid(int code, dword *a, dword *d) {
CPUID_INTELBRANDSTRINGEND,
asm volatile("cpuid":"=a"(*a),"=d"(*d):"0"(code):"ecx","ebx");
};
}
/** issue a single request to CPUID. Fits 'intel features', for instance
/** issue a complete request, storing general registers output as a string
*/
* note that even if only "eax" and "edx" are of interrest, other registers
static inline int cpuid_string(int code, dword where[4]) {
* will be modified by the operation, so we need to tell the compiler about it.
*/
int highest;
asm volatile("cpuid":"=a"(*where),"=b"(*(where+1)),
static inline void cpuid(int code, dword *a, dword *d) {
asm volatile("cpuid":"=a"(*a),"=d"(*d):"0"(code):"ecx","ebx");
"=c"(*(where+2)),"=d"(*(where+3)):"0"(code));
return highest;
}
}
</pre>
/** issue a complete request, storing general registers output as a string
}}
*/
static inline int cpuid_string(int code, dword where[4]) {
int highest;
asm volatile("cpuid":"=a"(*where),"=b"(*(where+1)),
"=c"(*(where+2)),"=d"(*(where+3)):"0"(code));
return highest;
}

== Links ==
== Links ==

Revision as of 06:17, 1 December 2006

The CPUID instruction can be used to retrieve various amount of information about your cpu, like its vendor string and model number, the size of internal caches and (more interesting), the list of CPU features supported.

How to use CPUID

Note that prior to use the CPUID instruction, you should also make sure the processor support it by testing the 'ID' bit in eflags (this is 0x200000 and is modifiable only when CPUID instruction is supported. For systems that doesn't support CPUID, writing a '1' at that place will have no effect)

CPU Brand

When called with EAX = 0, CPUID returns the brand name in EBX, EDX and ECX. Writing these to memory in this order results in a 12-character string. These can be tested against known brands:

Template:Code

Also, EAX is set to the maximum EAX value supported for CPUID calls, as not all queries are supported on all processors

CPU Features

When called with EAX = 1 (CPUID_GETFEATURES), CPUID returns a bit field in EDX containing the following values. Note that different brands of CPUs may have given different meanings to these. 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.

Template:Code

Using CPUID from GCC

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

Template:Code

Links