/* ----------------------------------------------------------------------- * * * Copyright 2006-2009 Erwan Velu - All Rights Reserved * * Portions of this file taken from the Linux kernel, * Copyright 1991-2009 Linus Torvalds and contributors * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston MA 02110-1301; * incorporated herein by reference. * * ----------------------------------------------------------------------- */ #ifndef _CPUID_H #define _CPUID_H #include #include #include #include #include #include #define PAGE_SIZE 4096 #define CPU_MODEL_SIZE 48 #define CPU_VENDOR_SIZE 48 typedef struct { bool fpu; /* Onboard FPU */ bool vme; /* Virtual Mode Extensions */ bool de; /* Debugging Extensions */ bool pse; /* Page Size Extensions */ bool tsc; /* Time Stamp Counter */ bool msr; /* Model-Specific Registers, RDMSR, WRMSR */ bool pae; /* Physical Address Extensions */ bool mce; /* Machine Check Architecture */ bool cx8; /* CMPXCHG8 instruction */ bool apic; /* Onboard APIC */ bool sep; /* SYSENTER/SYSEXIT */ bool mtrr; /* Memory Type Range Registers */ bool pge; /* Page Global Enable */ bool mca; /* Machine Check Architecture */ bool cmov; /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */ bool pat; /* Page Attribute Table */ bool pse_36; /* 36-bit PSEs */ bool psn; /* Processor serial number */ bool clflsh; /* Supports the CLFLUSH instruction */ bool dts; /* Debug Trace Store */ bool acpi; /* ACPI via MSR */ bool pbe; /* Pending Break Enable */ bool mmx; /* Multimedia Extensions */ bool fxsr; /* FXSAVE and FXRSTOR instructions (fast save and restore */ /* of FPU context), and CR4.OSFXSR available */ bool sse; /* Streaming SIMD Extensions */ bool sse2; /* Streaming SIMD Extensions 2 */ bool ss; /* CPU self snoop */ bool htt; /* Hyper-Threading */ bool acc; /* Automatic clock control */ bool syscall; /* SYSCALL/SYSRET */ bool mp; /* MP Capable. */ bool nx; /* Execute Disable */ bool mmxext; /* AMD MMX extensions */ bool fxsr_opt; /* FXSAVE/FXRSTOR optimizations */ bool gbpages; /* "pdpe1gb" GB pages */ bool rdtscp; /* RDTSCP */ bool lm; /* Long Mode (x86-64) */ bool nowext; /* AMD 3DNow! extensions */ bool now; /* 3DNow! */ bool smp; /* A smp configuration has been found */ bool pni; /* Streaming SIMD Extensions-3 */ bool pclmulqd; /* PCLMULQDQ instruction */ bool dtes64; /* 64-bit Debug Store */ bool vmx; /* Hardware virtualization */ bool smx; /* Safer Mode */ bool est; /* Enhanced SpeedStep */ bool tm2; /* Thermal Monitor 2 */ bool sse3; /* Supplemental SSE-3 */ bool cid; /* Context ID */ bool fma; /* Fused multiply-add */ bool cx16; /* CMPXCHG16B */ bool xtpr; /* Send Task Priority Messages */ bool pdcm; /* Performance Capabilities */ bool dca; /* Direct Cache Access */ bool xmm4_1; /* "sse4_1" SSE-4.1 */ bool xmm4_2; /* "sse4_2" SSE-4.2 */ bool x2apic; /* x2APIC */ bool movbe; /* MOVBE instruction */ bool popcnt; /* POPCNT instruction */ bool aes; /* AES Instruction */ bool xsave; /* XSAVE/XRSTOR/XSETBV/XGETBV */ bool osxsave; /* XSAVE enabled in the OS */ bool avx; /* Advanced Vector Extensions */ bool hypervisor; /* Running on a hypervisor */ bool ace2; /* Advanced Cryptography Engine v2 */ bool ace2_en; /* ACE v2 enabled */ bool phe; /* PadLock Hash Engine */ bool phe_en; /* PadLock Hash Engine Enabled */ bool pmm; /* PadLock Montgomery Multiplier */ bool pmm_en; /* PadLock Montgomery Multiplier enabled */ bool svm; /* Secure virtual machine */ bool extapic; /* Extended APIC space */ bool cr8_legacy; /* CR8 in 32-bit mode */ bool abm; /* Advanced bit manipulation */ bool sse4a; /* SSE4-A */ bool misalignsse; /* Misaligned SSE mode */ bool nowprefetch; /* 3DNow prefetch instructions */ bool osvw; /* OS Visible Workaround */ bool ibs; /* Instruction Based Sampling */ bool sse5; /* SSE5 */ bool skinit; /* SKINIT/STGI instructions */ bool wdt; /* Watchdog Timer */ bool ida; /* Intel Dynamic Acceleration */ bool arat; /* Always Running APIC Timer */ bool tpr_shadow; /* Intel TPR Shadow */ bool vnmi; /* Intel Virtual NMI */ bool flexpriority; /* Intel FlexPriority */ bool ept; /* Intel Extended Page Table */ bool vpid; /* Intel Virtual Processor ID */ } s_cpu_flags; typedef struct { char vendor[CPU_VENDOR_SIZE]; uint8_t vendor_id; uint8_t family; char model[CPU_MODEL_SIZE]; uint8_t model_id; uint8_t stepping; uint8_t num_cores; uint16_t l1_data_cache_size; uint16_t l1_instruction_cache_size; uint16_t l2_cache_size; s_cpu_flags flags; } s_cpu; /**********************************************************************************/ /**********************************************************************************/ /* From this point this is some internal stuff mainly taken from the linux kernel */ /**********************************************************************************/ /**********************************************************************************/ /* * EFLAGS bits */ #define X86_EFLAGS_CF 0x00000001 /* Carry Flag */ #define X86_EFLAGS_PF 0x00000004 /* Parity Flag */ #define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */ #define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */ #define X86_EFLAGS_SF 0x00000080 /* Sign Flag */ #define X86_EFLAGS_TF 0x00000100 /* Trap Flag */ #define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */ #define X86_EFLAGS_DF 0x00000400 /* Direction Flag */ #define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */ #define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */ #define X86_EFLAGS_NT 0x00004000 /* Nested Task */ #define X86_EFLAGS_RF 0x00010000 /* Resume Flag */ #define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */ #define X86_EFLAGS_AC 0x00040000 /* Alignment Check */ #define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */ #define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ #define X86_VENDOR_INTEL 0 #define X86_VENDOR_CYRIX 1 #define X86_VENDOR_AMD 2 #define X86_VENDOR_UMC 3 #define X86_VENDOR_NEXGEN 4 #define X86_VENDOR_CENTAUR 5 #define X86_VENDOR_RISE 6 #define X86_VENDOR_TRANSMETA 7 #define X86_VENDOR_NSC 8 #define X86_VENDOR_NUM 9 #define X86_VENDOR_UNKNOWN 0xff #define cpu_has(c, bit) test_bit(bit, (c)->x86_capability) /* * CPU type and hardware bug flags. Kept separately for each CPU. * Members of this structure are referenced in head.S, so think twice * before touching them. [mj] */ struct cpuinfo_x86 { uint8_t x86; /* CPU family */ uint8_t x86_vendor; /* CPU vendor */ uint8_t x86_model; uint8_t x86_mask; char wp_works_ok; /* It doesn't on 386's */ char hlt_works_ok; /* Problems on some 486Dx4's and old 386's */ char hard_math; char rfu; int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */ uint32_t x86_capability[NCAPINTS]; char x86_vendor_id[16]; char x86_model_id[64]; uint16_t x86_l1_data_cache_size; /* in KB, if available */ uint16_t x86_l1_instruction_cache_size; /* in KB, if available */ uint16_t x86_l2_cache_size; /* in KB, if available */ int x86_cache_alignment; /* in bytes */ char fdiv_bug; char f00f_bug; char coma_bug; char pad0; int x86_power; unsigned long loops_per_jiffy; #ifdef CONFIG_SMP cpumask_t llc_shared_map; /* cpus sharing the last level cache */ #endif unsigned char x86_num_cores; /* cpuid returned the number of cores */ unsigned char booted_cores; /* number of cores as seen by OS */ unsigned char apicid; unsigned char x86_clflush_size; } __attribute__ ((__packed__)); struct cpu_model_info { int vendor; int family; char *model_names[16]; }; /* attempt to consolidate cpu attributes */ struct cpu_dev { const char *c_vendor; /* some have two possibilities for cpuid string */ const char *c_ident[2]; struct cpu_model_info c_models[4]; void (*c_init) (struct cpuinfo_x86 * c); void (*c_identify) (struct cpuinfo_x86 * c); unsigned int (*c_size_cache) (struct cpuinfo_x86 * c, unsigned int size); }; /* * Structure definitions for SMP machines following the * Intel Multiprocessing Specification 1.1 and 1.4. */ /* * This tag identifies where the SMP configuration * information is. */ #define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_') struct intel_mp_floating { char mpf_signature[4]; /* "_MP_" */ uint32_t mpf_physptr; /* Configuration table address */ uint8_t mpf_length; /* Our length (paragraphs) */ uint8_t mpf_specification; /* Specification version */ uint8_t mpf_checksum; /* Checksum (makes sum 0) */ uint8_t mpf_feature1; /* Standard or configuration ? */ uint8_t mpf_feature2; /* Bit7 set for IMCR|PIC */ uint8_t mpf_feature3; /* Unused (0) */ uint8_t mpf_feature4; /* Unused (0) */ uint8_t mpf_feature5; /* Unused (0) */ }; extern void get_cpu_vendor(struct cpuinfo_x86 *c); extern void detect_cpu(s_cpu * cpu); #endif