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@
29 #ifndef _I386_CPU_TOPOLOGY_H_
30 #define _I386_CPU_TOPOLOGY_H_
33 * This was originally part of cpu_threads.h. It was split out so that
34 * these structures could be referenced without pulling in all of the headers
35 * required for the definition of cpu_data. These data structures are
36 * used by KEXTs in order to deal with the physical topology.
38 * NOTE: this header must stand on its own as much as possible
39 * and not be dependent upon any unexported, kernel-private header.
43 * Cache structure that can be used to identify the cache heirarchy.
45 typedef struct x86_cpu_cache
{
46 struct x86_cpu_cache
*next
; /* next cache at this level/lcpu */
47 struct x86_die
*die
; /* die containing this cache (only for LLC) */
48 uint8_t maxcpus
; /* maximum # of cpus that can share */
49 uint8_t nlcpus
; /* # of logical cpus sharing this cache */
50 uint8_t type
; /* type of cache */
51 uint8_t level
; /* level of cache */
52 uint16_t ways
; /* # of ways in cache */
53 uint16_t partitions
; /* # of partitions in cache */
54 uint16_t line_size
; /* size of a cache line */
55 uint32_t cache_size
; /* total size of cache */
56 struct x86_lcpu
*cpus
[0]; /* cpus sharing this cache */
59 #define CPU_CACHE_TYPE_DATA 1 /* data cache */
60 #define CPU_CACHE_TYPE_INST 2 /* instruction cache */
61 #define CPU_CACHE_TYPE_UNIF 3 /* unified cache */
63 #define CPU_CACHE_DEPTH_L1 0
64 #define CPU_CACHE_DEPTH_L2 1
65 #define CPU_CACHE_DEPTH_L3 2
67 #define MAX_CACHE_DEPTH 3 /* deepest cache */
74 * Define the states that a (logical) CPU can be in.
76 * LCPU_OFF This indicates that the CPU is "off". It requires a full
77 * restart. This is the state of a CPU when the system first
78 * boots or when it comes out of "sleep" (aka S3/S5).
80 * LCPU_HALT This indicates that the CPU has been "halted". It has been
81 * removed from the system but still retains its internal state
82 * so that it can be quickly brought back on-line.
84 * LCPU_NONSCHED This indicates that the CPU is not schedulable. It
85 * will still appear in the system as a viable CPU however no
86 * work will be sceduled on it.
88 * LCPU_PAUSE This indicates that the CPU is "paused". This is usually
89 * done only during kernel debug.
91 * LCPU_IDLE This indicates that the CPU is idle. The scheduler has
92 * determined that there is no work for this CPU to do.
94 * LCPU_RUN This indicates that the CPU is running code and performing work.
96 * In normal system operation, CPUs will usually be transitioning between
97 * LCPU_IDLE and LCPU_RUN.
99 typedef enum lcpu_state
{
100 LCPU_OFF
= 0,/* 0 so the right thing happens on boot */
109 * In each topology structure there are two numbers: a logical number and a
112 * The logical numbers represent the ID of that structure
113 * relative to the enclosing structure and always starts at 0. So when using
114 * logical numbers, it is necessary to specify all elements in the topology
115 * (ie to "name" a logical CPU using logical numbers, 4 numbers are required:
116 * package, die, core, logical CPU).
118 * The physical numbers represent the ID of that structure and is unique (for
119 * that structure) across the entire topology.
121 * The logical CPU structure contains a third number which is the CPU number.
122 * This number is identical to the CPU number used in other parts of the kernel.
124 typedef struct x86_lcpu
{
125 struct x86_lcpu
*next_in_core
;/* next logical cpu in core */
126 struct x86_lcpu
*next_in_die
;/* next logical cpu in die */
127 struct x86_lcpu
*next_in_pkg
;/* next logical cpu in package */
128 struct x86_lcpu
*lcpu
; /* pointer back to self */
129 struct x86_core
*core
; /* core containing the logical cpu */
130 struct x86_die
*die
; /* die containing the logical cpu */
131 struct x86_pkg
*package
; /* package containing the logical cpu */
132 struct cpu_data
*cpu
; /* cpu_data structure */
134 uint32_t cpu_num
; /* cpu number */
135 uint32_t lnum
; /* logical cpu number (within core) */
136 uint32_t pnum
; /* physical cpu number */
137 boolean_t master
; /* logical cpu is the master (boot) CPU */
138 boolean_t primary
; /* logical cpu is primary CPU in package */
139 volatile lcpu_state_t state
;/* state of the logical CPU */
140 volatile boolean_t stopped
; /* used to indicate that the CPU has "stopped" */
141 uint64_t rtcPop
; /* next timer pop programmed */
142 uint64_t rtcDeadline
;/* next etimer-requested deadline */
143 x86_cpu_cache_t
*caches
[MAX_CACHE_DEPTH
];
144 void *pmStats
; /* Power management stats for lcpu */
145 void *pmState
; /* Power management state for lcpu */
148 #define X86CORE_FL_PRESENT 0x80000000 /* core is present */
149 #define X86CORE_FL_READY 0x40000000 /* core struct is init'd */
150 #define X86CORE_FL_HAS_HPET 0x10000000 /* core has HPET assigned */
151 #define X86CORE_FL_HALTED 0x00008000 /* core is halted */
152 #define X86CORE_FL_IDLE 0x00004000 /* core is idle */
154 typedef struct x86_core
{
155 struct x86_core
*next_in_die
;/* next core in die */
156 struct x86_core
*next_in_pkg
;/* next core in package */
157 struct x86_die
*die
; /* die containing the core */
158 struct x86_pkg
*package
; /* package containing core */
159 struct x86_lcpu
*lcpus
; /* list of logical cpus in core */
161 uint32_t lcore_num
; /* logical core # (unique within die) */
162 uint32_t pcore_num
; /* physical core # (globally unique) */
163 uint32_t num_lcpus
; /* Number of logical cpus */
164 uint32_t active_lcpus
;/* Number of {running, idle} cpus */
165 void *pmStats
; /* Power management stats for core */
166 void *pmState
; /* Power management state for core */
169 #define X86DIE_FL_PRESENT 0x80000000 /* die is present */
170 #define X86DIE_FL_READY 0x40000000 /* die struct is init'd */
172 typedef struct x86_die
{
173 struct x86_die
*next_in_pkg
;/* next die in package */
174 struct x86_lcpu
*lcpus
; /* list of lcpus in die */
175 struct x86_core
*cores
; /* list of cores in die */
176 struct x86_pkg
*package
; /* package containing the die */
178 uint32_t ldie_num
; /* logical die # (unique to package) */
179 uint32_t pdie_num
; /* physical die # (globally unique) */
180 uint32_t num_cores
; /* Number of cores in die */
181 x86_cpu_cache_t
*LLC
; /* LLC contained in this die */
182 void *pmStats
; /* Power Management stats for die */
183 void *pmState
; /* Power Management state for die */
186 #define X86PKG_FL_PRESENT 0x80000000 /* package is present */
187 #define X86PKG_FL_READY 0x40000000 /* package struct init'd */
188 #define X86PKG_FL_HAS_HPET 0x10000000 /* package has HPET assigned */
189 #define X86PKG_FL_HALTED 0x00008000 /* package is halted */
190 #define X86PKG_FL_IDLE 0x00004000 /* package is idle */
192 typedef struct x86_pkg
{
193 struct x86_pkg
*next
; /* next package */
194 struct x86_lcpu
*lcpus
; /* list of logical cpus in package */
195 struct x86_core
*cores
; /* list of cores in package */
196 struct x86_die
*dies
; /* list of dies in package */
198 uint32_t lpkg_num
; /* logical package # */
199 uint32_t ppkg_num
; /* physical package # */
200 uint32_t num_dies
; /* number of dies in package */
201 void *pmStats
; /* Power Management stats for package*/
202 void *pmState
; /* Power Management state for package*/
203 struct mca_state
*mca_state
; /* MCA state for memory errors */
204 uint64_t package_idle_exits
;
208 extern x86_pkg_t
*x86_pkgs
; /* root of all CPU packages */
210 typedef struct x86_topology_parameters
{
212 uint32_t nCoresSharingLLC
;
213 uint32_t nLCPUsSharingLLC
;
214 uint32_t maxSharingLLC
;
215 uint32_t nLThreadsPerCore
;
216 uint32_t nPThreadsPerCore
;
217 uint32_t nLCoresPerDie
;
218 uint32_t nPCoresPerDie
;
219 uint32_t nLDiesPerPackage
;
220 uint32_t nPDiesPerPackage
;
221 uint32_t nLThreadsPerDie
;
222 uint32_t nPThreadsPerDie
;
223 uint32_t nLThreadsPerPackage
;
224 uint32_t nPThreadsPerPackage
;
225 uint32_t nLCoresPerPackage
;
226 uint32_t nPCoresPerPackage
;
229 } x86_topology_parameters_t
;
231 /* Called after cpu discovery */
232 extern void cpu_topology_sort(int ncpus
);
233 extern kern_return_t
cpu_topology_start_cpu(int cpunum
);
236 #endif /* _I386_CPU_TOPOLOGY_H_ */
237 #endif /* KERNEL_PRIVATE */