kpc.h
1 /* 2 * Copyright (c) 2012 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 29 #ifndef KERN_KPC_H 30 #define KERN_KPC_H 31 32 /* Kernel interfaces to KPC PMC infrastructure. */ 33 34 #include <machine/machine_kpc.h> 35 #include <kern/thread.h> /* thread_* */ 36 37 __BEGIN_DECLS 38 39 /* cross-platform class constants */ 40 #define KPC_CLASS_FIXED (0) 41 #define KPC_CLASS_CONFIGURABLE (1) 42 #define KPC_CLASS_POWER (2) 43 #define KPC_CLASS_RAWPMU (3) 44 45 #define KPC_CLASS_FIXED_MASK (1u << KPC_CLASS_FIXED) 46 #define KPC_CLASS_CONFIGURABLE_MASK (1u << KPC_CLASS_CONFIGURABLE) 47 #define KPC_CLASS_POWER_MASK (1u << KPC_CLASS_POWER) 48 #define KPC_CLASS_RAWPMU_MASK (1u << KPC_CLASS_RAWPMU) 49 50 #define KPC_PMU_ERROR (0) 51 #define KPC_PMU_INTEL_V3 (1) 52 #define KPC_PMU_ARM_APPLE (2) 53 #define KPC_PMU_INTEL_V2 (3) 54 #define KPC_PMU_ARM_V2 (4) 55 56 #define KPC_ALL_CPUS (1u << 31) 57 58 /* action id setters/getters */ 59 #define FIXED_ACTIONID(ctr) (kpc_actionid[(ctr)]) 60 #define CONFIGURABLE_ACTIONID(ctr) (kpc_actionid[(ctr) + kpc_fixed_count()]) 61 62 /* reload counter setters/getters */ 63 #define FIXED_RELOAD(ctr) (current_cpu_datap()->cpu_kpc_reload[(ctr)]) 64 #define FIXED_RELOAD_CPU(cpu, ctr) (cpu_datap(cpu)->cpu_kpc_reload[(ctr)]) 65 #define CONFIGURABLE_RELOAD(ctr) (current_cpu_datap()->cpu_kpc_reload[(ctr) + kpc_fixed_count()]) 66 #define CONFIGURABLE_RELOAD_CPU(cpu, ctr) (cpu_datap(cpu)->cpu_kpc_reload[(ctr) + kpc_fixed_count()]) 67 68 /* shadow counter setters/getters */ 69 #define FIXED_SHADOW(ctr) (current_cpu_datap()->cpu_kpc_shadow[(ctr)]) 70 #define FIXED_SHADOW_CPU(cpu, ctr) (cpu_datap(cpu)->cpu_kpc_shadow[(ctr)]) 71 #define CONFIGURABLE_SHADOW(ctr) (current_cpu_datap()->cpu_kpc_shadow[(ctr) + kpc_fixed_count()]) 72 #define CONFIGURABLE_SHADOW_CPU(cpu, ctr) (cpu_datap(cpu)->cpu_kpc_shadow[(ctr) + kpc_fixed_count()]) 73 74 /** 75 * Callback for notification when PMCs are acquired/released by a task. The 76 * argument is equal to TRUE if the Power Manager (PM) can use its reserved PMCs. 77 * Otherwise, the argument is equal to FALSE. 78 */ 79 typedef void (*kpc_pm_handler_t)(boolean_t); 80 81 /* 82 * Register a CPU to kpc and allocate its buffers. 83 * 84 * @param cpu_data 85 * CPU data associated to the CPU being registered. 86 * 87 * @return 88 * TRUE if buffers are correctly allocated, FALSE otherwise. 89 */ 90 struct cpu_data; 91 extern boolean_t kpc_register_cpu(struct cpu_data *cpu_data); 92 extern void kpc_unregister_cpu(struct cpu_data *cpu_data); 93 94 extern bool kpc_supported; 95 96 /* bootstrap */ 97 extern void kpc_init(void); 98 99 /* Architecture specific initialisation */ 100 extern void kpc_arch_init(void); 101 102 /* Get the bitmask of available classes */ 103 extern uint32_t kpc_get_classes(void); 104 105 /* Get the bitmask of currently running counter classes */ 106 extern uint32_t kpc_get_running(void); 107 108 /* Get the version of KPC that's being run */ 109 extern int kpc_get_pmu_version(void); 110 111 /* Set the bitmask of currently running counter classes. Specify 112 * classes = 0 to stop counters 113 */ 114 extern int kpc_set_running(uint32_t classes); 115 116 /* Read CPU counters */ 117 extern int kpc_get_cpu_counters(boolean_t all_cpus, uint32_t classes, 118 int *curcpu, uint64_t *buf); 119 120 /* Read shadow counters */ 121 extern int kpc_get_shadow_counters( boolean_t all_cpus, uint32_t classes, 122 int *curcpu, uint64_t *buf ); 123 124 /* Read current thread's counter accumulations */ 125 extern int kpc_get_curthread_counters(uint32_t *inoutcount, uint64_t *buf); 126 127 /* Given a config, how many counters and config registers there are */ 128 extern uint32_t kpc_get_counter_count(uint32_t classes); 129 extern uint32_t kpc_get_config_count(uint32_t classes); 130 131 /* enable/disable thread counting */ 132 extern uint32_t kpc_get_thread_counting(void); 133 extern int kpc_set_thread_counting(uint32_t classes); 134 135 /* get and set config registers */ 136 extern int kpc_get_config(uint32_t classes, kpc_config_t *current_config); 137 extern int kpc_set_config(uint32_t classes, kpc_config_t *new_config); 138 139 /* get and set PMI period */ 140 extern int kpc_get_period(uint32_t classes, uint64_t *period); 141 extern int kpc_set_period(uint32_t classes, uint64_t *period); 142 143 /* get and set kperf actionid */ 144 extern int kpc_get_actionid(uint32_t classes, uint32_t *actionid); 145 extern int kpc_set_actionid(uint32_t classes, uint32_t *actionid); 146 147 /* hooks on thread create and delete */ 148 extern void kpc_thread_create(thread_t thread); 149 extern void kpc_thread_destroy(thread_t thread); 150 151 /* allocate a buffer big enough for all counters */ 152 extern uint64_t *kpc_counterbuf_alloc(void); 153 extern void kpc_counterbuf_free(uint64_t*); 154 extern uint32_t kpc_get_counterbuf_size(void); 155 156 /* whether we're currently accounting into threads */ 157 extern int kpc_threads_counting; 158 159 /* AST callback for KPC */ 160 extern void kpc_thread_ast_handler( thread_t thread ); 161 162 #ifdef MACH_KERNEL_PRIVATE 163 164 /* context switch callback for KPC */ 165 166 extern boolean_t kpc_off_cpu_active; 167 168 extern void kpc_off_cpu_internal(thread_t thread); 169 extern void kpc_off_cpu_update(void); 170 171 static inline void 172 kpc_off_cpu(thread_t thread) 173 { 174 if (__improbable(kpc_off_cpu_active)) { 175 kpc_off_cpu_internal(thread); 176 } 177 } 178 179 #endif /* defined(MACH_KERNEL_PRIVATE) */ 180 181 /* acquire/release the counters used by the Power Manager */ 182 extern int kpc_force_all_ctrs( task_t task, int val ); 183 extern int kpc_get_force_all_ctrs( void ); 184 185 /* arch-specific routine for acquire/release the counters used by the Power Manager */ 186 extern int kpc_force_all_ctrs_arch( task_t task, int val ); 187 188 extern int kpc_set_sw_inc( uint32_t mask ); 189 190 /* disable/enable whitelist of allowed events */ 191 extern int kpc_get_whitelist_disabled( void ); 192 extern int kpc_disable_whitelist( int val ); 193 194 /* 195 * Register the Power Manager as a PMCs user. 196 * 197 * This is a deprecated function used by old Power Managers, new Power Managers 198 * should use the @em kpc_reserve_pm_counters() function. This function actually 199 * calls @em kpc_reserve_pm_counters() with the following arguments: 200 * - handler = handler 201 * - pmc_mask = 0x83 202 * - custom_config = TRUE 203 * 204 * See @em kpc_reserve_pm_counters() for more details about the return value. 205 */ 206 extern boolean_t kpc_register_pm_handler(void (*handler)(boolean_t)); 207 208 /* 209 * Register the Power Manager as a PMCs user. 210 * 211 * @param handler 212 * Notification callback to use when PMCs are acquired/released by a task. 213 * Power management must acknowledge the change using kpc_pm_acknowledge. 214 * 215 * @param pmc_mask 216 * Bitmask of the configurable PMCs used by the Power Manager. The number of bits 217 * set must less or equal than the number of configurable counters 218 * available on the SoC. 219 * 220 * @param custom_config 221 * If custom_config=TRUE, the legacy sharing mode is enabled, otherwise the 222 * Modern Sharing mode is enabled. These modes are explained in more details in 223 * the kperf documentation. 224 * 225 * @return 226 * FALSE if a task has acquired all the PMCs, otherwise TRUE and the Power 227 * Manager can start using the reserved PMCs. 228 */ 229 extern boolean_t kpc_reserve_pm_counters(uint64_t pmc_mask, kpc_pm_handler_t handler, 230 boolean_t custom_config); 231 232 /* 233 * Unregister the Power Manager as a PMCs user, and release the previously 234 * reserved counters. 235 */ 236 extern void kpc_release_pm_counters(void); 237 238 /* 239 * Acknowledge the callback that PMCs are available to power management. 240 * 241 * @param available_to_pm Whether the counters were made available to power 242 * management in the callback. Pass in whatever was passed into the handler 243 * function. After this point, power management is able to use POWER_CLASS 244 * counters. 245 */ 246 extern void kpc_pm_acknowledge(boolean_t available_to_pm); 247 248 /* 249 * Is the PMU used by both the power manager and userspace? 250 * 251 * This is true when the power manager has been registered. It disables certain 252 * counter configurations (like RAWPMU) that are incompatible with sharing 253 * counters. 254 */ 255 extern boolean_t kpc_multiple_clients(void); 256 257 /* 258 * Is kpc controlling the fixed counters? 259 * 260 * This returns false when the power manager has requested custom configuration 261 * control. 262 */ 263 extern boolean_t kpc_controls_fixed_counters(void); 264 265 /* 266 * Is kpc controlling a specific PMC ? 267 */ 268 extern boolean_t kpc_controls_counter(uint32_t ctr); 269 270 271 extern void kpc_idle(void); 272 extern void kpc_idle_exit(void); 273 274 275 /* 276 * KPC PRIVATE 277 */ 278 279 extern uint32_t kpc_actionid[KPC_MAX_COUNTERS]; 280 281 /* handler for mp operations */ 282 struct kpc_config_remote { 283 uint32_t classes; 284 kpc_config_t *configv; 285 uint64_t pmc_mask; 286 }; 287 288 /* handler for mp operations */ 289 struct kpc_running_remote { 290 uint32_t classes; /* classes to run */ 291 uint64_t cfg_target_mask; /* configurable counters selected */ 292 uint64_t cfg_state_mask; /* configurable counters new state */ 293 }; 294 295 /* handler for mp operations */ 296 struct kpc_get_counters_remote { 297 uint32_t classes; 298 uint32_t nb_counters; 299 uint32_t buf_stride; 300 uint64_t *buf; 301 }; 302 303 int kpc_get_all_cpus_counters(uint32_t classes, int *curcpu, uint64_t *buf); 304 int kpc_get_curcpu_counters(uint32_t classes, int *curcpu, uint64_t *buf); 305 int kpc_get_fixed_counters(uint64_t *counterv); 306 int kpc_get_configurable_counters(uint64_t *counterv, uint64_t pmc_mask); 307 boolean_t kpc_is_running_fixed(void); 308 boolean_t kpc_is_running_configurable(uint64_t pmc_mask); 309 uint32_t kpc_fixed_count(void); 310 uint32_t kpc_configurable_count(void); 311 uint32_t kpc_fixed_config_count(void); 312 uint32_t kpc_configurable_config_count(uint64_t pmc_mask); 313 uint32_t kpc_rawpmu_config_count(void); 314 int kpc_get_fixed_config(kpc_config_t *configv); 315 int kpc_get_configurable_config(kpc_config_t *configv, uint64_t pmc_mask); 316 int kpc_get_rawpmu_config(kpc_config_t *configv); 317 uint64_t kpc_fixed_max(void); 318 uint64_t kpc_configurable_max(void); 319 int kpc_set_config_arch(struct kpc_config_remote *mp_config); 320 int kpc_set_period_arch(struct kpc_config_remote *mp_config); 321 322 __options_decl(kperf_kpc_flags_t, uint16_t, { 323 KPC_KERNEL_PC = 0x01, 324 KPC_KERNEL_COUNTING = 0x02, 325 KPC_USER_COUNTING = 0x04, 326 }); 327 328 void kpc_sample_kperf(uint32_t actionid, uint32_t counter, uint64_t config, 329 uint64_t count, uintptr_t pc, kperf_kpc_flags_t flags); 330 331 int kpc_set_running_arch(struct kpc_running_remote *mp_config); 332 333 334 /* 335 * Helpers 336 */ 337 338 /* count the number of bits set */ 339 extern uint8_t kpc_popcount(uint64_t value); 340 341 /* for a set of classes, retrieve the configurable PMCs mask */ 342 extern uint64_t kpc_get_configurable_pmc_mask(uint32_t classes); 343 344 345 /* Interface for kexts to publish a kpc interface */ 346 struct kpc_driver { 347 uint32_t (*get_classes)(void); 348 uint32_t (*get_running)(void); 349 int (*set_running)(uint32_t classes); 350 int (*get_cpu_counters)(boolean_t all_cpus, uint32_t classes, 351 int *curcpu, uint64_t *buf); 352 int (*get_curthread_counters)(uint32_t *inoutcount, uint64_t *buf); 353 uint32_t (*get_counter_count)(uint32_t classes); 354 uint32_t (*get_config_count)(uint32_t classes); 355 int (*get_config)(uint32_t classes, kpc_config_t *current_config); 356 int (*set_config)(uint32_t classes, kpc_config_t *new_config); 357 int (*get_period)(uint32_t classes, uint64_t *period); 358 int (*set_period)(uint32_t classes, uint64_t *period); 359 }; 360 361 __END_DECLS 362 363 #endif /* !definde(KERN_KPC_H) */