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