1/* 2 * Copyright (c) 2003-2008 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 */ 45typedef struct x86_cpu_cache 46{ 47 struct x86_cpu_cache *next; /* next cache at this level/lcpu */ 48 struct x86_die *die; /* die containing this cache (only for LLC) */ 49 uint8_t maxcpus; /* maximum # of cpus that can share */ 50 uint8_t nlcpus; /* # of logical cpus sharing this cache */ 51 uint8_t type; /* type of cache */ 52 uint8_t level; /* level of cache */ 53 uint16_t ways; /* # of ways in cache */ 54 uint16_t partitions; /* # of partitions in cache */ 55 uint16_t line_size; /* size of a cache line */ 56 uint32_t cache_size; /* total size of cache */ 57 struct x86_lcpu *cpus[0]; /* cpus sharing this cache */ 58} x86_cpu_cache_t; 59 60#define CPU_CACHE_TYPE_DATA 1 /* data cache */ 61#define CPU_CACHE_TYPE_INST 2 /* instruction cache */ 62#define CPU_CACHE_TYPE_UNIF 3 /* unified cache */ 63 64#define CPU_CACHE_DEPTH_L1 0 65#define CPU_CACHE_DEPTH_L2 1 66#define CPU_CACHE_DEPTH_L3 2 67 68#define MAX_CACHE_DEPTH 3 /* deepest cache */ 69 70struct pmc; 71struct cpu_data; 72struct mca_state; 73 74/* 75 * Define the states that a (logical) CPU can be in. 76 * 77 * LCPU_OFF This indicates that the CPU is "off". It requires a full 78 * restart. This is the state of a CPU when the system first 79 * boots or when it comes out of "sleep" (aka S3/S5). 80 * 81 * LCPU_HALT This indicates that the CPU has been "halted". It has been 82 * removed from the system but still retains its internal state 83 * so that it can be quickly brought back on-line. 84 * 85 * LCPU_NONSCHED This indicates that the CPU is not schedulable. It 86 * will still appear in the system as a viable CPU however no 87 * work will be sceduled on it. 88 * 89 * LCPU_PAUSE This indicates that the CPU is "paused". This is usually 90 * done only during kernel debug. 91 * 92 * LCPU_IDLE This indicates that the CPU is idle. The scheduler has 93 * determined that there is no work for this CPU to do. 94 * 95 * LCPU_RUN This indicates that the CPU is running code and performing work. 96 * 97 * In normal system operation, CPUs will usually be transitioning between 98 * LCPU_IDLE and LCPU_RUN. 99 */ 100typedef enum lcpu_state 101{ 102 LCPU_OFF = 0, /* 0 so the right thing happens on boot */ 103 LCPU_HALT = 1, 104 LCPU_NONSCHED = 2, 105 LCPU_PAUSE = 3, 106 LCPU_IDLE = 4, 107 LCPU_RUN = 5, 108} lcpu_state_t; 109 110/* 111 * In each topology structure there are two numbers: a logical number and a 112 * physical number. 113 * 114 * The logical numbers represent the ID of that structure 115 * relative to the enclosing structure and always starts at 0. So when using 116 * logical numbers, it is necessary to specify all elements in the topology 117 * (ie to "name" a logical CPU using logical numbers, 4 numbers are required: 118 * package, die, core, logical CPU). 119 * 120 * The physical numbers represent the ID of that structure and is unique (for 121 * that structure) across the entire topology. 122 * 123 * The logical CPU structure contains a third number which is the CPU number. 124 * This number is identical to the CPU number used in other parts of the kernel. 125 */ 126typedef struct x86_lcpu 127{ 128 struct x86_lcpu *next_in_core; /* next logical cpu in core */ 129 struct x86_lcpu *next_in_die; /* next logical cpu in die */ 130 struct x86_lcpu *next_in_pkg; /* next logical cpu in package */ 131 struct x86_lcpu *lcpu; /* pointer back to self */ 132 struct x86_core *core; /* core containing the logical cpu */ 133 struct x86_die *die; /* die containing the logical cpu */ 134 struct x86_pkg *package; /* package containing the logical cpu */ 135 struct cpu_data *cpu; /* cpu_data structure */ 136 uint32_t flags; 137 uint32_t cpu_num; /* cpu number */ 138 uint32_t lnum; /* logical cpu number (within core) */ 139 uint32_t pnum; /* physical cpu number */ 140 boolean_t master; /* logical cpu is the master (boot) CPU */ 141 boolean_t primary; /* logical cpu is primary CPU in package */ 142 volatile lcpu_state_t state; /* state of the logical CPU */ 143 volatile boolean_t stopped; /* used to indicate that the CPU has "stopped" */ 144 uint64_t rtcPop; /* when etimer wants a timer pop */ 145 uint64_t rtcDeadline; 146 x86_cpu_cache_t *caches[MAX_CACHE_DEPTH]; 147 struct pmc *pmc; /* Pointer to perfmon data */ 148 void *pmStats; /* Power management stats for lcpu */ 149 void *pmState; /* Power management state for lcpu */ 150} x86_lcpu_t; 151 152#define X86CORE_FL_PRESENT 0x80000000 /* core is present */ 153#define X86CORE_FL_READY 0x40000000 /* core struct is init'd */ 154#define X86CORE_FL_HAS_HPET 0x10000000 /* core has HPET assigned */ 155#define X86CORE_FL_HALTED 0x00008000 /* core is halted */ 156#define X86CORE_FL_IDLE 0x00004000 /* core is idle */ 157#define X86CORE_FL_WAKEUP 0x00002000 /* wakeup is pending */ 158 159typedef struct x86_core 160{ 161 struct x86_core *next_in_die; /* next core in die */ 162 struct x86_core *next_in_pkg; /* next core in package */ 163 struct x86_die *die; /* die containing the core */ 164 struct x86_pkg *package; /* package containing core */ 165 struct x86_lcpu *lcpus; /* list of logical cpus in core */ 166 uint32_t flags; 167 uint32_t lcore_num; /* logical core # (unique within die) */ 168 uint32_t pcore_num; /* physical core # (globally unique) */ 169 uint32_t num_lcpus; /* Number of logical cpus */ 170 uint32_t active_lcpus; /* Number of {running, idle} cpus */ 171 void *pmStats; /* Power management stats for core */ 172 void *pmState; /* Power management state for core */ 173} x86_core_t; 174 175#define X86DIE_FL_PRESENT 0x80000000 /* die is present */ 176#define X86DIE_FL_READY 0x40000000 /* die struct is init'd */ 177 178typedef struct x86_die 179{ 180 struct x86_die *next_in_pkg; /* next die in package */ 181 struct x86_lcpu *lcpus; /* list of lcpus in die */ 182 struct x86_core *cores; /* list of cores in die */ 183 struct x86_pkg *package; /* package containing the die */ 184 uint32_t flags; 185 uint32_t ldie_num; /* logical die # (unique to package) */ 186 uint32_t pdie_num; /* physical die # (globally unique) */ 187 uint32_t num_cores; /* Number of cores in die */ 188 x86_cpu_cache_t *LLC; /* LLC contained in this die */ 189 void *pmStats; /* Power Management stats for die */ 190 void *pmState; /* Power Management state for die */ 191} x86_die_t; 192 193#define X86PKG_FL_PRESENT 0x80000000 /* package is present */ 194#define X86PKG_FL_READY 0x40000000 /* package struct init'd */ 195#define X86PKG_FL_HAS_HPET 0x10000000 /* package has HPET assigned */ 196#define X86PKG_FL_HALTED 0x00008000 /* package is halted */ 197#define X86PKG_FL_IDLE 0x00004000 /* package is idle */ 198 199typedef struct x86_pkg 200{ 201 struct x86_pkg *next; /* next package */ 202 struct x86_lcpu *lcpus; /* list of logical cpus in package */ 203 struct x86_core *cores; /* list of cores in package */ 204 struct x86_die *dies; /* list of dies in package */ 205 uint32_t flags; 206 uint32_t lpkg_num; /* logical package # */ 207 uint32_t ppkg_num; /* physical package # */ 208 uint32_t num_dies; /* number of dies in package */ 209 void *pmStats; /* Power Management stats for package*/ 210 void *pmState; /* Power Management state for package*/ 211 struct mca_state *mca_state; /* MCA state for memory errors */ 212} x86_pkg_t; 213 214extern x86_pkg_t *x86_pkgs; /* root of all CPU packages */ 215 216typedef struct x86_topology_parameters 217{ 218 uint32_t LLCDepth; 219 uint32_t nCoresSharingLLC; 220 uint32_t nLCPUsSharingLLC; 221 uint32_t maxSharingLLC; 222 uint32_t nLThreadsPerCore; 223 uint32_t nPThreadsPerCore; 224 uint32_t nLCoresPerDie; 225 uint32_t nPCoresPerDie; 226 uint32_t nLDiesPerPackage; 227 uint32_t nPDiesPerPackage; 228 uint32_t nLThreadsPerDie; 229 uint32_t nPThreadsPerDie; 230 uint32_t nLThreadsPerPackage; 231 uint32_t nPThreadsPerPackage; 232 uint32_t nLCoresPerPackage; 233 uint32_t nPCoresPerPackage; 234 uint32_t nPackages; 235} x86_topology_parameters_t; 236 237/* Called after cpu discovery */ 238extern void cpu_topology_start(void); 239 240#endif /* _I386_CPU_TOPOLOGY_H_ */ 241#endif /* KERNEL_PRIVATE */ 242