| /* |
| * cpuid.h -- |
| * contains the data structures required for CPUID |
| * implementation. |
| */ |
| |
| #define CPUID_VENDOR_LENGTH 3 /* 3 GPRs hold vendor ID */ |
| #define CPUID_VENDOR_STR_LENGTH (CPUID_VENDOR_LENGTH * sizeof(uint32_t) + 1) |
| #define CPUID_BRAND_LENGTH 12 /* 12 GPRs hold vendor ID */ |
| #define CPUID_BRAND_STR_LENGTH (CPUID_BRAND_LENGTH * sizeof(uint32_t) + 1) |
| |
| static inline void __cpuid(unsigned int *eax, unsigned int *ebx, |
| unsigned int *ecx, unsigned int *edx) |
| { |
| /* ecx is often an input as well as an output. */ |
| asm volatile("\t" |
| "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" |
| : "=a" (*eax), |
| "=D" (*ebx), |
| "=c" (*ecx), |
| "=d" (*edx) |
| : "0" (*eax), "2" (*ecx)); |
| } |
| |
| static inline void cpuid(unsigned int op, |
| unsigned int *eax, unsigned int *ebx, |
| unsigned int *ecx, unsigned int *edx) |
| { |
| *eax = op; |
| *ecx = 0; |
| __cpuid(eax, ebx, ecx, edx); |
| } |
| |
| /* Some CPUID calls want 'count' to be placed in ecx */ |
| static inline void cpuid_count(unsigned int op, int count, |
| unsigned int *eax, unsigned int *ebx, |
| unsigned int *ecx, unsigned int *edx) |
| { |
| *eax = op; |
| *ecx = count; |
| __cpuid(eax, ebx, ecx, edx); |
| } |
| |
| /* Typedef for storing the Cache Information */ |
| typedef union { |
| unsigned char ch[48]; |
| uint32_t uint[12]; |
| struct { |
| uint32_t fill1:24; /* Bit 0 */ |
| uint32_t l1_i_sz:8; |
| uint32_t fill2:24; |
| uint32_t l1_d_sz:8; |
| uint32_t fill3:16; |
| uint32_t l2_sz:16; |
| uint32_t fill4:18; |
| uint32_t l3_sz:14; |
| uint32_t fill5[8]; |
| } amd; |
| } cpuid_cache_info_t; |
| |
| /* Typedef for storing the CPUID Vendor String */ |
| typedef union { |
| /* Note: the extra byte in the char array is for '\0'. */ |
| char char_array[CPUID_VENDOR_STR_LENGTH]; |
| uint32_t uint32_array[CPUID_VENDOR_LENGTH]; |
| } cpuid_vendor_string_t; |
| |
| /* Typedef for storing the CPUID Brand String */ |
| typedef union { |
| /* Note: the extra byte in the char array is for '\0'. */ |
| char char_array[CPUID_BRAND_STR_LENGTH]; |
| uint32_t uint32_array[CPUID_BRAND_LENGTH]; |
| } cpuid_brand_string_t; |
| |
| /* Typedef for storing CPUID Version */ |
| typedef union { |
| uint32_t flat; |
| struct { |
| uint32_t stepping:4; /* Bit 0 */ |
| uint32_t model:4; |
| uint32_t family:4; |
| uint32_t processorType:2; |
| uint32_t reserved1514:2; |
| uint32_t extendedModel:4; |
| uint32_t extendedFamily:8; |
| uint32_t reserved3128:4; /* Bit 31 */ |
| } bits; |
| } cpuid_version_t; |
| |
| /* Typedef for storing CPUID Processor Information */ |
| typedef union { |
| uint32_t flat; |
| struct { |
| uint32_t brandIndex:8; /* Bit 0 */ |
| uint32_t cflushLineSize:8; |
| uint32_t logicalProcessorCount:8; |
| uint32_t apicID:8; /* Bit 31 */ |
| } bits; |
| } cpuid_proc_info_t; |
| |
| /* Typedef for storing CPUID Feature flags */ |
| typedef union { |
| uint64_t flat; |
| uint32_t uint32_array[2]; |
| struct { |
| uint32_t fpu:1; /* Bit 0 */ |
| uint32_t vme:1; |
| uint32_t de:1; |
| uint32_t pse:1; |
| uint32_t tsc:1; |
| uint32_t msr:1; |
| uint32_t pae:1; |
| uint32_t mce:1; |
| uint32_t cx8:1; |
| uint32_t apic:1; |
| uint32_t reserved10:1; |
| uint32_t sep:1; |
| uint32_t mtrr:1; |
| uint32_t pge:1; |
| uint32_t mca:1; |
| uint32_t cmov:1; |
| uint32_t pat:1; |
| uint32_t pse36:1; |
| uint32_t psn:1; |
| uint32_t cflush:1; |
| uint32_t reserved20:1; |
| uint32_t ds:1; |
| uint32_t acpi:1; |
| uint32_t mmx:1; |
| uint32_t fxsr:1; |
| uint32_t sse:1; |
| uint32_t sse2:1; |
| uint32_t ss:1; |
| uint32_t htt:1; |
| uint32_t tm:1; |
| uint32_t reserved30:1; |
| uint32_t pbe:1; /* Bit 31 */ |
| uint32_t sse3:1; /* Bit 32 */ |
| uint32_t reserved3433:2; |
| uint32_t monitor:1; |
| uint32_t dscpl:1; |
| uint32_t reserved3937:3; |
| uint32_t tm2:1; |
| uint32_t reserved41:1; |
| uint32_t cnxtid:1; |
| uint32_t reserved4443:2; |
| uint32_t cmpxchg16b:1; |
| uint32_t reserved6346:18; /* Bit 63 */ |
| } bits; |
| } cpuid_feature_flags_t; |
| |
| /* Feature flags returned by extended CPUID node function 8000_0001. */ |
| typedef union { |
| uint64_t flat; |
| uint32_t uint32_array[2]; |
| struct { |
| uint32_t fpu:1; /* Bit 0 */ |
| uint32_t vme:1; |
| uint32_t de:1; |
| uint32_t pse:1; |
| uint32_t tsc:1; |
| uint32_t msr:1; |
| uint32_t pae:1; |
| uint32_t mce:1; |
| uint32_t cx8:1; |
| uint32_t apic:1; |
| uint32_t reserved10:1; |
| uint32_t sep:1; |
| uint32_t mtrr:1; |
| uint32_t pge:1; |
| uint32_t mca:1; |
| uint32_t cmov:1; |
| uint32_t pat:1; |
| uint32_t pse36:1; |
| uint32_t reserved1918:2; |
| uint32_t nx:1; |
| uint32_t reserved21:1; |
| uint32_t mmxamd:1; |
| uint32_t mmx:1; |
| uint32_t fxsr:1; |
| uint32_t ffxsr:1; |
| uint32_t reserved26:1; |
| uint32_t rdtscp:1; |
| uint32_t reserved28:1; |
| uint32_t lm:1; |
| uint32_t threedeenowext:1; |
| uint32_t threedeenow:1; /* Bit 31 */ |
| uint32_t lahf:1; /* Bit 32 */ |
| uint32_t cmplegacy:1; |
| uint32_t reserved3534:2; |
| uint32_t cr8avail:1; |
| uint32_t reserved6337:27; /* Bit 63 */ |
| } bits; |
| } cpuid_ext_feature_flags_t; |
| |
| /* An overall structure to cache all of the CPUID information */ |
| struct cpu_ident { |
| uint32_t max_cpuid; |
| cpuid_version_t vers; |
| cpuid_proc_info_t info; |
| cpuid_feature_flags_t fid; |
| cpuid_vendor_string_t vend_id; |
| cpuid_brand_string_t brand_id; |
| cpuid_cache_info_t cache_info; |
| }; |
| |
| struct cpuid4_eax { |
| uint32_t ctype:5; |
| uint32_t level:3; |
| uint32_t is_self_initializing:1; |
| uint32_t is_fully_associative:1; |
| uint32_t reserved:4; |
| uint32_t num_threads_sharing:12; |
| uint32_t num_cores_on_die:6; |
| }; |
| |
| struct cpuid4_ebx { |
| uint32_t coherency_line_size:12; |
| uint32_t physical_line_partition:10; |
| uint32_t ways_of_associativity:10; |
| }; |
| |
| struct cpuid4_ecx { |
| uint32_t number_of_sets:32; |
| }; |
| |