summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/cmd/cpc/common/caps.c38
-rw-r--r--usr/src/cmd/cpc/common/strtoset.c7
-rw-r--r--usr/src/lib/libcpc/common/libcpc.c125
-rw-r--r--usr/src/lib/libcpc/common/libcpc.h13
-rw-r--r--usr/src/lib/libcpc/common/mapfile-vers10
-rw-r--r--usr/src/pkgdefs/SUNWcpcu/Makefile16
-rw-r--r--usr/src/pkgdefs/SUNWust1.v/Makefile12
-rw-r--r--usr/src/pkgdefs/SUNWust2.v/Makefile7
-rw-r--r--usr/src/tools/opensolaris/license-list3
-rw-r--r--usr/src/uts/intel/pcbe/THIRDPARTYLICENSE33
-rw-r--r--usr/src/uts/intel/pcbe/THIRDPARTYLICENSE.descrip1
-rw-r--r--usr/src/uts/intel/pcbe/opteron_pcbe.c159
-rw-r--r--usr/src/uts/intel/pcbe/p123_pcbe.c205
-rw-r--r--usr/src/uts/intel/pcbe/p4_pcbe.c155
-rw-r--r--usr/src/uts/sun4u/pcbe/THIRDPARTYLICENSE33
-rw-r--r--usr/src/uts/sun4u/pcbe/THIRDPARTYLICENSE.descrip1
-rw-r--r--usr/src/uts/sun4u/pcbe/opl_pcbe.c159
-rw-r--r--usr/src/uts/sun4u/pcbe/us234_pcbe.c210
-rw-r--r--usr/src/uts/sun4v/pcbe/THIRDPARTYLICENSE33
-rw-r--r--usr/src/uts/sun4v/pcbe/THIRDPARTYLICENSE.descrip1
-rw-r--r--usr/src/uts/sun4v/pcbe/niagara2_pcbe.c118
-rw-r--r--usr/src/uts/sun4v/pcbe/niagara_pcbe.c122
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);