CPUID: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content deleted Content added
Combuster (talk | contribs)
Ported CPUID page, reorganized it
 
updated to use code templates
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:
 
/*{{code|CPUID Vendor-strings. */Strings|
<pre>
#define CPUID_VENDOR_AMD "AuthenticAMD"
/* Vendor-strings. */
#define CPUID_VENDOR_INTEL "GenuineIntel"
#define CPUID_VENDOR_VIACPUID_VENDOR_AMD "CentaurHaulsAuthenticAMD"
#define CPUID_VENDOR_INTEL "GenuineIntel"
#define CPUID_VENDOR_TRANSMETA "GenuineTMx86"
#define CPUID_VENDOR_VIA "CentaurHauls"
#define CPUID_VENDOR_CYRIX "CyrixInstead"
#define CPUID_VENDOR_CENTAUR CPUID_VENDOR_TRANSMETA "CentaurHaulsGenuineTMx86"
#define CPUID_VENDOR_NEXGENCPUID_VENDOR_CYRIX "NexGenDrivenCyrixInstead"
#define CPUID_VENDOR_CENTAUR "CentaurHauls"
#define CPUID_VENDOR_UMC "UMC UMC UMC " /* FIXME - Is the space right? */
#define CPUID_VENDOR_SIS CPUID_VENDOR_NEXGEN "SiS SiS SiS NexGenDriven" /* FIXME - Same. */
#define CPUID_VENDOR_NSCCPUID_VENDOR_UMC "GeodeUMC byUMC UMC NSC" /* FIXME - Is the space right? */
#define CPUID_VENDOR_UMCCPUID_VENDOR_SIS "UMCSiS UMCSiS UMCSiS " /* FIXME - Is the space right?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
Line 29 ⟶ 33:
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.
 
{{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_DECPUID_FLAG_FPU 0x40x1 /* DebuggingFloating Point ExtensionsUnit. */
#define CPUID_FLAG_PSECPUID_FLAG_VME 0x80x2 /* PageVirtual SizeMode Extensions. */
#define CPUID_FLAG_DE #define CPUID_FLAG_TSC 0x4 0x10 /* Time StampDebugging CounterExtensions. */
#define CPUID_FLAG_MSRCPUID_FLAG_PSE 0x200x8 /* Model-specificPage Size registersExtensions. */
#define CPUID_FLAG_PAECPUID_FLAG_TSC 0x400x10 /* PhysicalTime AddressStamp ExtensionsCounter. */
#define CPUID_FLAG_MCECPUID_FLAG_MSR 0x800x20 /* Machine CheckModel-specific Exceptionsregisters. */
#define CPUID_FLAG_PAE #define CPUID_FLAG_CXCHG8 0x40 0x100 /* Compare andPhysical exchangeAddress 8-byteExtensions. */
#define CPUID_FLAG_MCE #define CPUID_FLAG_APIC 0x80 0x200 /* On-chipMachine Check APICExceptions. */
#define CPUID_FLAG_SEPCPUID_FLAG_CXCHG8 0x8000x100 /* FastCompare and Systemexchange Calls8-byte. */
#define CPUID_FLAG_MTRRCPUID_FLAG_APIC 0x10000x200 /* Memory Type RangeOn-chip RegistersAPIC. */
#define CPUID_FLAG_PGECPUID_FLAG_SEP 0x800 0x2000 /* PageFast GlobalSystem EnableCalls. */
#define CPUID_FLAG_MCACPUID_FLAG_MTRR 0x40000x1000 /* MachineMemory CheckType ArchitectureRange Registers. */
#define CPUID_FLAG_CMOVCPUID_FLAG_PGE 0x8000 0x2000 /* ConditionalPage move-instructionGlobal Enable. */
#define CPUID_FLAG_PATCPUID_FLAG_MCA 0x4000 0x10000 /* PageMachine AttributeCheck TableArchitecture. */
#define CPUID_FLAG_CMOV #define CPUID_FLAG_PSE36 0x8000 0x20000 /* 36Conditional move-bit Page Size Extensionsinstruction. */
#define CPUID_FLAG_PSNCPUID_FLAG_PAT 0x400000x10000 /* ProcessorPage SerialAttribute NumberTable. */
#define CPUID_FLAG_CLFLCPUID_FLAG_PSE36 0x800000x20000 /* CLFLUSH 36-bit Page Size fixme?Extensions. */
#define CPUID_FLAG_PSN #define CPUID_FLAG_DTES 0x40000 0x200000 /* Debug Trace and EMONProcessor StoreSerial MSRsNumber. */
#define CPUID_FLAG_ACPICPUID_FLAG_CLFL 0x80000 0x400000 /* ThermalCLFLUSH Cotrol- MSR.fixme? */
#define CPUID_FLAG_MMXCPUID_FLAG_DTES 0x8000000x200000 /* MMXDebug Trace and EMON instructionStore setMSRs. */
#define CPUID_FLAG_FXSRCPUID_FLAG_ACPI 0x10000000x400000 /* FastThermal floatingCotrol point save/restoreMSR. */
#define CPUID_FLAG_SSECPUID_FLAG_MMX 0x20000000x800000 /* SSE (StreamingMMX SIMDinstruction Extensions)set. */
#define CPUID_FLAG_SSE2CPUID_FLAG_FXSR 0x40000000x1000000 /* SSE2Fast (Streamingfloating SIMDpoint Extensions - #2)save/restore. */
#define CPUID_FLAG_SSCPUID_FLAG_SSE 0x80000000x2000000 /* Selfsnoop.SSE (Streaming SIMD Extensions) */
#define CPUID_FLAG_HTTCPUID_FLAG_SSE2 0x4000000 0x10000000 /* HyperSSE2 (Streaming SIMD Extensions -Threading Technology.#2) */
#define CPUID_FLAG_SS #define CPUID_FLAG_TM1 0x8000000 0x20000000 /* Thermal Interrupts, Status MSRsSelfsnoop. */
#define CPUID_FLAG_IA64CPUID_FLAG_HTT 0x40000000 0x10000000 /* IAHyper-64 (64-bit IntelThreading CPU)Technology. */
#define CPUID_FLAG_PBECPUID_FLAG_TM1 0x800000000x20000000 /* PendingThermal Interrupts, BreakStatus EventMSRs. */
#define CPUID_FLAG_IA64 0x40000000 /* IA-64 (64-bit Intel CPU) */
#define CPUID_FLAG_PBE 0x80000000 /* Pending Break Event. */
</pre>
}}
 
== Using CPUID from GCC ==
Line 66 ⟶ 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
 
{{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"(*wherea),"=bd"(*d):"0"(where+1)code):"ecx","ebx");
};
}
/** issue a singlecomplete request, tostoring CPUID.general Fitsregisters 'inteloutput features',as fora instancestring
*/
* 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":"=ca"(*(where+2)),"=db"(*(where+31)):"0"(code));,
static inline void cpuid(int code, dword *a, dword *d) {
asm volatile("cpuid": "=ac"(*a(where+2)),"=d"(*d(where+3)):"0"(code):"ecx","ebx");
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 ==

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