diff options
22 files changed, 1323 insertions, 138 deletions
diff --git a/usr/src/cmd/cpc/common/caps.c b/usr/src/cmd/cpc/common/caps.c index 8057df3c57..5ed12182d3 100644 --- a/usr/src/cmd/cpc/common/caps.c +++ b/usr/src/cmd/cpc/common/caps.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #define __EXTENSIONS__ /* header bug! strtok_r is overly hidden */ #include <string.h> #include <strings.h> @@ -139,7 +136,7 @@ allpics_equal(cpc_t *cpc) for (i = 1; i < npics; i++) if (lists[i]->size != lists[0]->size || strncmp(lists[i]->list, lists[0]->list, - lists[0]->size) != 0) { + lists[0]->size) != 0) { ret = 0; break; } @@ -160,7 +157,7 @@ capabilities(cpc_t *cpc, FILE *fp) char *text, *tok, *cp; const char *ccp; int npic = cpc_npic(cpc); - int i; + int i, pics_equal = allpics_equal(cpc); args->fp = fp; @@ -174,7 +171,30 @@ capabilities(cpc_t *cpc, FILE *fp) (void) fprintf(args->fp, "\t[picn=]<eventn>[,attr[n][=<val>]]" "[,[picn=]<eventn>[,attr[n][=<val>]],...]\n"); - if (allpics_equal(cpc)) { + (void) fprintf(args->fp, gettext("\n\tGeneric Events:\n")); + + if (pics_equal) { + args->margin = args->colnum = EVENT_MARGIN; + (void) fprintf(args->fp, "\n\tevent[0-%d]: ", npic - 1); + cpc_walk_generic_events_pic(cpc, 0, args, list_cap); + (void) fprintf(args->fp, "\n"); + } else { + args->margin = EVENT_MARGIN; + for (i = 0; i < npic; i++) { + (void) fprintf(args->fp, "\n\tevent%d: ", i); + if (i < 10) (void) fprintf(args->fp, " "); + args->colnum = EVENT_MARGIN; + cpc_walk_generic_events_pic(cpc, i, args, list_cap); + (void) fprintf(args->fp, "\n"); + } + } + + (void) fprintf(args->fp, gettext("\n\tSee generic_events(3CPC) for" + " descriptions of these events\n\n")); + + (void) fprintf(args->fp, gettext("\tPlatform Specific Events:\n")); + + if (pics_equal) { args->margin = args->colnum = EVENT_MARGIN; (void) fprintf(args->fp, "\n\tevent[0-%d]: ", npic - 1); cpc_walk_events_pic(cpc, 0, args, list_cap); diff --git a/usr/src/cmd/cpc/common/strtoset.c b/usr/src/cmd/cpc/common/strtoset.c index b61f7d75b8..a5236fd376 100644 --- a/usr/src/cmd/cpc/common/strtoset.c +++ b/usr/src/cmd/cpc/common/strtoset.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <alloca.h> @@ -125,6 +123,11 @@ event_valid(int picnum, char *event) if (found) return (1); + cpc_walk_generic_events_pic(cpc, picnum, event, event_walker); + + if (found) + return (1); + /* * Before assuming this is an invalid event, see if we have been given * a raw event code. An event code of '0' is not recognized, as it diff --git a/usr/src/lib/libcpc/common/libcpc.c b/usr/src/lib/libcpc/common/libcpc.c index df431abcc4..ad9e288781 100644 --- a/usr/src/lib/libcpc/common/libcpc.c +++ b/usr/src/lib/libcpc/common/libcpc.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <libcpc.h> #include <stdio.h> #include <stdlib.h> @@ -809,12 +807,73 @@ cpc_walk_events_all(cpc_t *cpc, void *arg, p = list[i]; while ((e = strchr(p, ',')) != NULL) { *e = '\0'; + + /* Skip any generic event names we find. */ + if ((strncmp(p, "PAPI", 4)) == 0) { + p = e + 1; + continue; + } + if (__cpc_strhash_add(hash, p) == -1) goto err; p = e + 1; } - if (__cpc_strhash_add(hash, p) == -1) + if ((strncmp(p, "PAPI", 4)) != 0) { + if (__cpc_strhash_add(hash, p) == -1) + goto err; + } + } + + while ((p = __cpc_strhash_next(hash)) != NULL) + action(arg, p); + +err: + __cpc_strhash_free(hash); + for (i = 0; i < ncounters; i++) + free(list[i]); + free(list); +} + +/*ARGSUSED*/ +void +cpc_walk_generic_events_all(cpc_t *cpc, void *arg, + void (*action)(void *arg, const char *event)) +{ + char **list; + char *p, *e; + int i; + int ncounters = cpc_npic(cpc); + cpc_strhash_t *hash; + + if ((list = malloc(ncounters * sizeof (char *))) == NULL) + return; + + if ((hash = __cpc_strhash_alloc()) == NULL) { + free(list); + return; + } + + for (i = 0; i < ncounters; i++) { + if ((list[i] = strdup(cpc->cpc_evlist[i])) == NULL) goto err; + p = list[i]; + while ((e = strchr(p, ',')) != NULL) { + *e = '\0'; + + /* Skip any platform specific event names we find. */ + if ((strncmp(p, "PAPI", 4)) != 0) { + p = e + 1; + continue; + } + + if (__cpc_strhash_add(hash, p) == -1) + goto err; + p = e + 1; + } + if ((strncmp(p, "PAPI", 4)) == 0) { + if (__cpc_strhash_add(hash, p) == -1) + goto err; + } } while ((p = __cpc_strhash_next(hash)) != NULL) @@ -851,11 +910,67 @@ cpc_walk_events_pic(cpc_t *cpc, uint_t picno, void *arg, p = list; while ((e = strchr(p, ',')) != NULL) { *e = '\0'; + + /* Skip any generic event names we find. */ + if ((strncmp(p, "PAPI", 4)) == 0) { + p = e + 1; + continue; + } + action(arg, picno, p); p = e + 1; } + + if ((strncmp(p, "PAPI", 4)) == 0) + goto out; + action(arg, picno, p); +out: + free(list); +} + +/*ARGSUSED*/ +void +cpc_walk_generic_events_pic(cpc_t *cpc, uint_t picno, void *arg, + void (*action)(void *arg, uint_t picno, const char *event)) +{ + char *p; + char *e; + char *list; + + if (picno >= cpc->cpc_npic) { + errno = EINVAL; + return; + } + + if ((list = strdup(cpc->cpc_evlist[picno])) == NULL) + return; + + /* + * List now points to a comma-separated list of events supported by + * the designated pic. + */ + p = list; + while ((e = strchr(p, ',')) != NULL) { + *e = '\0'; + + /* Skip any platform specific event names we find. */ + if ((strncmp(p, "PAPI", 4)) != 0) { + p = e + 1; + continue; + } + + action(arg, picno, p); + p = e + 1; + } + + if ((strncmp(p, "PAPI", 4)) != 0) + goto out; + + action(arg, picno, p); + +out: free(list); } @@ -1081,6 +1196,10 @@ cpc_valid_event(cpc_t *cpc, uint_t pic, const char *ev) if (pr.found) return (1); + cpc_walk_generic_events_pic(cpc, pic, &pr, ev_walker); + if (pr.found) + return (1); + /* * Before assuming this is an invalid event, see if we have been given * a raw event code. An event code of '0' is not recognized, as it diff --git a/usr/src/lib/libcpc/common/libcpc.h b/usr/src/lib/libcpc/common/libcpc.h index 547cb62319..384474a76c 100644 --- a/usr/src/lib/libcpc/common/libcpc.h +++ b/usr/src/lib/libcpc/common/libcpc.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _LIBCPC_H #define _LIBCPC_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/cpc_impl.h> #include <inttypes.h> @@ -154,8 +151,12 @@ extern void cpc_walk_requests(cpc_t *cpc, cpc_set_t *set, void *arg, extern void cpc_walk_events_all(cpc_t *cpc, void *arg, void (*action)(void *arg, const char *event)); +extern void cpc_walk_generic_events_all(cpc_t *cpc, void *arg, + void (*action)(void *arg, const char *event)); extern void cpc_walk_events_pic(cpc_t *cpc, uint_t picno, void *arg, void (*action)(void *arg, uint_t picno, const char *event)); +extern void cpc_walk_generic_events_pic(cpc_t *cpc, uint_t picno, void *arg, + void (*action)(void *arg, uint_t picno, const char *event)); extern void cpc_walk_attrs(cpc_t *cpc, void *arg, void (*action)(void *arg, const char *attr)); diff --git a/usr/src/lib/libcpc/common/mapfile-vers b/usr/src/lib/libcpc/common/mapfile-vers index f4403fa877..2f812b76a6 100644 --- a/usr/src/lib/libcpc/common/mapfile-vers +++ b/usr/src/lib/libcpc/common/mapfile-vers @@ -19,11 +19,15 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# + +SUNW_1.3 { + global: + cpc_walk_generic_events_pic; + cpc_walk_generic_events_all; +} SUNW_1.2; SUNW_1.2 { global: diff --git a/usr/src/pkgdefs/SUNWcpcu/Makefile b/usr/src/pkgdefs/SUNWcpcu/Makefile index 8663901ec9..226eda0e97 100644 --- a/usr/src/pkgdefs/SUNWcpcu/Makefile +++ b/usr/src/pkgdefs/SUNWcpcu/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,16 +19,19 @@ # CDDL HEADER END # # -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 1999 by Sun Microsystems, Inc. -# All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # + include ../Makefile.com DATAFILES += depend +LICENSEFILES_i386 = ../../uts/intel/pcbe/THIRDPARTYLICENSE +LICENSEFILES_sparc = ../../uts/sun4u/pcbe/THIRDPARTYLICENSE +LICENSEFILES += $(LICENSEFILES_$(MACH)) + .KEEP_STATE: all: $(FILES) diff --git a/usr/src/pkgdefs/SUNWust1.v/Makefile b/usr/src/pkgdefs/SUNWust1.v/Makefile index 8ffeac0898..9c8a5a65ff 100644 --- a/usr/src/pkgdefs/SUNWust1.v/Makefile +++ b/usr/src/pkgdefs/SUNWust1.v/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,16 +19,17 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# include ../Makefile.com DATAFILES += depend +LICENSEFILES_sparc = ../../uts/sun4v/pcbe/THIRDPARTYLICENSE +LICENSEFILES += $(LICENSEFILES_$(MACH)) + .KEEP_STATE: all: $(FILES) diff --git a/usr/src/pkgdefs/SUNWust2.v/Makefile b/usr/src/pkgdefs/SUNWust2.v/Makefile index fbabdf4e9e..9c8a5a65ff 100644 --- a/usr/src/pkgdefs/SUNWust2.v/Makefile +++ b/usr/src/pkgdefs/SUNWust2.v/Makefile @@ -19,16 +19,17 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# include ../Makefile.com DATAFILES += depend +LICENSEFILES_sparc = ../../uts/sun4v/pcbe/THIRDPARTYLICENSE +LICENSEFILES += $(LICENSEFILES_$(MACH)) + .KEEP_STATE: all: $(FILES) diff --git a/usr/src/tools/opensolaris/license-list b/usr/src/tools/opensolaris/license-list index 010eb1612a..0175ca863c 100644 --- a/usr/src/tools/opensolaris/license-list +++ b/usr/src/tools/opensolaris/license-list @@ -155,6 +155,9 @@ usr/src/uts/intel/THIRDPARTYLICENSE usr/src/uts/intel/io/acpica/THIRDPARTYLICENSE usr/src/uts/intel/io/amd8111s/THIRDPARTYLICENSE.amd8111s usr/src/uts/intel/io/amr/THIRDPARTYLICENSE +usr/src/uts/intel/pcbe/THIRDPARTYLICENSE +usr/src/uts/sun4u/pcbe/THIRDPARTYLICENSE +usr/src/uts/sun4v/pcbe/THIRDPARTYLICENSE usr/src/common/mpi/THIRDPARTYLICENSE usr/src/lib/libsmbfs/smb/THIRDPARTYLICENSE.apple usr/src/lib/libsmbfs/smb/THIRDPARTYLICENSE.boris_popov diff --git a/usr/src/uts/intel/pcbe/THIRDPARTYLICENSE b/usr/src/uts/intel/pcbe/THIRDPARTYLICENSE new file mode 100644 index 0000000000..9b3f5f1b38 --- /dev/null +++ b/usr/src/uts/intel/pcbe/THIRDPARTYLICENSE @@ -0,0 +1,33 @@ + Copyright (c) 2005,6 + Innovative Computing Labs + Computer Science Department, + University of Tennessee, + Knoxville, TN. + All Rights Reserved. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the University of Tennessee nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +This open source software license conforms to the BSD License template. diff --git a/usr/src/uts/intel/pcbe/THIRDPARTYLICENSE.descrip b/usr/src/uts/intel/pcbe/THIRDPARTYLICENSE.descrip new file mode 100644 index 0000000000..1cc8c623bf --- /dev/null +++ b/usr/src/uts/intel/pcbe/THIRDPARTYLICENSE.descrip @@ -0,0 +1 @@ +PAPI PRESET EVENT NAMES diff --git a/usr/src/uts/intel/pcbe/opteron_pcbe.c b/usr/src/uts/intel/pcbe/opteron_pcbe.c index 7ec2337296..556372e548 100644 --- a/usr/src/uts/intel/pcbe/opteron_pcbe.c +++ b/usr/src/uts/intel/pcbe/opteron_pcbe.c @@ -23,7 +23,45 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * This file contains preset event names from the Performance Application + * Programming Interface v3.5 which included the following notice: + * + * Copyright (c) 2005,6 + * Innovative Computing Labs + * Computer Science Department, + * University of Tennessee, + * Knoxville, TN. + * All Rights Reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of Tennessee nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * This open source software license conforms to the BSD License template. + */ /* * Performance Counter Back-End for AMD Opteron and AMD Athlon 64 processors. @@ -124,6 +162,12 @@ typedef struct _amd_event { uint8_t umask_valid; /* Mask of unreserved UNIT_MASK bits */ } amd_event_t; +typedef struct _amd_generic_event { + char *name; + char *event; + uint8_t umask; +} amd_generic_event_t; + /* * Base MSR addresses for the PerfEvtSel registers and the counters themselves. * Add counter number to base address to get corresponding MSR address. @@ -134,6 +178,7 @@ typedef struct _amd_event { #define MASK48 0xFFFFFFFFFFFF #define EV_END {NULL, 0, 0} +#define GEN_EV_END {NULL, NULL, 0 } #define AMD_cmn_events \ { "FP_dispatched_fpu_ops", 0x0, 0x3F }, \ @@ -282,6 +327,51 @@ typedef struct _amd_event { { "L3_l2_eviction_l3_fill", 0x4E2, 0xFF }, \ { "L3_eviction", 0x4E3, 0xF } +#define AMD_cmn_generic_events \ + { "PAPI_br_ins", "FR_retired_branches_w_excp_intr", 0x0 },\ + { "PAPI_br_msp", "FR_retired_branches_mispred", 0x0 }, \ + { "PAPI_br_tkn", "FR_retired_taken_branches", 0x0 }, \ + { "PAPI_fp_ops", "FP_dispatched_fpu_ops", 0x3 }, \ + { "PAPI_fad_ins", "FP_dispatched_fpu_ops", 0x1 }, \ + { "PAPI_fml_ins", "FP_dispatched_fpu_ops", 0x2 }, \ + { "PAPI_fpu_idl", "FP_cycles_no_fpu_ops_retired", 0x0 }, \ + { "PAPI_tot_cyc", "BU_cpu_clk_unhalted", 0x0 }, \ + { "PAPI_tot_ins", "FR_retired_x86_instr_w_excp_intr", 0x0 }, \ + { "PAPI_l1_dca", "DC_access", 0x0 }, \ + { "PAPI_l1_dcm", "DC_miss", 0x0 }, \ + { "PAPI_l1_ldm", "DC_refill_from_L2", 0xe }, \ + { "PAPI_l1_stm", "DC_refill_from_L2", 0x10 }, \ + { "PAPI_l1_ica", "IC_fetch", 0x0 }, \ + { "PAPI_l1_icm", "IC_miss", 0x0 }, \ + { "PAPI_l1_icr", "IC_fetch", 0x0 }, \ + { "PAPI_l2_dch", "DC_refill_from_L2", 0x1e }, \ + { "PAPI_l2_dcm", "DC_refill_from_system", 0x1e }, \ + { "PAPI_l2_dcr", "DC_refill_from_L2", 0xe }, \ + { "PAPI_l2_dcw", "DC_refill_from_L2", 0x10 }, \ + { "PAPI_l2_ich", "IC_refill_from_L2", 0x0 }, \ + { "PAPI_l2_icm", "IC_refill_from_system", 0x0 }, \ + { "PAPI_l2_ldm", "DC_refill_from_system", 0xe }, \ + { "PAPI_l2_stm", "DC_refill_from_system", 0x10 }, \ + { "PAPI_res_stl", "FR_dispatch_stalls", 0x0 }, \ + { "PAPI_stl_icy", "FR_nothing_to_dispatch", 0x0 }, \ + { "PAPI_hw_int", "FR_taken_hardware_intrs", 0x0 } + +#define OPT_cmn_generic_events \ + { "PAPI_tlb_dm", "DC_dtlb_L1_miss_L2_miss", 0x0 }, \ + { "PAPI_tlb_im", "IC_itlb_L1_miss_L2_miss", 0x0 }, \ + { "PAPI_fp_ins", "FR_retired_fpu_instr", 0xd }, \ + { "PAPI_vec_ins", "FR_retired_fpu_instr", 0x4 } + +#define AMD_FAMILY_10h_generic_events \ + { "PAPI_tlb_dm", "DC_dtlb_L1_miss_L2_miss", 0x7 }, \ + { "PAPI_tlb_im", "IC_itlb_L1_miss_L2_miss", 0x3 }, \ + { "PAPI_l3_dcr", "L3_read_req", 0xf1 }, \ + { "PAPI_l3_icr", "L3_read_req", 0xf2 }, \ + { "PAPI_l3_tcr", "L3_read_req", 0xf7 }, \ + { "PAPI_l3_stm", "L3_miss", 0xf4 }, \ + { "PAPI_l3_ldm", "L3_miss", 0xf3 }, \ + { "PAPI_l3_tcm", "L3_miss", 0xf7 } + static amd_event_t opt_events[] = { AMD_cmn_events, OPT_events, @@ -310,10 +400,23 @@ static amd_event_t family_10h_events[] = { EV_END }; +static amd_generic_event_t opt_generic_events[] = { + AMD_cmn_generic_events, + OPT_cmn_generic_events, + GEN_EV_END +}; + +static amd_generic_event_t family_10h_generic_events[] = { + AMD_cmn_generic_events, + AMD_FAMILY_10h_generic_events, + GEN_EV_END +}; + static char *evlist; static size_t evlist_sz; static amd_event_t *amd_events = NULL; static uint_t amd_family; +static amd_generic_event_t *amd_generic_events = NULL; #define BITS(v, u, l) \ (((v) >> (l)) & ((1 << (1 + (u) - (l))) - 1)) @@ -325,6 +428,7 @@ static int opt_pcbe_init(void) { amd_event_t *evp; + amd_generic_event_t *gevp; uint32_t rev; amd_family = cpuid_getfamily(CPU); @@ -346,6 +450,7 @@ opt_pcbe_init(void) rev = cpuid_getchiprev(CPU); if (amd_family == OPTERON_FAMILY) { + amd_generic_events = opt_generic_events; if (!X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_D)) { amd_events = opt_events; } else if X86_CHIPREV_MATCH(rev, X86_CHIPREV_AMD_F_REV_D) { @@ -359,6 +464,7 @@ opt_pcbe_init(void) } } else { amd_events = family_10h_events; + amd_generic_events = family_10h_generic_events; } /* @@ -372,6 +478,9 @@ opt_pcbe_init(void) for (evp = amd_events; evp->name != NULL; evp++) evlist_sz += strlen(evp->name) + 1; + for (gevp = amd_generic_events; gevp->name != NULL; gevp++) + evlist_sz += strlen(gevp->name) + 1; + evlist = kmem_alloc(evlist_sz + 1, KM_SLEEP); evlist[0] = '\0'; @@ -379,6 +488,12 @@ opt_pcbe_init(void) (void) strcat(evlist, evp->name); (void) strcat(evlist, ","); } + + for (gevp = amd_generic_events; gevp->name != NULL; gevp++) { + (void) strcat(evlist, gevp->name); + (void) strcat(evlist, ","); + } + /* * Remove trailing comma. */ @@ -454,10 +569,22 @@ opt_pcbe_overflow_bitmap(void) return (0xF); } +static amd_generic_event_t * +find_generic_event(char *name) +{ + amd_generic_event_t *gevp; + + for (gevp = amd_generic_events; gevp->name != NULL; gevp++) + if (strcmp(name, gevp->name) == 0) + return (gevp); + + return (NULL); +} + static amd_event_t * find_event(char *name) { - amd_event_t *evp; + amd_event_t *evp; for (evp = amd_events; evp->name != NULL; evp++) if (strcmp(name, evp->name) == 0) @@ -474,6 +601,7 @@ opt_pcbe_configure(uint_t picnum, char *event, uint64_t preset, uint32_t flags, opt_pcbe_config_t *cfg; amd_event_t *evp; amd_event_t ev_raw = { "raw", 0, 0xFF }; + amd_generic_event_t *gevp; int i; uint64_t evsel = 0, evsel_tmp = 0; @@ -491,16 +619,27 @@ opt_pcbe_configure(uint_t picnum, char *event, uint64_t preset, uint32_t flags, return (CPC_INVALID_PICNUM); if ((evp = find_event(event)) == NULL) { - long tmp; + if ((gevp = find_generic_event(event)) != NULL) { + evp = find_event(gevp->event); + ASSERT(evp != NULL); + + if (nattrs > 0) + return (CPC_ATTRIBUTE_OUT_OF_RANGE); + + evsel |= gevp->umask << OPT_PES_UMASK_SHIFT; + } else { + long tmp; - /* - * If ddi_strtol() likes this event, use it as a raw event code. - */ - if (ddi_strtol(event, NULL, 0, &tmp) != 0) - return (CPC_INVALID_EVENT); + /* + * If ddi_strtol() likes this event, use it as a raw + * event code. + */ + if (ddi_strtol(event, NULL, 0, &tmp) != 0) + return (CPC_INVALID_EVENT); - ev_raw.emask = tmp; - evp = &ev_raw; + ev_raw.emask = tmp; + evp = &ev_raw; + } } /* diff --git a/usr/src/uts/intel/pcbe/p123_pcbe.c b/usr/src/uts/intel/pcbe/p123_pcbe.c index b9f641b633..e9f671af58 100644 --- a/usr/src/uts/intel/pcbe/p123_pcbe.c +++ b/usr/src/uts/intel/pcbe/p123_pcbe.c @@ -23,7 +23,45 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * This file contains preset event names from the Performance Application + * Programming Interface v3.5 which included the following notice: + * + * Copyright (c) 2005,6 + * Innovative Computing Labs + * Computer Science Department, + * University of Tennessee, + * Knoxville, TN. + * All Rights Reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of Tennessee nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * This open source software license conforms to the BSD License template. + */ /* * Performance Counter Back-End for Pentiums I, II, and III. @@ -109,7 +147,14 @@ struct nametable { const char *name; }; +typedef struct _ptm_generic_events { + char *name; + char *event; + uint8_t umask; +} ptm_generic_event_t; + #define NT_END 0xFF +#define CPC_GEN_END { NULL, NULL } /* * Basic Pentium events @@ -347,7 +392,69 @@ static const struct nametable *P6_names[2] = { _P6_names }; +#define P5_GENERIC_EVENTS \ + { "PAPI_tot_ins", "instr_exec", 0x0 }, \ + { "PAPI_tlb_dm", "data_tlb_miss", 0x0 }, \ + { "PAPI_tlb_im", "code_tlb_miss", 0x0 }, \ + { "PAPI_fp_ops", "flops" } + +static const ptm_generic_event_t P5mmx_generic_names0[] = { + P5_GENERIC_EVENTS, + { "PAPI_tot_cyc", "clks_not_HLT", 0x0 }, + CPC_GEN_END +}; + +static const ptm_generic_event_t P5mmx_generic_names1[] = { + P5_GENERIC_EVENTS, + { "PAPI_br_ins", "taken_br", 0x0 }, + CPC_GEN_END +}; + +static const ptm_generic_event_t *P5mmx_generic_names[2] = { + P5mmx_generic_names0, + P5mmx_generic_names1 +}; + +static const ptm_generic_event_t _P6_generic_names[] = { + { "PAPI_ca_shr", "l2_ifetch", 0xf }, + { "PAPI_ca_cln", "bus_tran_rfo", 0x0 }, + { "PAPI_ca_itv", "bus_tran_inval", 0x0 }, + { "PAPI_tlb_im", "itlb_miss", 0x0 }, + { "PAPI_btac_m", "btb_misses", 0x0 }, + { "PAPI_hw_int", "hw_int_rx", 0x0 }, + { "PAPI_br_cn", "br_inst_retired", 0x0 }, + { "PAPI_br_tkn", "br_taken_retired", 0x0 }, + { "PAPI_br_msp", "br_miss_pred_taken_ret", 0x0 }, + { "PAPI_br_ins", "br_inst_retired", 0x0 }, + { "PAPI_res_stl", "resource_stalls", 0x0 }, + { "PAPI_tot_iis", "inst_decoder", 0x0 }, + { "PAPI_tot_ins", "inst_retired", 0x0 }, + { "PAPI_tot_cyc", "cpu_clk_unhalted", 0x0 }, + { "PAPI_l1_dcm", "dcu_lines_in", 0x0 }, + { "PAPI_l1_icm", "l2_ifetch", 0xf }, + { "PAPI_l1_tcm", "l2_rqsts", 0xf }, + { "PAPI_l1_dca", "data_mem_refs", 0x0 }, + { "PAPI_l1_stm", "l2_st", 0xf }, + { "PAPI_l2_icm", "bus_tran_ifetch", 0x0 }, + { "PAPI_l2_dcr", "l2_ld", 0xf }, + { "PAPI_l2_dcw", "l2_st", 0xf }, + { "PAPI_l2_tcm", "l2_lines_in", 0x0 }, + { "PAPI_l2_tca", "l2_rqsts", 0xf }, + { "PAPI_l2_tcw", "l2_st", 0xf }, + { "PAPI_l2_stm", "l2_m_lines_inm", 0x0 }, + { "PAPI_fp_ins", "flops", 0x0 }, + { "PAPI_fp_ops", "flops", 0x0 }, + { "PAPI_fml_ins", "mul", 0x0 }, + { "PAPI_fdv_ins", "div", 0x0 } +}; + +static const ptm_generic_event_t *P6_generic_names[2] = { + _P6_generic_names, + _P6_generic_names +}; + static const struct nametable **events; +static const ptm_generic_event_t **generic_events; #define BITS(v, u, l) \ (((v) >> (l)) & ((1 << (1 + (u) - (l))) - 1)) @@ -424,9 +531,10 @@ static const struct nametable **events; static int ptm_pcbe_init(void) { - const struct nametable *n; - int i; - size_t size; + const struct nametable *n; + const ptm_generic_event_t *gevp; + int i; + size_t size; if (x86_feature & X86_MMX) ptm_rdpmc_avail = 1; @@ -445,6 +553,7 @@ ptm_pcbe_init(void) switch (cpuid_getfamily(CPU)) { case 5: /* Pentium and Pentium with MMX */ events = P5mmx_names; + generic_events = P5mmx_generic_names; ptm_ver = PTM_VER_P5; ptm_cpuref = P5_CPUREF; if (cpuid_getmodel(CPU) < 4) @@ -454,6 +563,7 @@ ptm_pcbe_init(void) break; case 6: /* Pentium Pro and Pentium II and III */ events = P6_names; + generic_events = P6_generic_names; ptm_ver = PTM_VER_P6; ptm_cpuref = P6_CPUREF; ptm_pcbe_ops.pcbe_caps = CPC_CAP_OVERFLOW_INTERRUPT; @@ -475,12 +585,19 @@ ptm_pcbe_init(void) size = 0; for (n = events[i]; n->bits != NT_END; n++) size += strlen(n->name) + 1; + for (gevp = generic_events[i]; gevp->name != NULL; gevp++) + size += strlen(gevp->name) + 1; pic_events[i] = kmem_alloc(size + 1, KM_SLEEP); *pic_events[i] = '\0'; for (n = events[i]; n->bits != NT_END; n++) { (void) strcat(pic_events[i], n->name); (void) strcat(pic_events[i], ","); } + for (gevp = generic_events[i]; gevp->name != NULL; gevp++) { + (void) strcat(pic_events[i], gevp->name); + (void) strcat(pic_events[i], ","); + } + /* * Remove trailing comma. */ @@ -529,6 +646,18 @@ ptm_pcbe_list_attrs(void) return ("noedge,pc,inv,int,umask,cmask"); } +static const ptm_generic_event_t * +find_generic_event(int regno, char *name) +{ + const ptm_generic_event_t *gevp; + + for (gevp = generic_events[regno]; gevp->name != NULL; gevp++) + if (strcmp(name, gevp->name) == 0) + return (gevp); + + return (NULL); +} + static const struct nametable * find_event(int regno, char *name) { @@ -548,9 +677,11 @@ ptm_pcbe_event_coverage(char *event) { uint64_t bitmap = 0; - if (find_event(0, event) != NULL) + if ((find_event(0, event) != NULL) || + (find_generic_event(0, event) != NULL)) bitmap = 0x1; - if (find_event(1, event) != NULL) + if ((find_event(1, event) != NULL) || + (find_generic_event(1, event) != NULL)) bitmap |= 0x2; return (bitmap); @@ -599,11 +730,12 @@ ptm_pcbe_configure(uint_t picnum, char *eventname, uint64_t preset, uint32_t flags, uint_t nattrs, kcpc_attr_t *attrs, void **data, void *token) { - ptm_pcbe_config_t *conf; - const struct nametable *n; - struct nametable nt_raw = { 0, "raw" }; - int i; - int ptm_flags = 0; + ptm_pcbe_config_t *conf; + const struct nametable *n; + const ptm_generic_event_t *gevp; + struct nametable nt_raw = { 0, "raw" }; + int i; + int ptm_flags = 0; /* * If we've been handed an existing configuration, we need only preset @@ -618,30 +750,47 @@ ptm_pcbe_configure(uint_t picnum, char *eventname, uint64_t preset, if (picnum != 0 && picnum != 1) return (CPC_INVALID_PICNUM); + conf = kmem_alloc(sizeof (ptm_pcbe_config_t), KM_SLEEP); + + conf->ptm_picno = picnum; + conf->ptm_rawpic = trunc3931(preset); + conf->ptm_ctl = 0; + if ((n = find_event(picnum, eventname)) == NULL) { - long tmp; + if ((gevp = find_generic_event(picnum, eventname)) != NULL) { + n = find_event(picnum, gevp->event); + ASSERT(n != NULL); - /* - * If ddi_strtol() likes this event, use it as a raw event code. - */ - if (ddi_strtol(eventname, NULL, 0, &tmp) != 0) - return (CPC_INVALID_EVENT); + if (nattrs > 0) { + kmem_free(conf, sizeof (ptm_pcbe_config_t)); + return (CPC_ATTRIBUTE_OUT_OF_RANGE); + } - nt_raw.bits = tmp; + if (ptm_ver == PTM_VER_P6) + conf->ptm_ctl |= gevp->umask << + CPC_P6_PES_UMASK_SHIFT; + } else { + long tmp; - if (ptm_ver == PTM_VER_P5) - nt_raw.bits &= CPC_P5_CESR_ES0_MASK; - else - nt_raw.bits &= CPC_P6_PES_PIC0_MASK; + /* + * If ddi_strtol() likes this event, use it as a raw + * event code. + */ + if (ddi_strtol(eventname, NULL, 0, &tmp) != 0) { + kmem_free(conf, sizeof (ptm_pcbe_config_t)); + return (CPC_INVALID_EVENT); + } - n = &nt_raw; - } + nt_raw.bits = tmp; - conf = kmem_alloc(sizeof (ptm_pcbe_config_t), KM_SLEEP); + if (ptm_ver == PTM_VER_P5) + nt_raw.bits &= CPC_P5_CESR_ES0_MASK; + else + nt_raw.bits &= CPC_P6_PES_PIC0_MASK; - conf->ptm_picno = picnum; - conf->ptm_rawpic = trunc3931(preset); - conf->ptm_ctl = 0; + n = &nt_raw; + } + } if (ptm_ver == PTM_VER_P5) { int picshift; diff --git a/usr/src/uts/intel/pcbe/p4_pcbe.c b/usr/src/uts/intel/pcbe/p4_pcbe.c index 35f8cca61d..4633676b2f 100644 --- a/usr/src/uts/intel/pcbe/p4_pcbe.c +++ b/usr/src/uts/intel/pcbe/p4_pcbe.c @@ -23,7 +23,45 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * This file contains preset event names from the Performance Application + * Programming Interface v3.5 which included the following notice: + * + * Copyright (c) 2005,6 + * Innovative Computing Labs + * Computer Science Department, + * University of Tennessee, + * Knoxville, TN. + * All Rights Reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of Tennessee nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * This open source software license conforms to the BSD License template. + */ /* * Performance Counter Back-End for Pentium 4. @@ -306,7 +344,15 @@ typedef struct _p4_event { uint32_t pe_ctr_mask; /* Bitmap of capable counters */ } p4_event_t; +typedef struct _p4_generic_event { + char *name; + char *event; + uint16_t emask; + uint32_t ctr_mask; +} p4_generic_event_t; + #define C(n) (1 << n) +#define GEN_EVT_END { NULL, NULL, 0x0, 0x0 } p4_event_t p4_events[] = { { "branch_retired", CRU2|CRU3, 0xF, 0x6, 0x5, C(12)|C(13)|C(14)|C(15)|C(16) }, @@ -339,7 +385,7 @@ p4_event_t p4_events[] = { { "x87_SIMD_moves_uop", FIRM0|FIRM1, 0x18, 0x2E, 0x1, C(8)|C(9)|C(10)|C(11) }, { "machine_clear", CRU2|CRU3, 0xD, 0x2, 0x5, C(12)|C(13)|C(14)|C(15)|C(16)|C(17)}, -{ "global_power_events", FSB0|FSB1, 0x1, 0x5, 0x6, C(0)|C(1)|C(2)|C(3) }, +{ "global_power_events", FSB0|FSB1, 0x1, 0x13, 0x6, C(0)|C(1)|C(2)|C(3) }, { "tc_ms_xfer", MS0|MS1, 0x1, 0x5, 0x0, C(4)|C(5)|C(6)|C(7) }, { "uop_queue_writes", MS0|MS1, 0x7, 0x9, 0x0, C(4)|C(5)|C(6)|C(7) }, { "front_end_event", CRU2|CRU3, 0x3, 0x8, 0x5, @@ -359,6 +405,24 @@ p4_event_t p4_events[] = { { NULL, 0, 0, 0, 0 } }; +static p4_generic_event_t p4_generic_events[] = { +{ "PAPI_br_msp", "branch_retired", 0xa, C(12)|C(13)|C(14)|C(15)|C(16) }, +{ "PAPI_br_ins", "branch_retired", 0xf, C(12)|C(13)|C(14)|C(15)|C(16) }, +{ "PAPI_br_tkn", "branch_retired", 0xc, C(12)|C(13)|C(14)|C(15)|C(16) }, +{ "PAPI_br_ntk", "branch_retired", 0x3, C(12)|C(13)|C(14)|C(15)|C(16) }, +{ "PAPI_br_prc", "branch_retired", 0x5, C(12)|C(13)|C(14)|C(15)|C(16) }, +{ "PAPI_tot_ins", "instr_retired", 0x3, C(12)|C(13)|C(14)|C(15)|C(16)|C(17) }, +{ "PAPI_tot_cyc", "global_power_events", 0x1, C(0)|C(1)|C(2)|C(3) }, +{ "PAPI_tlb_dm", "page_walk_type", 0x1, C(0)|C(1)|C(2)|C(3) }, +{ "PAPI_tlb_im", "page_walk_type", 0x2, C(0)|C(1)|C(2)|C(3) }, +{ "PAPI_tlb_tm", "page_walk_type", 0x3, C(0)|C(1)|C(2)|C(3) }, +{ "PAPI_l1_icm", "BPU_fetch_request", 0x1, C(0)|C(1)|C(2)|C(3) }, +{ "PAPI_l2_ldm", "BSQ_cache_reference", 0x100, C(0)|C(1)|C(2)|C(3) }, +{ "PAPI_l2_stm", "BSQ_cache_reference", 0x400, C(0)|C(1)|C(2)|C(3) }, +{ "PAPI_l2_tcm", "BSQ_cache_reference", 0x500, C(0)|C(1)|C(2)|C(3) }, +GEN_EVT_END +}; + /* * Indicates whether the "rdpmc" instruction is available on this processor. */ @@ -378,9 +442,10 @@ static int p4_htt = 0; static int p4_pcbe_init(void) { - int i; - size_t size; - p4_event_t *ev; + int i; + size_t size; + p4_event_t *ev; + p4_generic_event_t *gevp; /* * If we're not running on a P4, refuse to load. @@ -397,11 +462,17 @@ p4_pcbe_init(void) */ for (i = 0; i < 18; i++) { size = 0; + for (ev = p4_events; ev->pe_name != NULL; ev++) { if (ev->pe_ctr_mask & C(i)) size += strlen(ev->pe_name) + 1; } + for (gevp = p4_generic_events; gevp->name != NULL; gevp++) { + if (gevp->ctr_mask & C(i)) + size += strlen(gevp->name) + 1; + } + /* * We use 'size + 1' here to ensure room for the final * strcat when it terminates the string. @@ -415,6 +486,14 @@ p4_pcbe_init(void) (void) strcat(p4_eventlist[i], ","); } } + + for (gevp = p4_generic_events; gevp->name != NULL; gevp++) { + if (gevp->ctr_mask & C(i)) { + (void) strcat(p4_eventlist[i], gevp->name); + (void) strcat(p4_eventlist[i], ","); + } + } + /* * Remove trailing ',' */ @@ -474,14 +553,41 @@ p4_pcbe_list_attrs(void) return (P4_ATTRS); } +static p4_generic_event_t * +find_generic_event(char *name) +{ + p4_generic_event_t *gevp; + + for (gevp = p4_generic_events; gevp != NULL; gevp++) + if (strcmp(name, gevp->name) == 0) + return (gevp); + + return (NULL); +} + +static p4_event_t * +find_event(char *name) +{ + p4_event_t *evp; + + for (evp = p4_events; evp->pe_name != NULL; evp++) + if (strcmp(name, evp->pe_name) == 0) + return (evp); + + return (NULL); +} + static uint64_t p4_pcbe_event_coverage(char *event) { - p4_event_t *ev; + p4_event_t *ev; + p4_generic_event_t *gevp; - for (ev = p4_events; ev->pe_name != NULL; ev++) { - if (strcmp(event, ev->pe_name) == 0) - break; + if ((ev = find_event(event)) == NULL) { + if ((gevp = find_generic_event(event)) != NULL) + return (gevp->ctr_mask); + else + return (0); } return (ev->pe_ctr_mask); @@ -568,6 +674,7 @@ p4_pcbe_configure(uint_t picnum, char *eventname, uint64_t preset, p4_pcbe_config_t *cfgs[18]; p4_pcbe_config_t *cfg; p4_event_t *ev; + p4_generic_event_t *gevp; int escr_ndx; int i; uint16_t emask = 0; @@ -580,6 +687,7 @@ p4_pcbe_configure(uint_t picnum, char *eventname, uint64_t preset, int edge = 0; int sibling_usr = 0; /* count usr on other cpu */ int sibling_sys = 0; /* count sys on other cpu */ + int invalid_attr = 0; /* * If we've been handed an existing configuration, we need only preset @@ -594,12 +702,31 @@ p4_pcbe_configure(uint_t picnum, char *eventname, uint64_t preset, if (picnum < 0 || picnum >= 18) return (CPC_INVALID_PICNUM); - for (ev = p4_events; ev->pe_name != NULL; ev++) { - if (strcmp(eventname, ev->pe_name) == 0) - break; + if ((ev = find_event(eventname)) == NULL) { + if ((gevp = find_generic_event(eventname)) != NULL) { + ev = find_event(gevp->event); + ASSERT(ev != NULL); + + /* + * For generic events a HTT processor is only allowed + * to specify the 'active_thread', 'count_sibling_usr' + * and 'count_sibling_sys' attributes. + */ + if (p4_htt) + for (i = 0; i < nattrs; i++) + if (strstr(P4_ATTRS, + attrs[i].ka_name) != NULL) + invalid_attr = 1; + + if ((p4_htt && invalid_attr) || + (!p4_htt && nattrs > 0)) + return (CPC_ATTRIBUTE_OUT_OF_RANGE); + + emask = gevp->emask; + } else { + return (CPC_INVALID_EVENT); + } } - if (ev->pe_name == NULL) - return (CPC_INVALID_EVENT); build_cfgs(cfgs, NULL, token); diff --git a/usr/src/uts/sun4u/pcbe/THIRDPARTYLICENSE b/usr/src/uts/sun4u/pcbe/THIRDPARTYLICENSE new file mode 100644 index 0000000000..9b3f5f1b38 --- /dev/null +++ b/usr/src/uts/sun4u/pcbe/THIRDPARTYLICENSE @@ -0,0 +1,33 @@ + Copyright (c) 2005,6 + Innovative Computing Labs + Computer Science Department, + University of Tennessee, + Knoxville, TN. + All Rights Reserved. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the University of Tennessee nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +This open source software license conforms to the BSD License template. diff --git a/usr/src/uts/sun4u/pcbe/THIRDPARTYLICENSE.descrip b/usr/src/uts/sun4u/pcbe/THIRDPARTYLICENSE.descrip new file mode 100644 index 0000000000..1cc8c623bf --- /dev/null +++ b/usr/src/uts/sun4u/pcbe/THIRDPARTYLICENSE.descrip @@ -0,0 +1 @@ +PAPI PRESET EVENT NAMES diff --git a/usr/src/uts/sun4u/pcbe/opl_pcbe.c b/usr/src/uts/sun4u/pcbe/opl_pcbe.c index 5cc8c03421..733ab21253 100644 --- a/usr/src/uts/sun4u/pcbe/opl_pcbe.c +++ b/usr/src/uts/sun4u/pcbe/opl_pcbe.c @@ -24,10 +24,48 @@ */ /* - * SPARC64 VI & VII Performance Counter Backend + * This file contains preset event names from the Performance Application + * Programming Interface v3.5 which included the following notice: + * + * Copyright (c) 2005,6 + * Innovative Computing Labs + * Computer Science Department, + * University of Tennessee, + * Knoxville, TN. + * All Rights Reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of Tennessee nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * This open source software license conforms to the BSD License template. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * SPARC64 VI & VII Performance Counter Backend + */ #include <sys/cpuvar.h> #include <sys/systm.h> @@ -90,6 +128,11 @@ struct nametable { const char *name; }; +typedef struct _opl_generic_event { + char *name; + char *event; +} opl_generic_event_t; + /* * Performance Control Register (PCR) * @@ -178,6 +221,7 @@ struct nametable { } #define NT_END 0xFF +#define CPC_GEN_END { NULL, NULL } static const uint64_t allstopped = SPARC64_VI_PCR_PRIVPIC | SPARC64_VI_PCR_ULRO | SPARC64_VI_PCR_OVRO; @@ -395,7 +439,71 @@ opl_pcbe_config_t nullpic[CPC_SPARC64_VI_NPIC] = { {7, 0x3f, 0, 0} }; +#define SPARC64_VI_GENERIC_EVENTS_comm \ + { "PAPI_tot_cyc", "cycle_counts" }, \ + { "PAPI_tot_ins", "instruction_counts" }, \ + { "PAPI_br_tkn", "branch_instructions" }, \ + { "PAPI_fp_ops", "floating_instructions" }, \ + { "PAPI_fma_ins", "impdep2_instructions" } + +static const opl_generic_event_t SPARC64_VI_generic_names_l0[] = { + SPARC64_VI_GENERIC_EVENTS_comm, + CPC_GEN_END +}; + +static const opl_generic_event_t SPARC64_VI_generic_names_u0[] = { + SPARC64_VI_GENERIC_EVENTS_comm, + CPC_GEN_END +}; + +static const opl_generic_event_t SPARC64_VI_generic_names_l1[] = { + SPARC64_VI_GENERIC_EVENTS_comm, + CPC_GEN_END +}; + +static const opl_generic_event_t SPARC64_VI_generic_names_u1[] = { + SPARC64_VI_GENERIC_EVENTS_comm, + CPC_GEN_END +}; + +static const opl_generic_event_t SPARC64_VI_generic_names_l2[] = { + SPARC64_VI_GENERIC_EVENTS_comm, + { "PAPI_l1_dcm", "op_r_iu_req_mi_go" }, + CPC_GEN_END +}; + +static const opl_generic_event_t SPARC64_VI_generic_names_u2[] = { + SPARC64_VI_GENERIC_EVENTS_comm, + { "PAPI_l1_icm", "if_r_iu_req_mi_go" }, + CPC_GEN_END +}; + +static const opl_generic_event_t SPARC64_VI_generic_names_l3[] = { + SPARC64_VI_GENERIC_EVENTS_comm, + { "PAPI_tlb_dm", "trap_DMMU_miss" }, + CPC_GEN_END +}; + +static const opl_generic_event_t SPARC64_VI_generic_names_u3[] = { + SPARC64_VI_GENERIC_EVENTS_comm, + { "PAPI_tlb_im", "trap_IMMU_miss" }, + CPC_GEN_END +}; + +static const opl_generic_event_t + *SPARC64_VI_generic_names[CPC_SPARC64_VI_NPIC] = { + SPARC64_VI_generic_names_l0, + SPARC64_VI_generic_names_u0, + SPARC64_VI_generic_names_l1, + SPARC64_VI_generic_names_u1, + SPARC64_VI_generic_names_l2, + SPARC64_VI_generic_names_u2, + SPARC64_VI_generic_names_l3, + SPARC64_VI_generic_names_u3 +}; + static const struct nametable **events; +static const opl_generic_event_t **generic_events; static const char *opl_impl_name; static const char *opl_cpuref; static char *pic_events[CPC_SPARC64_VI_NPIC]; @@ -406,9 +514,10 @@ static const char *sp_6_ref = "See the \"SPARC64 VI extensions\" and " static int opl_pcbe_init(void) { - const struct nametable *n; - int i; - size_t size; + const struct nametable *n; + const opl_generic_event_t *gevp; + int i; + size_t size; /* * Discover type of CPU @@ -419,6 +528,7 @@ opl_pcbe_init(void) case OLYMPUS_C_IMPL: case JUPITER_IMPL: events = SPARC64_VI_names; + generic_events = SPARC64_VI_generic_names; opl_impl_name = "SPARC64 VI & VII"; opl_cpuref = sp_6_ref; break; @@ -435,12 +545,19 @@ opl_pcbe_init(void) size = 0; for (n = events[i]; n->bits != NT_END; n++) size += strlen(n->name) + 1; + for (gevp = generic_events[i]; gevp->name != NULL; gevp++) + size += strlen(gevp->name) + 1; pic_events[i] = kmem_alloc(size + 1, KM_SLEEP); *pic_events[i] = '\0'; for (n = events[i]; n->bits != NT_END; n++) { (void) strcat(pic_events[i], n->name); (void) strcat(pic_events[i], ","); } + for (gevp = generic_events[i]; gevp->name != NULL; gevp++) { + (void) strcat(pic_events[i], gevp->name); + (void) strcat(pic_events[i], ","); + } + /* * Remove trailing comma. */ @@ -482,6 +599,18 @@ opl_pcbe_list_attrs(void) return (""); } +static const opl_generic_event_t * +find_generic_event(int regno, char *name) +{ + const opl_generic_event_t *gevp; + + for (gevp = generic_events[regno]; gevp->name != NULL; gevp++) + if (strcmp(name, gevp->name) == 0) + return (gevp); + + return (NULL); +} + static const struct nametable * find_event(int regno, char *name) { @@ -503,7 +632,8 @@ opl_pcbe_event_coverage(char *event) int i; for (i = 0; i < CPC_SPARC64_VI_NPIC; i++) { - if (find_event(i, event) != NULL) + if ((find_event(i, event) != NULL) || + (find_generic_event(i, event) != NULL)) bitmap |= (1 << i); } @@ -529,9 +659,10 @@ static int opl_pcbe_configure(uint_t picnum, char *event, uint64_t preset, uint32_t flags, uint_t nattrs, kcpc_attr_t *attrs, void **data, void *token) { - opl_pcbe_config_t *conf; - const struct nametable *n; - opl_pcbe_config_t *other_config; + opl_pcbe_config_t *conf; + const struct nametable *n; + const opl_generic_event_t *gevp; + opl_pcbe_config_t *other_config; /* * If we've been handed an existing configuration, we need only preset @@ -557,8 +688,14 @@ opl_pcbe_configure(uint_t picnum, char *event, uint64_t preset, uint32_t flags, (other_config->opl_flags != flags)) return (CPC_CONFLICTING_REQS); - if ((n = find_event(picnum, event)) == NULL) - return (CPC_INVALID_EVENT); + if ((n = find_event(picnum, event)) == NULL) { + if ((gevp = find_generic_event(picnum, event)) != NULL) { + n = find_event(picnum, gevp->event); + ASSERT(n != NULL); + } else { + return (CPC_INVALID_EVENT); + } + } conf = kmem_alloc(sizeof (opl_pcbe_config_t), KM_SLEEP); diff --git a/usr/src/uts/sun4u/pcbe/us234_pcbe.c b/usr/src/uts/sun4u/pcbe/us234_pcbe.c index 55a08c8dfd..d214a34794 100644 --- a/usr/src/uts/sun4u/pcbe/us234_pcbe.c +++ b/usr/src/uts/sun4u/pcbe/us234_pcbe.c @@ -24,10 +24,48 @@ */ /* - * UltraSPARC Performance Counter Backend + * This file contains preset event names from the Performance Application + * Programming Interface v3.5 which included the following notice: + * + * Copyright (c) 2005,6 + * Innovative Computing Labs + * Computer Science Department, + * University of Tennessee, + * Knoxville, TN. + * All Rights Reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of Tennessee nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * This open source software license conforms to the BSD License template. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * UltraSPARC Performance Counter Backend + */ #include <sys/cpuvar.h> #include <sys/systm.h> @@ -91,6 +129,11 @@ struct nametable { const char *name; }; +typedef struct _us_generic_event { + char *name; + char *event; +} us_generic_event_t; + #define PIC0_MASK (((uint64_t)1 << 32) - 1) #define ULTRA_PCR_SYS (UINT64_C(1) << CPC_ULTRA_PCR_SYS) @@ -106,6 +149,7 @@ struct nametable { #define CPC_ULTRA_PCR_PIC1_SHIFT 11 #define NT_END 0xFF +#define CPC_GEN_END { NULL, NULL } static const uint64_t allstopped = ULTRA_PCR_PRIVPIC; @@ -412,7 +456,115 @@ static const struct nametable *US3_I_names[2] = { US3_I_names1 }; +static const us_generic_event_t US12_generic_names0[] = { + { "PAPI_tot_cyc", "Cycle_cnt" }, + { "PAPI_tot_ins", "Instr_cnt" }, + { "PAPI_tot_iis", "Instr_cnt" }, + { "PAPI_l1_dcr", "DC_rd" }, + { "PAPI_l1_dcw", "DC_wr" }, + { "PAPI_l1_ica", "IC_ref" }, + { "PAPI_l2_tca", "EC_ref" }, + { "PAPI_l2_dch", "EC_rd_hit" }, + { "PAPI_ca_inv", "EC_snoop_inv" }, + CPC_GEN_END +}; + +static const us_generic_event_t US12_generic_names1[] = { + { "PAPI_tot_cyc", "Cycle_cnt" }, + { "PAPI_tot_ins", "Instr_cnt" }, + { "PAPI_tot_iis", "Instr_cnt" }, + { "PAPI_br_msp", "Dispatch0_mispred" }, + { "PAPI_ca_snp", "EC_snoop_cb" }, + { "PAPI_l1_ich", "IC_hit" }, + { "PAPI_l2_tch", "EC_hit" }, + { "PAPI_l2_ich", "EC_ic_hit" }, + CPC_GEN_END +}; + +static const us_generic_event_t US3_generic_names0[] = { + { "PAPI_tot_cyc", "Cycle_cnt" }, + { "PAPI_tot_ins", "Instr_cnt" }, + { "PAPI_tot_iis", "Instr_cnt" }, + { "PAPI_fad_ins", "FA_pipe_completion" }, + { "PAPI_l1_dcr", "DC_rd" }, + { "PAPI_l1_dcw", "DC_wr" }, + { "PAPI_l1_ica", "IC_ref" }, + { "PAPI_l2_tca", "EC_ref" }, + { "PAPI_l2_ldm", "EC_rd_miss" }, + { "PAPI_ca_inv", "EC_snoop_inv" }, + { "PAPI_br_tkn", "IU_Stat_Br_count_taken" }, + CPC_GEN_END +}; + +static const us_generic_event_t US3_generic_names1[] = { + { "PAPI_tot_cyc", "Cycle_cnt" }, + { "PAPI_tot_ins", "Instr_cnt" }, + { "PAPI_tot_iis", "Instr_cnt" }, + { "PAPI_fml_ins", "FM_pipe_completion" }, + { "PAPI_l1_icm", "IC_miss" }, + { "PAPI_l1_ldm", "DC_rd_miss" }, + { "PAPI_l1_stm", "DC_wr_miss" }, + { "PAPI_l2_tcm", "EC_misses" }, + { "PAPI_l2_icm", "EC_ic_miss" }, + { "PAPI_tlb_dm", "DTLB_miss" }, + { "PAPI_tlb_im", "ITLB_miss" }, + { "PAPI_br_ntk", "IU_Stat_Br_count_untaken" }, + { "PAPI_br_msp", "Dispatch0_mispred" }, + { "PAPI_ca_snp", "EC_snoop_cb" }, + CPC_GEN_END +}; + +static const us_generic_event_t US4_PLUS_generic_names0[] = { + { "PAPI_tot_cyc", "Cycle_cnt" }, + { "PAPI_tot_ins", "Instr_cnt" }, + { "PAPI_tot_iis", "Instr_cnt" }, + { "PAPI_fma_ins", "FA_pipe_completion" }, + { "PAPI_l1_dcr", "DC_rd" }, + { "PAPI_l1_stm", "DC_wr_miss" }, + { "PAPI_l1_ica", "IC_ref" }, + { "PAPI_l2_tca", "L2_ref" }, + { "PAPI_l2_ldm", "L2_rd_miss" }, + { "PAPI_l2_icm", "L2_IC_miss" }, + { "PAPI_l2_stm", "L2_write_miss" }, + { "PAPI_l3_ldm", "L3_rd_miss" }, + { "PAPI_br_ntk", "IU_stat_br_count_untaken" }, + CPC_GEN_END +}; + +static const us_generic_event_t US4_PLUS_generic_names1[] = { + { "PAPI_tot_cyc", "Cycle_cnt" }, + { "PAPI_tot_ins", "Instr_cnt" }, + { "PAPI_tot_iis", "Instr_cnt" }, + { "PAPI_fml_ins", "FM_pipe_completion" }, + { "PAPI_l1_icm", "IC_L2_req" }, + { "PAPI_l1_ldm", "DC_rd_miss" }, + { "PAPI_l1_dcw", "DC_wr" }, + { "PAPI_l2_tcm", "L2_miss" }, + { "PAPI_l3_tcm", "L3_miss" }, + { "PAPI_l3_icm", "L3_IC_miss" }, + { "PAPI_tlb_im", "ITLB_miss" }, + { "PAPI_tlb_dm", "DTLB_miss" }, + { "PAPI_br_tkn", "IU_stat_br_count_taken" }, + CPC_GEN_END +}; + +static const us_generic_event_t *US12_generic_names[2] = { + US12_generic_names0, + US12_generic_names1 +}; + +static const us_generic_event_t *US3_generic_names[2] = { + US3_generic_names0, + US3_generic_names1 +}; + +static const us_generic_event_t *US4_PLUS_generic_names[2] = { + US4_PLUS_generic_names0, + US4_PLUS_generic_names1 +}; + static const struct nametable **events; +static const us_generic_event_t **generic_events; static const char *us_impl_name; static const char *us_cpuref; static char *pic_events[2]; @@ -437,9 +589,10 @@ static const char *us_3i_ref = "See the \"UltraSPARC IIIi User's Manual\" " static int us_pcbe_init(void) { - const struct nametable *n; - int i; - size_t size; + const struct nametable *n; + const us_generic_event_t *gevp; + int i; + size_t size; /* * Discover type of CPU @@ -452,6 +605,7 @@ us_pcbe_init(void) case SABRE_IMPL: case HUMMBRD_IMPL: events = US12_names; + generic_events = US12_generic_names; us_impl_name = "UltraSPARC I&II"; us_cpuref = us_2_ref; pcr_pic_mask = CPC_ULTRA2_PCR_PIC_MASK; @@ -459,6 +613,7 @@ us_pcbe_init(void) break; case CHEETAH_IMPL: events = US3_names; + generic_events = US3_generic_names; us_impl_name = "UltraSPARC III"; us_cpuref = us_3cu_ref; pcr_pic_mask = CPC_ULTRA3_PCR_PIC_MASK; @@ -466,12 +621,14 @@ us_pcbe_init(void) case CHEETAH_PLUS_IMPL: case JAGUAR_IMPL: events = US3_PLUS_names; + generic_events = US3_generic_names; us_impl_name = "UltraSPARC III+ & IV"; us_cpuref = us_3cu_ref; pcr_pic_mask = CPC_ULTRA3_PCR_PIC_MASK; break; case PANTHER_IMPL: events = US4_PLUS_names; + generic_events = US4_PLUS_generic_names; us_impl_name = "UltraSPARC IV+"; us_cpuref = us4_plus_ref; pcr_pic_mask = CPC_ULTRA3_PCR_PIC_MASK; @@ -479,6 +636,7 @@ us_pcbe_init(void) case JALAPENO_IMPL: case SERRANO_IMPL: events = US3_I_names; + generic_events = US3_generic_names; us_impl_name = "UltraSPARC IIIi & IIIi+"; us_cpuref = us_3i_ref; pcr_pic_mask = CPC_ULTRA3_PCR_PIC_MASK; @@ -496,12 +654,19 @@ us_pcbe_init(void) size = 0; for (n = events[i]; n->bits != NT_END; n++) size += strlen(n->name) + 1; + for (gevp = generic_events[i]; gevp->name != NULL; gevp++) + size += strlen(gevp->name) + 1; pic_events[i] = kmem_alloc(size + 1, KM_SLEEP); *pic_events[i] = '\0'; for (n = events[i]; n->bits != NT_END; n++) { (void) strcat(pic_events[i], n->name); (void) strcat(pic_events[i], ","); } + for (gevp = generic_events[i]; gevp->name != NULL; gevp++) { + (void) strcat(pic_events[i], gevp->name); + (void) strcat(pic_events[i], ","); + } + /* * Remove trailing comma. */ @@ -543,6 +708,18 @@ us_pcbe_list_attrs(void) return (""); } +static const us_generic_event_t * +find_generic_event(int regno, char *name) +{ + const us_generic_event_t *gevp; + + for (gevp = generic_events[regno]; gevp->name != NULL; gevp++) + if (strcmp(name, gevp->name) == 0) + return (gevp); + + return (NULL); +} + static const struct nametable * find_event(int regno, char *name) { @@ -562,9 +739,11 @@ us_pcbe_event_coverage(char *event) { uint64_t bitmap = 0; - if (find_event(0, event) != NULL) + if ((find_event(0, event) != NULL) || + (find_generic_event(0, event) != NULL)) bitmap = 0x1; - if (find_event(1, event) != NULL) + if ((find_event(1, event) != NULL) || + (find_generic_event(1, event) != NULL)) bitmap |= 0x2; return (bitmap); @@ -585,9 +764,10 @@ static int us_pcbe_configure(uint_t picnum, char *event, uint64_t preset, uint32_t flags, uint_t nattrs, kcpc_attr_t *attrs, void **data, void *token) { - us_pcbe_config_t *conf; - const struct nametable *n; - us_pcbe_config_t *other_config; + us_pcbe_config_t *conf; + const struct nametable *n; + const us_generic_event_t *gevp; + us_pcbe_config_t *other_config; /* * If we've been handed an existing configuration, we need only preset @@ -613,8 +793,14 @@ us_pcbe_configure(uint_t picnum, char *event, uint64_t preset, uint32_t flags, (other_config->us_flags != flags)) return (CPC_CONFLICTING_REQS); - if ((n = find_event(picnum, event)) == NULL) - return (CPC_INVALID_EVENT); + if ((n = find_event(picnum, event)) == NULL) { + if ((gevp = find_generic_event(picnum, event)) != NULL) { + n = find_event(picnum, gevp->event); + ASSERT(n != NULL); + } else { + return (CPC_INVALID_EVENT); + } + } conf = kmem_alloc(sizeof (us_pcbe_config_t), KM_SLEEP); diff --git a/usr/src/uts/sun4v/pcbe/THIRDPARTYLICENSE b/usr/src/uts/sun4v/pcbe/THIRDPARTYLICENSE new file mode 100644 index 0000000000..9b3f5f1b38 --- /dev/null +++ b/usr/src/uts/sun4v/pcbe/THIRDPARTYLICENSE @@ -0,0 +1,33 @@ + Copyright (c) 2005,6 + Innovative Computing Labs + Computer Science Department, + University of Tennessee, + Knoxville, TN. + All Rights Reserved. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the University of Tennessee nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +This open source software license conforms to the BSD License template. diff --git a/usr/src/uts/sun4v/pcbe/THIRDPARTYLICENSE.descrip b/usr/src/uts/sun4v/pcbe/THIRDPARTYLICENSE.descrip new file mode 100644 index 0000000000..1cc8c623bf --- /dev/null +++ b/usr/src/uts/sun4v/pcbe/THIRDPARTYLICENSE.descrip @@ -0,0 +1 @@ +PAPI PRESET EVENT NAMES diff --git a/usr/src/uts/sun4v/pcbe/niagara2_pcbe.c b/usr/src/uts/sun4v/pcbe/niagara2_pcbe.c index fe29ffa242..2d42e7ee76 100644 --- a/usr/src/uts/sun4v/pcbe/niagara2_pcbe.c +++ b/usr/src/uts/sun4v/pcbe/niagara2_pcbe.c @@ -24,6 +24,46 @@ */ /* + * This file contains preset event names from the Performance Application + * Programming Interface v3.5 which included the following notice: + * + * Copyright (c) 2005,6 + * Innovative Computing Labs + * Computer Science Department, + * University of Tennessee, + * Knoxville, TN. + * All Rights Reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of Tennessee nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * This open source software license conforms to the BSD License template. + */ + +/* * Niagara2 Performance Counter Backend */ @@ -95,8 +135,14 @@ typedef struct _ni2_event { const uint32_t emask_valid; /* Mask of unreserved MASK bits */ } ni2_event_t; +typedef struct _ni2_generic_event { + char *name; + char *event; +} ni2_generic_event_t; + #define ULTRA_PCR_PRIVPIC (UINT64_C(1) << CPC_NIAGARA2_PCR_PRIV_SHIFT) #define EV_END {NULL, 0, 0} +#define GEN_EV_END {NULL, NULL} static const uint64_t allstopped = (ULTRA_PCR_PRIVPIC | CPC_NIAGARA2_PCR_HOLDOV0 | CPC_NIAGARA2_PCR_HOLDOV1); @@ -151,6 +197,22 @@ static ni2_event_t ni2_events[] = { EV_END }; +static ni2_generic_event_t ni2_generic_events[] = { + { "PAPI_tot_ins", "Instr_cnt" }, + { "PAPI_l1_dcm", "DC_miss" }, + { "PAPI_l1_icm", "IC_miss" }, + { "PAPI_l2_icm", "L2_imiss" }, + { "PAPI_l2_ldm", "L2_dmiss_ld" }, + { "PAPI_tlb_dm", "DTLB_miss" }, + { "PAPI_tlb_im", "ITLB_miss" }, + { "PAPI_tlb_tm", "TLB_miss" }, + { "PAPI_br_tkn", "Br_taken" }, + { "PAPI_br_ins", "Br_completed" }, + { "PAPI_ld_ins", "Instr_ld" }, + { "PAPI_sr_ins", "Instr_st" }, + GEN_EV_END +}; + static char *evlist; static size_t evlist_sz; static uint16_t pcr_pic0_mask; @@ -174,16 +236,17 @@ static boolean_t cpu_hsvc_available = B_TRUE; static int ni2_pcbe_init(void) { - ni2_event_t *evp; - int status; - uint64_t cpu_hsvc_major; - uint64_t cpu_hsvc_minor; + ni2_event_t *evp; + ni2_generic_event_t *gevp; + int status; + uint64_t cpu_hsvc_major; + uint64_t cpu_hsvc_minor; #if defined(NIAGARA2_IMPL) - uint64_t hsvc_cpu_group = HSVC_GROUP_NIAGARA2_CPU; - uint64_t hsvc_cpu_major = NIAGARA2_HSVC_MAJOR; + uint64_t hsvc_cpu_group = HSVC_GROUP_NIAGARA2_CPU; + uint64_t hsvc_cpu_major = NIAGARA2_HSVC_MAJOR; #elif defined(VFALLS_IMPL) - uint64_t hsvc_cpu_group = HSVC_GROUP_VFALLS_CPU; - uint64_t hsvc_cpu_major = VFALLS_HSVC_MAJOR; + uint64_t hsvc_cpu_group = HSVC_GROUP_VFALLS_CPU; + uint64_t hsvc_cpu_major = VFALLS_HSVC_MAJOR; #endif pcr_pic0_mask = CPC_NIAGARA2_PCR_PIC0_MASK; @@ -213,6 +276,9 @@ ni2_pcbe_init(void) for (evp = ni2_events; evp->name != NULL; evp++) evlist_sz += strlen(evp->name) + 1; + for (gevp = ni2_generic_events; gevp->name != NULL; gevp++) + evlist_sz += strlen(gevp->name) + 1; + evlist = kmem_alloc(evlist_sz + 1, KM_SLEEP); evlist[0] = '\0'; @@ -220,6 +286,12 @@ ni2_pcbe_init(void) (void) strcat(evlist, evp->name); (void) strcat(evlist, ","); } + + for (gevp = ni2_generic_events; gevp->name != NULL; gevp++) { + (void) strcat(evlist, gevp->name); + (void) strcat(evlist, ","); + } + /* * Remove trailing comma. */ @@ -267,10 +339,23 @@ ni2_pcbe_list_attrs(void) return ("emask"); } +static ni2_generic_event_t * +find_generic_event(char *name) +{ + ni2_generic_event_t *gevp; + + for (gevp = ni2_generic_events; gevp->name != NULL; gevp++) { + if (strcmp(name, gevp->name) == 0) + return (gevp); + } + + return (NULL); +} + static ni2_event_t * find_event(char *name) { - ni2_event_t *evp; + ni2_event_t *evp; for (evp = ni2_events; evp->name != NULL; evp++) if (strcmp(name, evp->name) == 0) @@ -350,6 +435,7 @@ ni2_pcbe_configure(uint_t picnum, char *event, uint64_t preset, uint32_t flags, ni2_pcbe_config_t *cfg; ni2_pcbe_config_t *other_config; ni2_event_t *evp; + ni2_generic_event_t *gevp; int i; uint32_t evsel; #if defined(VFALLS_IMPL) @@ -369,8 +455,18 @@ ni2_pcbe_configure(uint_t picnum, char *event, uint64_t preset, uint32_t flags, if (picnum > 1) return (CPC_INVALID_PICNUM); - if ((evp = find_event(event)) == NULL) - return (CPC_INVALID_EVENT); + + if ((evp = find_event(event)) == NULL) { + if ((gevp = find_generic_event(event)) != NULL) { + evp = find_event(gevp->event); + ASSERT(evp != NULL); + + if (nattrs > 0) + return (CPC_ATTRIBUTE_OUT_OF_RANGE); + } else { + return (CPC_INVALID_EVENT); + } + } evsel = evp->emask; diff --git a/usr/src/uts/sun4v/pcbe/niagara_pcbe.c b/usr/src/uts/sun4v/pcbe/niagara_pcbe.c index edc9f1bbbf..4f42bddd8e 100644 --- a/usr/src/uts/sun4v/pcbe/niagara_pcbe.c +++ b/usr/src/uts/sun4v/pcbe/niagara_pcbe.c @@ -24,10 +24,48 @@ */ /* - * Niagara Performance Counter Backend + * This file contains preset event names from the Performance Application + * Programming Interface v3.5 which included the following notice: + * + * Copyright (c) 2005,6 + * Innovative Computing Labs + * Computer Science Department, + * University of Tennessee, + * Knoxville, TN. + * All Rights Reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of Tennessee nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * + * This open source software license conforms to the BSD License template. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Niagara Performance Counter Backend + */ #include <sys/cpuvar.h> #include <sys/systm.h> @@ -90,8 +128,14 @@ struct nametable { const char *name; }; +typedef struct _ni_generic_events { + char *name; + char *event; +} ni_generic_event_t; + #define ULTRA_PCR_PRIVPIC (UINT64_C(1) << CPC_NIAGARA_PCR_PRIVPIC) #define NT_END 0xFF +#define GEN_EVT_END { NULL, NULL } static const uint64_t allstopped = ULTRA_PCR_PRIVPIC; @@ -117,7 +161,29 @@ static const struct nametable *Niagara_names[2] = { Niagara_names1 }; +static const ni_generic_event_t Niagara_generic_names1[] = { + { "PAPI_tot_ins", "Instr_cnt" }, + { NULL, NULL } +}; + +static const ni_generic_event_t Niagara_generic_names0[] = { + { "PAPI_l2_icm", "L2_imiss" }, + { "PAPI_l2_ldm", "L2_dmiss_ld" }, + { "PAPI_fp_ops", "FP_instr_cnt" }, + { "PAPI_l1_icm", "IC_miss" }, + { "PAPI_l1_dcm", "DC_miss" }, + { "PAPI_tlb_im", "ITLB_miss" }, + { "PAPI_tlb_dm", "DTLB_miss" }, + { NULL, NULL } +}; + +static const ni_generic_event_t *Niagara_generic_names[2] = { + Niagara_generic_names0, + Niagara_generic_names1 +}; + static const struct nametable **events; +static const ni_generic_event_t **generic_events; static const char *ni_impl_name = "UltraSPARC T1"; static char *pic_events[2]; static uint16_t pcr_pic0_mask; @@ -132,11 +198,13 @@ static const char *niagara_cpuref = "See the \"UltraSPARC T1 User's Manual\" " static int ni_pcbe_init(void) { - const struct nametable *n; - int i; - size_t size; + const struct nametable *n; + const ni_generic_event_t *gevp; + int i; + size_t size; events = Niagara_names; + generic_events = Niagara_generic_names; pcr_pic0_mask = CPC_NIAGARA_PCR_PIC0_MASK; pcr_pic1_mask = CPC_NIAGARA_PCR_PIC1_MASK; @@ -149,12 +217,18 @@ ni_pcbe_init(void) size = 0; for (n = events[i]; n->bits != NT_END; n++) size += strlen(n->name) + 1; + for (gevp = generic_events[i]; gevp->name != NULL; gevp++) + size += strlen(gevp->name) + 1; pic_events[i] = kmem_alloc(size + 1, KM_SLEEP); *pic_events[i] = '\0'; for (n = events[i]; n->bits != NT_END; n++) { (void) strcat(pic_events[i], n->name); (void) strcat(pic_events[i], ","); } + for (gevp = generic_events[i]; gevp->name != NULL; gevp++) { + (void) strcat(pic_events[i], gevp->name); + (void) strcat(pic_events[i], ","); + } /* * Remove trailing comma. */ @@ -196,10 +270,23 @@ ni_pcbe_list_attrs(void) return (""); } +static const ni_generic_event_t * +find_generic_event(int regno, char *name) +{ + const ni_generic_event_t *gevp; + + for (gevp = generic_events[regno]; gevp->name != NULL; gevp++) { + if (strcmp(gevp->name, name) == 0) + return (gevp); + } + + return (NULL); +} + static const struct nametable * find_event(int regno, char *name) { - const struct nametable *n; + const struct nametable *n; n = events[regno]; @@ -215,9 +302,11 @@ ni_pcbe_event_coverage(char *event) { uint64_t bitmap = 0; - if (find_event(0, event) != NULL) + if ((find_event(0, event) != NULL) || + (find_generic_event(0, event) != NULL)) bitmap = 0x1; - if (find_event(1, event) != NULL) + if ((find_event(1, event) != NULL) || + (find_generic_event(1, event) != NULL)) bitmap |= 0x2; return (bitmap); @@ -252,9 +341,10 @@ static int ni_pcbe_configure(uint_t picnum, char *event, uint64_t preset, uint32_t flags, uint_t nattrs, kcpc_attr_t *attrs, void **data, void *token) { - ni_pcbe_config_t *conf; - const struct nametable *n; - ni_pcbe_config_t *other_config; + ni_pcbe_config_t *conf; + const struct nametable *n; + const ni_generic_event_t *gevp; + ni_pcbe_config_t *other_config; /* * If we've been handed an existing configuration, we need only preset @@ -279,8 +369,14 @@ ni_pcbe_configure(uint_t picnum, char *event, uint64_t preset, uint32_t flags, (other_config->pcbe_flags != flags)) return (CPC_CONFLICTING_REQS); - if ((n = find_event(picnum, event)) == NULL) - return (CPC_INVALID_EVENT); + if ((n = find_event(picnum, event)) == NULL) { + if ((gevp = find_generic_event(picnum, event)) != NULL) { + n = find_event(picnum, gevp->event); + ASSERT(n != NULL); + } else { + return (CPC_INVALID_EVENT); + } + } conf = kmem_alloc(sizeof (ni_pcbe_config_t), KM_SLEEP); |