/ duct-tape / xnu / osfmk / kern / kpc.h
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) */