1 /* $NetBSD: pmc.c,v 1.2 2003/03/09 00:42:56 lukem Exp $ */
4 * Copyright (c 2002 Wasabi Systems, Inc.
7 * Written by Jason R. Thorpe 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
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
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 __RCSID("$NetBSD: pmc.c,v 1.2 2003/03/09 00:42:56 lukem Exp $");
41 #include <sys/param.h>
46 #include "pmc_private.h"
48 static const struct pmc_class2evid
*
49 _pmc_type_lookup(int classval
)
51 const struct pmc_class2evid
*class;
53 for (class = _pmc_md_classes
; class->name
!= NULL
; class++) {
54 if (class->class == classval
)
60 static const struct pmc_event
*
61 _pmc_evid_lookup(const char *evname
)
63 const struct pmc_class2evid
*class;
64 const struct pmc_event
*evid
;
67 if (pmc_get_info(-1, PMC_INFO_CPUCTR_TYPE
, &classval
) == -1) {
68 /* Sets errno for us. */
72 if ((class = _pmc_type_lookup(classval
)) == NULL
) {
77 for (evid
= class->evids
; evid
->name
!= NULL
; evid
++) {
78 if (evname
[0] == evid
->name
[0] &&
79 strcmp(evname
, evid
->name
) == 0)
82 if (evid
->name
== NULL
) {
91 pmc_configure_counter(int ctr
, const char *evname
, pmc_ctr_t reset_val
,
94 struct pmc_counter_cfg pcfg
;
95 const struct pmc_event
*evid
;
97 evid
= _pmc_evid_lookup(evname
);
99 /* _pmc_evid_lookup() set errno */
103 pcfg
.event_id
= evid
->val
;
104 pcfg
.reset_value
= reset_val
;
107 return (pmc_control(ctr
, PMC_OP_CONFIGURE
, &pcfg
));
111 pmc_start_counter(int ctr
)
113 return (pmc_control(ctr
, PMC_OP_START
, NULL
));
117 pmc_stop_counter(int ctr
)
119 return (pmc_control(ctr
, PMC_OP_STOP
, NULL
));
123 pmc_get_num_counters(void)
127 if (pmc_get_info(-1, PMC_INFO_NCOUNTERS
, &rv
) == -1)
134 pmc_get_counter_class(void)
138 if (pmc_get_info(-1, PMC_INFO_CPUCTR_TYPE
, &rv
) == -1)
145 pmc_get_counter_type(int ctr
, int *typep
)
147 /* If they want class, they should call pmc_get_counter_class(). */
153 return (pmc_get_info(ctr
, PMC_INFO_CPUCTR_TYPE
, typep
));
157 pmc_get_counter_value(int ctr
, uint64_t *valp
)
159 return (pmc_get_info(ctr
, PMC_INFO_COUNTER_VALUE
, valp
));
163 pmc_get_accumulated_counter_value(int ctr
, uint64_t *valp
)
165 return (pmc_get_info(ctr
, PMC_INFO_ACCUMULATED_COUNTER_VALUE
, valp
));
169 pmc_get_counter_class_name(int classval
)
171 const struct pmc_class2evid
*class;
173 class = _pmc_type_lookup(classval
);
179 return (class->name
);
183 pmc_get_counter_type_name(int type
)
185 const struct pmc_class2evid
*class;
187 class = _pmc_type_lookup(type
);
193 return (class->name
);
197 pmc_get_counter_event_name(pmc_evid_t event
)
199 const struct pmc_class2evid
*class;
200 const struct pmc_event
*evid
;
203 if (pmc_get_info(-1, PMC_INFO_CPUCTR_TYPE
, &classval
) == -1) {
204 /* Sets errno for us. */
208 if ((class = _pmc_type_lookup(classval
)) == NULL
) {
213 for (evid
= class->evids
; evid
->name
!= NULL
; evid
++) {
214 if (evid
->val
== event
)
217 if (evid
->name
== NULL
) {
225 const struct pmc_event
*
226 pmc_get_counter_event_list(void)
228 const struct pmc_class2evid
*class;
231 if (pmc_get_info(-1, PMC_INFO_CPUCTR_TYPE
, &classval
) == -1) {
232 /* Sets errno for us. */
236 if ((class = _pmc_type_lookup(classval
)) == NULL
) {
241 return (class->evids
);