17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 58d4e547dSae112802 * Common Development and Distribution License (the "License"). 68d4e547dSae112802 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*af4595edSJonathan Haslam * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #ifndef _SYS_CPC_IMPL_H 277c478bd9Sstevel@tonic-gate #define _SYS_CPC_IMPL_H 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <sys/types.h> 307c478bd9Sstevel@tonic-gate #include <sys/time.h> 314568bee7Strevtom #include <sys/ksynch.h> 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #if defined(_KERNEL) && defined(_MULTI_DATAMODEL) 347c478bd9Sstevel@tonic-gate #include <sys/types32.h> 357c478bd9Sstevel@tonic-gate #endif 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #ifdef __cplusplus 387c478bd9Sstevel@tonic-gate extern "C" { 397c478bd9Sstevel@tonic-gate #endif 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate typedef struct { 427c478bd9Sstevel@tonic-gate char *ca_name; 437c478bd9Sstevel@tonic-gate uint64_t ca_val; 447c478bd9Sstevel@tonic-gate } cpc_attr_t; 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* 477c478bd9Sstevel@tonic-gate * Flag arguments to cpc_bind_event and cpc_ctx_bind_event 487c478bd9Sstevel@tonic-gate */ 497c478bd9Sstevel@tonic-gate #define CPC_BIND_LWP_INHERIT (0x1) 507c478bd9Sstevel@tonic-gate #define CPC_BIND_EMT_OVF (0x2) 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate #define CPC_MAX_IMPL_NAME 512 /* Max len of PCBE's description str */ 537c478bd9Sstevel@tonic-gate #define CPC_MAX_CPUREF 1024 /* Max len of PCBE's CPU ref string */ 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate #define CPC_OVF_NOTIFY_EMT 0x1 567c478bd9Sstevel@tonic-gate #define CPC_COUNT_USER 0x2 577c478bd9Sstevel@tonic-gate #define CPC_COUNT_SYSTEM 0x4 588d4e547dSae112802 #define CPC_COUNT_HV 0x8 594df55fdeSJanie Lu #define CPC_COUNT_SAMPLE_MODE 0x10 607c478bd9Sstevel@tonic-gate 618d4e547dSae112802 #define KCPC_REQ_ALL_FLAGS (CPC_OVF_NOTIFY_EMT | CPC_COUNT_USER | \ 624df55fdeSJanie Lu CPC_COUNT_SYSTEM | CPC_COUNT_HV | CPC_COUNT_SAMPLE_MODE) 637c478bd9Sstevel@tonic-gate #define KCPC_REQ_VALID_FLAGS(flags) \ 647c478bd9Sstevel@tonic-gate (((flags) | KCPC_REQ_ALL_FLAGS) == KCPC_REQ_ALL_FLAGS) 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate /* 677c478bd9Sstevel@tonic-gate * CPC Capabilities 687c478bd9Sstevel@tonic-gate */ 697c478bd9Sstevel@tonic-gate #define CPC_CAP_OVERFLOW_INTERRUPT 0x1 707c478bd9Sstevel@tonic-gate #define CPC_CAP_OVERFLOW_PRECISE 0x2 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate /* 737c478bd9Sstevel@tonic-gate * The only valid per-set flag is CPC_BIND_LWP_INHERIT, which must remain in 747c478bd9Sstevel@tonic-gate * cpc_event.h for backwards compatibility. 757c478bd9Sstevel@tonic-gate */ 767c478bd9Sstevel@tonic-gate #define CPC_SET_ALL_FLAGS 0x1 777c478bd9Sstevel@tonic-gate #define CPC_SET_VALID_FLAGS(flags) \ 787c478bd9Sstevel@tonic-gate (((flags) | CPC_SET_ALL_FLAGS) == CPC_SET_ALL_FLAGS) 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate /* 817c478bd9Sstevel@tonic-gate * These system call subcodes and ioctls allow the implementation of the 827c478bd9Sstevel@tonic-gate * libcpc library to store and retrieve performance counter data. Subject 837c478bd9Sstevel@tonic-gate * to arbitrary change without notice at any time. Do not invoke them 847c478bd9Sstevel@tonic-gate * directly! 857c478bd9Sstevel@tonic-gate */ 867c478bd9Sstevel@tonic-gate #define CPC_BIND 0 877c478bd9Sstevel@tonic-gate #define CPC_SAMPLE 1 887c478bd9Sstevel@tonic-gate #define CPC_INVALIDATE 2 897c478bd9Sstevel@tonic-gate #define CPC_RELE 3 907c478bd9Sstevel@tonic-gate #define CPC_EVLIST_SIZE 4 917c478bd9Sstevel@tonic-gate #define CPC_LIST_EVENTS 5 927c478bd9Sstevel@tonic-gate #define CPC_ATTRLIST_SIZE 6 937c478bd9Sstevel@tonic-gate #define CPC_LIST_ATTRS 7 947c478bd9Sstevel@tonic-gate #define CPC_IMPL_NAME 8 957c478bd9Sstevel@tonic-gate #define CPC_CPUREF 9 967c478bd9Sstevel@tonic-gate #define CPC_USR_EVENTS 10 977c478bd9Sstevel@tonic-gate #define CPC_SYS_EVENTS 11 987c478bd9Sstevel@tonic-gate #define CPC_NPIC 12 997c478bd9Sstevel@tonic-gate #define CPC_CAPS 13 1007c478bd9Sstevel@tonic-gate #define CPC_ENABLE 14 1017c478bd9Sstevel@tonic-gate #define CPC_DISABLE 15 1027c478bd9Sstevel@tonic-gate #define CPC_PRESET 16 1037c478bd9Sstevel@tonic-gate #define CPC_RESTART 17 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate #define _CPCIO_IOC ((((('c'<<8)|'p')<<8)|'c')<<8) 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate #define CPCIO_BIND (_CPCIO_IOC | 0x1) 1087c478bd9Sstevel@tonic-gate #define CPCIO_SAMPLE (_CPCIO_IOC | 0x2) 1097c478bd9Sstevel@tonic-gate #define CPCIO_RELE (_CPCIO_IOC | 0x3) 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate /* 1127c478bd9Sstevel@tonic-gate * Forward declarations. 1137c478bd9Sstevel@tonic-gate */ 1147c478bd9Sstevel@tonic-gate struct _kthread; 1157c478bd9Sstevel@tonic-gate struct _kcpc_set; 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate #define CPC_MAX_EVENT_LEN 512 1187c478bd9Sstevel@tonic-gate #define CPC_MAX_ATTR_LEN 32 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate typedef struct _kcpc_attr { 1217c478bd9Sstevel@tonic-gate char ka_name[CPC_MAX_ATTR_LEN]; 1227c478bd9Sstevel@tonic-gate uint64_t ka_val; 1237c478bd9Sstevel@tonic-gate } kcpc_attr_t; 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate typedef struct _kcpc_pic { 1267c478bd9Sstevel@tonic-gate uint_t kp_flags; 1277c478bd9Sstevel@tonic-gate struct _kcpc_request *kp_req; /* request this PIC counts for */ 1287c478bd9Sstevel@tonic-gate } kcpc_pic_t; 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate typedef struct _kcpc_ctx kcpc_ctx_t; 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate struct _kcpc_ctx { 1337c478bd9Sstevel@tonic-gate struct _kcpc_set *kc_set; /* linked list of all bound sets */ 134b885580bSAlexander Kolbasov volatile uint_t kc_flags; 1357c478bd9Sstevel@tonic-gate kcpc_pic_t *kc_pics; /* pointer to array of per-pic data */ 1367c478bd9Sstevel@tonic-gate hrtime_t kc_hrtime; /* gethrtime() at last sample */ 1377c478bd9Sstevel@tonic-gate uint64_t kc_vtick; /* virtualized %tick */ 1387c478bd9Sstevel@tonic-gate uint64_t kc_rawtick; /* last snapshot of tick/tsc */ 1397c478bd9Sstevel@tonic-gate struct _kthread *kc_thread; /* thread this context is measuring */ 1407c478bd9Sstevel@tonic-gate int kc_cpuid; /* CPU this context is measuring */ 1417c478bd9Sstevel@tonic-gate kcpc_ctx_t *kc_next; /* Global list of all contexts */ 1424568bee7Strevtom kmutex_t kc_lock; /* protects kc_flags */ 1434568bee7Strevtom kcondvar_t kc_condv; /* wait for kcpc_restore completion */ 1447c478bd9Sstevel@tonic-gate }; 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate typedef struct __cpc_args { 1477c478bd9Sstevel@tonic-gate void *udata1; 1487c478bd9Sstevel@tonic-gate void *udata2; 1497c478bd9Sstevel@tonic-gate void *udata3; 1507c478bd9Sstevel@tonic-gate } __cpc_args_t; 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate #ifdef _KERNEL 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate #ifdef _MULTI_DATAMODEL 1557c478bd9Sstevel@tonic-gate typedef struct __cpc_args32 { 1567c478bd9Sstevel@tonic-gate caddr32_t udata1; 1577c478bd9Sstevel@tonic-gate caddr32_t udata2; 1587c478bd9Sstevel@tonic-gate caddr32_t udata3; 1597c478bd9Sstevel@tonic-gate } __cpc_args32_t; 1607c478bd9Sstevel@tonic-gate #endif /* _MULTI_DATAMODEL */ 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate #define KCPC_LOG2_HASH_BUCKETS 6 /* => 64 buckets for now */ 1637c478bd9Sstevel@tonic-gate #define CPC_HASH_BUCKETS (1l << KCPC_LOG2_HASH_BUCKETS) 1647c478bd9Sstevel@tonic-gate #define CPC_HASH_CTX(ctx) ((((long)(ctx)) >> 7) & \ 1657c478bd9Sstevel@tonic-gate (CPC_HASH_BUCKETS - 1)) 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate /* 1687c478bd9Sstevel@tonic-gate * Context flags. 1697c478bd9Sstevel@tonic-gate */ 1707c478bd9Sstevel@tonic-gate #define KCPC_CTX_FREEZE 0x1 /* => no sampling */ 1717c478bd9Sstevel@tonic-gate #define KCPC_CTX_SIGOVF 0x2 /* => send signal on overflow */ 1727c478bd9Sstevel@tonic-gate #define KCPC_CTX_NONPRIV 0x4 /* => non-priv access to counters */ 1737c478bd9Sstevel@tonic-gate #define KCPC_CTX_LWPINHERIT 0x8 /* => lwp_create inherits ctx */ 1747c478bd9Sstevel@tonic-gate #define KCPC_CTX_INVALID 0x100 /* => context stolen; discard */ 1757c478bd9Sstevel@tonic-gate #define KCPC_CTX_INVALID_STOPPED 0x200 /* => invalid ctx has been stopped */ 1764568bee7Strevtom #define KCPC_CTX_RESTORE 0x400 /* => kcpc_restore in progress */ 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate /* 1797c478bd9Sstevel@tonic-gate * PIC flags. 1807c478bd9Sstevel@tonic-gate */ 1817c478bd9Sstevel@tonic-gate #define KCPC_PIC_OVERFLOWED 0x1 /* pic overflowed & requested notify */ 1827c478bd9Sstevel@tonic-gate 183b9e93c10SJonathan Haslam /* 184b9e93c10SJonathan Haslam * The following flags are used by the DTrace CPU performance counter provider 185b9e93c10SJonathan Haslam * and the overflow handler. The 'DCPC_INTR_*' flags are used to synchronize 186b9e93c10SJonathan Haslam * performance counter configuration events performed by the cpc provider and 187b9e93c10SJonathan Haslam * interrupt processing carried out by the overflow handler. The 'DCPC_?MASK' 188b9e93c10SJonathan Haslam * flags are used by the dcpc provider to indicate which type of mask attribute 189b9e93c10SJonathan Haslam * a platform supports. 190b9e93c10SJonathan Haslam */ 191b9e93c10SJonathan Haslam 192*af4595edSJonathan Haslam enum dcpc_intr_state { 193*af4595edSJonathan Haslam DCPC_INTR_INACTIVE, /* The dcpc provider is currently not in use */ 194*af4595edSJonathan Haslam DCPC_INTR_FREE, /* No config events or ovf ints in progress */ 195*af4595edSJonathan Haslam DCPC_INTR_PROCESSING, /* An overflow interrupt is being processed */ 196*af4595edSJonathan Haslam DCPC_INTR_CONFIG /* cpc subsystem being configured by dcpc */ 197*af4595edSJonathan Haslam }; 198b9e93c10SJonathan Haslam 199*af4595edSJonathan Haslam enum dcpc_mask_attr { 200*af4595edSJonathan Haslam DCPC_UMASK = 0x1, /* The platform supports a "umask" attribute */ 201*af4595edSJonathan Haslam DCPC_EMASK = 0x2 /* The platform supports an "emask" attribute */ 202*af4595edSJonathan Haslam }; 203b9e93c10SJonathan Haslam 2047c478bd9Sstevel@tonic-gate #ifdef __sparc 2057c478bd9Sstevel@tonic-gate extern uint64_t ultra_gettick(void); 2067c478bd9Sstevel@tonic-gate #define KCPC_GET_TICK ultra_gettick 2077c478bd9Sstevel@tonic-gate #else 2087c478bd9Sstevel@tonic-gate extern hrtime_t tsc_read(void); 2097c478bd9Sstevel@tonic-gate #define KCPC_GET_TICK tsc_read 2107c478bd9Sstevel@tonic-gate #endif /* __sparc */ 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate #define PCBE_NAMELEN 30 /* Enough room for "pcbe." plus full PCBE name spec */ 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate struct cpu; 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate extern uint_t cpc_ncounters; 2177c478bd9Sstevel@tonic-gate extern krwlock_t kcpc_cpuctx_lock; /* lock for 'kcpc_cpuctx' below */ 2187c478bd9Sstevel@tonic-gate extern int kcpc_cpuctx; /* number of cpu-specific contexts */ 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate extern void kcpc_invalidate_all(void); 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate extern void kcpc_passivate(void); 223b885580bSAlexander Kolbasov extern void kcpc_cpu_stop(struct cpu *, boolean_t); 2247c478bd9Sstevel@tonic-gate extern int kcpc_pcbe_tryload(const char *, uint_t, uint_t, uint_t); 225b885580bSAlexander Kolbasov extern void kcpc_cpu_program(struct cpu *, kcpc_ctx_t *); 226b9e93c10SJonathan Haslam extern void kcpc_register_dcpc(void (*func)(uint64_t)); 227b9e93c10SJonathan Haslam extern void kcpc_unregister_dcpc(void); 228b885580bSAlexander Kolbasov extern kcpc_ctx_t *kcpc_ctx_alloc(int); 229b9e93c10SJonathan Haslam extern int kcpc_assign_reqs(struct _kcpc_set *, kcpc_ctx_t *); 230b9e93c10SJonathan Haslam extern void kcpc_ctx_free(kcpc_ctx_t *); 231b9e93c10SJonathan Haslam extern int kcpc_configure_reqs(kcpc_ctx_t *, struct _kcpc_set *, int *); 232b9e93c10SJonathan Haslam extern void kcpc_free_configs(struct _kcpc_set *); 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate /* 2377c478bd9Sstevel@tonic-gate * Error subcodes. 2387c478bd9Sstevel@tonic-gate */ 2397c478bd9Sstevel@tonic-gate #define CPC_INVALID_EVENT 1 /* Unknown event */ 2407c478bd9Sstevel@tonic-gate #define CPC_INVALID_PICNUM 2 /* Requested PIC out of range */ 2417c478bd9Sstevel@tonic-gate #define CPC_INVALID_ATTRIBUTE 3 /* Unknown attribute */ 2427c478bd9Sstevel@tonic-gate #define CPC_ATTRIBUTE_OUT_OF_RANGE 4 /* Attribute val out of range */ 2437c478bd9Sstevel@tonic-gate #define CPC_RESOURCE_UNAVAIL 5 /* Can't get needed resource */ 2447c478bd9Sstevel@tonic-gate #define CPC_PIC_NOT_CAPABLE 6 /* PIC can't count this event */ 2457c478bd9Sstevel@tonic-gate #define CPC_REQ_INVALID_FLAGS 7 /* Invalid flags in req(s) */ 2467c478bd9Sstevel@tonic-gate #define CPC_CONFLICTING_REQS 8 /* Reqs in the set conflict */ 2477c478bd9Sstevel@tonic-gate #define CPC_ATTR_REQUIRES_PRIVILEGE 9 /* Insufficient privs for atr */ 2487c478bd9Sstevel@tonic-gate #define CPC_PBIND_FAILED 10 /* Couldn't bind to processor */ 2498d4e547dSae112802 #define CPC_HV_NO_ACCESS 11 /* No perm for HV events */ 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate #ifdef __cplusplus 2527c478bd9Sstevel@tonic-gate } 2537c478bd9Sstevel@tonic-gate #endif 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate #endif /* _SYS_CPC_IMPL_H */ 256