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*6275Strevtom * Copyright 2008 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 #pragma ident "%Z%%M% %I% %E% SMI" 300Sstevel@tonic-gate 310Sstevel@tonic-gate #include <sys/types.h> 320Sstevel@tonic-gate #include <sys/time.h> 33*6275Strevtom #include <sys/ksynch.h> 340Sstevel@tonic-gate 350Sstevel@tonic-gate #if defined(_KERNEL) && defined(_MULTI_DATAMODEL) 360Sstevel@tonic-gate #include <sys/types32.h> 370Sstevel@tonic-gate #endif 380Sstevel@tonic-gate 390Sstevel@tonic-gate #ifdef __cplusplus 400Sstevel@tonic-gate extern "C" { 410Sstevel@tonic-gate #endif 420Sstevel@tonic-gate 430Sstevel@tonic-gate typedef struct { 440Sstevel@tonic-gate char *ca_name; 450Sstevel@tonic-gate uint64_t ca_val; 460Sstevel@tonic-gate } cpc_attr_t; 470Sstevel@tonic-gate 480Sstevel@tonic-gate /* 490Sstevel@tonic-gate * Flag arguments to cpc_bind_event and cpc_ctx_bind_event 500Sstevel@tonic-gate */ 510Sstevel@tonic-gate #define CPC_BIND_LWP_INHERIT (0x1) 520Sstevel@tonic-gate #define CPC_BIND_EMT_OVF (0x2) 530Sstevel@tonic-gate 540Sstevel@tonic-gate #define CPC_MAX_IMPL_NAME 512 /* Max len of PCBE's description str */ 550Sstevel@tonic-gate #define CPC_MAX_CPUREF 1024 /* Max len of PCBE's CPU ref string */ 560Sstevel@tonic-gate 570Sstevel@tonic-gate #define CPC_OVF_NOTIFY_EMT 0x1 580Sstevel@tonic-gate #define CPC_COUNT_USER 0x2 590Sstevel@tonic-gate #define CPC_COUNT_SYSTEM 0x4 603732Sae112802 #define CPC_COUNT_HV 0x8 610Sstevel@tonic-gate 623732Sae112802 #define KCPC_REQ_ALL_FLAGS (CPC_OVF_NOTIFY_EMT | CPC_COUNT_USER | \ 633732Sae112802 CPC_COUNT_SYSTEM | CPC_COUNT_HV) 640Sstevel@tonic-gate #define KCPC_REQ_VALID_FLAGS(flags) \ 650Sstevel@tonic-gate (((flags) | KCPC_REQ_ALL_FLAGS) == KCPC_REQ_ALL_FLAGS) 660Sstevel@tonic-gate 670Sstevel@tonic-gate /* 680Sstevel@tonic-gate * CPC Capabilities 690Sstevel@tonic-gate */ 700Sstevel@tonic-gate #define CPC_CAP_OVERFLOW_INTERRUPT 0x1 710Sstevel@tonic-gate #define CPC_CAP_OVERFLOW_PRECISE 0x2 720Sstevel@tonic-gate 730Sstevel@tonic-gate /* 740Sstevel@tonic-gate * The only valid per-set flag is CPC_BIND_LWP_INHERIT, which must remain in 750Sstevel@tonic-gate * cpc_event.h for backwards compatibility. 760Sstevel@tonic-gate */ 770Sstevel@tonic-gate #define CPC_SET_ALL_FLAGS 0x1 780Sstevel@tonic-gate #define CPC_SET_VALID_FLAGS(flags) \ 790Sstevel@tonic-gate (((flags) | CPC_SET_ALL_FLAGS) == CPC_SET_ALL_FLAGS) 800Sstevel@tonic-gate 810Sstevel@tonic-gate /* 820Sstevel@tonic-gate * These system call subcodes and ioctls allow the implementation of the 830Sstevel@tonic-gate * libcpc library to store and retrieve performance counter data. Subject 840Sstevel@tonic-gate * to arbitrary change without notice at any time. Do not invoke them 850Sstevel@tonic-gate * directly! 860Sstevel@tonic-gate */ 870Sstevel@tonic-gate #define CPC_BIND 0 880Sstevel@tonic-gate #define CPC_SAMPLE 1 890Sstevel@tonic-gate #define CPC_INVALIDATE 2 900Sstevel@tonic-gate #define CPC_RELE 3 910Sstevel@tonic-gate #define CPC_EVLIST_SIZE 4 920Sstevel@tonic-gate #define CPC_LIST_EVENTS 5 930Sstevel@tonic-gate #define CPC_ATTRLIST_SIZE 6 940Sstevel@tonic-gate #define CPC_LIST_ATTRS 7 950Sstevel@tonic-gate #define CPC_IMPL_NAME 8 960Sstevel@tonic-gate #define CPC_CPUREF 9 970Sstevel@tonic-gate #define CPC_USR_EVENTS 10 980Sstevel@tonic-gate #define CPC_SYS_EVENTS 11 990Sstevel@tonic-gate #define CPC_NPIC 12 1000Sstevel@tonic-gate #define CPC_CAPS 13 1010Sstevel@tonic-gate #define CPC_ENABLE 14 1020Sstevel@tonic-gate #define CPC_DISABLE 15 1030Sstevel@tonic-gate #define CPC_PRESET 16 1040Sstevel@tonic-gate #define CPC_RESTART 17 1050Sstevel@tonic-gate 1060Sstevel@tonic-gate #define _CPCIO_IOC ((((('c'<<8)|'p')<<8)|'c')<<8) 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate #define CPCIO_BIND (_CPCIO_IOC | 0x1) 1090Sstevel@tonic-gate #define CPCIO_SAMPLE (_CPCIO_IOC | 0x2) 1100Sstevel@tonic-gate #define CPCIO_RELE (_CPCIO_IOC | 0x3) 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate /* 1130Sstevel@tonic-gate * Forward declarations. 1140Sstevel@tonic-gate */ 1150Sstevel@tonic-gate struct _kthread; 1160Sstevel@tonic-gate struct _kcpc_set; 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate #define CPC_MAX_EVENT_LEN 512 1190Sstevel@tonic-gate #define CPC_MAX_ATTR_LEN 32 1200Sstevel@tonic-gate 1210Sstevel@tonic-gate typedef struct _kcpc_attr { 1220Sstevel@tonic-gate char ka_name[CPC_MAX_ATTR_LEN]; 1230Sstevel@tonic-gate uint64_t ka_val; 1240Sstevel@tonic-gate } kcpc_attr_t; 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate typedef struct _kcpc_pic { 1270Sstevel@tonic-gate uint_t kp_flags; 1280Sstevel@tonic-gate struct _kcpc_request *kp_req; /* request this PIC counts for */ 1290Sstevel@tonic-gate } kcpc_pic_t; 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate typedef struct _kcpc_ctx kcpc_ctx_t; 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate struct _kcpc_ctx { 1340Sstevel@tonic-gate struct _kcpc_set *kc_set; /* linked list of all bound sets */ 1350Sstevel@tonic-gate uint32_t kc_flags; 1360Sstevel@tonic-gate kcpc_pic_t *kc_pics; /* pointer to array of per-pic data */ 1370Sstevel@tonic-gate hrtime_t kc_hrtime; /* gethrtime() at last sample */ 1380Sstevel@tonic-gate uint64_t kc_vtick; /* virtualized %tick */ 1390Sstevel@tonic-gate uint64_t kc_rawtick; /* last snapshot of tick/tsc */ 1400Sstevel@tonic-gate struct _kthread *kc_thread; /* thread this context is measuring */ 1410Sstevel@tonic-gate int kc_cpuid; /* CPU this context is measuring */ 1420Sstevel@tonic-gate kcpc_ctx_t *kc_next; /* Global list of all contexts */ 143*6275Strevtom kmutex_t kc_lock; /* protects kc_flags */ 144*6275Strevtom kcondvar_t kc_condv; /* wait for kcpc_restore completion */ 1450Sstevel@tonic-gate }; 1460Sstevel@tonic-gate 1470Sstevel@tonic-gate typedef struct __cpc_args { 1480Sstevel@tonic-gate void *udata1; 1490Sstevel@tonic-gate void *udata2; 1500Sstevel@tonic-gate void *udata3; 1510Sstevel@tonic-gate } __cpc_args_t; 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate #ifdef _KERNEL 1540Sstevel@tonic-gate 1550Sstevel@tonic-gate #ifdef _MULTI_DATAMODEL 1560Sstevel@tonic-gate typedef struct __cpc_args32 { 1570Sstevel@tonic-gate caddr32_t udata1; 1580Sstevel@tonic-gate caddr32_t udata2; 1590Sstevel@tonic-gate caddr32_t udata3; 1600Sstevel@tonic-gate } __cpc_args32_t; 1610Sstevel@tonic-gate #endif /* _MULTI_DATAMODEL */ 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate #define KCPC_LOG2_HASH_BUCKETS 6 /* => 64 buckets for now */ 1640Sstevel@tonic-gate #define CPC_HASH_BUCKETS (1l << KCPC_LOG2_HASH_BUCKETS) 1650Sstevel@tonic-gate #define CPC_HASH_CTX(ctx) ((((long)(ctx)) >> 7) & \ 1660Sstevel@tonic-gate (CPC_HASH_BUCKETS - 1)) 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate /* 1690Sstevel@tonic-gate * Context flags. 1700Sstevel@tonic-gate */ 1710Sstevel@tonic-gate #define KCPC_CTX_FREEZE 0x1 /* => no sampling */ 1720Sstevel@tonic-gate #define KCPC_CTX_SIGOVF 0x2 /* => send signal on overflow */ 1730Sstevel@tonic-gate #define KCPC_CTX_NONPRIV 0x4 /* => non-priv access to counters */ 1740Sstevel@tonic-gate #define KCPC_CTX_LWPINHERIT 0x8 /* => lwp_create inherits ctx */ 1750Sstevel@tonic-gate #define KCPC_CTX_INVALID 0x100 /* => context stolen; discard */ 1760Sstevel@tonic-gate #define KCPC_CTX_INVALID_STOPPED 0x200 /* => invalid ctx has been stopped */ 177*6275Strevtom #define KCPC_CTX_RESTORE 0x400 /* => kcpc_restore in progress */ 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate /* 1800Sstevel@tonic-gate * PIC flags. 1810Sstevel@tonic-gate */ 1820Sstevel@tonic-gate #define KCPC_PIC_OVERFLOWED 0x1 /* pic overflowed & requested notify */ 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate #ifdef __sparc 1850Sstevel@tonic-gate extern uint64_t ultra_gettick(void); 1860Sstevel@tonic-gate #define KCPC_GET_TICK ultra_gettick 1870Sstevel@tonic-gate #else 1880Sstevel@tonic-gate extern hrtime_t tsc_read(void); 1890Sstevel@tonic-gate #define KCPC_GET_TICK tsc_read 1900Sstevel@tonic-gate #endif /* __sparc */ 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate #define PCBE_NAMELEN 30 /* Enough room for "pcbe." plus full PCBE name spec */ 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate struct cpu; 1950Sstevel@tonic-gate 1960Sstevel@tonic-gate extern uint_t cpc_ncounters; 1970Sstevel@tonic-gate extern kmutex_t kcpc_ctx_llock[]; /* protects ctx_list */ 1980Sstevel@tonic-gate extern kcpc_ctx_t *kcpc_ctx_list[]; /* head of list */ 1990Sstevel@tonic-gate extern krwlock_t kcpc_cpuctx_lock; /* lock for 'kcpc_cpuctx' below */ 2000Sstevel@tonic-gate extern int kcpc_cpuctx; /* number of cpu-specific contexts */ 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate extern void kcpc_invalidate_all(void); 2030Sstevel@tonic-gate 2040Sstevel@tonic-gate extern void kcpc_passivate(void); 2050Sstevel@tonic-gate extern void kcpc_remote_stop(struct cpu *cp); 2060Sstevel@tonic-gate extern int kcpc_pcbe_tryload(const char *, uint_t, uint_t, uint_t); 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate #endif /* _KERNEL */ 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate /* 2110Sstevel@tonic-gate * Error subcodes. 2120Sstevel@tonic-gate */ 2130Sstevel@tonic-gate #define CPC_INVALID_EVENT 1 /* Unknown event */ 2140Sstevel@tonic-gate #define CPC_INVALID_PICNUM 2 /* Requested PIC out of range */ 2150Sstevel@tonic-gate #define CPC_INVALID_ATTRIBUTE 3 /* Unknown attribute */ 2160Sstevel@tonic-gate #define CPC_ATTRIBUTE_OUT_OF_RANGE 4 /* Attribute val out of range */ 2170Sstevel@tonic-gate #define CPC_RESOURCE_UNAVAIL 5 /* Can't get needed resource */ 2180Sstevel@tonic-gate #define CPC_PIC_NOT_CAPABLE 6 /* PIC can't count this event */ 2190Sstevel@tonic-gate #define CPC_REQ_INVALID_FLAGS 7 /* Invalid flags in req(s) */ 2200Sstevel@tonic-gate #define CPC_CONFLICTING_REQS 8 /* Reqs in the set conflict */ 2210Sstevel@tonic-gate #define CPC_ATTR_REQUIRES_PRIVILEGE 9 /* Insufficient privs for atr */ 2220Sstevel@tonic-gate #define CPC_PBIND_FAILED 10 /* Couldn't bind to processor */ 2233732Sae112802 #define CPC_HV_NO_ACCESS 11 /* No perm for HV events */ 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate #ifdef __cplusplus 2260Sstevel@tonic-gate } 2270Sstevel@tonic-gate #endif 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate #endif /* _SYS_CPC_IMPL_H */ 230