Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / arch / x86_64 / kernel / cpuinfo.c
1 #include <lwk/kernel.h>
2 #include <lwk/init.h>
3 #include <lwk/smp.h>
4 #include <lwk/cpuinfo.h>
5 #include <lwk/aspace.h>
6 #include <arch/processor.h>
7 #include <arch/proto.h>
8
9 /**
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.
14  */
15 struct cpuinfo boot_cpu_data;
16
17 /**
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.
20  */
21 static void __init
22 amd_detect_cmp(struct cpuinfo *c)
23 {
24         struct arch_cpuinfo *a = &c->arch;
25         unsigned bits;
26         unsigned ecx = cpuid_ecx(0x80000008);
27
28         a->x86_pkg_cores = (ecx & 0xff) + 1;
29
30         /* CPU telling us the core id bits shift? */
31         bits = (ecx >> 12) & 0xF;
32
33         /* Otherwise recompute */
34         if (bits == 0) {
35                 while ((1 << bits) < a->x86_pkg_cores)
36                         bits++;
37         }
38
39         /* Determine the physical socket ID */
40         c->phys_socket_id = c->physical_id >> bits;
41
42         /* Determine the physical core ID (index of core in socket) */
43         c->phys_core_id = c->physical_id & ((1 << bits)-1);
44 }
45
46 static void __init
47 amd_cpu(struct cpuinfo *c)
48 {
49         unsigned level;
50         unsigned long value;
51         unsigned int eax, ebx, ecx, edx;
52         struct arch_cpuinfo *a = &c->arch;
53
54         /*
55          * Disable TLB flush filter by setting HWCR.FFDIS on K8
56          * bit 6 of msr C001_0015
57          *
58          * Errata 63 for SH-B3 steppings
59          * Errata 122 for all steppings (F+ have it disabled by default)
60          */
61         if (a->x86_family == 15) {
62                 rdmsrl(MSR_K8_HWCR, value);
63                 value |= 1 << 6;
64                 wrmsrl(MSR_K8_HWCR, value);
65         }
66
67         /*
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
70          */
71         clear_bit(0*32+31, &a->x86_capability);
72         
73         /* On C+ stepping K8 rep microcode works well for copy/memset */
74         level = cpuid_eax(1);
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);
79
80         /* Enable workaround for FXSAVE leak */
81         if (a->x86_family >= 6)
82                 set_bit(X86_FEATURE_FXSAVE_LEAK, &a->x86_capability);
83
84         /* Determine L1 Cache and TLB Information */
85         if (a->extended_cpuid_level >= 0x80000005) {
86                 cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
87
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);
91
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);
95
96                 /* L1 Instruction Cache */
97                 a->x86_cache_size[INST][L1] = (edx >> 24);
98                 a->x86_cache_line[INST][L1] = (edx & 0xff);
99
100                 /* L1 Data Cache */
101                 a->x86_cache_size[DATA][L1] = (ecx >> 24);
102                 a->x86_cache_line[DATA][L1] = (ecx & 0xff);
103         }
104
105         /* Determine L2 Cache and TLB Information */
106         if (a->extended_cpuid_level >= 0x80000006) {
107                 cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
108
109                 /* 2-MB L2 TLB */
110                 if ((eax & 0xffff0000) == 0) {
111                         /* Unified I+D 2-MB L2 TLB */
112                         a->x86_tlb_size[UNIF][L2][PAGE_2MB] = eax & 0xfff;
113                 } else {
114                         a->x86_tlb_size[INST][L2][PAGE_2MB] = eax & 0xfff;
115                         a->x86_tlb_size[DATA][L2][PAGE_2MB] = (eax>>16) & 0xfff;
116                 }
117
118                 /* 4-KB L2 TLB */
119                 if ((ebx & 0xffff0000) == 0) {
120                         /* Unified I+D 4-KB L2 TLB */
121                         a->x86_tlb_size[UNIF][L2][PAGE_4KB] = ebx & 0xfff;
122                 } else {
123                         a->x86_tlb_size[INST][L2][PAGE_4KB] = ebx & 0xfff;
124                         a->x86_tlb_size[DATA][L2][PAGE_4KB] = (ebx>>16) & 0xfff;
125                 }
126
127                 /* Unified L2 Cache */
128                 a->x86_cache_size[UNIF][L2] = ecx >> 16;
129                 a->x86_cache_line[UNIF][L2] = ecx & 0xff;
130         }
131
132         /* Determine Advanced Power Management Features */
133         if (a->extended_cpuid_level >= 0x80000007) {
134                 a->x86_power = cpuid_edx(0x80000007);
135         }
136
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;
142         }
143
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);
147
148         /* Multi core CPU? */
149         if (a->extended_cpuid_level >= 0x80000008)
150                 amd_detect_cmp(c);
151
152         if (a->x86_family == 0xf || a->x86_family == 0x10 || a->x86_family == 0x11)
153                 set_bit(X86_FEATURE_K8, &a->x86_capability);
154
155         /* RDTSC can be speculated around */
156         clear_bit(X86_FEATURE_SYNC_RDTSC, &a->x86_capability);
157
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);
161 }
162
163 static void __init
164 intel_cpu(struct cpuinfo *c)
165 {
166         /* TODO */
167 }
168
169 /*
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
172  * below.
173  */
174 void __init
175 early_identify_cpu(struct cpuinfo *c)
176 {
177         struct arch_cpuinfo *a = &c->arch;
178         uint32_t tfms;
179         uint32_t misc;
180
181         /*
182          * Zero structure, except apic_id should have already been filled in.
183          */
184         uint8_t apic_id = a->apic_id;
185         memset(a, 0, sizeof(*a));
186         a->apic_id = apic_id;
187
188         /*
189          * Set some defaults to begin with.
190          */
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));
200
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]);
206
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;
212         else
213                 a->x86_vendor = X86_VENDOR_UNKNOWN;
214
215         if (a->cpuid_level == 0)
216                 panic("CPU only has CPUID level 0... is your CPU ancient?");
217
218         /*
219          * Determine Intel-defined CPU features and other standard info.
220          * NOTE: Vendor-specific code may override these later.
221          */
222         cpuid(0x00000001,
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 */
227         );
228
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);
233
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);
238
239         /* Determine the CPU stepping */
240         a->x86_stepping = tfms & 0xf;
241
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;
245
246         /*
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.
252          */
253         a->initial_lapic_id = (misc >> 24) & 0xff;
254
255         /* TODO: determine page sizes supported via CPUID */
256         c->pagesz_mask = (VM_PAGE_4KB | VM_PAGE_2MB);
257 }
258
259 /*
260  * This does the hard work of actually picking apart the CPU stuff...
261  */
262 void __init
263 identify_cpu(void)
264 {
265         int i;
266         struct cpuinfo *c = &cpu_info[this_cpu];
267         struct arch_cpuinfo *a = &c->arch;
268
269         early_identify_cpu(c);
270
271         /* Determine the extended CPUID level */
272         a->extended_cpuid_level = cpuid_eax(0x80000000);
273
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);
280                 }
281
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';
289                 } else {
290                         strcpy(a->x86_model_id, "Unknown x86-64 Model");
291                 }
292         }
293
294         /*
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.
300          *
301          * At the end of this section, c->x86_capability better
302          * indicate the features this CPU genuinely supports!
303          */
304         switch (a->x86_vendor) {
305         case X86_VENDOR_AMD:
306                 amd_cpu(c);
307                 break;
308
309         case X86_VENDOR_INTEL:
310                 intel_cpu(c);
311                 break;
312
313         case X86_VENDOR_UNKNOWN:
314         default:
315                 panic("Unknown x86 CPU Vendor.");
316         }
317
318         /*
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.
323          */
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];
328         }
329 }
330
331 /**
332  * Prints architecture specific CPU information to the console.
333  */
334 void
335 print_arch_cpuinfo(struct cpuinfo *c)
336 {
337         int i;
338         struct arch_cpuinfo *a = &c->arch;
339         char buf[1024];
340
341         /* 
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.
345          */
346         static char *x86_cap_flags[] = {
347                 /* Intel-defined */
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",
352
353                 /* AMD-defined */
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",
358                 "3dnowext", "3dnow",
359
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,
365
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,
373
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,
379
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,
385
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,
393
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,
399         };
400         static char *x86_power_flags[] = { 
401                 "ts",   /* temperature sensor */
402                 "fid",  /* frequency id control */
403                 "vid",  /* voltage id control */
404                 "ttp",  /* thermal trip */
405                 "tm",
406                 "stc",
407                 "100mhzsteps",
408                 "hwpstate",
409                 "",     /* tsc invariant mapped to constant_tsc */
410                 /* nothing */
411         };
412
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));
421
422         /* L1 Cache Info */
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]);
428         } else {
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]);
432         }
433
434         /* L2 Cache Info */
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]);
440         } else {
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]);
444         }
445
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]
452         );
453
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]
460         );
461
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]
468         );
469
470         /* Address bits */
471         printk(KERN_DEBUG "  Address bits:   %u bits physical, %u bits virtual\n",
472                 a->x86_phys_bits,
473                 a->x86_virt_bits);
474
475         /* Bytes flushed by CLFLUSH instruction */
476         printk(KERN_DEBUG "  CLFLUSH size:   %u bytes\n", a->x86_clflush_size);
477
478         /* CPU Features */
479         buf[0] = '\0';
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]);
483                         strcat(buf, " ");
484                 }
485         }
486         printk(KERN_DEBUG "  CPU Features:   %s\n", buf);
487
488         /* Power Management Features */
489         if (a->x86_power == 0) {
490                 strcpy(buf, "none");
491         } else {
492                 buf[0] = '\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]);
496                                 strcat(buf, " ");
497                         } else {
498                                 char bit_str[7];
499                                 bit_str[0] = '\0';
500                                 sprintf(bit_str, "[%d] ", i);
501                                 strcat(buf, bit_str);
502                         }
503                 }
504         }
505         printk(KERN_DEBUG "  Power Features: %s\n", buf);
506 }
507