]> git.saurik.com Git - apple/xnu.git/blob - bsd/sys/monotonic.h
xnu-4570.20.62.tar.gz
[apple/xnu.git] / bsd / sys / monotonic.h
1 #ifndef SYS_MONOTONIC_H
2 #define SYS_MONOTONIC_H
3
4 #include <stdbool.h>
5 #include <stdint.h>
6 #include <sys/cdefs.h>
7 #include <sys/ioccom.h>
8
9 __BEGIN_DECLS
10
11 /*
12 * XXX These declarations are subject to change at any time.
13 */
14
15 struct monotonic_config {
16 uint64_t event;
17 uint64_t allowed_ctr_mask;
18 };
19
20 union monotonic_ctl_add {
21 struct {
22 struct monotonic_config config;
23 } in;
24
25 struct {
26 uint32_t ctr;
27 } out;
28 };
29
30 union monotonic_ctl_enable {
31 struct {
32 bool enable;
33 } in;
34 };
35
36 union monotonic_ctl_counts {
37 struct {
38 uint64_t ctr_mask;
39 } in;
40
41 struct {
42 uint64_t counts[1];
43 } out;
44 };
45
46 #define MT_IOC(x) _IO('m', (x))
47
48 /*
49 * FIXME
50 *
51 * - Consider a separate IOC for disable -- to avoid the copyin to determine which way to set it.
52 *
53 * - Maybe IOC_COUNTS should just return all the enable counters' counts.
54 */
55 enum monotonic_ioc {
56 MT_IOC_RESET = MT_IOC(0),
57 MT_IOC_ADD = MT_IOC(1),
58 MT_IOC_ENABLE = MT_IOC(2),
59 MT_IOC_COUNTS = MT_IOC(3),
60 };
61
62 #undef MT_IOC
63
64 #if XNU_KERNEL_PRIVATE
65
66 #include <kern/monotonic.h>
67 #include <machine/monotonic.h>
68 #include <sys/kdebug.h>
69 #include <kern/locks.h>
70
71 #ifdef MT_CORE_INSTRS
72 #define COUNTS_INSTRS __counts[MT_CORE_INSTRS]
73 #else /* defined(MT_CORE_INSTRS) */
74 #define COUNTS_INSTRS 0
75 #endif /* !defined(MT_CORE_INSTRS) */
76
77 /*
78 * MT_KDBG_TMP* macros are meant for temporary (i.e. not checked-in)
79 * performance investigations.
80 */
81
82 /*
83 * Record the current CPU counters.
84 *
85 * Preemption must be disabled.
86 */
87 #define MT_KDBG_TMPCPU_EVT(CODE) \
88 KDBG_EVENTID(DBG_MONOTONIC, DBG_MT_TMPCPU, CODE)
89
90 #define MT_KDBG_TMPCPU_(CODE, FUNC) \
91 do { \
92 if (kdebug_enable && \
93 kdebug_debugid_enabled(MT_KDBG_TMPCPU_EVT(CODE))) { \
94 uint64_t __counts[MT_CORE_NFIXED]; \
95 mt_fixed_counts(__counts); \
96 KDBG(MT_KDBG_TMPCPU_EVT(CODE) | (FUNC), COUNTS_INSTRS, \
97 __counts[MT_CORE_CYCLES]); \
98 } \
99 } while (0)
100
101 #define MT_KDBG_TMPCPU(CODE) MT_KDBG_TMPCPU_(CODE, DBG_FUNC_NONE)
102 #define MT_KDBG_TMPCPU_START(CODE) MT_KDBG_TMPCPU_(CODE, DBG_FUNC_START)
103 #define MT_KDBG_TMPCPU_END(CODE) MT_KDBG_TMPCPU_(CODE, DBG_FUNC_END)
104
105 /*
106 * Record the current thread counters.
107 *
108 * Interrupts must be disabled.
109 */
110 #define MT_KDBG_TMPTH_EVT(CODE) \
111 KDBG_EVENTID(DBG_MONOTONIC, DBG_MT_TMPTH, CODE)
112
113 #define MT_KDBG_TMPTH_(CODE, FUNC) \
114 do { \
115 if (kdebug_enable && \
116 kdebug_debugid_enabled(MT_KDBG_TMPTH_EVT(CODE))) { \
117 uint64_t __counts[MT_CORE_NFIXED]; \
118 mt_cur_thread_fixed_counts(__counts); \
119 KDBG(MT_KDBG_TMPTH_EVT(CODE) | (FUNC), COUNTS_INSTRS, \
120 __counts[MT_CORE_CYCLES]); \
121 } \
122 } while (0)
123
124 #define MT_KDBG_TMPTH(CODE) MT_KDBG_TMPTH_(CODE, DBG_FUNC_NONE)
125 #define MT_KDBG_TMPTH_START(CODE) MT_KDBG_TMPTH_(CODE, DBG_FUNC_START)
126 #define MT_KDBG_TMPTH_END(CODE) MT_KDBG_TMPTH_(CODE, DBG_FUNC_END)
127
128 /* maybe provider, bank, group, set, unit, pmu */
129
130 struct monotonic_dev {
131 const char *mtd_name;
132 int (*mtd_init)(void);
133 int (*mtd_add)(struct monotonic_config *config, uint32_t *ctr_out);
134 void (*mtd_reset)(void);
135 void (*mtd_enable)(bool enable);
136 int (*mtd_read)(uint64_t ctr_mask, uint64_t *counts_out);
137 };
138
139 extern const struct monotonic_dev monotonic_devs[];
140
141 extern lck_grp_t *mt_lock_grp;
142
143 int mt_dev_init(void);
144
145 #endif /* XNU_KERNEL_PRIVATE */
146
147 __END_DECLS
148
149 #endif /* !defined(SYS_MONOTONIC_H) */