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