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 /* 22*11455SJonathan.Haslam@Sun.COM * Copyright 2010 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_CPC_IMPL_H 270Sstevel@tonic-gate #define _SYS_CPC_IMPL_H 280Sstevel@tonic-gate 290Sstevel@tonic-gate #include <sys/types.h> 300Sstevel@tonic-gate #include <sys/time.h> 316275Strevtom #include <sys/ksynch.h> 320Sstevel@tonic-gate 330Sstevel@tonic-gate #if defined(_KERNEL) && defined(_MULTI_DATAMODEL) 340Sstevel@tonic-gate #include <sys/types32.h> 350Sstevel@tonic-gate #endif 360Sstevel@tonic-gate 370Sstevel@tonic-gate #ifdef __cplusplus 380Sstevel@tonic-gate extern "C" { 390Sstevel@tonic-gate #endif 400Sstevel@tonic-gate 410Sstevel@tonic-gate typedef struct { 420Sstevel@tonic-gate char *ca_name; 430Sstevel@tonic-gate uint64_t ca_val; 440Sstevel@tonic-gate } cpc_attr_t; 450Sstevel@tonic-gate 460Sstevel@tonic-gate /* 470Sstevel@tonic-gate * Flag arguments to cpc_bind_event and cpc_ctx_bind_event 480Sstevel@tonic-gate */ 490Sstevel@tonic-gate #define CPC_BIND_LWP_INHERIT (0x1) 500Sstevel@tonic-gate #define CPC_BIND_EMT_OVF (0x2) 510Sstevel@tonic-gate 520Sstevel@tonic-gate #define CPC_MAX_IMPL_NAME 512 /* Max len of PCBE's description str */ 530Sstevel@tonic-gate #define CPC_MAX_CPUREF 1024 /* Max len of PCBE's CPU ref string */ 540Sstevel@tonic-gate 550Sstevel@tonic-gate #define CPC_OVF_NOTIFY_EMT 0x1 560Sstevel@tonic-gate #define CPC_COUNT_USER 0x2 570Sstevel@tonic-gate #define CPC_COUNT_SYSTEM 0x4 583732Sae112802 #define CPC_COUNT_HV 0x8 5911304SJanie.Lu@Sun.COM #define CPC_COUNT_SAMPLE_MODE 0x10 600Sstevel@tonic-gate 613732Sae112802 #define KCPC_REQ_ALL_FLAGS (CPC_OVF_NOTIFY_EMT | CPC_COUNT_USER | \ 6211304SJanie.Lu@Sun.COM CPC_COUNT_SYSTEM | CPC_COUNT_HV | CPC_COUNT_SAMPLE_MODE) 630Sstevel@tonic-gate #define KCPC_REQ_VALID_FLAGS(flags) \ 640Sstevel@tonic-gate (((flags) | KCPC_REQ_ALL_FLAGS) == KCPC_REQ_ALL_FLAGS) 650Sstevel@tonic-gate 660Sstevel@tonic-gate /* 670Sstevel@tonic-gate * CPC Capabilities 680Sstevel@tonic-gate */ 690Sstevel@tonic-gate #define CPC_CAP_OVERFLOW_INTERRUPT 0x1 700Sstevel@tonic-gate #define CPC_CAP_OVERFLOW_PRECISE 0x2 710Sstevel@tonic-gate 720Sstevel@tonic-gate /* 730Sstevel@tonic-gate * The only valid per-set flag is CPC_BIND_LWP_INHERIT, which must remain in 740Sstevel@tonic-gate * cpc_event.h for backwards compatibility. 750Sstevel@tonic-gate */ 760Sstevel@tonic-gate #define CPC_SET_ALL_FLAGS 0x1 770Sstevel@tonic-gate #define CPC_SET_VALID_FLAGS(flags) \ 780Sstevel@tonic-gate (((flags) | CPC_SET_ALL_FLAGS) == CPC_SET_ALL_FLAGS) 790Sstevel@tonic-gate 800Sstevel@tonic-gate /* 810Sstevel@tonic-gate * These system call subcodes and ioctls allow the implementation of the 820Sstevel@tonic-gate * libcpc library to store and retrieve performance counter data. Subject 830Sstevel@tonic-gate * to arbitrary change without notice at any time. Do not invoke them 840Sstevel@tonic-gate * directly! 850Sstevel@tonic-gate */ 860Sstevel@tonic-gate #define CPC_BIND 0 870Sstevel@tonic-gate #define CPC_SAMPLE 1 880Sstevel@tonic-gate #define CPC_INVALIDATE 2 890Sstevel@tonic-gate #define CPC_RELE 3 900Sstevel@tonic-gate #define CPC_EVLIST_SIZE 4 910Sstevel@tonic-gate #define CPC_LIST_EVENTS 5 920Sstevel@tonic-gate #define CPC_ATTRLIST_SIZE 6 930Sstevel@tonic-gate #define CPC_LIST_ATTRS 7 940Sstevel@tonic-gate #define CPC_IMPL_NAME 8 950Sstevel@tonic-gate #define CPC_CPUREF 9 960Sstevel@tonic-gate #define CPC_USR_EVENTS 10 970Sstevel@tonic-gate #define CPC_SYS_EVENTS 11 980Sstevel@tonic-gate #define CPC_NPIC 12 990Sstevel@tonic-gate #define CPC_CAPS 13 1000Sstevel@tonic-gate #define CPC_ENABLE 14 1010Sstevel@tonic-gate #define CPC_DISABLE 15 1020Sstevel@tonic-gate #define CPC_PRESET 16 1030Sstevel@tonic-gate #define CPC_RESTART 17 1040Sstevel@tonic-gate 1050Sstevel@tonic-gate #define _CPCIO_IOC ((((('c'<<8)|'p')<<8)|'c')<<8) 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate #define CPCIO_BIND (_CPCIO_IOC | 0x1) 1080Sstevel@tonic-gate #define CPCIO_SAMPLE (_CPCIO_IOC | 0x2) 1090Sstevel@tonic-gate #define CPCIO_RELE (_CPCIO_IOC | 0x3) 1100Sstevel@tonic-gate 1110Sstevel@tonic-gate /* 1120Sstevel@tonic-gate * Forward declarations. 1130Sstevel@tonic-gate */ 1140Sstevel@tonic-gate struct _kthread; 1150Sstevel@tonic-gate struct _kcpc_set; 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate #define CPC_MAX_EVENT_LEN 512 1180Sstevel@tonic-gate #define CPC_MAX_ATTR_LEN 32 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate typedef struct _kcpc_attr { 1210Sstevel@tonic-gate char ka_name[CPC_MAX_ATTR_LEN]; 1220Sstevel@tonic-gate uint64_t ka_val; 1230Sstevel@tonic-gate } kcpc_attr_t; 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate typedef struct _kcpc_pic { 1260Sstevel@tonic-gate uint_t kp_flags; 1270Sstevel@tonic-gate struct _kcpc_request *kp_req; /* request this PIC counts for */ 1280Sstevel@tonic-gate } kcpc_pic_t; 1290Sstevel@tonic-gate 1300Sstevel@tonic-gate typedef struct _kcpc_ctx kcpc_ctx_t; 1310Sstevel@tonic-gate 1320Sstevel@tonic-gate struct _kcpc_ctx { 1330Sstevel@tonic-gate struct _kcpc_set *kc_set; /* linked list of all bound sets */ 13411389SAlexander.Kolbasov@Sun.COM volatile uint_t kc_flags; 1350Sstevel@tonic-gate kcpc_pic_t *kc_pics; /* pointer to array of per-pic data */ 1360Sstevel@tonic-gate hrtime_t kc_hrtime; /* gethrtime() at last sample */ 1370Sstevel@tonic-gate uint64_t kc_vtick; /* virtualized %tick */ 1380Sstevel@tonic-gate uint64_t kc_rawtick; /* last snapshot of tick/tsc */ 1390Sstevel@tonic-gate struct _kthread *kc_thread; /* thread this context is measuring */ 1400Sstevel@tonic-gate int kc_cpuid; /* CPU this context is measuring */ 1410Sstevel@tonic-gate kcpc_ctx_t *kc_next; /* Global list of all contexts */ 1426275Strevtom kmutex_t kc_lock; /* protects kc_flags */ 1436275Strevtom kcondvar_t kc_condv; /* wait for kcpc_restore completion */ 1440Sstevel@tonic-gate }; 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate typedef struct __cpc_args { 1470Sstevel@tonic-gate void *udata1; 1480Sstevel@tonic-gate void *udata2; 1490Sstevel@tonic-gate void *udata3; 1500Sstevel@tonic-gate } __cpc_args_t; 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate #ifdef _KERNEL 1530Sstevel@tonic-gate 1540Sstevel@tonic-gate #ifdef _MULTI_DATAMODEL 1550Sstevel@tonic-gate typedef struct __cpc_args32 { 1560Sstevel@tonic-gate caddr32_t udata1; 1570Sstevel@tonic-gate caddr32_t udata2; 1580Sstevel@tonic-gate caddr32_t udata3; 1590Sstevel@tonic-gate } __cpc_args32_t; 1600Sstevel@tonic-gate #endif /* _MULTI_DATAMODEL */ 1610Sstevel@tonic-gate 1620Sstevel@tonic-gate #define KCPC_LOG2_HASH_BUCKETS 6 /* => 64 buckets for now */ 1630Sstevel@tonic-gate #define CPC_HASH_BUCKETS (1l << KCPC_LOG2_HASH_BUCKETS) 1640Sstevel@tonic-gate #define CPC_HASH_CTX(ctx) ((((long)(ctx)) >> 7) & \ 1650Sstevel@tonic-gate (CPC_HASH_BUCKETS - 1)) 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate /* 1680Sstevel@tonic-gate * Context flags. 1690Sstevel@tonic-gate */ 1700Sstevel@tonic-gate #define KCPC_CTX_FREEZE 0x1 /* => no sampling */ 1710Sstevel@tonic-gate #define KCPC_CTX_SIGOVF 0x2 /* => send signal on overflow */ 1720Sstevel@tonic-gate #define KCPC_CTX_NONPRIV 0x4 /* => non-priv access to counters */ 1730Sstevel@tonic-gate #define KCPC_CTX_LWPINHERIT 0x8 /* => lwp_create inherits ctx */ 1740Sstevel@tonic-gate #define KCPC_CTX_INVALID 0x100 /* => context stolen; discard */ 1750Sstevel@tonic-gate #define KCPC_CTX_INVALID_STOPPED 0x200 /* => invalid ctx has been stopped */ 1766275Strevtom #define KCPC_CTX_RESTORE 0x400 /* => kcpc_restore in progress */ 1770Sstevel@tonic-gate 1780Sstevel@tonic-gate /* 1790Sstevel@tonic-gate * PIC flags. 1800Sstevel@tonic-gate */ 1810Sstevel@tonic-gate #define KCPC_PIC_OVERFLOWED 0x1 /* pic overflowed & requested notify */ 1820Sstevel@tonic-gate 1838803SJonathan.Haslam@Sun.COM /* 1848803SJonathan.Haslam@Sun.COM * The following flags are used by the DTrace CPU performance counter provider 1858803SJonathan.Haslam@Sun.COM * and the overflow handler. The 'DCPC_INTR_*' flags are used to synchronize 1868803SJonathan.Haslam@Sun.COM * performance counter configuration events performed by the cpc provider and 1878803SJonathan.Haslam@Sun.COM * interrupt processing carried out by the overflow handler. The 'DCPC_?MASK' 1888803SJonathan.Haslam@Sun.COM * flags are used by the dcpc provider to indicate which type of mask attribute 1898803SJonathan.Haslam@Sun.COM * a platform supports. 1908803SJonathan.Haslam@Sun.COM */ 1918803SJonathan.Haslam@Sun.COM 192*11455SJonathan.Haslam@Sun.COM enum dcpc_intr_state { 193*11455SJonathan.Haslam@Sun.COM DCPC_INTR_INACTIVE, /* The dcpc provider is currently not in use */ 194*11455SJonathan.Haslam@Sun.COM DCPC_INTR_FREE, /* No config events or ovf ints in progress */ 195*11455SJonathan.Haslam@Sun.COM DCPC_INTR_PROCESSING, /* An overflow interrupt is being processed */ 196*11455SJonathan.Haslam@Sun.COM DCPC_INTR_CONFIG /* cpc subsystem being configured by dcpc */ 197*11455SJonathan.Haslam@Sun.COM }; 1988803SJonathan.Haslam@Sun.COM 199*11455SJonathan.Haslam@Sun.COM enum dcpc_mask_attr { 200*11455SJonathan.Haslam@Sun.COM DCPC_UMASK = 0x1, /* The platform supports a "umask" attribute */ 201*11455SJonathan.Haslam@Sun.COM DCPC_EMASK = 0x2 /* The platform supports an "emask" attribute */ 202*11455SJonathan.Haslam@Sun.COM }; 2038803SJonathan.Haslam@Sun.COM 2040Sstevel@tonic-gate #ifdef __sparc 2050Sstevel@tonic-gate extern uint64_t ultra_gettick(void); 2060Sstevel@tonic-gate #define KCPC_GET_TICK ultra_gettick 2070Sstevel@tonic-gate #else 2080Sstevel@tonic-gate extern hrtime_t tsc_read(void); 2090Sstevel@tonic-gate #define KCPC_GET_TICK tsc_read 2100Sstevel@tonic-gate #endif /* __sparc */ 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate #define PCBE_NAMELEN 30 /* Enough room for "pcbe." plus full PCBE name spec */ 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate struct cpu; 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate extern uint_t cpc_ncounters; 2170Sstevel@tonic-gate extern krwlock_t kcpc_cpuctx_lock; /* lock for 'kcpc_cpuctx' below */ 2180Sstevel@tonic-gate extern int kcpc_cpuctx; /* number of cpu-specific contexts */ 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate extern void kcpc_invalidate_all(void); 2210Sstevel@tonic-gate 2220Sstevel@tonic-gate extern void kcpc_passivate(void); 22311389SAlexander.Kolbasov@Sun.COM extern void kcpc_cpu_stop(struct cpu *, boolean_t); 2240Sstevel@tonic-gate extern int kcpc_pcbe_tryload(const char *, uint_t, uint_t, uint_t); 22511389SAlexander.Kolbasov@Sun.COM extern void kcpc_cpu_program(struct cpu *, kcpc_ctx_t *); 2268803SJonathan.Haslam@Sun.COM extern void kcpc_register_dcpc(void (*func)(uint64_t)); 2278803SJonathan.Haslam@Sun.COM extern void kcpc_unregister_dcpc(void); 22811389SAlexander.Kolbasov@Sun.COM extern kcpc_ctx_t *kcpc_ctx_alloc(int); 2298803SJonathan.Haslam@Sun.COM extern int kcpc_assign_reqs(struct _kcpc_set *, kcpc_ctx_t *); 2308803SJonathan.Haslam@Sun.COM extern void kcpc_ctx_free(kcpc_ctx_t *); 2318803SJonathan.Haslam@Sun.COM extern int kcpc_configure_reqs(kcpc_ctx_t *, struct _kcpc_set *, int *); 2328803SJonathan.Haslam@Sun.COM extern void kcpc_free_configs(struct _kcpc_set *); 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate #endif /* _KERNEL */ 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate /* 2370Sstevel@tonic-gate * Error subcodes. 2380Sstevel@tonic-gate */ 2390Sstevel@tonic-gate #define CPC_INVALID_EVENT 1 /* Unknown event */ 2400Sstevel@tonic-gate #define CPC_INVALID_PICNUM 2 /* Requested PIC out of range */ 2410Sstevel@tonic-gate #define CPC_INVALID_ATTRIBUTE 3 /* Unknown attribute */ 2420Sstevel@tonic-gate #define CPC_ATTRIBUTE_OUT_OF_RANGE 4 /* Attribute val out of range */ 2430Sstevel@tonic-gate #define CPC_RESOURCE_UNAVAIL 5 /* Can't get needed resource */ 2440Sstevel@tonic-gate #define CPC_PIC_NOT_CAPABLE 6 /* PIC can't count this event */ 2450Sstevel@tonic-gate #define CPC_REQ_INVALID_FLAGS 7 /* Invalid flags in req(s) */ 2460Sstevel@tonic-gate #define CPC_CONFLICTING_REQS 8 /* Reqs in the set conflict */ 2470Sstevel@tonic-gate #define CPC_ATTR_REQUIRES_PRIVILEGE 9 /* Insufficient privs for atr */ 2480Sstevel@tonic-gate #define CPC_PBIND_FAILED 10 /* Couldn't bind to processor */ 2493732Sae112802 #define CPC_HV_NO_ACCESS 11 /* No perm for HV events */ 2500Sstevel@tonic-gate 2510Sstevel@tonic-gate #ifdef __cplusplus 2520Sstevel@tonic-gate } 2530Sstevel@tonic-gate #endif 2540Sstevel@tonic-gate 2550Sstevel@tonic-gate #endif /* _SYS_CPC_IMPL_H */ 256