1/*
2 * Copyright (c) 2017-2019 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 SYS_MONOTONIC_H
30#define SYS_MONOTONIC_H
31
32#include <stdbool.h>
33#include <stdint.h>
34#include <sys/cdefs.h>
35
36#if !MACH_KERNEL_PRIVATE
37
38#include <sys/ioccom.h>
39
40__BEGIN_DECLS
41
42/*
43 * XXX These declarations are subject to change at any time.
44 */
45
46#define MT_IOC(x) _IO('m', (x))
47#define MT_IOC_RESET MT_IOC(0)
48#define MT_IOC_ADD MT_IOC(1)
49#define MT_IOC_ENABLE MT_IOC(2)
50#define MT_IOC_COUNTS MT_IOC(3)
51#define MT_IOC_GET_INFO MT_IOC(4)
52
53__END_DECLS
54
55#endif /* !MACH_KERNEL_PRIVATE */
56
57__BEGIN_DECLS
58
59struct monotonic_config {
60 uint64_t event;
61 uint64_t allowed_ctr_mask;
62 uint64_t cpu_mask;
63};
64
65union monotonic_ctl_add {
66 struct {
67 struct monotonic_config config;
68 } in;
69
70 struct {
71 uint32_t ctr;
72 } out;
73};
74
75union monotonic_ctl_enable {
76 struct {
77 bool enable;
78 } in;
79};
80
81
82union monotonic_ctl_counts {
83 struct {
84 uint64_t ctr_mask;
85 } in;
86
87 struct {
88 uint64_t counts[1];
89 } out;
90};
91
92
93union monotonic_ctl_info {
94 struct {
95 unsigned int nmonitors;
96 unsigned int ncounters;
97 } out;
98};
99
100__END_DECLS
101
102#if XNU_KERNEL_PRIVATE
103
104#if CONFIG_CPU_COUNTERS
105
106#include <kern/monotonic.h>
107#include <machine/monotonic.h>
108#include <sys/kdebug.h>
109#include <kern/locks.h>
110
111__BEGIN_DECLS
112
113/*
114 * MT_KDBG_TMP* macros are meant for temporary (i.e. not checked-in)
115 * performance investigations.
116 */
117
118/*
119 * Record the current CPU counters.
120 *
121 * Preemption must be disabled.
122 */
123#define MT_KDBG_TMPCPU_EVT(CODE) \
124 KDBG_EVENTID(DBG_MONOTONIC, DBG_MT_TMPCPU, CODE)
125
126#define MT_KDBG_TMPCPU_(CODE, FUNC) \
127 do { \
128 if (kdebug_enable && \
129 kdebug_debugid_enabled(MT_KDBG_TMPCPU_EVT(CODE))) { \
130 uint64_t __counts[MT_CORE_NFIXED]; \
131 mt_fixed_counts(__counts); \
132 KDBG(MT_KDBG_TMPCPU_EVT(CODE) | (FUNC), __counts[MT_CORE_INSTRS], \
133 __counts[MT_CORE_CYCLES]); \
134 } \
135 } while (0)
136
137#define MT_KDBG_TMPCPU(CODE) MT_KDBG_TMPCPU_(CODE, DBG_FUNC_NONE)
138#define MT_KDBG_TMPCPU_START(CODE) MT_KDBG_TMPCPU_(CODE, DBG_FUNC_START)
139#define MT_KDBG_TMPCPU_END(CODE) MT_KDBG_TMPCPU_(CODE, DBG_FUNC_END)
140
141extern lck_grp_t mt_lock_grp;
142
143int mt_dev_init(void);
144
145struct mt_device {
146 const char *mtd_name;
147 int(*const mtd_init)(struct mt_device *dev);
148 int(*const mtd_add)(struct monotonic_config *config, uint32_t *ctr_out);
149 void(*const mtd_reset)(void);
150 void(*const mtd_enable)(bool enable);
151 int(*const mtd_read)(uint64_t ctr_mask, uint64_t *counts_out);
152 decl_lck_mtx_data(, mtd_lock);
153
154 uint8_t mtd_nmonitors;
155 uint8_t mtd_ncounters;
156 bool mtd_inuse;
157};
158typedef struct mt_device *mt_device_t;
159
160extern struct mt_device mt_devices[];
161
162__END_DECLS
163
164#endif /* CONFIG_CPU_COUNTERS */
165
166#endif /* XNU_KERNEL_PRIVATE */
167
168#endif /* !defined(SYS_MONOTONIC_H) */
169