1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67#include <profiling/profile-internal.h>
68
69#ifdef MACH_KERNEL
70#include <profiling/machine/profile-md.h>
71#endif
72
73#ifndef PROFILE_VARS
74#define PROFILE_VARS(cpu) (&_profile_vars)
75#endif
76
77extern int printf(const char *, ...);
78
79
80
81
82
83
84
85long
86_profile_kgmon(int write,
87 size_t count,
88 long indx,
89 int max_cpus,
90 void **p_ptr,
91 void (*control_func)(kgmon_control_t))
92{
93 kgmon_control_t kgmon;
94 int cpu;
95 int error = 0;
96 int i;
97 struct profile_vars *pv;
98 static struct callback dummy_callback;
99
100 *p_ptr = (void *)0;
101
102
103
104
105
106 if (!LEGAL_KGMON(indx)) {
107 *p_ptr = (void *)indx;
108 if (!write) {
109 if (PROFILE_VARS(0)->debug) {
110 printf("_profile_kgmon: copy %5ld bytes, from 0x%lx\n",
111 (long)count,
112 (long)indx);
113 }
114
115 } else {
116 if (PROFILE_VARS(0)->debug) {
117 printf("_profile_kgmon: copy %5ld bytes, to 0x%lx\n",
118 (long)count,
119 (long)indx);
120 }
121 }
122
123 return count;
124 }
125
126
127
128
129
130 DECODE_KGMON(indx, kgmon, cpu);
131
132 if (PROFILE_VARS(0)->debug) {
133 printf("_profile_kgmon: start: kgmon control = %2d, cpu = %d, count = %ld\n",
134 kgmon, cpu, (long)count);
135 }
136
137
138 if (cpu < 0 || cpu >= max_cpus) {
139 if (PROFILE_VARS(0)->debug) {
140 printf("KGMON, bad cpu %d\n", cpu);
141 }
142
143 return -1;
144
145 } else {
146 pv = PROFILE_VARS(cpu);
147
148 if (!write) {
149 switch (kgmon) {
150 default:
151 if (PROFILE_VARS(0)->debug) {
152 printf("Unknown KGMON read command\n");
153 }
154
155 error = -1;
156 break;
157
158 case KGMON_GET_STATUS:
159 if (cpu != 0) {
160 if (PROFILE_VARS(0)->debug) {
161 printf("KGMON_GET_STATUS: cpu = %d\n", cpu);
162 }
163
164 error = -1;
165 break;
166 }
167
168 if (count != sizeof(pv->active)) {
169 if (PROFILE_VARS(0)->debug) {
170 printf("KGMON_GET_STATUS: count = %ld, should be %ld\n",
171 (long)count,
172 (long)sizeof(pv->active));
173 }
174
175 error = -1;
176 break;
177 }
178
179 *p_ptr = (void *)&pv->active;
180 break;
181
182 case KGMON_GET_DEBUG:
183 if (cpu != 0) {
184 if (PROFILE_VARS(0)->debug) {
185 printf("KGMON_GET_DEBUG: cpu = %d\n", cpu);
186 }
187
188 error = -1;
189 break;
190 }
191
192 if (count != sizeof(pv->debug)) {
193 if (PROFILE_VARS(0)->debug) {
194 printf("KGMON_GET_DEBUG: count = %ld, should be %ld\n",
195 (long)count,
196 (long)sizeof(pv->active));
197 }
198
199 error = -1;
200 break;
201 }
202
203 *p_ptr = (void *)&pv->debug;
204 break;
205
206 case KGMON_GET_PROFILE_VARS:
207 if (count != sizeof(struct profile_vars)) {
208 if (PROFILE_VARS(0)->debug) {
209 printf("KGMON_GET_PROFILE_VARS: count = %ld, should be %ld\n",
210 (long)count,
211 (long)sizeof(struct profile_vars));
212 }
213
214 error = -1;
215 break;
216 }
217
218 _profile_update_stats(pv);
219 *p_ptr = (void *)pv;
220 break;
221
222 case KGMON_GET_PROFILE_STATS:
223 if (count != sizeof(struct profile_stats)) {
224 if (PROFILE_VARS(0)->debug) {
225 printf("KGMON_GET_PROFILE_STATS: count = %ld, should be = %ld\n",
226 (long)count,
227 (long)sizeof(struct profile_stats));
228 }
229
230 error = -1;
231 break;
232 }
233
234 _profile_update_stats(pv);
235 *p_ptr = (void *)&pv->stats;
236 break;
237 }
238
239 } else {
240 switch (kgmon) {
241 default:
242 if (PROFILE_VARS(0)->debug) {
243 printf("Unknown KGMON write command\n");
244 }
245
246 error = -1;
247 break;
248
249 case KGMON_SET_PROFILE_ON:
250 if (cpu != 0) {
251 if (PROFILE_VARS(0)->debug) {
252 printf("KGMON_SET_PROFILE_ON, cpu = %d\n", cpu);
253 }
254
255 error = -1;
256 break;
257 }
258
259 if (!PROFILE_VARS(0)->active) {
260 for (i = 0; i < max_cpus; i++) {
261 PROFILE_VARS(i)->active = 1;
262 }
263
264 if (control_func) {
265 (*control_func)(kgmon);
266 }
267
268 _profile_md_start();
269 }
270
271 count = 0;
272 break;
273
274 case KGMON_SET_PROFILE_OFF:
275 if (cpu != 0) {
276 if (PROFILE_VARS(0)->debug) {
277 printf("KGMON_SET_PROFILE_OFF, cpu = %d\n", cpu);
278 }
279
280 error = -1;
281 break;
282 }
283
284 if (PROFILE_VARS(0)->active) {
285 for (i = 0; i < max_cpus; i++) {
286 PROFILE_VARS(i)->active = 0;
287 }
288
289 _profile_md_stop();
290
291 if (control_func) {
292 (*control_func)(kgmon);
293 }
294 }
295
296 count = 0;
297 break;
298
299 case KGMON_SET_PROFILE_RESET:
300 if (cpu != 0) {
301 if (PROFILE_VARS(0)->debug) {
302 printf("KGMON_SET_PROFILE_RESET, cpu = %d\n", cpu);
303 }
304
305 error = -1;
306 break;
307 }
308
309 for (i = 0; i < max_cpus; i++) {
310 _profile_reset(PROFILE_VARS(i));
311 }
312
313 if (control_func) {
314 (*control_func)(kgmon);
315 }
316
317 count = 0;
318 break;
319
320 case KGMON_SET_DEBUG_ON:
321 if (cpu != 0) {
322 if (PROFILE_VARS(0)->debug) {
323 printf("KGMON_SET_DEBUG_ON, cpu = %d\n", cpu);
324 }
325
326 error = -1;
327 break;
328 }
329
330 if (!PROFILE_VARS(0)->debug) {
331 for (i = 0; i < max_cpus; i++) {
332 PROFILE_VARS(i)->debug = 1;
333 }
334
335 if (control_func) {
336 (*control_func)(kgmon);
337 }
338 }
339
340 count = 0;
341 break;
342
343 case KGMON_SET_DEBUG_OFF:
344 if (cpu != 0) {
345 if (PROFILE_VARS(0)->debug) {
346 printf("KGMON_SET_DEBUG_OFF, cpu = %d\n", cpu);
347 }
348
349 error = -1;
350 break;
351 }
352
353 if (PROFILE_VARS(0)->debug) {
354 for (i = 0; i < max_cpus; i++) {
355 PROFILE_VARS(i)->debug = 0;
356 }
357
358 if (control_func) {
359 (*control_func)(kgmon);
360 }
361 }
362
363 count = 0;
364 break;
365 }
366 }
367 }
368
369 if (error) {
370 if (PROFILE_VARS(0)->debug) {
371 printf("_profile_kgmon: done: kgmon control = %2d, cpu = %d, error = %d\n",
372 kgmon, cpu, error);
373 }
374
375 return -1;
376 }
377
378 if (PROFILE_VARS(0)->debug) {
379 printf("_profile_kgmon: done: kgmon control = %2d, cpu = %d, count = %ld\n",
380 kgmon, cpu, (long)count);
381 }
382
383 return count;
384}
385