xref: /xnu-8796.121.2/osfmk/i386/cpu_topology.h (revision c54f35ca767986246321eb901baf8f5ff7923f6a)
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 #ifdef KERNEL_PRIVATE
29 #ifndef _I386_CPU_TOPOLOGY_H_
30 #define _I386_CPU_TOPOLOGY_H_
31 
32 /*
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.
37  *
38  * NOTE: this header must stand on its own as much as possible
39  * and not be dependent upon any unexported, kernel-private header.
40  */
41 
42 /*
43  * Cache structure that can be used to identify the cache heirarchy.
44  */
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 */
57 } x86_cpu_cache_t;
58 
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 */
62 
63 #define CPU_CACHE_DEPTH_L1      0
64 #define CPU_CACHE_DEPTH_L2      1
65 #define CPU_CACHE_DEPTH_L3      2
66 
67 #define MAX_CACHE_DEPTH         3       /* deepest cache */
68 
69 struct pmc;
70 struct cpu_data;
71 struct mca_state;
72 
73 /*
74  * Define the states that a (logical) CPU can be in.
75  *
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).
79  *
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.
83  *
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.
87  *
88  * LCPU_PAUSE	This indicates that the CPU is "paused".  This is usually
89  *		done only during kernel debug.
90  *
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.
93  *
94  * LCPU_RUN	This indicates that the CPU is running code and performing work.
95  *
96  * In normal system operation, CPUs will usually be transitioning between
97  * LCPU_IDLE and LCPU_RUN.
98  */
99 typedef enum lcpu_state {
100 	LCPU_OFF            = 0,/* 0 so the right thing happens on boot */
101 	LCPU_HALT           = 1,
102 	LCPU_NONSCHED       = 2,
103 	LCPU_PAUSE          = 3,
104 	LCPU_IDLE           = 4,
105 	LCPU_RUN            = 5,
106 } lcpu_state_t;
107 
108 /*
109  * In each topology structure there are two numbers: a logical number and a
110  * physical number.
111  *
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).
117  *
118  * The physical numbers represent the ID of that structure and is unique (for
119  * that structure) across the entire topology.
120  *
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.
123  */
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 */
133 	uint32_t            flags;
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 */
146 } x86_lcpu_t;
147 
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 */
153 
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 */
160 	uint32_t            flags;
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 */
167 } x86_core_t;
168 
169 #define X86DIE_FL_PRESENT       0x80000000      /* die is present */
170 #define X86DIE_FL_READY         0x40000000      /* die struct is init'd */
171 
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 */
177 	uint32_t            flags;
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 */
184 } x86_die_t;
185 
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 */
191 
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 */
197 	uint32_t            flags;
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;
205 	uint32_t            num_idle;
206 } x86_pkg_t;
207 
208 extern x86_pkg_t        *x86_pkgs;      /* root of all CPU packages */
209 
210 typedef struct x86_topology_parameters {
211 	uint32_t            LLCDepth;
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;
227 	uint32_t            nPackages;
228 	boolean_t           stable;
229 } x86_topology_parameters_t;
230 
231 /* Called after cpu discovery */
232 extern void             cpu_topology_sort(int ncpus);
233 extern kern_return_t    cpu_topology_start_cpu(int cpunum);
234 
235 
236 #endif /* _I386_CPU_TOPOLOGY_H_ */
237 #endif /* KERNEL_PRIVATE */
238