xref: /onnv-gate/usr/src/uts/common/sys/kcpc.h (revision 11389:dd00b884e84f)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
53732Sae112802  * Common Development and Distribution License (the "License").
63732Sae112802  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
228803SJonathan.Haslam@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #ifndef _SYS_KCPC_H
270Sstevel@tonic-gate #define	_SYS_KCPC_H
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <sys/cpc_impl.h>
306275Strevtom #include <sys/ksynch.h>
31*11389SAlexander.Kolbasov@Sun.COM #include <sys/types.h>
320Sstevel@tonic-gate 
330Sstevel@tonic-gate #ifdef	__cplusplus
340Sstevel@tonic-gate extern "C" {
350Sstevel@tonic-gate #endif
360Sstevel@tonic-gate 
37*11389SAlexander.Kolbasov@Sun.COM 
380Sstevel@tonic-gate /*
390Sstevel@tonic-gate  * Kernel clients need this file in order to know what a request is and how to
400Sstevel@tonic-gate  * program one.
410Sstevel@tonic-gate  */
420Sstevel@tonic-gate 
430Sstevel@tonic-gate typedef struct _kcpc_set kcpc_set_t;
440Sstevel@tonic-gate 
450Sstevel@tonic-gate #ifdef _KERNEL
460Sstevel@tonic-gate 
470Sstevel@tonic-gate /*
480Sstevel@tonic-gate  * Forward declarations.
490Sstevel@tonic-gate  */
500Sstevel@tonic-gate struct _kthread;
510Sstevel@tonic-gate struct cpu;
520Sstevel@tonic-gate typedef struct _kcpc_request kcpc_request_t;
530Sstevel@tonic-gate struct __pcbe_ops;
540Sstevel@tonic-gate 
556275Strevtom #define	KCPC_SET_BOUND		0x0001		/* Used in ks_state */
566275Strevtom 
570Sstevel@tonic-gate struct _kcpc_set {
580Sstevel@tonic-gate 	int			ks_flags;
590Sstevel@tonic-gate 	int			ks_nreqs;	/* Number of reqs */
600Sstevel@tonic-gate 	kcpc_request_t		*ks_req;	/* Pointer to reqs */
610Sstevel@tonic-gate 	uint64_t		*ks_data;	/* Data store for this set */
620Sstevel@tonic-gate 	kcpc_ctx_t		*ks_ctx;	/* ctx this set belongs to */
636275Strevtom 	ushort_t		ks_state;	/* Set is bound or unbound */
646275Strevtom 	kmutex_t		ks_lock;	/* Protects ks_state */
656275Strevtom 	kcondvar_t		ks_condv;	/* Wait for bind to complete */
660Sstevel@tonic-gate };
670Sstevel@tonic-gate 
680Sstevel@tonic-gate struct _kcpc_request {
690Sstevel@tonic-gate 	void			*kr_config;
700Sstevel@tonic-gate 	int			kr_index;	/* indx of data for this req */
710Sstevel@tonic-gate 	int			kr_picnum;	/* Number of phys pic */
720Sstevel@tonic-gate 	kcpc_pic_t		*kr_picp;	/* Ptr to PIC in context */
730Sstevel@tonic-gate 	uint64_t		*kr_data;	/* Ptr to virtual 64-bit pic */
740Sstevel@tonic-gate 	char			kr_event[CPC_MAX_EVENT_LEN];
750Sstevel@tonic-gate 	uint64_t		kr_preset;
760Sstevel@tonic-gate 	uint_t			kr_flags;
770Sstevel@tonic-gate 	uint_t			kr_nattrs;
780Sstevel@tonic-gate 	kcpc_attr_t		*kr_attr;
79*11389SAlexander.Kolbasov@Sun.COM 	void			*kr_ptr;	/* Ptr assigned by requester */
800Sstevel@tonic-gate };
810Sstevel@tonic-gate 
82*11389SAlexander.Kolbasov@Sun.COM typedef struct _kcpc_request_list {
83*11389SAlexander.Kolbasov@Sun.COM 	kcpc_request_t		*krl_list;	/* counter event requests */
84*11389SAlexander.Kolbasov@Sun.COM 	int			krl_cnt;	/* how many requests */
85*11389SAlexander.Kolbasov@Sun.COM 	int			krl_max;	/* max request entries */
86*11389SAlexander.Kolbasov@Sun.COM } kcpc_request_list_t;
87*11389SAlexander.Kolbasov@Sun.COM 
88*11389SAlexander.Kolbasov@Sun.COM /*
89*11389SAlexander.Kolbasov@Sun.COM  * Type of update function to be called when reading counters on current CPU in
90*11389SAlexander.Kolbasov@Sun.COM  * kcpc_read()
91*11389SAlexander.Kolbasov@Sun.COM  */
92*11389SAlexander.Kolbasov@Sun.COM typedef int (*kcpc_update_func_t)(void *, uint64_t);
93*11389SAlexander.Kolbasov@Sun.COM 
94*11389SAlexander.Kolbasov@Sun.COM /*
95*11389SAlexander.Kolbasov@Sun.COM  * Type of read function to be called when reading counters on current CPU
96*11389SAlexander.Kolbasov@Sun.COM  * (ie. should be same type signature as kcpc_read())
97*11389SAlexander.Kolbasov@Sun.COM  */
98*11389SAlexander.Kolbasov@Sun.COM typedef int (*kcpc_read_func_t)(kcpc_update_func_t);
99*11389SAlexander.Kolbasov@Sun.COM 
100*11389SAlexander.Kolbasov@Sun.COM 
101*11389SAlexander.Kolbasov@Sun.COM /*
102*11389SAlexander.Kolbasov@Sun.COM  * Initialize the kcpc framework
103*11389SAlexander.Kolbasov@Sun.COM  */
104*11389SAlexander.Kolbasov@Sun.COM extern int kcpc_init(void);
105*11389SAlexander.Kolbasov@Sun.COM 
1060Sstevel@tonic-gate /*
1070Sstevel@tonic-gate  * Bind the set to the indicated thread.
1080Sstevel@tonic-gate  * Returns 0 on success, or an errno in case of error. If EINVAL is returned,
1090Sstevel@tonic-gate  * a specific error code will be returned in the subcode parameter.
1100Sstevel@tonic-gate  */
1110Sstevel@tonic-gate extern int kcpc_bind_thread(kcpc_set_t *set, struct _kthread *t, int *subcode);
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate /*
1140Sstevel@tonic-gate  * Bind the set to the indicated CPU.
1150Sstevel@tonic-gate  * Same return convention as kcpc_bind_thread().
1160Sstevel@tonic-gate  */
1170Sstevel@tonic-gate extern int kcpc_bind_cpu(kcpc_set_t *set, int cpuid, int *subcode);
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate /*
1200Sstevel@tonic-gate  * Request the system to sample the current state of the set into users buf.
1210Sstevel@tonic-gate  */
1220Sstevel@tonic-gate extern int kcpc_sample(kcpc_set_t *set, uint64_t *buf, hrtime_t *hrtime,
1230Sstevel@tonic-gate     uint64_t *tick);
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate /*
126*11389SAlexander.Kolbasov@Sun.COM  * Create CPC context containing specified list of requested counter events
127*11389SAlexander.Kolbasov@Sun.COM  */
128*11389SAlexander.Kolbasov@Sun.COM extern int kcpc_cpu_ctx_create(struct cpu *cp, kcpc_request_list_t *req_list,
129*11389SAlexander.Kolbasov@Sun.COM     int kmem_flags, kcpc_ctx_t ***ctx_ptr_array, size_t *ctx_ptr_array_sz);
130*11389SAlexander.Kolbasov@Sun.COM 
131*11389SAlexander.Kolbasov@Sun.COM /*
132*11389SAlexander.Kolbasov@Sun.COM  * Returns whether specified counter event is supported
133*11389SAlexander.Kolbasov@Sun.COM  */
134*11389SAlexander.Kolbasov@Sun.COM extern boolean_t kcpc_event_supported(char *event);
135*11389SAlexander.Kolbasov@Sun.COM 
136*11389SAlexander.Kolbasov@Sun.COM /*
137*11389SAlexander.Kolbasov@Sun.COM  * Initialize list of CPC event requests
138*11389SAlexander.Kolbasov@Sun.COM  */
139*11389SAlexander.Kolbasov@Sun.COM extern kcpc_request_list_t *kcpc_reqs_init(int nreqs, int kmem_flags);
140*11389SAlexander.Kolbasov@Sun.COM 
141*11389SAlexander.Kolbasov@Sun.COM /*
142*11389SAlexander.Kolbasov@Sun.COM  * Add counter event request to given list of counter event requests
143*11389SAlexander.Kolbasov@Sun.COM  */
144*11389SAlexander.Kolbasov@Sun.COM extern int kcpc_reqs_add(kcpc_request_list_t *req_list, char *event,
145*11389SAlexander.Kolbasov@Sun.COM     uint64_t preset, uint_t flags, uint_t nattrs, kcpc_attr_t *attr, void *ptr,
146*11389SAlexander.Kolbasov@Sun.COM     int kmem_flags);
147*11389SAlexander.Kolbasov@Sun.COM 
148*11389SAlexander.Kolbasov@Sun.COM /*
149*11389SAlexander.Kolbasov@Sun.COM  * Reset list of CPC event requests so its space can be used for another set
150*11389SAlexander.Kolbasov@Sun.COM  * of requests
151*11389SAlexander.Kolbasov@Sun.COM  */
152*11389SAlexander.Kolbasov@Sun.COM extern int kcpc_reqs_reset(kcpc_request_list_t *req_list);
153*11389SAlexander.Kolbasov@Sun.COM 
154*11389SAlexander.Kolbasov@Sun.COM /*
155*11389SAlexander.Kolbasov@Sun.COM  * Free given list of counter event requests
156*11389SAlexander.Kolbasov@Sun.COM  */
157*11389SAlexander.Kolbasov@Sun.COM extern int kcpc_reqs_fini(kcpc_request_list_t *req_list);
158*11389SAlexander.Kolbasov@Sun.COM 
159*11389SAlexander.Kolbasov@Sun.COM /*
160*11389SAlexander.Kolbasov@Sun.COM  * Read CPC data for given event on current CPU
161*11389SAlexander.Kolbasov@Sun.COM  */
162*11389SAlexander.Kolbasov@Sun.COM extern int kcpc_read(kcpc_update_func_t);
163*11389SAlexander.Kolbasov@Sun.COM 
164*11389SAlexander.Kolbasov@Sun.COM /*
165*11389SAlexander.Kolbasov@Sun.COM  * Program current CPU with given CPC context
166*11389SAlexander.Kolbasov@Sun.COM  */
167*11389SAlexander.Kolbasov@Sun.COM extern void kcpc_program(kcpc_ctx_t *ctx, boolean_t for_thread,
168*11389SAlexander.Kolbasov@Sun.COM     boolean_t cu_interpose);
169*11389SAlexander.Kolbasov@Sun.COM 
170*11389SAlexander.Kolbasov@Sun.COM /*
171*11389SAlexander.Kolbasov@Sun.COM  * Unprogram CPC counters on current CPU
172*11389SAlexander.Kolbasov@Sun.COM  */
173*11389SAlexander.Kolbasov@Sun.COM extern void kcpc_unprogram(kcpc_ctx_t *ctx, boolean_t cu_interpose);
174*11389SAlexander.Kolbasov@Sun.COM 
175*11389SAlexander.Kolbasov@Sun.COM /*
1760Sstevel@tonic-gate  * Unbind a request and release the associated resources.
1770Sstevel@tonic-gate  */
1780Sstevel@tonic-gate extern int kcpc_unbind(kcpc_set_t *set);
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate /*
1810Sstevel@tonic-gate  * Preset the indicated request's counter and underlying PCBE config to the
1820Sstevel@tonic-gate  * given value.
1830Sstevel@tonic-gate  */
1840Sstevel@tonic-gate extern int kcpc_preset(kcpc_set_t *set, int index, uint64_t preset);
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate /*
1870Sstevel@tonic-gate  * Unfreeze the set and get it counting again.
1880Sstevel@tonic-gate  */
1890Sstevel@tonic-gate extern int kcpc_restart(kcpc_set_t *set);
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate extern int kcpc_enable(struct _kthread *t, int cmd, int enable);
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate /*
1940Sstevel@tonic-gate  * Mark a thread's CPC context, if it exists, INVALID.
1950Sstevel@tonic-gate  */
1960Sstevel@tonic-gate extern void kcpc_invalidate(struct _kthread *t);
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate extern int kcpc_overflow_ast(void);
1990Sstevel@tonic-gate extern uint_t kcpc_hw_overflow_intr(caddr_t, caddr_t);
2000Sstevel@tonic-gate extern int kcpc_hw_cpu_hook(int cpuid, ulong_t *kcpc_cpumap);
2010Sstevel@tonic-gate extern int kcpc_hw_lwp_hook(void);
2020Sstevel@tonic-gate extern void kcpc_idle_save(struct cpu *cp);
2030Sstevel@tonic-gate extern void kcpc_idle_restore(struct cpu *cp);
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate extern krwlock_t	kcpc_cpuctx_lock;  /* lock for 'kcpc_cpuctx' below */
2060Sstevel@tonic-gate extern int		kcpc_cpuctx;	   /* number of cpu-specific contexts */
2070Sstevel@tonic-gate 
208*11389SAlexander.Kolbasov@Sun.COM extern void kcpc_free(kcpc_ctx_t *ctx, int isexec);
209*11389SAlexander.Kolbasov@Sun.COM 
2108803SJonathan.Haslam@Sun.COM /*
2118803SJonathan.Haslam@Sun.COM  * 'dtrace_cpc_in_use' contains the number of currently active cpc provider
2128803SJonathan.Haslam@Sun.COM  * based enablings. See the block comment in uts/common/os/dtrace_subr.c for
2138803SJonathan.Haslam@Sun.COM  * details of its actual usage.
2148803SJonathan.Haslam@Sun.COM  */
2158803SJonathan.Haslam@Sun.COM extern uint32_t		dtrace_cpc_in_use;
2168803SJonathan.Haslam@Sun.COM extern void (*dtrace_cpc_fire)(uint64_t);
2178803SJonathan.Haslam@Sun.COM 
2180Sstevel@tonic-gate extern void kcpc_free_set(kcpc_set_t *set);
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate extern void *kcpc_next_config(void *token, void *current,
2210Sstevel@tonic-gate     uint64_t **data);
2223732Sae112802 extern void kcpc_invalidate_config(void *token);
2238803SJonathan.Haslam@Sun.COM extern char *kcpc_list_attrs(void);
2248803SJonathan.Haslam@Sun.COM extern char *kcpc_list_events(uint_t pic);
2258803SJonathan.Haslam@Sun.COM extern void kcpc_free_configs(kcpc_set_t *set);
2268803SJonathan.Haslam@Sun.COM extern uint_t kcpc_pcbe_capabilities(void);
2278803SJonathan.Haslam@Sun.COM extern int kcpc_pcbe_loaded(void);
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate /*
2300Sstevel@tonic-gate  * Called by a PCBE to determine if nonprivileged access to counters should be
2310Sstevel@tonic-gate  * allowed. Returns non-zero if non-privileged access is allowed, 0 if not.
2320Sstevel@tonic-gate  */
2330Sstevel@tonic-gate extern int kcpc_allow_nonpriv(void *token);
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate extern void kcpc_register_pcbe(struct __pcbe_ops *);
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate #endif /* _KERNEL */
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate #ifdef	__cplusplus
2400Sstevel@tonic-gate }
2410Sstevel@tonic-gate #endif
2420Sstevel@tonic-gate 
2430Sstevel@tonic-gate #endif /* _SYS_KCPC_H */
244