xref: /xnu-8019.80.24/bsd/sys/monotonic.h (revision a325d9c4a84054e40bbe985afedcb50ab80993ea)
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 __BEGIN_DECLS
37 
38 struct mt_cpu_inscyc {
39 	uint64_t mtci_instructions;
40 	uint64_t mtci_cycles;
41 };
42 
43 __END_DECLS
44 
45 #if !MACH_KERNEL_PRIVATE
46 
47 #include <sys/ioccom.h>
48 
49 __BEGIN_DECLS
50 
51 /*
52  * XXX These declarations are subject to change at any time.
53  */
54 
55 #define MT_IOC(x) _IO('m', (x))
56 #define MT_IOC_RESET MT_IOC(0)
57 #define MT_IOC_ADD MT_IOC(1)
58 #define MT_IOC_ENABLE MT_IOC(2)
59 #define MT_IOC_COUNTS MT_IOC(3)
60 #define MT_IOC_GET_INFO MT_IOC(4)
61 
62 __END_DECLS
63 
64 #endif /* !MACH_KERNEL_PRIVATE */
65 
66 __BEGIN_DECLS
67 
68 struct monotonic_config {
69 	uint64_t event;
70 	uint64_t allowed_ctr_mask;
71 	uint64_t cpu_mask;
72 };
73 
74 union monotonic_ctl_add {
75 	struct {
76 		struct monotonic_config config;
77 	} in;
78 
79 	struct {
80 		uint32_t ctr;
81 	} out;
82 };
83 
84 union monotonic_ctl_enable {
85 	struct {
86 		bool enable;
87 	} in;
88 };
89 
90 
91 union monotonic_ctl_counts {
92 	struct {
93 		uint64_t ctr_mask;
94 	} in;
95 
96 	struct {
97 		uint64_t counts[1];
98 	} out;
99 };
100 
101 
102 union monotonic_ctl_info {
103 	struct {
104 		unsigned int nmonitors;
105 		unsigned int ncounters;
106 	} out;
107 };
108 
109 __END_DECLS
110 
111 #if XNU_KERNEL_PRIVATE
112 
113 #if MONOTONIC
114 
115 #include <kern/monotonic.h>
116 #include <machine/monotonic.h>
117 #include <sys/kdebug.h>
118 #include <kern/locks.h>
119 
120 __BEGIN_DECLS
121 
122 #ifdef MT_CORE_INSTRS
123 #define COUNTS_INSTRS __counts[MT_CORE_INSTRS]
124 #else /* defined(MT_CORE_INSTRS) */
125 #define COUNTS_INSTRS 0
126 #endif /* !defined(MT_CORE_INSTRS) */
127 
128 /*
129  * MT_KDBG_TMP* macros are meant for temporary (i.e. not checked-in)
130  * performance investigations.
131  */
132 
133 /*
134  * Record the current CPU counters.
135  *
136  * Preemption must be disabled.
137  */
138 #define MT_KDBG_TMPCPU_EVT(CODE) \
139 	KDBG_EVENTID(DBG_MONOTONIC, DBG_MT_TMPCPU, CODE)
140 
141 #define MT_KDBG_TMPCPU_(CODE, FUNC) \
142 	do { \
143 	        if (kdebug_enable && \
144 	                        kdebug_debugid_enabled(MT_KDBG_TMPCPU_EVT(CODE))) { \
145 	                uint64_t __counts[MT_CORE_NFIXED]; \
146 	                mt_fixed_counts(__counts); \
147 	                KDBG(MT_KDBG_TMPCPU_EVT(CODE) | (FUNC), COUNTS_INSTRS, \
148 	                                __counts[MT_CORE_CYCLES]); \
149 	        } \
150 	} while (0)
151 
152 #define MT_KDBG_TMPCPU(CODE) MT_KDBG_TMPCPU_(CODE, DBG_FUNC_NONE)
153 #define MT_KDBG_TMPCPU_START(CODE) MT_KDBG_TMPCPU_(CODE, DBG_FUNC_START)
154 #define MT_KDBG_TMPCPU_END(CODE) MT_KDBG_TMPCPU_(CODE, DBG_FUNC_END)
155 
156 /*
157  * Record the current thread counters.
158  *
159  * Interrupts must be disabled.
160  */
161 #define MT_KDBG_TMPTH_EVT(CODE) \
162 	KDBG_EVENTID(DBG_MONOTONIC, DBG_MT_TMPTH, CODE)
163 
164 #define MT_KDBG_TMPTH_(CODE, FUNC) \
165 	do { \
166 	        if (kdebug_enable && \
167 	                        kdebug_debugid_enabled(MT_KDBG_TMPTH_EVT(CODE))) { \
168 	                uint64_t __counts[MT_CORE_NFIXED]; \
169 	                mt_cur_thread_fixed_counts(__counts); \
170 	                KDBG(MT_KDBG_TMPTH_EVT(CODE) | (FUNC), COUNTS_INSTRS, \
171 	                                __counts[MT_CORE_CYCLES]); \
172 	        } \
173 	} while (0)
174 
175 #define MT_KDBG_TMPTH(CODE) MT_KDBG_TMPTH_(CODE, DBG_FUNC_NONE)
176 #define MT_KDBG_TMPTH_START(CODE) MT_KDBG_TMPTH_(CODE, DBG_FUNC_START)
177 #define MT_KDBG_TMPTH_END(CODE) MT_KDBG_TMPTH_(CODE, DBG_FUNC_END)
178 
179 extern lck_grp_t mt_lock_grp;
180 
181 int mt_dev_init(void);
182 
183 struct mt_device {
184 	const char *mtd_name;
185 	int(*const mtd_init)(struct mt_device *dev);
186 	int(*const mtd_add)(struct monotonic_config *config, uint32_t *ctr_out);
187 	void(*const mtd_reset)(void);
188 	void(*const mtd_enable)(bool enable);
189 	int(*const mtd_read)(uint64_t ctr_mask, uint64_t *counts_out);
190 	decl_lck_mtx_data(, mtd_lock);
191 
192 	uint8_t mtd_nmonitors;
193 	uint8_t mtd_ncounters;
194 	bool mtd_inuse;
195 };
196 typedef struct mt_device *mt_device_t;
197 
198 extern struct mt_device mt_devices[];
199 
200 __END_DECLS
201 
202 #endif /* MONOTONIC */
203 
204 #endif /* XNU_KERNEL_PRIVATE */
205 
206 #endif /* !defined(SYS_MONOTONIC_H) */
207