/* ----------------------------------------------------------------------- * * * 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 #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 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 lm; /* Long Mode (x86-64) */ bool nowext;/* AMD 3DNow! extensions */ bool now; /* 3DNow! */ bool smp; /* A smp configuration has been found*/ } 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; 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 static inline __purefunc bool test_bit(int nr, const uint32_t *addr) { return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0; } #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]; int x86_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_max_cores; /* cpuid returned max cores value */ unsigned char booted_cores; /* number of cores as seen by OS */ unsigned char apicid; unsigned char x86_clflush_size; } __attribute__((__packed__)); #endif struct cpu_model_info { int vendor; int family; char *model_names[16]; }; /* attempt to consolidate cpu attributes */ struct cpu_dev { char * c_vendor; /* some have two possibilities for cpuid string */ 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);