]> git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/cpu_threads.c
529da7af5c245614056eaac1140618f92a77a750
[apple/xnu.git] / osfmk / i386 / cpu_threads.c
1 /*
2 * Copyright (c) 2003-2009 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 #include <vm/vm_kern.h>
29 #include <kern/kalloc.h>
30 #include <mach/machine.h>
31 #include <i386/cpu_threads.h>
32 #include <i386/cpuid.h>
33 #include <i386/machine_cpu.h>
34 #include <i386/pmCPU.h>
35 #include <i386/lock.h>
36
37 //#define TOPO_DEBUG 1
38 #if TOPO_DEBUG
39 void debug_topology_print(void);
40 #define DBG(x...) kprintf("DBG: " x)
41 #else
42 #define DBG(x...)
43 #endif /* TOPO_DEBUG */
44
45
46 void validate_topology(void);
47
48 /* Only for 32bit values */
49 #define bit(n) (1U << (n))
50 #define bitmask(h,l) ((bit(h)|(bit(h)-1)) & ~(bit(l)-1))
51 #define bitfield(x,h,l) (((x) & bitmask(h,l)) >> l)
52
53 x86_pkg_t *x86_pkgs = NULL;
54 uint32_t num_Lx_caches[MAX_CACHE_DEPTH] = { 0 };
55
56 static x86_pkg_t *free_pkgs = NULL;
57 static x86_die_t *free_dies = NULL;
58 static x86_core_t *free_cores = NULL;
59 static uint32_t num_dies = 0;
60
61 static x86_cpu_cache_t *x86_caches = NULL;
62 static uint32_t num_caches = 0;
63
64 static boolean_t topoParmsInited = FALSE;
65 x86_topology_parameters_t topoParms;
66
67 decl_simple_lock_data(, x86_topo_lock);
68
69 static boolean_t
70 cpu_is_hyperthreaded(void)
71 {
72 i386_cpu_info_t *cpuinfo;
73
74 cpuinfo = cpuid_info();
75 return(cpuinfo->thread_count > cpuinfo->core_count);
76 }
77
78 static x86_cpu_cache_t *
79 x86_cache_alloc(void)
80 {
81 x86_cpu_cache_t *cache;
82 int i;
83
84 if (x86_caches == NULL) {
85 cache = kalloc(sizeof(x86_cpu_cache_t) + (MAX_CPUS * sizeof(x86_lcpu_t *)));
86 if (cache == NULL)
87 return(NULL);
88 } else {
89 cache = x86_caches;
90 x86_caches = cache->next;
91 cache->next = NULL;
92 }
93
94 bzero(cache, sizeof(x86_cpu_cache_t));
95 cache->next = NULL;
96 cache->maxcpus = MAX_CPUS;
97 for (i = 0; i < cache->maxcpus; i += 1) {
98 cache->cpus[i] = NULL;
99 }
100
101 num_caches += 1;
102
103 return(cache);
104 }
105
106 static void
107 x86_LLC_info(void)
108 {
109 uint32_t index;
110 uint32_t cache_info[4];
111 uint32_t cache_level = 0;
112 uint32_t nCPUsSharing = 1;
113 i386_cpu_info_t *cpuinfo;
114
115 cpuinfo = cpuid_info();
116
117 do_cpuid(0, cache_info);
118
119 if (cache_info[eax] < 4) {
120 /*
121 * Processor does not support deterministic
122 * cache information. Set LLC sharing to 1, since
123 * we have no better information.
124 */
125 if (cpu_is_hyperthreaded()) {
126 topoParms.nCoresSharingLLC = 1;
127 topoParms.nLCPUsSharingLLC = 2;
128 topoParms.maxSharingLLC = 2;
129 } else {
130 topoParms.nCoresSharingLLC = 1;
131 topoParms.nLCPUsSharingLLC = 1;
132 topoParms.maxSharingLLC = 1;
133 }
134 return;
135 }
136
137 for (index = 0; ; index += 1) {
138 uint32_t this_level;
139
140 cache_info[eax] = 4;
141 cache_info[ecx] = index;
142 cache_info[ebx] = 0;
143 cache_info[edx] = 0;
144
145 cpuid(cache_info);
146
147 /*
148 * See if all levels have been queried.
149 */
150 if (bitfield(cache_info[eax], 4, 0) == 0)
151 break;
152
153 /*
154 * Get the current level.
155 */
156 this_level = bitfield(cache_info[eax], 7, 5);
157
158 /*
159 * Only worry about it if it's a deeper level than
160 * what we've seen before.
161 */
162 if (this_level > cache_level) {
163 cache_level = this_level;
164
165 /*
166 * Save the number of CPUs sharing this cache.
167 */
168 nCPUsSharing = bitfield(cache_info[eax], 25, 14) + 1;
169 }
170 }
171
172 /*
173 * Make the level of the LLC be 0 based.
174 */
175 topoParms.LLCDepth = cache_level - 1;
176
177 /*
178 * nCPUsSharing represents the *maximum* number of cores or
179 * logical CPUs sharing the cache.
180 */
181 topoParms.maxSharingLLC = nCPUsSharing;
182
183 topoParms.nCoresSharingLLC = nCPUsSharing;
184 topoParms.nLCPUsSharingLLC = nCPUsSharing;
185
186 /*
187 * nCPUsSharing may not be the number of *active* cores or
188 * threads that are sharing the cache.
189 */
190 if (nCPUsSharing > cpuinfo->core_count)
191 topoParms.nCoresSharingLLC = cpuinfo->core_count;
192 if (nCPUsSharing > cpuinfo->thread_count)
193 topoParms.nLCPUsSharingLLC = cpuinfo->thread_count;
194 }
195
196 static void
197 initTopoParms(void)
198 {
199 i386_cpu_info_t *cpuinfo;
200
201 cpuinfo = cpuid_info();
202
203 /*
204 * We need to start with getting the LLC information correct.
205 */
206 x86_LLC_info();
207
208 /*
209 * Compute the number of threads (logical CPUs) per core.
210 */
211 topoParms.nLThreadsPerCore = cpuinfo->thread_count / cpuinfo->core_count;
212 topoParms.nPThreadsPerCore = cpuinfo->cpuid_logical_per_package / cpuinfo->cpuid_cores_per_package;
213
214 /*
215 * Compute the number of dies per package.
216 */
217 topoParms.nLDiesPerPackage = cpuinfo->core_count / topoParms.nCoresSharingLLC;
218 topoParms.nPDiesPerPackage = cpuinfo->cpuid_cores_per_package / (topoParms.maxSharingLLC / topoParms.nPThreadsPerCore);
219
220 /*
221 * Compute the number of cores per die.
222 */
223 topoParms.nLCoresPerDie = topoParms.nCoresSharingLLC;
224 topoParms.nPCoresPerDie = (topoParms.maxSharingLLC / topoParms.nPThreadsPerCore);
225
226 /*
227 * Compute the number of threads per die.
228 */
229 topoParms.nLThreadsPerDie = topoParms.nLThreadsPerCore * topoParms.nLCoresPerDie;
230 topoParms.nPThreadsPerDie = topoParms.nPThreadsPerCore * topoParms.nPCoresPerDie;
231
232 /*
233 * Compute the number of cores per package.
234 */
235 topoParms.nLCoresPerPackage = topoParms.nLCoresPerDie * topoParms.nLDiesPerPackage;
236 topoParms.nPCoresPerPackage = topoParms.nPCoresPerDie * topoParms.nPDiesPerPackage;
237
238 /*
239 * Compute the number of threads per package.
240 */
241 topoParms.nLThreadsPerPackage = topoParms.nLThreadsPerCore * topoParms.nLCoresPerPackage;
242 topoParms.nPThreadsPerPackage = topoParms.nPThreadsPerCore * topoParms.nPCoresPerPackage;
243
244 DBG("\nLogical Topology Parameters:\n");
245 DBG("\tThreads per Core: %d\n", topoParms.nLThreadsPerCore);
246 DBG("\tCores per Die: %d\n", topoParms.nLCoresPerDie);
247 DBG("\tThreads per Die: %d\n", topoParms.nLThreadsPerDie);
248 DBG("\tDies per Package: %d\n", topoParms.nLDiesPerPackage);
249 DBG("\tCores per Package: %d\n", topoParms.nLCoresPerPackage);
250 DBG("\tThreads per Package: %d\n", topoParms.nLThreadsPerPackage);
251
252 DBG("\nPhysical Topology Parameters:\n");
253 DBG("\tThreads per Core: %d\n", topoParms.nPThreadsPerCore);
254 DBG("\tCores per Die: %d\n", topoParms.nPCoresPerDie);
255 DBG("\tThreads per Die: %d\n", topoParms.nPThreadsPerDie);
256 DBG("\tDies per Package: %d\n", topoParms.nPDiesPerPackage);
257 DBG("\tCores per Package: %d\n", topoParms.nPCoresPerPackage);
258 DBG("\tThreads per Package: %d\n", topoParms.nPThreadsPerPackage);
259
260 topoParmsInited = TRUE;
261 }
262
263 static void
264 x86_cache_free(x86_cpu_cache_t *cache)
265 {
266 num_caches -= 1;
267 if (cache->level > 0 && cache->level <= MAX_CACHE_DEPTH)
268 num_Lx_caches[cache->level - 1] -= 1;
269 cache->next = x86_caches;
270 x86_caches = cache;
271 }
272
273 /*
274 * This returns a list of cache structures that represent the
275 * caches for a CPU. Some of the structures may have to be
276 * "freed" if they are actually shared between CPUs.
277 */
278 static x86_cpu_cache_t *
279 x86_cache_list(void)
280 {
281 x86_cpu_cache_t *root = NULL;
282 x86_cpu_cache_t *cur = NULL;
283 x86_cpu_cache_t *last = NULL;
284 uint32_t index;
285 uint32_t cache_info[4];
286 uint32_t nsets;
287
288 do_cpuid(0, cache_info);
289
290 if (cache_info[eax] < 4) {
291 /*
292 * Processor does not support deterministic
293 * cache information. Don't report anything
294 */
295 return NULL;
296 }
297
298 for (index = 0; ; index += 1) {
299 cache_info[eax] = 4;
300 cache_info[ecx] = index;
301 cache_info[ebx] = 0;
302 cache_info[edx] = 0;
303
304 cpuid(cache_info);
305
306 /*
307 * See if all levels have been queried.
308 */
309 if (bitfield(cache_info[eax], 4, 0) == 0)
310 break;
311
312 cur = x86_cache_alloc();
313 if (cur == NULL) {
314 break;
315 }
316
317 cur->type = bitfield(cache_info[eax], 4, 0);
318 cur->level = bitfield(cache_info[eax], 7, 5);
319 cur->nlcpus = (bitfield(cache_info[eax], 25, 14) + 1);
320 if (cpuid_info()->cpuid_model == 26)
321 cur->nlcpus /= cpu_is_hyperthreaded() ? 1 : 2;
322 cur->maxcpus = (bitfield(cache_info[eax], 25, 14) + 1);
323 cur->line_size = bitfield(cache_info[ebx], 11, 0) + 1;
324 cur->partitions = bitfield(cache_info[ebx], 21, 12) + 1;
325 cur->ways = bitfield(cache_info[ebx], 31, 22) + 1;
326 nsets = bitfield(cache_info[ecx], 31, 0) + 1;
327 cur->cache_size = cur->line_size * cur->ways * cur->partitions * nsets;
328
329 if (last == NULL) {
330 root = cur;
331 last = cur;
332 } else {
333 last->next = cur;
334 last = cur;
335 }
336
337 cur->nlcpus = 0;
338 num_Lx_caches[cur->level - 1] += 1;
339 }
340
341 return(root);
342 }
343
344 static x86_cpu_cache_t *
345 x86_match_cache(x86_cpu_cache_t *list, x86_cpu_cache_t *matcher)
346 {
347 x86_cpu_cache_t *cur_cache;
348
349 cur_cache = list;
350 while (cur_cache != NULL) {
351 if (cur_cache->maxcpus == matcher->maxcpus
352 && cur_cache->type == matcher->type
353 && cur_cache->level == matcher->level
354 && cur_cache->ways == matcher->ways
355 && cur_cache->partitions == matcher->partitions
356 && cur_cache->line_size == matcher->line_size
357 && cur_cache->cache_size == matcher->cache_size)
358 break;
359
360 cur_cache = cur_cache->next;
361 }
362
363 return(cur_cache);
364 }
365
366 static void
367 x86_lcpu_init(int cpu)
368 {
369 cpu_data_t *cpup;
370 x86_lcpu_t *lcpu;
371 int i;
372
373 cpup = cpu_datap(cpu);
374
375 lcpu = &cpup->lcpu;
376 lcpu->lcpu = lcpu;
377 lcpu->cpu = cpup;
378 lcpu->next_in_core = NULL;
379 lcpu->next_in_die = NULL;
380 lcpu->next_in_pkg = NULL;
381 lcpu->core = NULL;
382 lcpu->die = NULL;
383 lcpu->package = NULL;
384 lcpu->cpu_num = cpu;
385 lcpu->lnum = cpu;
386 lcpu->pnum = cpup->cpu_phys_number;
387 lcpu->state = LCPU_OFF;
388 for (i = 0; i < MAX_CACHE_DEPTH; i += 1)
389 lcpu->caches[i] = NULL;
390
391 lcpu->master = (lcpu->cpu_num == (unsigned int) master_cpu);
392 lcpu->primary = (lcpu->pnum % topoParms.nPThreadsPerPackage) == 0;
393 }
394
395 static x86_core_t *
396 x86_core_alloc(int cpu)
397 {
398 x86_core_t *core;
399 cpu_data_t *cpup;
400
401 cpup = cpu_datap(cpu);
402
403 simple_lock(&x86_topo_lock);
404 if (free_cores != NULL) {
405 core = free_cores;
406 free_cores = core->next_in_die;
407 core->next_in_die = NULL;
408 simple_unlock(&x86_topo_lock);
409 } else {
410 simple_unlock(&x86_topo_lock);
411 core = kalloc(sizeof(x86_core_t));
412 if (core == NULL)
413 panic("x86_core_alloc() kalloc of x86_core_t failed!\n");
414 }
415
416 bzero((void *) core, sizeof(x86_core_t));
417
418 core->pcore_num = cpup->cpu_phys_number / topoParms.nPThreadsPerCore;
419 core->lcore_num = core->pcore_num % topoParms.nPCoresPerPackage;
420
421 core->flags = X86CORE_FL_PRESENT | X86CORE_FL_READY
422 | X86CORE_FL_HALTED | X86CORE_FL_IDLE;
423
424 return(core);
425 }
426
427 static void
428 x86_core_free(x86_core_t *core)
429 {
430 simple_lock(&x86_topo_lock);
431 core->next_in_die = free_cores;
432 free_cores = core;
433 simple_unlock(&x86_topo_lock);
434 }
435
436 static x86_pkg_t *
437 x86_package_find(int cpu)
438 {
439 x86_pkg_t *pkg;
440 cpu_data_t *cpup;
441 uint32_t pkg_num;
442
443 cpup = cpu_datap(cpu);
444
445 pkg_num = cpup->cpu_phys_number / topoParms.nPThreadsPerPackage;
446
447 pkg = x86_pkgs;
448 while (pkg != NULL) {
449 if (pkg->ppkg_num == pkg_num)
450 break;
451 pkg = pkg->next;
452 }
453
454 return(pkg);
455 }
456
457 static x86_die_t *
458 x86_die_find(int cpu)
459 {
460 x86_die_t *die;
461 x86_pkg_t *pkg;
462 cpu_data_t *cpup;
463 uint32_t die_num;
464
465 cpup = cpu_datap(cpu);
466
467 die_num = cpup->cpu_phys_number / topoParms.nPThreadsPerDie;
468
469 pkg = x86_package_find(cpu);
470 if (pkg == NULL)
471 return(NULL);
472
473 die = pkg->dies;
474 while (die != NULL) {
475 if (die->pdie_num == die_num)
476 break;
477 die = die->next_in_pkg;
478 }
479
480 return(die);
481 }
482
483 static x86_core_t *
484 x86_core_find(int cpu)
485 {
486 x86_core_t *core;
487 x86_die_t *die;
488 cpu_data_t *cpup;
489 uint32_t core_num;
490
491 cpup = cpu_datap(cpu);
492
493 core_num = cpup->cpu_phys_number / topoParms.nPThreadsPerCore;
494
495 die = x86_die_find(cpu);
496 if (die == NULL)
497 return(NULL);
498
499 core = die->cores;
500 while (core != NULL) {
501 if (core->pcore_num == core_num)
502 break;
503 core = core->next_in_die;
504 }
505
506 return(core);
507 }
508
509 void
510 x86_set_lcpu_numbers(x86_lcpu_t *lcpu)
511 {
512 lcpu->lnum = lcpu->cpu_num % topoParms.nLThreadsPerCore;
513 }
514
515 void
516 x86_set_core_numbers(x86_core_t *core, x86_lcpu_t *lcpu)
517 {
518 core->pcore_num = lcpu->cpu_num / topoParms.nLThreadsPerCore;
519 core->lcore_num = core->pcore_num % topoParms.nLCoresPerDie;
520 }
521
522 void
523 x86_set_die_numbers(x86_die_t *die, x86_lcpu_t *lcpu)
524 {
525 die->pdie_num = lcpu->cpu_num / (topoParms.nLThreadsPerCore * topoParms.nLCoresPerDie);
526 die->ldie_num = die->pdie_num % topoParms.nLDiesPerPackage;
527 }
528
529 void
530 x86_set_pkg_numbers(x86_pkg_t *pkg, x86_lcpu_t *lcpu)
531 {
532 pkg->ppkg_num = lcpu->cpu_num / topoParms.nLThreadsPerPackage;
533 pkg->lpkg_num = pkg->ppkg_num;
534 }
535
536 static x86_die_t *
537 x86_die_alloc(int cpu)
538 {
539 x86_die_t *die;
540 cpu_data_t *cpup;
541
542 cpup = cpu_datap(cpu);
543
544 simple_lock(&x86_topo_lock);
545 if (free_dies != NULL) {
546 die = free_dies;
547 free_dies = die->next_in_pkg;
548 die->next_in_pkg = NULL;
549 simple_unlock(&x86_topo_lock);
550 } else {
551 simple_unlock(&x86_topo_lock);
552 die = kalloc(sizeof(x86_die_t));
553 if (die == NULL)
554 panic("x86_die_alloc() kalloc of x86_die_t failed!\n");
555 }
556
557 bzero((void *) die, sizeof(x86_die_t));
558
559 die->pdie_num = cpup->cpu_phys_number / topoParms.nPThreadsPerDie;
560
561 die->ldie_num = num_dies;
562 atomic_incl((long *) &num_dies, 1);
563
564 die->flags = X86DIE_FL_PRESENT;
565 return(die);
566 }
567
568 static void
569 x86_die_free(x86_die_t *die)
570 {
571 simple_lock(&x86_topo_lock);
572 die->next_in_pkg = free_dies;
573 free_dies = die;
574 atomic_decl((long *) &num_dies, 1);
575 simple_unlock(&x86_topo_lock);
576 }
577
578 static x86_pkg_t *
579 x86_package_alloc(int cpu)
580 {
581 x86_pkg_t *pkg;
582 cpu_data_t *cpup;
583
584 cpup = cpu_datap(cpu);
585
586 simple_lock(&x86_topo_lock);
587 if (free_pkgs != NULL) {
588 pkg = free_pkgs;
589 free_pkgs = pkg->next;
590 pkg->next = NULL;
591 simple_unlock(&x86_topo_lock);
592 } else {
593 simple_unlock(&x86_topo_lock);
594 pkg = kalloc(sizeof(x86_pkg_t));
595 if (pkg == NULL)
596 panic("x86_package_alloc() kalloc of x86_pkg_t failed!\n");
597 }
598
599 bzero((void *) pkg, sizeof(x86_pkg_t));
600
601 pkg->ppkg_num = cpup->cpu_phys_number / topoParms.nPThreadsPerPackage;
602
603 pkg->lpkg_num = topoParms.nPackages;
604 atomic_incl((long *) &topoParms.nPackages, 1);
605
606 pkg->flags = X86PKG_FL_PRESENT | X86PKG_FL_READY;
607 return(pkg);
608 }
609
610 static void
611 x86_package_free(x86_pkg_t *pkg)
612 {
613 simple_lock(&x86_topo_lock);
614 pkg->next = free_pkgs;
615 free_pkgs = pkg;
616 atomic_decl((long *) &topoParms.nPackages, 1);
617 simple_unlock(&x86_topo_lock);
618 }
619
620 static void
621 x86_cache_add_lcpu(x86_cpu_cache_t *cache, x86_lcpu_t *lcpu)
622 {
623 x86_cpu_cache_t *cur_cache;
624 int i;
625
626 /*
627 * Put the new CPU into the list of the cache.
628 */
629 cur_cache = lcpu->caches[cache->level - 1];
630 lcpu->caches[cache->level - 1] = cache;
631 cache->next = cur_cache;
632 cache->nlcpus += 1;
633 for (i = 0; i < cache->nlcpus; i += 1) {
634 if (cache->cpus[i] == NULL) {
635 cache->cpus[i] = lcpu;
636 break;
637 }
638 }
639 }
640
641 static void
642 x86_lcpu_add_caches(x86_lcpu_t *lcpu)
643 {
644 x86_cpu_cache_t *list;
645 x86_cpu_cache_t *cur;
646 x86_cpu_cache_t *match;
647 x86_die_t *die;
648 x86_core_t *core;
649 x86_lcpu_t *cur_lcpu;
650 uint32_t level;
651 boolean_t found = FALSE;
652
653 assert(lcpu != NULL);
654
655 /*
656 * Add the cache data to the topology.
657 */
658 list = x86_cache_list();
659
660 simple_lock(&x86_topo_lock);
661
662 while (list != NULL) {
663 /*
664 * Remove the cache from the front of the list.
665 */
666 cur = list;
667 list = cur->next;
668 cur->next = NULL;
669 level = cur->level - 1;
670
671 /*
672 * If the cache isn't shared then just put it where it
673 * belongs.
674 */
675 if (cur->maxcpus == 1) {
676 x86_cache_add_lcpu(cur, lcpu);
677 continue;
678 }
679
680 /*
681 * We'll assume that all of the caches at a particular level
682 * have the same sharing. So if we have a cache already at
683 * this level, we'll just skip looking for the match.
684 */
685 if (lcpu->caches[level] != NULL) {
686 x86_cache_free(cur);
687 continue;
688 }
689
690 /*
691 * This is a shared cache, so we have to figure out if
692 * this is the first time we've seen this cache. We do
693 * this by searching through the topology and seeing if
694 * this cache is already described.
695 *
696 * Assume that L{LLC-1} are all at the core level and that
697 * LLC is shared at the die level.
698 */
699 if (level < topoParms.LLCDepth) {
700 /*
701 * Shared at the core.
702 */
703 core = lcpu->core;
704 cur_lcpu = core->lcpus;
705 while (cur_lcpu != NULL) {
706 /*
707 * Skip ourselves.
708 */
709 if (cur_lcpu == lcpu) {
710 cur_lcpu = cur_lcpu->next_in_core;
711 continue;
712 }
713
714 /*
715 * If there's a cache on this logical CPU,
716 * then use that one.
717 */
718 match = x86_match_cache(cur_lcpu->caches[level], cur);
719 if (match != NULL) {
720 x86_cache_free(cur);
721 x86_cache_add_lcpu(match, lcpu);
722 found = TRUE;
723 break;
724 }
725
726 cur_lcpu = cur_lcpu->next_in_core;
727 }
728 } else {
729 /*
730 * Shared at the die.
731 */
732 die = lcpu->die;
733 cur_lcpu = die->lcpus;
734 while (cur_lcpu != NULL) {
735 /*
736 * Skip ourselves.
737 */
738 if (cur_lcpu == lcpu) {
739 cur_lcpu = cur_lcpu->next_in_die;
740 continue;
741 }
742
743 /*
744 * If there's a cache on this logical CPU,
745 * then use that one.
746 */
747 match = x86_match_cache(cur_lcpu->caches[level], cur);
748 if (match != NULL) {
749 x86_cache_free(cur);
750 x86_cache_add_lcpu(match, lcpu);
751 found = TRUE;
752 break;
753 }
754
755 cur_lcpu = cur_lcpu->next_in_die;
756 }
757 }
758
759 /*
760 * If a shared cache wasn't found, then this logical CPU must
761 * be the first one encountered.
762 */
763 if (!found) {
764 x86_cache_add_lcpu(cur, lcpu);
765 }
766 }
767
768 simple_unlock(&x86_topo_lock);
769 }
770
771 static void
772 x86_core_add_lcpu(x86_core_t *core, x86_lcpu_t *lcpu)
773 {
774 assert(core != NULL);
775 assert(lcpu != NULL);
776
777 simple_lock(&x86_topo_lock);
778
779 lcpu->next_in_core = core->lcpus;
780 lcpu->core = core;
781 core->lcpus = lcpu;
782 core->num_lcpus += 1;
783 simple_unlock(&x86_topo_lock);
784 }
785
786 static void
787 x86_die_add_lcpu(x86_die_t *die, x86_lcpu_t *lcpu)
788 {
789 assert(die != NULL);
790 assert(lcpu != NULL);
791
792 lcpu->next_in_die = die->lcpus;
793 lcpu->die = die;
794 die->lcpus = lcpu;
795 }
796
797 static void
798 x86_die_add_core(x86_die_t *die, x86_core_t *core)
799 {
800 assert(die != NULL);
801 assert(core != NULL);
802
803 core->next_in_die = die->cores;
804 core->die = die;
805 die->cores = core;
806 die->num_cores += 1;
807 }
808
809 static void
810 x86_package_add_lcpu(x86_pkg_t *pkg, x86_lcpu_t *lcpu)
811 {
812 assert(pkg != NULL);
813 assert(lcpu != NULL);
814
815 lcpu->next_in_pkg = pkg->lcpus;
816 lcpu->package = pkg;
817 pkg->lcpus = lcpu;
818 }
819
820 static void
821 x86_package_add_core(x86_pkg_t *pkg, x86_core_t *core)
822 {
823 assert(pkg != NULL);
824 assert(core != NULL);
825
826 core->next_in_pkg = pkg->cores;
827 core->package = pkg;
828 pkg->cores = core;
829 }
830
831 static void
832 x86_package_add_die(x86_pkg_t *pkg, x86_die_t *die)
833 {
834 assert(pkg != NULL);
835 assert(die != NULL);
836
837 die->next_in_pkg = pkg->dies;
838 die->package = pkg;
839 pkg->dies = die;
840 pkg->num_dies += 1;
841 }
842
843 void *
844 cpu_thread_alloc(int cpu)
845 {
846 x86_core_t *core = NULL;
847 x86_die_t *die = NULL;
848 x86_pkg_t *pkg = NULL;
849 cpu_data_t *cpup;
850 uint32_t phys_cpu;
851
852 /*
853 * Only allow one to manipulate the topology at a time.
854 */
855 simple_lock(&x86_topo_lock);
856
857 /*
858 * Make sure all of the topology parameters have been initialized.
859 */
860 if (!topoParmsInited)
861 initTopoParms();
862
863 cpup = cpu_datap(cpu);
864
865 phys_cpu = cpup->cpu_phys_number;
866
867 x86_lcpu_init(cpu);
868
869 /*
870 * Assume that all cpus have the same features.
871 */
872 if (cpu_is_hyperthreaded()) {
873 cpup->cpu_threadtype = CPU_THREADTYPE_INTEL_HTT;
874 } else {
875 cpup->cpu_threadtype = CPU_THREADTYPE_NONE;
876 }
877
878 /*
879 * Get the package that the logical CPU is in.
880 */
881 do {
882 pkg = x86_package_find(cpu);
883 if (pkg == NULL) {
884 /*
885 * Package structure hasn't been created yet, do it now.
886 */
887 simple_unlock(&x86_topo_lock);
888 pkg = x86_package_alloc(cpu);
889 simple_lock(&x86_topo_lock);
890 if (x86_package_find(cpu) != NULL) {
891 x86_package_free(pkg);
892 continue;
893 }
894
895 /*
896 * Add the new package to the global list of packages.
897 */
898 pkg->next = x86_pkgs;
899 x86_pkgs = pkg;
900 }
901 } while (pkg == NULL);
902
903 /*
904 * Get the die that the logical CPU is in.
905 */
906 do {
907 die = x86_die_find(cpu);
908 if (die == NULL) {
909 /*
910 * Die structure hasn't been created yet, do it now.
911 */
912 simple_unlock(&x86_topo_lock);
913 die = x86_die_alloc(cpu);
914 simple_lock(&x86_topo_lock);
915 if (x86_die_find(cpu) != NULL) {
916 x86_die_free(die);
917 continue;
918 }
919
920 /*
921 * Add the die to the package.
922 */
923 x86_package_add_die(pkg, die);
924 }
925 } while (die == NULL);
926
927 /*
928 * Get the core for this logical CPU.
929 */
930 do {
931 core = x86_core_find(cpu);
932 if (core == NULL) {
933 /*
934 * Allocate the core structure now.
935 */
936 simple_unlock(&x86_topo_lock);
937 core = x86_core_alloc(cpu);
938 simple_lock(&x86_topo_lock);
939 if (x86_core_find(cpu) != NULL) {
940 x86_core_free(core);
941 continue;
942 }
943
944 /*
945 * Add the core to the die & package.
946 */
947 x86_die_add_core(die, core);
948 x86_package_add_core(pkg, core);
949 machine_info.physical_cpu_max += 1;
950 }
951 } while (core == NULL);
952
953
954 /*
955 * Done manipulating the topology, so others can get in.
956 */
957 machine_info.logical_cpu_max += 1;
958 simple_unlock(&x86_topo_lock);
959
960 /*
961 * Add the logical CPU to the other topology structures.
962 */
963 x86_core_add_lcpu(core, &cpup->lcpu);
964 x86_die_add_lcpu(core->die, &cpup->lcpu);
965 x86_package_add_lcpu(core->package, &cpup->lcpu);
966 x86_lcpu_add_caches(&cpup->lcpu);
967
968 return (void *) core;
969 }
970
971 void
972 cpu_thread_init(void)
973 {
974 int my_cpu = get_cpu_number();
975 cpu_data_t *cpup = current_cpu_datap();
976 x86_core_t *core;
977 static int initialized = 0;
978
979 /*
980 * If we're the boot processor, we do all of the initialization of
981 * the CPU topology infrastructure.
982 */
983 if (my_cpu == master_cpu && !initialized) {
984 simple_lock_init(&x86_topo_lock, 0);
985
986 /*
987 * Put this logical CPU into the physical CPU topology.
988 */
989 cpup->lcpu.core = cpu_thread_alloc(my_cpu);
990
991 initialized = 1;
992 }
993
994 /*
995 * Do the CPU accounting.
996 */
997 core = cpup->lcpu.core;
998 simple_lock(&x86_topo_lock);
999 machine_info.logical_cpu += 1;
1000 if (core->active_lcpus == 0)
1001 machine_info.physical_cpu += 1;
1002 core->active_lcpus += 1;
1003 simple_unlock(&x86_topo_lock);
1004
1005 pmCPUMarkRunning(cpup);
1006 etimer_resync_deadlines();
1007 }
1008
1009 /*
1010 * Called for a cpu to halt permanently
1011 * (as opposed to halting and expecting an interrupt to awaken it).
1012 */
1013 void
1014 cpu_thread_halt(void)
1015 {
1016 x86_core_t *core;
1017 cpu_data_t *cpup = current_cpu_datap();
1018
1019 simple_lock(&x86_topo_lock);
1020 machine_info.logical_cpu -= 1;
1021 core = cpup->lcpu.core;
1022 core->active_lcpus -= 1;
1023 if (core->active_lcpus == 0)
1024 machine_info.physical_cpu -= 1;
1025 simple_unlock(&x86_topo_lock);
1026
1027 /*
1028 * Let the power management code determine the best way to "stop"
1029 * the processor.
1030 */
1031 ml_set_interrupts_enabled(FALSE);
1032 while (1) {
1033 pmCPUHalt(PM_HALT_NORMAL);
1034 }
1035 /* NOT REACHED */
1036 }
1037
1038 /*
1039 * Validates that the topology was built correctly. Must be called only
1040 * after the complete topology is built and no other changes are being made.
1041 */
1042 void
1043 validate_topology(void)
1044 {
1045 x86_pkg_t *pkg;
1046 x86_die_t *die;
1047 x86_core_t *core;
1048 x86_lcpu_t *lcpu;
1049 uint32_t nDies;
1050 uint32_t nCores;
1051 uint32_t nCPUs;
1052
1053 /*
1054 * XXX
1055 *
1056 * Right now this only works if the number of CPUs started is the total
1057 * number of CPUs. However, when specifying cpus=n the topology is only
1058 * partially constructed and the checks below will fail.
1059 *
1060 * We should *always* build the complete topology and only start the CPUs
1061 * indicated by cpus=n. Until that happens, this code will not check the
1062 * topology if the number of cpus defined is < that described the the
1063 * topology parameters.
1064 */
1065 nCPUs = topoParms.nPackages * topoParms.nLThreadsPerPackage;
1066 if (nCPUs > real_ncpus)
1067 return;
1068
1069 pkg = x86_pkgs;
1070 while (pkg != NULL) {
1071 /*
1072 * Make sure that the package has the correct number of dies.
1073 */
1074 nDies = 0;
1075 die = pkg->dies;
1076 while (die != NULL) {
1077 if (die->package == NULL)
1078 panic("Die(%d)->package is NULL",
1079 die->pdie_num);
1080 if (die->package != pkg)
1081 panic("Die %d points to package %d, should be %d",
1082 die->pdie_num, die->package->lpkg_num, pkg->lpkg_num);
1083
1084 DBG("Die(%d)->package %d\n",
1085 die->pdie_num, pkg->lpkg_num);
1086
1087 /*
1088 * Make sure that the die has the correct number of cores.
1089 */
1090 DBG("Die(%d)->cores: ");
1091 nCores = 0;
1092 core = die->cores;
1093 while (core != NULL) {
1094 if (core->die == NULL)
1095 panic("Core(%d)->die is NULL",
1096 core->pcore_num);
1097 if (core->die != die)
1098 panic("Core %d points to die %d, should be %d",
1099 core->pcore_num, core->die->pdie_num, die->pdie_num);
1100 nCores += 1;
1101 DBG("%d ", core->pcore_num);
1102 core = core->next_in_die;
1103 }
1104 DBG("\n");
1105
1106 if (nCores != topoParms.nLCoresPerDie)
1107 panic("Should have %d Cores, but only found %d for Die %d",
1108 topoParms.nLCoresPerDie, nCores, die->pdie_num);
1109
1110 /*
1111 * Make sure that the die has the correct number of CPUs.
1112 */
1113 DBG("Die(%d)->lcpus: ", die->pdie_num);
1114 nCPUs = 0;
1115 lcpu = die->lcpus;
1116 while (lcpu != NULL) {
1117 if (lcpu->die == NULL)
1118 panic("CPU(%d)->die is NULL",
1119 lcpu->cpu_num);
1120 if (lcpu->die != die)
1121 panic("CPU %d points to die %d, should be %d",
1122 lcpu->cpu_num, lcpu->die->pdie_num, die->pdie_num);
1123 nCPUs += 1;
1124 DBG("%d ", lcpu->cpu_num);
1125 lcpu = lcpu->next_in_die;
1126 }
1127 DBG("\n");
1128
1129 if (nCPUs != topoParms.nLThreadsPerDie)
1130 panic("Should have %d Threads, but only found %d for Die %d",
1131 topoParms.nLThreadsPerDie, nCPUs, die->pdie_num);
1132
1133 nDies += 1;
1134 die = die->next_in_pkg;
1135 }
1136
1137 if (nDies != topoParms.nLDiesPerPackage)
1138 panic("Should have %d Dies, but only found %d for package %d",
1139 topoParms.nLDiesPerPackage, nDies, pkg->lpkg_num);
1140
1141 /*
1142 * Make sure that the package has the correct number of cores.
1143 */
1144 nCores = 0;
1145 core = pkg->cores;
1146 while (core != NULL) {
1147 if (core->package == NULL)
1148 panic("Core(%d)->package is NULL",
1149 core->pcore_num);
1150 if (core->package != pkg)
1151 panic("Core %d points to package %d, should be %d",
1152 core->pcore_num, core->package->lpkg_num, pkg->lpkg_num);
1153 DBG("Core(%d)->package %d\n",
1154 core->pcore_num, pkg->lpkg_num);
1155
1156 /*
1157 * Make sure that the core has the correct number of CPUs.
1158 */
1159 nCPUs = 0;
1160 lcpu = core->lcpus;
1161 DBG("Core(%d)->lcpus: ");
1162 while (lcpu != NULL) {
1163 if (lcpu->core == NULL)
1164 panic("CPU(%d)->core is NULL",
1165 lcpu->cpu_num);
1166 if (lcpu->core != core)
1167 panic("CPU %d points to core %d, should be %d",
1168 lcpu->cpu_num, lcpu->core->pcore_num, core->pcore_num);
1169 DBG("%d ", lcpu->cpu_num);
1170 nCPUs += 1;
1171 lcpu = lcpu->next_in_core;
1172 }
1173 DBG("\n");
1174
1175 if (nCPUs != topoParms.nLThreadsPerCore)
1176 panic("Should have %d Threads, but only found %d for Core %d",
1177 topoParms.nLThreadsPerCore, nCPUs, core->pcore_num);
1178 nCores += 1;
1179 core = core->next_in_pkg;
1180 }
1181
1182 if (nCores != topoParms.nLCoresPerPackage)
1183 panic("Should have %d Cores, but only found %d for package %d",
1184 topoParms.nLCoresPerPackage, nCores, pkg->lpkg_num);
1185
1186 /*
1187 * Make sure that the package has the correct number of CPUs.
1188 */
1189 nCPUs = 0;
1190 lcpu = pkg->lcpus;
1191 while (lcpu != NULL) {
1192 if (lcpu->package == NULL)
1193 panic("CPU(%d)->package is NULL",
1194 lcpu->cpu_num);
1195 if (lcpu->package != pkg)
1196 panic("CPU %d points to package %d, should be %d",
1197 lcpu->cpu_num, lcpu->package->lpkg_num, pkg->lpkg_num);
1198 DBG("CPU(%d)->package %d\n",
1199 lcpu->cpu_num, pkg->lpkg_num);
1200 nCPUs += 1;
1201 lcpu = lcpu->next_in_pkg;
1202 }
1203
1204 if (nCPUs != topoParms.nLThreadsPerPackage)
1205 panic("Should have %d Threads, but only found %d for package %d",
1206 topoParms.nLThreadsPerPackage, nCPUs, pkg->lpkg_num);
1207
1208 pkg = pkg->next;
1209 }
1210 }
1211
1212 #if TOPO_DEBUG
1213 /*
1214 * Prints out the topology
1215 */
1216 void
1217 debug_topology_print(void)
1218 {
1219 x86_pkg_t *pkg;
1220 x86_die_t *die;
1221 x86_core_t *core;
1222 x86_lcpu_t *cpu;
1223
1224 pkg = x86_pkgs;
1225 while (pkg != NULL) {
1226 kprintf("Package:\n");
1227 kprintf(" Physical: %d\n", pkg->ppkg_num);
1228 kprintf(" Logical: %d\n", pkg->lpkg_num);
1229
1230 die = pkg->dies;
1231 while (die != NULL) {
1232 kprintf(" Die:\n");
1233 kprintf(" Physical: %d\n", die->pdie_num);
1234 kprintf(" Logical: %d\n", die->ldie_num);
1235
1236 core = die->cores;
1237 while (core != NULL) {
1238 kprintf(" Core:\n");
1239 kprintf(" Physical: %d\n", core->pcore_num);
1240 kprintf(" Logical: %d\n", core->lcore_num);
1241
1242 cpu = core->lcpus;
1243 while (cpu != NULL) {
1244 kprintf(" LCPU:\n");
1245 kprintf(" CPU #: %d\n", cpu->cpu_num);
1246 kprintf(" Physical: %d\n", cpu->pnum);
1247 kprintf(" Logical: %d\n", cpu->lnum);
1248 kprintf(" Flags: ");
1249 if (cpu->master)
1250 kprintf("MASTER ");
1251 if (cpu->primary)
1252 kprintf("PRIMARY");
1253 if (!cpu->master && !cpu->primary)
1254 kprintf("(NONE)");
1255 kprintf("\n");
1256
1257 cpu = cpu->next_in_core;
1258 }
1259
1260 core = core->next_in_die;
1261 }
1262
1263 die = die->next_in_pkg;
1264 }
1265
1266 pkg = pkg->next;
1267 }
1268 }
1269 #endif /* TOPO_DEBUG */