No empty .Rs/.Re
[netbsd-mini2440.git] / sys / kern / sys_pmc.c
blob04023d49ad6f900868cbe2b4668ff2f22b2ade62
1 /* $NetBSD: sys_pmc.c,v 1.9 2007/12/20 23:03:11 dsl Exp $ */
3 /*
4 * Copyright (c) 2002 Wasabi Systems, Inc.
5 * All rights reserved.
7 * Written by Allen Briggs for Wasabi Systems, Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed for the NetBSD Project by
20 * Wasabi Systems, Inc.
21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior
23 * written permission.
25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: sys_pmc.c,v 1.9 2007/12/20 23:03:11 dsl Exp $");
41 #include "opt_perfctrs.h"
43 #include <sys/param.h>
44 #include <sys/proc.h>
45 #include <sys/mount.h>
46 #include <sys/systm.h>
47 #include <sys/syscallargs.h>
48 #include <sys/types.h>
50 #if defined(PERFCTRS)
51 #include <sys/pmc.h>
52 #endif
55 * XXX We need a multiprocessor locking protocol!
58 int
59 sys_pmc_control(struct lwp *l, const struct sys_pmc_control_args *uap, register_t *retval)
61 /* {
62 syscallarg(int) ctr;
63 syscallarg(int) op;
64 syscallarg(void *) args;
65 } */
66 #ifndef PERFCTRS
67 return ENXIO;
68 #else
69 struct pmc_counter_cfg cfg;
70 void *args;
71 int ctr, operation, error=0;
73 ctr = SCARG(uap, ctr);
74 operation = SCARG(uap, op);
76 KERNEL_LOCK(1, NULL);
77 switch (operation) {
78 case PMC_OP_START:
79 if (!pmc_counter_isconfigured(l->l_proc, ctr)) {
80 error = ENXIO;
81 } else if (pmc_counter_isrunning(l->l_proc, ctr)) {
82 error = EINPROGRESS;
83 } else {
84 pmc_enable_counter(l->l_proc, ctr);
86 break;
87 case PMC_OP_STOP:
88 if (!pmc_counter_isconfigured(l->l_proc, ctr)) {
89 error = ENXIO;
90 } else if (pmc_counter_isrunning(l->l_proc, ctr)) {
91 pmc_disable_counter(l->l_proc, ctr);
93 break;
94 case PMC_OP_CONFIGURE:
95 args = SCARG(uap, args);
97 if (pmc_counter_isrunning(l->l_proc, ctr)) {
98 pmc_disable_counter(l->l_proc, ctr);
100 error = copyin(args, &cfg, sizeof(struct pmc_counter_cfg));
101 if (error == 0) {
102 error = pmc_configure_counter(l->l_proc, ctr, &cfg);
104 break;
105 case PMC_OP_PROFSTART:
106 args = SCARG(uap, args);
108 error = copyin(args, &cfg, sizeof(struct pmc_counter_cfg));
109 if (error == 0) {
110 error = pmc_start_profiling(ctr, &cfg);
112 break;
113 case PMC_OP_PROFSTOP:
114 error = pmc_stop_profiling(ctr);
115 break;
116 default:
117 error = EINVAL;
118 break;
120 KERNEL_UNLOCK_ONE(NULL);
121 return error;
122 #endif
126 sys_pmc_get_info(struct lwp *l, const struct sys_pmc_get_info_args *uap, register_t *retval)
128 /* {
129 syscallarg(int) ctr;
130 syscallarg(int) op;
131 syscallarg(void *) args;
132 } */
133 #ifndef PERFCTRS
134 return ENXIO;
135 #else
136 uint64_t val;
137 void *args;
138 int nctrs, ctr, ctrt, request, error=0, flags=0;
140 ctr = SCARG(uap, ctr);
141 request = SCARG(uap, op);
142 args = SCARG(uap, args);
144 KERNEL_LOCK(1, NULL);
145 nctrs = pmc_get_num_counters();
146 switch (request) {
147 case PMC_INFO_NCOUNTERS: /* args should be (int *) */
148 error = copyout(&nctrs, args, sizeof(int));
149 break;
151 case PMC_INFO_CPUCTR_TYPE: /* args should be (int *) */
152 ctrt = pmc_get_counter_type(ctr);
153 error = copyout(&ctrt, args, sizeof(int));
154 break;
155 /* args should be (pmc_ctr_t *) */
156 case PMC_INFO_ACCUMULATED_COUNTER_VALUE:
157 flags = PMC_VALUE_FLAGS_CHILDREN;
158 /*FALLTHROUGH*/
159 case PMC_INFO_COUNTER_VALUE:
160 if (ctr < 0 || ctr >= nctrs) {
161 error = EINVAL;
162 break;
164 error = pmc_get_counter_value(l->l_proc, ctr, flags, &val);
165 if (error == 0) {
166 error = copyout(&val, args, sizeof(uint64_t));
168 break;
169 default:
170 error = EINVAL;
171 break;
173 KERNEL_UNLOCK_ONE(NULL);
174 return error;
175 #endif