LinuxAsmTools |
LinuxAsmTools - HowTo read CPU informationFinding CPU information mini-HOWTO jeff owens, jeff@linuxasmtools.net v1.01, 06 April 2009 How to find CPU information. ______________________________________________________________________ Table of Contents 1. Disclaimer 2. Introduction 3. Why do we need CPU information? 4. How do we get CPU data? 5. Running the Example program 6. Compiling the example program 7. Finding more information ______________________________________________________________________ 1. Disclaimer The following document is offered in good faith as comprising only safe programming and procedures. No responsibility is accepted by the author for any loss or damage caused in any way to any person or equipment, as a direct or indirect consequence of following these instructions. 2. Introduction The most recent version of this document can always be found at https://thlorenz.com/linuxasmtools-net The CPU (Central Processing Unit) is the engine that runs a computer. Over the years this engine has changed and grown in complexity. This howto describes the X86 family of CPU's which is found in most comuters. The sample program used here is built from two files: CPU.asm and CPU.inc. 3. Why do we need CPU information? The X86 family started with the 8086 processor and grew as enhancements were added. Each processer added a few new instructions that assembly programmers could utilize. When these new instructions were used, the resulting programs could not be run on older processors. Additionally, new features were added to memory handling and modes of operation. Today, the latest processors can run legacy code from the 8086, but older processors present problems for programmers. Each program may need to check the CPU and decide it their program is compatable. 4. How do we Get CPU data? CPU data is obtained by executing the "cpuid" instruction and others. By watching how the computer handles various instructions we can determine the type of processor. The code to do this can be lengthy, so most programmers rely on libraries, programs, or other ways of obtaining the information. On linux we have the /proc file system which does the job. All we need to do is read /proc/cpuinfo and we get something like this: processor : 0 vendor_id : AuthenticAMD cpu family : 6 model : 8 model name : AMD Athlon(tm) MP stepping : 1 cpu MHz : 1050.092 cache size : 256 KB fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 1 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 mmx fxsr sse syscall mp mmxext 3dnowext 3dnow up ts bogomips : 2103.10 clflush size : 32 Next, we look at a sample program to read /proc/cpuinfo. The sample program consists of two files which are available as cpu.asm and cpu.inc ------------ start of source file cpu.asm ---------- extern crt_write extern block_read_all extern sys_exit global _start,main main: _start: mov ecx,cpu_msg ;message ptr mov edx,cpu_msg_size ;message length call crt_write ;kernel call mov ebx,cpuinfo_path mov ecx,buffer mov edx,buffer_size call block_read_all or eax,eax js sc_exit ;exit if error mov edx,eax ;size to edx mov ecx,buffer ;data ptr call crt_write sc_exit: call sys_exit ;---------- [section .data] cpuinfo_path: db '/proc/cpuinfo',0 cpu_msg: incbin "cpu.inc" cpu_msg_size equ $ - cpu_msg [section .bss] buffer resb 200 buffer_size equ $ - buffer ------------- end of source file cpu.asm --------------- ------------- start of source file cpu.inc ------------- The CPU is a computers engine. It executes all programs after converting them to machine code. A computer can have multiple cpu's (called multi core's) that work as a team. When multiple cpu's are found, each one is described. The following Information about the CPU is obtained from the Linux proc file system at: /proc/cpuinfo ------------- end of source file cup.inc -------------- Some of the information we want is shown as flags (fpu vme de psc). To decode these flags we can use the kernel include file cpufeatures_32.h. See the links for more information. Here is the information from the include: /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */ #define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */ #define X86_FEATURE_VME (0*32+ 1) /* Virtual Mode Extensions */ #define X86_FEATURE_DE (0*32+ 2) /* Debugging Extensions */ #define X86_FEATURE_PSE (0*32+ 3) /* Page Size Extensions */ #define X86_FEATURE_TSC (0*32+ 4) /* Time Stamp Counter */ #define X86_FEATURE_MSR (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */ #define X86_FEATURE_PAE (0*32+ 6) /* Physical Address Extensions */ #define X86_FEATURE_MCE (0*32+ 7) /* Machine Check Architecture */ #define X86_FEATURE_CX8 (0*32+ 8) /* CMPXCHG8 instruction */ #define X86_FEATURE_APIC (0*32+ 9) /* Onboard APIC */ #define X86_FEATURE_SEP (0*32+11) /* SYSENTER/SYSEXIT */ #define X86_FEATURE_MTRR (0*32+12) /* Memory Type Range Registers */ #define X86_FEATURE_PGE (0*32+13) /* Page Global Enable */ #define X86_FEATURE_MCA (0*32+14) /* Machine Check Architecture */ #define X86_FEATURE_CMOV (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */ #define X86_FEATURE_PAT (0*32+16) /* Page Attribute Table */ #define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */ #define X86_FEATURE_PN (0*32+18) /* Processor serial number */ #define X86_FEATURE_CLFLSH (0*32+19) /* Supports the CLFLUSH instruction */ #define X86_FEATURE_DS (0*32+21) /* Debug Store */ #define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */ #define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */ #define X86_FEATURE_FXSR (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */ /* of FPU context), and CR4.OSFXSR available */ #define X86_FEATURE_XMM (0*32+25) /* Streaming SIMD Extensions */ #define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */ #define X86_FEATURE_SELFSNOOP (0*32+27) /* CPU self snoop */ #define X86_FEATURE_HT (0*32+28) /* Hyper-Threading */ #define X86_FEATURE_ACC (0*32+29) /* Automatic clock control */ #define X86_FEATURE_IA64 (0*32+30) /* IA-64 processor */ /* AMD-defined CPU features, CPUID level 0x80000001, word 1 */ /* Don't duplicate feature flags which are redundant with Intel! */ #define X86_FEATURE_SYSCALL (1*32+11) /* SYSCALL/SYSRET */ #define X86_FEATURE_MP (1*32+19) /* MP Capable. */ #define X86_FEATURE_NX (1*32+20) /* Execute Disable */ #define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */ #define X86_FEATURE_RDTSCP (1*32+27) /* RDTSCP */ #define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */ #define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */ #define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */ /* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */ #define X86_FEATURE_RECOVERY (2*32+ 0) /* CPU in recovery mode */ #define X86_FEATURE_LONGRUN (2*32+ 1) /* Longrun power control */ #define X86_FEATURE_LRTI (2*32+ 3) /* LongRun table interface */ /* Other features, Linux-defined mapping, word 3 */ /* This range is used for feature bits which conflict or are synthesized */ #define X86_FEATURE_CXMMX (3*32+ 0) /* Cyrix MMX extensions */ #define X86_FEATURE_K6_MTRR (3*32+ 1) /* AMD K6 nonstandard MTRRs */ #define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */ #define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */ /* cpu types for specific tunings: */ #define X86_FEATURE_K8 (3*32+ 4) /* Opteron, Athlon64 */ #define X86_FEATURE_K7 (3*32+ 5) /* Athlon */ #define X86_FEATURE_P3 (3*32+ 6) /* P3 */ #define X86_FEATURE_P4 (3*32+ 7) /* P4 */ #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */ #define X86_FEATURE_UP (3*32+ 9) /* smp kernel running on up */ #define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */ #define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */ #define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */ #define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */ /* 14 free */ #define X86_FEATURE_SYNC_RDTSC (3*32+15) /* RDTSC synchronizes the CPU */ #define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ #define X86_FEATURE_MWAIT (4*32+ 3) /* Monitor/Mwait support */ #define X86_FEATURE_DSCPL (4*32+ 4) /* CPL Qualified Debug Store */ #define X86_FEATURE_EST (4*32+ 7) /* Enhanced SpeedStep */ #define X86_FEATURE_TM2 (4*32+ 8) /* Thermal Monitor 2 */ #define X86_FEATURE_CID (4*32+10) /* Context ID */ #define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */ #define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */ #define X86_FEATURE_DCA (4*32+18) /* Direct Cache Access */ /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ #define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */ #define X86_FEATURE_XSTORE_EN (5*32+ 3) /* on-CPU RNG enabled */ #define X86_FEATURE_XCRYPT (5*32+ 6) /* on-CPU crypto (xcrypt insn) */ #define X86_FEATURE_XCRYPT_EN (5*32+ 7) /* on-CPU crypto enabled */ #define X86_FEATURE_ACE2 (5*32+ 8) /* Advanced Cryptography Engine v2 */ #define X86_FEATURE_ACE2_EN (5*32+ 9) /* ACE v2 enabled */ #define X86_FEATURE_PHE (5*32+ 10) /* PadLock Hash Engine */ #define X86_FEATURE_PHE_EN (5*32+ 11) /* PHE enabled */ #define X86_FEATURE_PMM (5*32+ 12) /* PadLock Montgomery Multiplier */ #define X86_FEATURE_PMM_EN (5*32+ 13) /* PMM enabled */ /* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ #define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */ #define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */ /* * Auxiliary flags: Linux defined - For features scattered in various * CPUID levels like 0x6, 0xA etc */ #define X86_FEATURE_IDA (7*32+ 0) /* Intel Dynamic Acceleration */ 5. Running the example program. The example program can be started with: ./cpu To create a file with the CPU data use: ./cpu > file 6. Compiling the example program. The example program can be compiled with the following tools: nasm - assembler asmlib - library of assembler functions The easy way to do this is to install, asmide and start it as follows: asmide cpu.asm asmide will provide a menu, with compile and debug options. To manually compile the source use the following: nasm -g -f elf cpu.asm ld cpu.o -static -o cpu /usr/lib/asmlib.a 7. Finding more information flag definitions can be found in linux source include /usr/source/linux-headers.../include/asm-x86/cpufeature-32.h The various processors and the cpuid instruction can be researched at: http://sandpile.org http://www.x86.org http://developer.intel.com http://www.amd.com/support/techdocdir.html http://www.cyrix.com/products/cyrindex.htm |