1 #include <lwk/kernel.h>
4 #include <lwk/cpuinfo.h>
5 #include <lwk/aspace.h>
6 #include <arch/processor.h>
7 #include <arch/proto.h>
10 * Information about the boot CPU.
11 * The CPU capabilities stored in this structure are the lowest common
12 * denominator for all CPUs in the system... in this sense, boot_cpu_data
13 * is special compared to the corresponding entry in the cpu_info[] array.
15 struct cpuinfo boot_cpu_data;
18 * On AMD multi-core CPUs, the lower bits of the local APIC ID distinquish the
19 * cores. This function assumes the number of cores is a power of two.
22 amd_detect_cmp(struct cpuinfo *c)
24 struct arch_cpuinfo *a = &c->arch;
26 unsigned ecx = cpuid_ecx(0x80000008);
28 a->x86_pkg_cores = (ecx & 0xff) + 1;
30 /* CPU telling us the core id bits shift? */
31 bits = (ecx >> 12) & 0xF;
33 /* Otherwise recompute */
35 while ((1 << bits) < a->x86_pkg_cores)
39 /* Determine the physical socket ID */
40 c->phys_socket_id = c->physical_id >> bits;
42 /* Determine the physical core ID (index of core in socket) */
43 c->phys_core_id = c->physical_id & ((1 << bits)-1);
47 amd_cpu(struct cpuinfo *c)
51 unsigned int eax, ebx, ecx, edx;
52 struct arch_cpuinfo *a = &c->arch;
55 * Disable TLB flush filter by setting HWCR.FFDIS on K8
56 * bit 6 of msr C001_0015
58 * Errata 63 for SH-B3 steppings
59 * Errata 122 for all steppings (F+ have it disabled by default)
61 if (a->x86_family == 15) {
62 rdmsrl(MSR_K8_HWCR, value);
64 wrmsrl(MSR_K8_HWCR, value);
68 * Bit 31 in normal CPUID used for nonstandard 3DNow ID;
69 * 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway
71 clear_bit(0*32+31, &a->x86_capability);
73 /* On C+ stepping K8 rep microcode works well for copy/memset */
75 if (a->x86_family == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
76 set_bit(X86_FEATURE_REP_GOOD, &a->x86_capability);
77 if (a->x86_family == 0x10)
78 set_bit(X86_FEATURE_REP_GOOD, &a->x86_capability);
80 /* Enable workaround for FXSAVE leak */
81 if (a->x86_family >= 6)
82 set_bit(X86_FEATURE_FXSAVE_LEAK, &a->x86_capability);
84 /* Determine L1 Cache and TLB Information */
85 if (a->extended_cpuid_level >= 0x80000005) {
86 cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
88 /* 2-MB L1 TLB (inclusive with L2 TLB) */
89 a->x86_tlb_size[INST][L1][PAGE_2MB] = (eax & 0xff);
90 a->x86_tlb_size[DATA][L1][PAGE_2MB] = ((eax >> 16) & 0xff);
92 /* 4-KB L1 TLB (inclusive with L2 TLB) */
93 a->x86_tlb_size[INST][L1][PAGE_4KB] = (ebx & 0xff);
94 a->x86_tlb_size[DATA][L1][PAGE_4KB] = ((ebx >> 16) & 0xff);
96 /* L1 Instruction Cache */
97 a->x86_cache_size[INST][L1] = (edx >> 24);
98 a->x86_cache_line[INST][L1] = (edx & 0xff);
101 a->x86_cache_size[DATA][L1] = (ecx >> 24);
102 a->x86_cache_line[DATA][L1] = (ecx & 0xff);
105 /* Determine L2 Cache and TLB Information */
106 if (a->extended_cpuid_level >= 0x80000006) {
107 cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
110 if ((eax & 0xffff0000) == 0) {
111 /* Unified I+D 2-MB L2 TLB */
112 a->x86_tlb_size[UNIF][L2][PAGE_2MB] = eax & 0xfff;
114 a->x86_tlb_size[INST][L2][PAGE_2MB] = eax & 0xfff;
115 a->x86_tlb_size[DATA][L2][PAGE_2MB] = (eax>>16) & 0xfff;
119 if ((ebx & 0xffff0000) == 0) {
120 /* Unified I+D 4-KB L2 TLB */
121 a->x86_tlb_size[UNIF][L2][PAGE_4KB] = ebx & 0xfff;
123 a->x86_tlb_size[INST][L2][PAGE_4KB] = ebx & 0xfff;
124 a->x86_tlb_size[DATA][L2][PAGE_4KB] = (ebx>>16) & 0xfff;
127 /* Unified L2 Cache */
128 a->x86_cache_size[UNIF][L2] = ecx >> 16;
129 a->x86_cache_line[UNIF][L2] = ecx & 0xff;
132 /* Determine Advanced Power Management Features */
133 if (a->extended_cpuid_level >= 0x80000007) {
134 a->x86_power = cpuid_edx(0x80000007);
137 /* Determine Maximum Address Sizes */
138 if (a->extended_cpuid_level >= 0x80000008) {
139 cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
140 a->x86_virt_bits = (eax >> 8) & 0xff;
141 a->x86_phys_bits = eax & 0xff;
144 /* a->x86_power is 8000_0007 edx. Bit 8 is constant TSC */
145 if (a->x86_power & (1<<8))
146 set_bit(X86_FEATURE_CONSTANT_TSC, &a->x86_capability);
148 /* Multi core CPU? */
149 if (a->extended_cpuid_level >= 0x80000008)
152 if (a->x86_family == 0xf || a->x86_family == 0x10 || a->x86_family == 0x11)
153 set_bit(X86_FEATURE_K8, &a->x86_capability);
155 /* RDTSC can be speculated around */
156 clear_bit(X86_FEATURE_SYNC_RDTSC, &a->x86_capability);
158 /* Family 10 doesn't support C states in MWAIT so don't use it */
159 if (a->x86_family == 0x10)
160 clear_bit(X86_FEATURE_MWAIT, &a->x86_capability);
164 intel_cpu(struct cpuinfo *c)
170 * Do some early cpuid on the boot CPU to get some parameter that are
171 * needed before check_bugs. Everything advanced is in identify_cpu
175 early_identify_cpu(struct cpuinfo *c)
177 struct arch_cpuinfo *a = &c->arch;
182 * Zero structure, except apic_id should have already been filled in.
184 uint8_t apic_id = a->apic_id;
185 memset(a, 0, sizeof(*a));
186 a->apic_id = apic_id;
189 * Set some defaults to begin with.
191 a->x86_vendor_id[0] = '\0'; /* Unset */
192 a->x86_model_id[0] = '\0'; /* Unset */
193 a->x86_clflush_size = 64;
194 a->x86_pkg_cores = 1;
195 a->max_cpu_khz = 1000000; /* start out with 1 GHz */
196 a->min_cpu_khz = a->max_cpu_khz;
197 a->cur_cpu_khz = a->max_cpu_khz;
198 a->tsc_khz = a->max_cpu_khz;
199 memset(&a->x86_capability, 0, sizeof(a->x86_capability));
201 /* Determine the CPU vendor */
202 cpuid(0x00000000, &a->cpuid_level,
203 (unsigned int *)&a->x86_vendor_id[0],
204 (unsigned int *)&a->x86_vendor_id[8],
205 (unsigned int *)&a->x86_vendor_id[4]);
207 /* Derive the vendor ID from the vendor string */
208 if (!strcmp(a->x86_vendor_id, "AuthenticAMD"))
209 a->x86_vendor = X86_VENDOR_AMD;
210 else if (!strcmp(a->x86_vendor_id, "GenuineIntel"))
211 a->x86_vendor = X86_VENDOR_INTEL;
213 a->x86_vendor = X86_VENDOR_UNKNOWN;
215 if (a->cpuid_level == 0)
216 panic("CPU only has CPUID level 0... is your CPU ancient?");
219 * Determine Intel-defined CPU features and other standard info.
220 * NOTE: Vendor-specific code may override these later.
223 &tfms, /* type, family, model, stepping */
224 &misc, /* brand, cflush sz, logical cpus, apic id */
225 &a->x86_capability[4], /* extended cpu features */
226 &a->x86_capability[0] /* cpu features */
229 /* Determine the CPU family */
230 a->x86_family = (tfms >> 8) & 0xf;
231 if (a->x86_family == 0xf)
232 a->x86_family += ((tfms >> 20) & 0xff);
234 /* Determine the CPU model */
235 a->x86_model = (tfms >> 4) & 0xf;
236 if (a->x86_family >= 0x6)
237 a->x86_model += (((tfms >> 16) & 0xf) << 4);
239 /* Determine the CPU stepping */
240 a->x86_stepping = tfms & 0xf;
242 /* Determine the CLFLUSH size, if the CPU supports CLFLUSH */
243 if (a->x86_capability[0] & (1 << X86_FEATURE_CLFLSH))
244 a->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
247 * Determine the CPU's initial local APIC ID.
248 * NOTE: The BIOS may change the CPU's Local APIC ID before
249 * passing control to the OS kernel, however the value
250 * reported by CPUID will never change. The initial APIC
251 * ID can sometimes be used to discover CPU topology.
253 a->initial_lapic_id = (misc >> 24) & 0xff;
255 /* TODO: determine page sizes supported via CPUID */
256 c->pagesz_mask = (VM_PAGE_4KB | VM_PAGE_2MB);
260 * This does the hard work of actually picking apart the CPU stuff...
266 struct cpuinfo *c = &cpu_info[this_cpu];
267 struct arch_cpuinfo *a = &c->arch;
269 early_identify_cpu(c);
271 /* Determine the extended CPUID level */
272 a->extended_cpuid_level = cpuid_eax(0x80000000);
274 /* Parse extended CPUID information */
275 if ((a->extended_cpuid_level & 0xffff0000) == 0x80000000) {
276 /* Determine AMD-defined CPU features: level 0x80000001 */
277 if (a->extended_cpuid_level >= 0x80000001) {
278 a->x86_capability[1] = cpuid_edx(0x80000001);
279 a->x86_capability[6] = cpuid_ecx(0x80000001);
282 /* Determine processor brand/model string */
283 if (a->extended_cpuid_level >= 0x80000004) {
284 unsigned int *v = (unsigned int *) a->x86_model_id;
285 cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
286 cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
287 cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
288 a->x86_model_id[48] = '\0';
290 strcpy(a->x86_model_id, "Unknown x86-64 Model");
295 * Vendor-specific initialization. In this section we
296 * canonicalize the feature flags, meaning if there are
297 * features a certain CPU supports which CPUID doesn't
298 * tell us, CPUID claiming incorrect flags, or other bugs,
299 * we handle them here.
301 * At the end of this section, c->x86_capability better
302 * indicate the features this CPU genuinely supports!
304 switch (a->x86_vendor) {
309 case X86_VENDOR_INTEL:
313 case X86_VENDOR_UNKNOWN:
315 panic("Unknown x86 CPU Vendor.");
319 * boot_cpu_data holds the common feature set between
320 * all CPUs; so make sure that we indicate which features are
321 * common between the CPUs. The first time this routine gets
322 * executed, c == &boot_cpu_data.
324 if (c != &boot_cpu_data) {
325 /* AND the already accumulated flags with these */
326 for (i = 0 ; i < NCAPINTS ; i++)
327 boot_cpu_data.arch.x86_capability[i] &= c->arch.x86_capability[i];
332 * Prints architecture specific CPU information to the console.
335 print_arch_cpuinfo(struct cpuinfo *c)
338 struct arch_cpuinfo *a = &c->arch;
342 * These flag bits must match the definitions in <arch/cpufeature.h>.
343 * NULL means this bit is undefined or reserved; either way it doesn't
344 * have meaning as far as the kernel is concerned.
346 static char *x86_cap_flags[] = {
348 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
349 "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
350 "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
351 "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
354 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
355 NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
356 NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL,
357 NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm",
360 /* Transmeta-defined */
361 "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
362 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
363 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
364 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
366 /* Other (Linux-defined) */
367 "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
368 NULL, NULL, NULL, NULL,
369 "constant_tsc", "up", NULL, "arch_perfmon",
370 "pebs", "bts", NULL, "sync_rdtsc",
371 "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
372 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
374 /* Intel-defined (#2) */
375 "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est",
376 "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
377 NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
378 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
380 /* VIA/Cyrix/Centaur-defined */
381 NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
382 "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
383 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
384 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
386 /* AMD-defined (#2) */
387 "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8_legacy",
388 "altmovcr8", "abm", "sse4a",
389 "misalignsse", "3dnowprefetch",
390 "osvw", "ibs", NULL, NULL, NULL, NULL,
391 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
392 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
394 /* Auxiliary (Linux-defined) */
395 "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
396 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
397 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
398 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
400 static char *x86_power_flags[] = {
401 "ts", /* temperature sensor */
402 "fid", /* frequency id control */
403 "vid", /* voltage id control */
404 "ttp", /* thermal trip */
409 "", /* tsc invariant mapped to constant_tsc */
413 printk(KERN_DEBUG " Vendor: %s\n", a->x86_vendor_id);
414 printk(KERN_DEBUG " Family: %u\n", a->x86_family);
415 printk(KERN_DEBUG " Model: %u (%s)\n", a->x86_model, a->x86_model_id);
416 printk(KERN_DEBUG " Stepping: %u\n", a->x86_stepping);
417 printk(KERN_DEBUG " Frequency: %u.%03u MHz (max=%u.%03u, min=%u.%03u)\n",
418 a->cur_cpu_khz / 1000, (a->cur_cpu_khz % 1000),
419 a->max_cpu_khz / 1000, (a->max_cpu_khz % 1000),
420 a->min_cpu_khz / 1000, (a->min_cpu_khz % 1000));
423 if (a->x86_cache_size[UNIF][L1] == 0) {
424 printk(KERN_DEBUG " L1 Cache: I=%u KB, D=%u KB, line size=%u bytes\n",
425 a->x86_cache_size[INST][L1],
426 a->x86_cache_size[DATA][L1],
427 a->x86_cache_line[DATA][L1]);
429 printk(KERN_DEBUG " L1 Cache: %u KB (unified I+D), line size=%u bytes\n",
430 a->x86_cache_size[UNIF][L1],
431 a->x86_cache_line[UNIF][L1]);
435 if (a->x86_cache_size[UNIF][L2] == 0) {
436 printk(KERN_DEBUG " L2 Cache: I=%u KB, D=%u KB, line size=%u bytes\n",
437 a->x86_cache_size[INST][L2],
438 a->x86_cache_size[DATA][L2],
439 a->x86_cache_line[DATA][L2]);
441 printk(KERN_DEBUG " L2 Cache: %u KB (unified I+D), line size=%u bytes\n",
442 a->x86_cache_size[UNIF][L2],
443 a->x86_cache_line[UNIF][L2]);
446 /* 4-KB Page TLB Info */
447 printk(KERN_DEBUG " 4-KB TLB: I=%u/%u entries D=%d/%d entries\n",
448 a->x86_tlb_size[INST][L1][PAGE_4KB],
449 a->x86_tlb_size[INST][L2][PAGE_4KB],
450 a->x86_tlb_size[DATA][L1][PAGE_4KB],
451 a->x86_tlb_size[DATA][L2][PAGE_4KB]
454 /* 2-MB Page TLB Info */
455 printk(KERN_DEBUG " 2-MB TLB: I=%u/%u entries D=%d/%d entries\n",
456 a->x86_tlb_size[INST][L1][PAGE_2MB],
457 a->x86_tlb_size[INST][L2][PAGE_2MB],
458 a->x86_tlb_size[DATA][L1][PAGE_2MB],
459 a->x86_tlb_size[DATA][L2][PAGE_2MB]
462 /* 1-GB Page TLB Info */
463 printk(KERN_DEBUG " 1-GB TLB: I=%u/%u entries D=%d/%d entries\n",
464 a->x86_tlb_size[INST][L1][PAGE_1GB],
465 a->x86_tlb_size[INST][L2][PAGE_1GB],
466 a->x86_tlb_size[DATA][L1][PAGE_1GB],
467 a->x86_tlb_size[DATA][L2][PAGE_1GB]
471 printk(KERN_DEBUG " Address bits: %u bits physical, %u bits virtual\n",
475 /* Bytes flushed by CLFLUSH instruction */
476 printk(KERN_DEBUG " CLFLUSH size: %u bytes\n", a->x86_clflush_size);
480 for (i = 0; i < 32*NCAPINTS; i++) {
481 if (cpu_has(c, i) && x86_cap_flags[i] != NULL) {
482 strcat(buf, x86_cap_flags[i]);
486 printk(KERN_DEBUG " CPU Features: %s\n", buf);
488 /* Power Management Features */
489 if (a->x86_power == 0) {
493 for (i = 0; i < 32; i++) {
494 if ((i < ARRAY_SIZE(x86_power_flags)) && x86_power_flags[i]) {
495 strcat(buf, x86_power_flags[i]);
500 sprintf(bit_str, "[%d] ", i);
501 strcat(buf, bit_str);
505 printk(KERN_DEBUG " Power Features: %s\n", buf);