4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #ifndef _LIBCPC_IMPL_H
28 #define _LIBCPC_IMPL_H
30 #pragma ident "%Z%%M% %I% %E% SMI"
36 #include <sys/types.h>
37 #include <sys/cpc_impl.h>
44 #define CPC1_BUFSIZE (2 * sizeof (uint64_t))
47 char ca_name
[CPC_MAX_ATTR_LEN
];
51 typedef struct __cpc_request cpc_request_t
;
53 struct __cpc_request
{
54 char cr_event
[CPC_MAX_EVENT_LEN
];
55 uint64_t cr_preset
; /* Initial value */
56 uint16_t cr_index
; /* Index of request in data */
58 uint_t cr_nattrs
; /* # CPU-specific attrs */
60 cpc_request_t
*cr_next
; /* next request in set */
64 uint64_t *cb_data
; /* Pointer to data store */
65 hrtime_t cb_hrtime
; /* hrtime at last sample */
66 uint64_t cb_tick
; /* virtualized tsc/tick */
67 size_t cb_size
; /* Size of data store, bytes */
68 cpc_buf_t
*cb_next
; /* List of all bufs */
72 * Possible cpc_set_t states:
75 CS_UNBOUND
, /* Set is not currently bound */
76 CS_BOUND_CURLWP
, /* Set has been bound to curlwp */
77 CS_BOUND_PCTX
, /* Set has been bound via libpctx */
78 CS_BOUND_CPU
/* Set has been bound to a CPU */
82 cpc_request_t
*cs_request
; /* linked list of requests */
83 __cpc_state_t cs_state
; /* State of this set */
84 int cs_nreqs
; /* Number of requests in set */
85 int cs_fd
; /* file descriptor of cpc dev */
86 processorid_t cs_obind
; /* previous proc binding */
87 pctx_t
*cs_pctx
; /* pctx of process bound to */
88 id_t cs_id
; /* lwp ID of pctx binding */
89 thread_t cs_thr
; /* thread ID which bound set */
90 cpc_set_t
*cs_next
; /* Linked list of all sets */
94 cpc_set_t
*cpc_sets
; /* List of existing sets */
95 cpc_buf_t
*cpc_bufs
; /* List of existing bufs */
96 cpc_errhndlr_t
*cpc_errfn
; /* Handles library errors */
97 mutex_t cpc_lock
; /* Protect various ops */
98 char *cpc_attrlist
; /* List of supported attrs */
99 char **cpc_evlist
; /* List of events per pic */
100 char cpc_cpuref
[CPC_MAX_CPUREF
];
101 char cpc_cciname
[CPC_MAX_IMPL_NAME
];
107 * cpc_t handle for CPCv1 clients.
112 extern void __cpc_error(const char *fn
, const char *fmt
, ...);
114 extern const char *__cpc_reg_to_name(int cpuver
, int regno
, uint8_t bits
);
115 extern int __cpc_name_to_reg(int cpuver
, int regno
,
116 const char *name
, uint8_t *bits
);
118 extern uint_t __cpc_workver
;
119 extern int __cpc_v1_cpuver
;
121 extern uint64_t __cpc_v1_pcr
;
123 extern uint32_t __cpc_v1_pes
[2];
126 extern char *__cpc_pack_set(cpc_set_t
*set
, uint_t flags
, size_t *buflen
);
128 typedef struct __cpc_strhash cpc_strhash_t
;
130 struct __cpc_strhash
{
132 struct __cpc_strhash
*cur
;
133 struct __cpc_strhash
*next
;
136 extern cpc_strhash_t
*__cpc_strhash_alloc(void);
137 extern void __cpc_strhash_free(cpc_strhash_t
*hash
);
138 extern int __cpc_strhash_add(cpc_strhash_t
*hash
, char *key
);
139 extern char *__cpc_strhash_next(cpc_strhash_t
*hash
);
142 * Implementation-private system call used by libcpc
145 extern int __pctx_cpc(pctx_t
*pctx
, struct __cpc
*cpc
, int cmd
, id_t lwpid
,
146 void *data1
, void *data2
, void *data3
, int bufsize
);
148 #define CPUDRV "/devices/pseudo/cpc@0"
149 #define CPUDRV_SHARED CPUDRV":shared"
151 #if defined(__sparc) || defined(__i386)
153 * These two are only used for backwards compatibility to the Obsolete CPCv1.
155 extern int __cpc_init(void);
156 extern cpc_set_t
*__cpc_eventtoset(cpc_t
*cpc
, cpc_event_t
*event
, int flags
);
161 #define CPC_ULTRA1 1000
162 #define CPC_ULTRA2 1001 /* same as ultra1 for these purposes */
163 #define CPC_ULTRA3 1002
164 #define CPC_ULTRA3_PLUS 1003
165 #define CPC_ULTRA3_I 1004
166 #define CPC_ULTRA4_PLUS 1005
168 #define CPC_PENTIUM 2000
169 #define CPC_PENTIUM_MMX 2001
170 #define CPC_PENTIUM_PRO 2002
171 #define CPC_PENTIUM_PRO_MMX 2003
173 #define CPC_SPARC64_III 3000
174 #define CPC_SPARC64_V 3002
176 #endif /* __sparc || __i386 */
178 #if defined(__i386) || defined(__amd64)
180 * This is common between i386 and amd64, because amd64 implements %tick.
181 * Currently only used by the cpc tools to print the label atop the CPU ticks
184 #define CPC_TICKREG_NAME "tsc"
185 #endif /* __i386 || __amd64 */
190 * UltraSPARC I, II, III and IV processors
192 * The performance counters on these processors allow up to two 32-bit
193 * performance events to be captured simultaneously from a selection
194 * of metrics. The metrics are selected by writing to the performance
195 * control register, and subsequent values collected by reading from the
196 * performance instrumentation counter registers. Both registers are
197 * priviliged by default, and implemented as ASRs.
202 hrtime_t ce_hrt
; /* gethrtime() */
203 uint64_t ce_tick
; /* virtualized %tick */
204 uint64_t ce_pic
[2]; /* virtualized %pic */
205 uint64_t ce_pcr
; /* %pcr */
208 #define CPC_TICKREG(ev) ((ev)->ce_tick)
209 #define CPC_TICKREG_NAME "%tick"
212 * "Well known" bitfields in the UltraSPARC %pcr register
213 * The interfaces in libcpc should make these #defines uninteresting.
215 #define CPC_ULTRA_PCR_USR 2
216 #define CPC_ULTRA_PCR_SYS 1
217 #define CPC_ULTRA_PCR_PRIVPIC 0
219 #define CPC_ULTRA_PCR_PIC0_SHIFT 4
220 #define CPC_ULTRA2_PCR_PIC0_MASK UINT64_C(0xf)
221 #define CPC_ULTRA3_PCR_PIC0_MASK UINT64_C(0x3f)
222 #define CPC_ULTRA_PCR_PIC1_SHIFT 11
223 #define CPC_ULTRA2_PCR_PIC1_MASK UINT64_C(0xf)
224 #define CPC_ULTRA3_PCR_PIC1_MASK UINT64_C(0x3f)
226 #elif defined(__i386)
229 * Pentium I, II and III processors
231 * These CPUs allow pairs of events to captured.
232 * The hardware counters count up to 40-bits of significance, but
233 * only allow 32 (signed) bits to be programmed into them.
234 * Pentium I and Pentium II processors are programmed differently, but
235 * the resulting counters and timestamps can be handled portably.
240 hrtime_t ce_hrt
; /* gethrtime() */
241 uint64_t ce_tsc
; /* virtualized rdtsc value */
242 uint64_t ce_pic
[2]; /* virtualized PerfCtr[01] */
243 uint32_t ce_pes
[2]; /* Pentium II */
244 #define ce_cesr ce_pes[0] /* Pentium I */
247 #define CPC_TICKREG(ev) ((ev)->ce_tsc)
250 * "Well known" bit fields in the Pentium CES register
251 * The interfaces in libcpc should make these #defines uninteresting.
253 #define CPC_P5_CESR_ES0_SHIFT 0
254 #define CPC_P5_CESR_ES0_MASK 0x3f
255 #define CPC_P5_CESR_ES1_SHIFT 16
256 #define CPC_P5_CESR_ES1_MASK 0x3f
258 #define CPC_P5_CESR_OS0 6
259 #define CPC_P5_CESR_USR0 7
260 #define CPC_P5_CESR_CLK0 8
261 #define CPC_P5_CESR_PC0 9
262 #define CPC_P5_CESR_OS1 (CPC_P5_CESR_OS0 + 16)
263 #define CPC_P5_CESR_USR1 (CPC_P5_CESR_USR0 + 16)
264 #define CPC_P5_CESR_CLK1 (CPC_P5_CESR_CLK0 + 16)
265 #define CPC_P5_CESR_PC1 (CPC_P5_CESR_PC0 + 16)
268 * "Well known" bit fields in the Pentium Pro PerfEvtSel registers
269 * The interfaces in libcpc should make these #defines uninteresting.
271 #define CPC_P6_PES_INV 23
272 #define CPC_P6_PES_EN 22
273 #define CPC_P6_PES_INT 20
274 #define CPC_P6_PES_PC 19
275 #define CPC_P6_PES_E 18
276 #define CPC_P6_PES_OS 17
277 #define CPC_P6_PES_USR 16
279 #define CPC_P6_PES_UMASK_SHIFT 8
280 #define CPC_P6_PES_UMASK_MASK (0xffu)
282 #define CPC_P6_PES_CMASK_SHIFT 24
283 #define CPC_P6_PES_CMASK_MASK (0xffu)
285 #define CPC_P6_PES_PIC0_MASK (0xffu)
286 #define CPC_P6_PES_PIC1_MASK (0xffu)
294 #endif /* _LIBCPC_IMPL_H */