2 * Copyright (c) 2003-2010 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
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>
38 //#define TOPO_DEBUG 1
40 void debug_topology_print(void);
41 #define DBG(x...) kprintf("DBG: " x)
44 #endif /* TOPO_DEBUG */
47 void validate_topology(void);
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)
54 x86_pkg_t
*x86_pkgs
= NULL
;
55 uint32_t num_Lx_caches
[MAX_CACHE_DEPTH
] = { 0 };
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;
62 static x86_cpu_cache_t
*x86_caches
= NULL
;
63 static uint32_t num_caches
= 0;
65 static boolean_t topoParmsInited
= FALSE
;
66 x86_topology_parameters_t topoParms
;
68 decl_simple_lock_data(, x86_topo_lock
);
71 cpu_is_hyperthreaded(void)
73 i386_cpu_info_t
*cpuinfo
;
75 cpuinfo
= cpuid_info();
76 return(cpuinfo
->thread_count
> cpuinfo
->core_count
);
79 static x86_cpu_cache_t
*
82 x86_cpu_cache_t
*cache
;
85 if (x86_caches
== NULL
) {
86 cache
= kalloc(sizeof(x86_cpu_cache_t
) + (MAX_CPUS
* sizeof(x86_lcpu_t
*)));
91 x86_caches
= cache
->next
;
95 bzero(cache
, sizeof(x86_cpu_cache_t
));
97 cache
->maxcpus
= MAX_CPUS
;
98 for (i
= 0; i
< cache
->maxcpus
; i
+= 1) {
99 cache
->cpus
[i
] = NULL
;
111 uint32_t cache_info
[4];
112 uint32_t cache_level
= 0;
113 uint32_t nCPUsSharing
= 1;
114 i386_cpu_info_t
*cpuinfo
;
116 cpuinfo
= cpuid_info();
118 do_cpuid(0, cache_info
);
120 if (cache_info
[eax
] < 4) {
122 * Processor does not support deterministic
123 * cache information. Set LLC sharing to 1, since
124 * we have no better information.
126 if (cpu_is_hyperthreaded()) {
127 topoParms
.nCoresSharingLLC
= 1;
128 topoParms
.nLCPUsSharingLLC
= 2;
129 topoParms
.maxSharingLLC
= 2;
131 topoParms
.nCoresSharingLLC
= 1;
132 topoParms
.nLCPUsSharingLLC
= 1;
133 topoParms
.maxSharingLLC
= 1;
138 for (index
= 0; ; index
+= 1) {
142 cache_info
[ecx
] = index
;
149 * See if all levels have been queried.
151 if (bitfield(cache_info
[eax
], 4, 0) == 0)
155 * Get the current level.
157 this_level
= bitfield(cache_info
[eax
], 7, 5);
160 * Only worry about it if it's a deeper level than
161 * what we've seen before.
163 if (this_level
> cache_level
) {
164 cache_level
= this_level
;
167 * Save the number of CPUs sharing this cache.
169 nCPUsSharing
= bitfield(cache_info
[eax
], 25, 14) + 1;
174 * Make the level of the LLC be 0 based.
176 topoParms
.LLCDepth
= cache_level
- 1;
179 * nCPUsSharing represents the *maximum* number of cores or
180 * logical CPUs sharing the cache.
182 topoParms
.maxSharingLLC
= nCPUsSharing
;
184 topoParms
.nCoresSharingLLC
= nCPUsSharing
/ (cpuinfo
->thread_count
/
185 cpuinfo
->core_count
);
186 topoParms
.nLCPUsSharingLLC
= nCPUsSharing
;
189 * nCPUsSharing may not be the number of *active* cores or
190 * threads that are sharing the cache.
192 if (nCPUsSharing
> cpuinfo
->core_count
)
193 topoParms
.nCoresSharingLLC
= cpuinfo
->core_count
;
194 if (nCPUsSharing
> cpuinfo
->thread_count
)
195 topoParms
.nLCPUsSharingLLC
= cpuinfo
->thread_count
;
201 i386_cpu_info_t
*cpuinfo
;
203 topoParms
.stable
= FALSE
;
205 cpuinfo
= cpuid_info();
208 * We need to start with getting the LLC information correct.
213 * Compute the number of threads (logical CPUs) per core.
215 topoParms
.nLThreadsPerCore
= cpuinfo
->thread_count
/ cpuinfo
->core_count
;
216 topoParms
.nPThreadsPerCore
= cpuinfo
->cpuid_logical_per_package
/ cpuinfo
->cpuid_cores_per_package
;
219 * Compute the number of dies per package.
221 topoParms
.nLDiesPerPackage
= cpuinfo
->core_count
/ topoParms
.nCoresSharingLLC
;
222 topoParms
.nPDiesPerPackage
= cpuinfo
->cpuid_cores_per_package
/ (topoParms
.maxSharingLLC
/ topoParms
.nPThreadsPerCore
);
225 * Compute the number of cores per die.
227 topoParms
.nLCoresPerDie
= topoParms
.nCoresSharingLLC
;
228 topoParms
.nPCoresPerDie
= (topoParms
.maxSharingLLC
/ topoParms
.nPThreadsPerCore
);
231 * Compute the number of threads per die.
233 topoParms
.nLThreadsPerDie
= topoParms
.nLThreadsPerCore
* topoParms
.nLCoresPerDie
;
234 topoParms
.nPThreadsPerDie
= topoParms
.nPThreadsPerCore
* topoParms
.nPCoresPerDie
;
237 * Compute the number of cores per package.
239 topoParms
.nLCoresPerPackage
= topoParms
.nLCoresPerDie
* topoParms
.nLDiesPerPackage
;
240 topoParms
.nPCoresPerPackage
= topoParms
.nPCoresPerDie
* topoParms
.nPDiesPerPackage
;
243 * Compute the number of threads per package.
245 topoParms
.nLThreadsPerPackage
= topoParms
.nLThreadsPerCore
* topoParms
.nLCoresPerPackage
;
246 topoParms
.nPThreadsPerPackage
= topoParms
.nPThreadsPerCore
* topoParms
.nPCoresPerPackage
;
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
);
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
);
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
);
270 topoParmsInited
= TRUE
;
274 x86_cache_free(x86_cpu_cache_t
*cache
)
277 if (cache
->level
> 0 && cache
->level
<= MAX_CACHE_DEPTH
)
278 num_Lx_caches
[cache
->level
- 1] -= 1;
279 cache
->next
= x86_caches
;
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.
288 static x86_cpu_cache_t
*
291 x86_cpu_cache_t
*root
= NULL
;
292 x86_cpu_cache_t
*cur
= NULL
;
293 x86_cpu_cache_t
*last
= NULL
;
295 uint32_t cache_info
[4];
298 do_cpuid(0, cache_info
);
300 if (cache_info
[eax
] < 4) {
302 * Processor does not support deterministic
303 * cache information. Don't report anything
308 for (index
= 0; ; index
+= 1) {
310 cache_info
[ecx
] = index
;
317 * See if all levels have been queried.
319 if (bitfield(cache_info
[eax
], 4, 0) == 0)
322 cur
= x86_cache_alloc();
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
;
348 num_Lx_caches
[cur
->level
- 1] += 1;
354 static x86_cpu_cache_t
*
355 x86_match_cache(x86_cpu_cache_t
*list
, x86_cpu_cache_t
*matcher
)
357 x86_cpu_cache_t
*cur_cache
;
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
)
370 cur_cache
= cur_cache
->next
;
377 x86_lcpu_init(int cpu
)
383 cpup
= cpu_datap(cpu
);
388 lcpu
->next_in_core
= NULL
;
389 lcpu
->next_in_die
= NULL
;
390 lcpu
->next_in_pkg
= NULL
;
393 lcpu
->package
= NULL
;
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
;
401 lcpu
->master
= (lcpu
->cpu_num
== (unsigned int) master_cpu
);
402 lcpu
->primary
= (lcpu
->pnum
% topoParms
.nPThreadsPerPackage
) == 0;
406 x86_core_alloc(int cpu
)
411 cpup
= cpu_datap(cpu
);
413 simple_lock(&x86_topo_lock
);
414 if (free_cores
!= NULL
) {
416 free_cores
= core
->next_in_die
;
417 core
->next_in_die
= NULL
;
418 simple_unlock(&x86_topo_lock
);
420 simple_unlock(&x86_topo_lock
);
421 core
= kalloc(sizeof(x86_core_t
));
423 panic("x86_core_alloc() kalloc of x86_core_t failed!\n");
426 bzero((void *) core
, sizeof(x86_core_t
));
428 core
->pcore_num
= cpup
->cpu_phys_number
/ topoParms
.nPThreadsPerCore
;
429 core
->lcore_num
= core
->pcore_num
% topoParms
.nPCoresPerPackage
;
431 core
->flags
= X86CORE_FL_PRESENT
| X86CORE_FL_READY
432 | X86CORE_FL_HALTED
| X86CORE_FL_IDLE
;
438 x86_core_free(x86_core_t
*core
)
440 simple_lock(&x86_topo_lock
);
441 core
->next_in_die
= free_cores
;
443 simple_unlock(&x86_topo_lock
);
447 x86_package_find(int cpu
)
453 cpup
= cpu_datap(cpu
);
455 pkg_num
= cpup
->cpu_phys_number
/ topoParms
.nPThreadsPerPackage
;
458 while (pkg
!= NULL
) {
459 if (pkg
->ppkg_num
== pkg_num
)
468 x86_die_find(int cpu
)
475 cpup
= cpu_datap(cpu
);
477 die_num
= cpup
->cpu_phys_number
/ topoParms
.nPThreadsPerDie
;
479 pkg
= x86_package_find(cpu
);
484 while (die
!= NULL
) {
485 if (die
->pdie_num
== die_num
)
487 die
= die
->next_in_pkg
;
494 x86_core_find(int cpu
)
501 cpup
= cpu_datap(cpu
);
503 core_num
= cpup
->cpu_phys_number
/ topoParms
.nPThreadsPerCore
;
505 die
= x86_die_find(cpu
);
510 while (core
!= NULL
) {
511 if (core
->pcore_num
== core_num
)
513 core
= core
->next_in_die
;
520 x86_set_lcpu_numbers(x86_lcpu_t
*lcpu
)
522 lcpu
->lnum
= lcpu
->cpu_num
% topoParms
.nLThreadsPerCore
;
526 x86_set_core_numbers(x86_core_t
*core
, x86_lcpu_t
*lcpu
)
528 core
->pcore_num
= lcpu
->cpu_num
/ topoParms
.nLThreadsPerCore
;
529 core
->lcore_num
= core
->pcore_num
% topoParms
.nLCoresPerDie
;
533 x86_set_die_numbers(x86_die_t
*die
, x86_lcpu_t
*lcpu
)
535 die
->pdie_num
= lcpu
->cpu_num
/ (topoParms
.nLThreadsPerCore
* topoParms
.nLCoresPerDie
);
536 die
->ldie_num
= die
->pdie_num
% topoParms
.nLDiesPerPackage
;
540 x86_set_pkg_numbers(x86_pkg_t
*pkg
, x86_lcpu_t
*lcpu
)
542 pkg
->ppkg_num
= lcpu
->cpu_num
/ topoParms
.nLThreadsPerPackage
;
543 pkg
->lpkg_num
= pkg
->ppkg_num
;
547 x86_die_alloc(int cpu
)
552 cpup
= cpu_datap(cpu
);
554 simple_lock(&x86_topo_lock
);
555 if (free_dies
!= NULL
) {
557 free_dies
= die
->next_in_pkg
;
558 die
->next_in_pkg
= NULL
;
559 simple_unlock(&x86_topo_lock
);
561 simple_unlock(&x86_topo_lock
);
562 die
= kalloc(sizeof(x86_die_t
));
564 panic("x86_die_alloc() kalloc of x86_die_t failed!\n");
567 bzero((void *) die
, sizeof(x86_die_t
));
569 die
->pdie_num
= cpup
->cpu_phys_number
/ topoParms
.nPThreadsPerDie
;
571 die
->ldie_num
= num_dies
;
572 atomic_incl((long *) &num_dies
, 1);
574 die
->flags
= X86DIE_FL_PRESENT
;
579 x86_die_free(x86_die_t
*die
)
581 simple_lock(&x86_topo_lock
);
582 die
->next_in_pkg
= free_dies
;
584 atomic_decl((long *) &num_dies
, 1);
585 simple_unlock(&x86_topo_lock
);
589 x86_package_alloc(int cpu
)
594 cpup
= cpu_datap(cpu
);
596 simple_lock(&x86_topo_lock
);
597 if (free_pkgs
!= NULL
) {
599 free_pkgs
= pkg
->next
;
601 simple_unlock(&x86_topo_lock
);
603 simple_unlock(&x86_topo_lock
);
604 pkg
= kalloc(sizeof(x86_pkg_t
));
606 panic("x86_package_alloc() kalloc of x86_pkg_t failed!\n");
609 bzero((void *) pkg
, sizeof(x86_pkg_t
));
611 pkg
->ppkg_num
= cpup
->cpu_phys_number
/ topoParms
.nPThreadsPerPackage
;
613 pkg
->lpkg_num
= topoParms
.nPackages
;
614 atomic_incl((long *) &topoParms
.nPackages
, 1);
616 pkg
->flags
= X86PKG_FL_PRESENT
| X86PKG_FL_READY
;
621 x86_package_free(x86_pkg_t
*pkg
)
623 simple_lock(&x86_topo_lock
);
624 pkg
->next
= free_pkgs
;
626 atomic_decl((long *) &topoParms
.nPackages
, 1);
627 simple_unlock(&x86_topo_lock
);
631 x86_cache_add_lcpu(x86_cpu_cache_t
*cache
, x86_lcpu_t
*lcpu
)
633 x86_cpu_cache_t
*cur_cache
;
637 * Put the new CPU into the list of the cache.
639 cur_cache
= lcpu
->caches
[cache
->level
- 1];
640 lcpu
->caches
[cache
->level
- 1] = cache
;
641 cache
->next
= cur_cache
;
643 for (i
= 0; i
< cache
->nlcpus
; i
+= 1) {
644 if (cache
->cpus
[i
] == NULL
) {
645 cache
->cpus
[i
] = lcpu
;
652 x86_lcpu_add_caches(x86_lcpu_t
*lcpu
)
654 x86_cpu_cache_t
*list
;
655 x86_cpu_cache_t
*cur
;
656 x86_cpu_cache_t
*match
;
659 x86_lcpu_t
*cur_lcpu
;
661 boolean_t found
= FALSE
;
663 assert(lcpu
!= NULL
);
666 * Add the cache data to the topology.
668 list
= x86_cache_list();
670 simple_lock(&x86_topo_lock
);
672 while (list
!= NULL
) {
674 * Remove the cache from the front of the list.
679 level
= cur
->level
- 1;
682 * If the cache isn't shared then just put it where it
685 if (cur
->maxcpus
== 1) {
686 x86_cache_add_lcpu(cur
, lcpu
);
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.
695 if (lcpu
->caches
[level
] != NULL
) {
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.
706 * Assume that L{LLC-1} are all at the core level and that
707 * LLC is shared at the die level.
709 if (level
< topoParms
.LLCDepth
) {
711 * Shared at the core.
714 cur_lcpu
= core
->lcpus
;
715 while (cur_lcpu
!= NULL
) {
719 if (cur_lcpu
== lcpu
) {
720 cur_lcpu
= cur_lcpu
->next_in_core
;
725 * If there's a cache on this logical CPU,
728 match
= x86_match_cache(cur_lcpu
->caches
[level
], cur
);
731 x86_cache_add_lcpu(match
, lcpu
);
736 cur_lcpu
= cur_lcpu
->next_in_core
;
743 cur_lcpu
= die
->lcpus
;
744 while (cur_lcpu
!= NULL
) {
748 if (cur_lcpu
== lcpu
) {
749 cur_lcpu
= cur_lcpu
->next_in_die
;
754 * If there's a cache on this logical CPU,
757 match
= x86_match_cache(cur_lcpu
->caches
[level
], cur
);
760 x86_cache_add_lcpu(match
, lcpu
);
765 cur_lcpu
= cur_lcpu
->next_in_die
;
770 * If a shared cache wasn't found, then this logical CPU must
771 * be the first one encountered.
774 x86_cache_add_lcpu(cur
, lcpu
);
778 simple_unlock(&x86_topo_lock
);
782 x86_core_add_lcpu(x86_core_t
*core
, x86_lcpu_t
*lcpu
)
784 assert(core
!= NULL
);
785 assert(lcpu
!= NULL
);
787 simple_lock(&x86_topo_lock
);
789 lcpu
->next_in_core
= core
->lcpus
;
792 core
->num_lcpus
+= 1;
793 simple_unlock(&x86_topo_lock
);
797 x86_die_add_lcpu(x86_die_t
*die
, x86_lcpu_t
*lcpu
)
800 assert(lcpu
!= NULL
);
802 lcpu
->next_in_die
= die
->lcpus
;
808 x86_die_add_core(x86_die_t
*die
, x86_core_t
*core
)
811 assert(core
!= NULL
);
813 core
->next_in_die
= die
->cores
;
820 x86_package_add_lcpu(x86_pkg_t
*pkg
, x86_lcpu_t
*lcpu
)
823 assert(lcpu
!= NULL
);
825 lcpu
->next_in_pkg
= pkg
->lcpus
;
831 x86_package_add_core(x86_pkg_t
*pkg
, x86_core_t
*core
)
834 assert(core
!= NULL
);
836 core
->next_in_pkg
= pkg
->cores
;
842 x86_package_add_die(x86_pkg_t
*pkg
, x86_die_t
*die
)
847 die
->next_in_pkg
= pkg
->dies
;
854 cpu_thread_alloc(int cpu
)
856 x86_core_t
*core
= NULL
;
857 x86_die_t
*die
= NULL
;
858 x86_pkg_t
*pkg
= NULL
;
863 * Only allow one to manipulate the topology at a time.
865 simple_lock(&x86_topo_lock
);
868 * Make sure all of the topology parameters have been initialized.
870 if (!topoParmsInited
)
873 cpup
= cpu_datap(cpu
);
875 phys_cpu
= cpup
->cpu_phys_number
;
880 * Assume that all cpus have the same features.
882 if (cpu_is_hyperthreaded()) {
883 cpup
->cpu_threadtype
= CPU_THREADTYPE_INTEL_HTT
;
885 cpup
->cpu_threadtype
= CPU_THREADTYPE_NONE
;
889 * Get the package that the logical CPU is in.
892 pkg
= x86_package_find(cpu
);
895 * Package structure hasn't been created yet, do it now.
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
);
906 * Add the new package to the global list of packages.
908 pkg
->next
= x86_pkgs
;
911 } while (pkg
== NULL
);
914 * Get the die that the logical CPU is in.
917 die
= x86_die_find(cpu
);
920 * Die structure hasn't been created yet, do it now.
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
) {
931 * Add the die to the package.
933 x86_package_add_die(pkg
, die
);
935 } while (die
== NULL
);
938 * Get the core for this logical CPU.
941 core
= x86_core_find(cpu
);
944 * Allocate the core structure now.
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
) {
955 * Add the core to the die & package.
957 x86_die_add_core(die
, core
);
958 x86_package_add_core(pkg
, core
);
959 machine_info
.physical_cpu_max
+= 1;
961 } while (core
== NULL
);
965 * Done manipulating the topology, so others can get in.
967 machine_info
.logical_cpu_max
+= 1;
968 simple_unlock(&x86_topo_lock
);
971 * Add the logical CPU to the other topology structures.
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
);
978 return (void *) core
;
982 cpu_thread_init(void)
984 int my_cpu
= get_cpu_number();
985 cpu_data_t
*cpup
= current_cpu_datap();
987 static int initialized
= 0;
990 * If we're the boot processor, we do all of the initialization of
991 * the CPU topology infrastructure.
993 if (my_cpu
== master_cpu
&& !initialized
) {
994 simple_lock_init(&x86_topo_lock
, 0);
997 * Put this logical CPU into the physical CPU topology.
999 cpup
->lcpu
.core
= cpu_thread_alloc(my_cpu
);
1005 * Do the CPU accounting.
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
);
1015 pmCPUMarkRunning(cpup
);
1016 etimer_resync_deadlines();
1020 * Called for a cpu to halt permanently
1021 * (as opposed to halting and expecting an interrupt to awaken it).
1024 cpu_thread_halt(void)
1027 cpu_data_t
*cpup
= current_cpu_datap();
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
);
1038 * Let the power management code determine the best way to "stop"
1041 ml_set_interrupts_enabled(FALSE
);
1043 pmCPUHalt(PM_HALT_NORMAL
);
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.
1053 validate_topology(void)
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.
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.
1075 nCPUs
= topoParms
.nPackages
* topoParms
.nLThreadsPerPackage
;
1076 if (nCPUs
> real_ncpus
)
1080 while (pkg
!= NULL
) {
1082 * Make sure that the package has the correct number of dies.
1086 while (die
!= NULL
) {
1087 if (die
->package
== NULL
)
1088 panic("Die(%d)->package is NULL",
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
);
1094 DBG("Die(%d)->package %d\n",
1095 die
->pdie_num
, pkg
->lpkg_num
);
1098 * Make sure that the die has the correct number of cores.
1100 DBG("Die(%d)->cores: ", die
->pdie_num
);
1103 while (core
!= NULL
) {
1104 if (core
->die
== NULL
)
1105 panic("Core(%d)->die is NULL",
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
);
1111 DBG("%d ", core
->pcore_num
);
1112 core
= core
->next_in_die
;
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
);
1121 * Make sure that the die has the correct number of CPUs.
1123 DBG("Die(%d)->lcpus: ", die
->pdie_num
);
1126 while (lcpu
!= NULL
) {
1127 if (lcpu
->die
== NULL
)
1128 panic("CPU(%d)->die is NULL",
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
);
1134 DBG("%d ", lcpu
->cpu_num
);
1135 lcpu
= lcpu
->next_in_die
;
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
);
1144 die
= die
->next_in_pkg
;
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
);
1152 * Make sure that the package has the correct number of cores.
1156 while (core
!= NULL
) {
1157 if (core
->package
== NULL
)
1158 panic("Core(%d)->package is NULL",
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
);
1167 * Make sure that the core has the correct number of CPUs.
1171 DBG("Core(%d)->lcpus: ", core
->pcore_num
);
1172 while (lcpu
!= NULL
) {
1173 if (lcpu
->core
== NULL
)
1174 panic("CPU(%d)->core is NULL",
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
);
1181 lcpu
= lcpu
->next_in_core
;
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
);
1189 core
= core
->next_in_pkg
;
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
);
1197 * Make sure that the package has the correct number of CPUs.
1201 while (lcpu
!= NULL
) {
1202 if (lcpu
->package
== NULL
)
1203 panic("CPU(%d)->package is NULL",
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
);
1211 lcpu
= lcpu
->next_in_pkg
;
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
);
1224 * Prints out the topology
1227 debug_topology_print(void)
1235 while (pkg
!= NULL
) {
1236 kprintf("Package:\n");
1237 kprintf(" Physical: %d\n", pkg
->ppkg_num
);
1238 kprintf(" Logical: %d\n", pkg
->lpkg_num
);
1241 while (die
!= NULL
) {
1243 kprintf(" Physical: %d\n", die
->pdie_num
);
1244 kprintf(" Logical: %d\n", die
->ldie_num
);
1247 while (core
!= NULL
) {
1248 kprintf(" Core:\n");
1249 kprintf(" Physical: %d\n", core
->pcore_num
);
1250 kprintf(" Logical: %d\n", core
->lcore_num
);
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: ");
1263 if (!cpu
->master
&& !cpu
->primary
)
1267 cpu
= cpu
->next_in_core
;
1270 core
= core
->next_in_die
;
1273 die
= die
->next_in_pkg
;
1279 #endif /* TOPO_DEBUG */