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