1 /** 2 * @file cpu_type.c 3 * CPU determination 4 * 5 * @remark Copyright 2002 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author John Levon 9 * @author Philippe Elie 10 */ 11 12 #include "oprofile.h" 13 #include "op_msr.h" 14 15 #include <linux/smp.h> 16 17 EXPORT_NO_SYMBOLS; 18 19 MODULE_PARM(force_rtc, "i"); 20 MODULE_PARM_DESC(force_rtc, "force RTC mode."); 21 static int force_rtc; 22 23 #ifndef HT_SUPPORT 24 /** 25 * p4_threads - determines the number of logical processor threads in a die 26 * 27 * returns number of threads in p4 die (1 for non-HT processors) 28 */ 29 static int p4_threads(void) 30 { 31 int processor_threads = 1; 32 33 #ifdef CONFIG_SMP 34 if (test_bit(X86_FEATURE_HT, ¤t_cpu_data.x86_capability)) { 35 /* This it a Pentium 4 with HT, find number of threads */ 36 int eax, ebx, ecx, edx; 37 38 cpuid (1, &eax, &ebx, &ecx, &edx); 39 processor_threads = (ebx >> 16) & 0xff; 40 } 41 #endif /* CONFIG_SMP */ 42 43 return processor_threads; 44 } 45 46 #ifdef CONFIG_SMP 47 /** 48 * do_cpu_id - Call the cpuid instruction and fill in data at passed address 49 * 50 * We expect that data is pointing to an array of unsigned chars as big as there 51 * are cpus in an smp system. 52 */ 53 static void do_cpu_id(void * data) 54 { 55 int eax, ebx, ecx, edx; 56 unsigned char * ptr = (unsigned char *) data; 57 58 cpuid(1, &eax, &ebx, &ecx, &edx); 59 60 /* bits EBX[31:24] define APIC ID */ 61 ptr[smp_processor_id()] = (unsigned char) ((ebx & 0xff000000) >> 24); 62 } 63 #endif 64 65 /** 66 * p4_ht_enabled - Determines if Hyper Threading is enabled or not. 67 * 68 * A P4 can be capable of HT, but not enabled via BIOS. The check for 69 * this is unfortunately not simple and involves running cpuid on all 70 * logical processors and checking for bits in the APIC_ID fields. 71 * As per Intel docs. Returns 1 if enabled, 0 otherwise. 72 * 73 */ 74 static int p4_ht_enabled(void) 75 { 76 #ifndef CONFIG_SMP 77 return 0; 78 #else 79 int enabled, threads, i; 80 unsigned char mask; 81 unsigned char apic_id[smp_num_cpus]; 82 unsigned int cpu; 83 84 /* First check for capability */ 85 threads = p4_threads(); 86 if (threads == 1) return 0; 87 /* Create mask for low order bits */ 88 mask = 0xff; 89 i = 1; 90 while (i < threads) { 91 i *= 2; 92 mask <<= 1; 93 } 94 /* Get APIC_ID from all logial procs and self */ 95 smp_call_function(do_cpu_id, apic_id, 1, 1); 96 do_cpu_id(apic_id); 97 /* If the low order bits are on, then HT is enabled */ 98 enabled = 0; 99 cpu = 0; 100 do { 101 if (apic_id[cpu] & ~mask) { 102 enabled = 1; 103 break; 104 } 105 cpu++; 106 } while (cpu < smp_num_cpus); 107 108 return enabled; 109 #endif /* CONFIG_SMP */ 110 } 111 #endif /* !HT_SUPPORT */ 112 113 114 op_cpu p4_cpu_type(void) 115 { 116 __u8 model = current_cpu_data.x86_model; 117 if (model <= 4) { 118 #ifdef HT_SUPPORT 119 if (smp_num_siblings == 1) { 120 return CPU_P4; 121 } else if (smp_num_siblings == 2) { 122 return CPU_P4_HT2; 123 } else { 124 printk(KERN_INFO 125 "oprofile: P4 HT unsupported number of siblings" 126 "processor, reverting to RTC\n"); 127 return CPU_RTC; 128 } 129 #else 130 /* Cannot handle enabled HT P4 hardware */ 131 if ((p4_threads() > 1) && p4_ht_enabled()) { 132 printk(KERN_INFO 133 "oprofile: P4 HT enabled, reverting to RTC\n"); 134 return CPU_RTC; 135 } 136 else 137 return CPU_P4; 138 #endif 139 } else 140 /* Do not know what it is */ 141 return CPU_RTC; 142 } 143 144 145 __init op_cpu get_cpu_type(void) 146 { 147 __u8 vendor = current_cpu_data.x86_vendor; 148 __u8 family = current_cpu_data.x86; 149 __u8 model = current_cpu_data.x86_model; 150 __u16 val; 151 152 if (force_rtc) 153 return CPU_RTC; 154 155 switch (vendor) { 156 case X86_VENDOR_AMD: 157 if (family == 6) { 158 /* certain models of K7 does not have apic. 159 * Check if apic is really present before enabling it. 160 * IA32 V3, 7.4.1 */ 161 val = cpuid_edx(1); 162 if (!(val & (1 << 9))) 163 return CPU_RTC; 164 return CPU_ATHLON; 165 } 166 if (family == 15) 167 return CPU_HAMMER; 168 return CPU_RTC; 169 170 case X86_VENDOR_INTEL: 171 switch (family) { 172 default: 173 return CPU_RTC; 174 case 6: 175 /* A P6-class processor */ 176 if (model == 14) 177 return CPU_CORE; 178 if (model > 0xd) 179 return CPU_RTC; 180 if (model > 5) 181 return CPU_PIII; 182 else if (model > 2) 183 return CPU_PII; 184 return CPU_PPRO; 185 case 0xf: 186 return p4_cpu_type(); 187 } 188 189 default: 190 return CPU_RTC; 191 } 192 } 193