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