Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 7 Jun 2009 10:00:35 +0000 (UTC)
From:      Fabien Thomas <fabient@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r193634 - in stable/7: lib/libpmc share/man/man4 sys/amd64/amd64 sys/amd64/include sys/conf sys/dev/hwpmc sys/i386/i386 sys/i386/include sys/kern sys/modules/hwpmc sys/sys usr.sbin usr....
Message-ID:  <200906071000.n57A0Zem089380@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: fabient
Date: Sun Jun  7 10:00:35 2009
New Revision: 193634
URL: http://svn.freebsd.org/changeset/base/193634

Log:
  MFC hwpmc framework:
  
  - capture with callchain
  - Intel Core 2 support
  - Intel Core i7 support
  - source code annotate (pmcannotate)
  - bug fixes
  
  Reviewed by: jkoshy (mentor)
  Approved by: re (gnn)

Added:
  stable/7/lib/libpmc/libpmcinternal.h   (contents, props changed)
  stable/7/lib/libpmc/pmc.atom.3   (contents, props changed)
  stable/7/lib/libpmc/pmc.core.3   (contents, props changed)
  stable/7/lib/libpmc/pmc.core2.3   (contents, props changed)
  stable/7/lib/libpmc/pmc.iaf.3   (contents, props changed)
  stable/7/lib/libpmc/pmc.k7.3   (contents, props changed)
  stable/7/lib/libpmc/pmc.k8.3   (contents, props changed)
  stable/7/lib/libpmc/pmc.p4.3   (contents, props changed)
  stable/7/lib/libpmc/pmc.p5.3   (contents, props changed)
  stable/7/lib/libpmc/pmc.p6.3   (contents, props changed)
  stable/7/lib/libpmc/pmc.tsc.3   (contents, props changed)
  stable/7/lib/libpmc/pmc_allocate.3   (contents, props changed)
  stable/7/lib/libpmc/pmc_attach.3   (contents, props changed)
  stable/7/lib/libpmc/pmc_capabilities.3   (contents, props changed)
  stable/7/lib/libpmc/pmc_configure_logfile.3   (contents, props changed)
  stable/7/lib/libpmc/pmc_disable.3   (contents, props changed)
  stable/7/lib/libpmc/pmc_event_names_of_class.3   (contents, props changed)
  stable/7/lib/libpmc/pmc_get_driver_stats.3   (contents, props changed)
  stable/7/lib/libpmc/pmc_get_msr.3   (contents, props changed)
  stable/7/lib/libpmc/pmc_init.3   (contents, props changed)
  stable/7/lib/libpmc/pmc_name_of_capability.3   (contents, props changed)
  stable/7/lib/libpmc/pmc_read.3   (contents, props changed)
  stable/7/lib/libpmc/pmc_set.3   (contents, props changed)
  stable/7/lib/libpmc/pmc_start.3   (contents, props changed)
  stable/7/sys/dev/hwpmc/hwpmc_core.c   (contents, props changed)
  stable/7/sys/dev/hwpmc/hwpmc_core.h   (contents, props changed)
  stable/7/sys/dev/hwpmc/hwpmc_intel.c   (contents, props changed)
  stable/7/sys/dev/hwpmc/hwpmc_tsc.c   (contents, props changed)
  stable/7/sys/dev/hwpmc/hwpmc_tsc.h   (contents, props changed)
  stable/7/usr.sbin/pmcannotate/
  stable/7/usr.sbin/pmcannotate/Makefile   (contents, props changed)
  stable/7/usr.sbin/pmcannotate/pmcannotate.8   (contents, props changed)
  stable/7/usr.sbin/pmcannotate/pmcannotate.c   (contents, props changed)
Modified:
  stable/7/lib/libpmc/Makefile
  stable/7/lib/libpmc/libpmc.c
  stable/7/lib/libpmc/pmc.3
  stable/7/lib/libpmc/pmclog.c
  stable/7/lib/libpmc/pmclog.h
  stable/7/share/man/man4/hwpmc.4
  stable/7/sys/amd64/amd64/exception.S
  stable/7/sys/amd64/amd64/genassym.c
  stable/7/sys/amd64/amd64/machdep.c
  stable/7/sys/amd64/amd64/mp_machdep.c
  stable/7/sys/amd64/amd64/trap.c
  stable/7/sys/amd64/include/intr_machdep.h
  stable/7/sys/amd64/include/pmc_mdep.h
  stable/7/sys/conf/Makefile.amd64
  stable/7/sys/conf/Makefile.i386
  stable/7/sys/conf/files.amd64
  stable/7/sys/conf/files.i386
  stable/7/sys/conf/files.pc98
  stable/7/sys/dev/hwpmc/hwpmc_amd.c
  stable/7/sys/dev/hwpmc/hwpmc_amd.h
  stable/7/sys/dev/hwpmc/hwpmc_arm.c
  stable/7/sys/dev/hwpmc/hwpmc_ia64.c
  stable/7/sys/dev/hwpmc/hwpmc_logging.c
  stable/7/sys/dev/hwpmc/hwpmc_mod.c
  stable/7/sys/dev/hwpmc/hwpmc_pentium.c
  stable/7/sys/dev/hwpmc/hwpmc_pentium.h
  stable/7/sys/dev/hwpmc/hwpmc_piv.c
  stable/7/sys/dev/hwpmc/hwpmc_piv.h
  stable/7/sys/dev/hwpmc/hwpmc_powerpc.c
  stable/7/sys/dev/hwpmc/hwpmc_ppro.c
  stable/7/sys/dev/hwpmc/hwpmc_ppro.h
  stable/7/sys/dev/hwpmc/hwpmc_sparc64.c
  stable/7/sys/dev/hwpmc/hwpmc_x86.c
  stable/7/sys/dev/hwpmc/pmc_events.h
  stable/7/sys/i386/i386/exception.s
  stable/7/sys/i386/i386/genassym.c
  stable/7/sys/i386/i386/trap.c
  stable/7/sys/i386/include/pmc_mdep.h
  stable/7/sys/kern/kern_pmc.c
  stable/7/sys/modules/hwpmc/Makefile
  stable/7/sys/sys/pmc.h
  stable/7/sys/sys/pmckern.h
  stable/7/sys/sys/pmclog.h
  stable/7/sys/sys/proc.h
  stable/7/usr.sbin/Makefile
  stable/7/usr.sbin/pmccontrol/pmccontrol.8
  stable/7/usr.sbin/pmccontrol/pmccontrol.c
  stable/7/usr.sbin/pmcstat/Makefile
  stable/7/usr.sbin/pmcstat/pmcstat.8
  stable/7/usr.sbin/pmcstat/pmcstat.c
  stable/7/usr.sbin/pmcstat/pmcstat.h
  stable/7/usr.sbin/pmcstat/pmcstat_log.c

Modified: stable/7/lib/libpmc/Makefile
==============================================================================
--- stable/7/lib/libpmc/Makefile	Sun Jun  7 09:23:50 2009	(r193633)
+++ stable/7/lib/libpmc/Makefile	Sun Jun  7 10:00:35 2009	(r193634)
@@ -7,40 +7,54 @@ INCS=	pmc.h pmclog.h
 
 WARNS?=	6
 
-MAN=	pmc.3 pmclog.3
+MAN=	pmc.3
+MAN+=	pmc_allocate.3
+MAN+=	pmc_attach.3
+MAN+=	pmc_capabilities.3
+MAN+=	pmc_configure_logfile.3
+MAN+=	pmc_disable.3
+MAN+=	pmc_event_names_of_class.3
+MAN+=	pmc_get_driver_stats.3
+MAN+=	pmc_get_msr.3
+MAN+=	pmc_init.3
+MAN+=	pmc_name_of_capability.3
+MAN+=	pmc_read.3
+MAN+=	pmc_set.3
+MAN+=	pmc_start.3
+MAN+=	pmclog.3
+
+# PMC-dependent manual pages
+MAN+=	pmc.atom.3
+MAN+=	pmc.core.3
+MAN+=	pmc.core2.3
+MAN+=	pmc.iaf.3
+MAN+=	pmc.k7.3
+MAN+=	pmc.k8.3
+MAN+=	pmc.p4.3
+MAN+=	pmc.p5.3
+MAN+=	pmc.p6.3
+MAN+=	pmc.tsc.3
 
 MLINKS+= \
-	pmc.3 pmc_allocate.3 \
-	pmc.3 pmc_attach.3 \
-	pmc.3 pmc_capabilities.3 \
-	pmc.3 pmc_configure_logfile.3 \
-	pmc.3 pmc_cpuinfo.3 \
-	pmc.3 pmc_detach.3 \
-	pmc.3 pmc_disable.3 \
-	pmc.3 pmc_enable.3 \
-	pmc.3 pmc_event_names_of_class.3 \
-	pmc.3 pmc_flush_logfile.3 \
-	pmc.3 pmc_get_driver_stats.3 \
-	pmc.3 pmc_init.3 \
-	pmc.3 pmc_name_of_capability.3 \
-	pmc.3 pmc_name_of_class.3 \
-	pmc.3 pmc_name_of_cputype.3 \
-	pmc.3 pmc_name_of_event.3 \
-	pmc.3 pmc_name_of_mode.3 \
-	pmc.3 pmc_name_of_state.3 \
-	pmc.3 pmc_ncpu.3 \
-	pmc.3 pmc_npmc.3 \
-	pmc.3 pmc_pmcinfo.3 \
-	pmc.3 pmc_read.3 \
-	pmc.3 pmc_release.3 \
-	pmc.3 pmc_rw.3 \
-	pmc.3 pmc_set.3 \
-	pmc.3 pmc_start.3 \
-	pmc.3 pmc_stop.3 \
-	pmc.3 pmc_width.3 \
-	pmc.3 pmc_write.3 \
-	pmc.3 pmc_writelog.3 \
-	pmc.3 pmc_x86_get_msr.3
+	pmc_allocate.3 pmc_release.3 \
+	pmc_attach.3 pmc_detach.3 \
+	pmc_capabilities.3 pmc_ncpu.3 \
+	pmc_capabilities.3 pmc_npmc.3 \
+	pmc_capabilities.3 pmc_pmcinfo.3 \
+	pmc_capabilities.3 pmc_cpuinfo.3 \
+	pmc_capabilities.3 pmc_width.3 \
+	pmc_configure_logfile.3 pmc_flush_logfile.3 \
+	pmc_configure_logfile.3 pmc_writelog.3 \
+	pmc_disable.3 pmc_enable.3 \
+	pmc_name_of_capability.3 pmc_name_of_class.3 \
+	pmc_name_of_capability.3 pmc_name_of_cputype.3 \
+	pmc_name_of_capability.3 pmc_name_of_disposition.3 \
+	pmc_name_of_capability.3 pmc_name_of_event.3 \
+	pmc_name_of_capability.3 pmc_name_of_mode.3 \
+	pmc_name_of_capability.3 pmc_name_of_state.3 \
+	pmc_read.3 pmc_rw.3 \
+	pmc_read.3 pmc_write.3 \
+	pmc_start.3 pmc_stop.3
 
 MLINKS+= \
 	pmclog.3 pmclog_open.3 \

Modified: stable/7/lib/libpmc/libpmc.c
==============================================================================
--- stable/7/lib/libpmc/libpmc.c	Sun Jun  7 09:23:50 2009	(r193633)
+++ stable/7/lib/libpmc/libpmc.c	Sun Jun  7 10:00:35 2009	(r193634)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2003-2006 Joseph Koshy
+ * Copyright (c) 2003-2008 Joseph Koshy
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,12 +42,18 @@ __FBSDID("$FreeBSD$");
 #include <strings.h>
 #include <unistd.h>
 
+#include "libpmcinternal.h"
+
 /* Function prototypes */
 #if defined(__i386__)
 static int k7_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
     struct pmc_op_pmcallocate *_pmc_config);
 #endif
 #if defined(__amd64__) || defined(__i386__)
+static int iaf_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
+    struct pmc_op_pmcallocate *_pmc_config);
+static int iap_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
+    struct pmc_op_pmcallocate *_pmc_config);
 static int k8_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
     struct pmc_op_pmcallocate *_pmc_config);
 static int p4_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
@@ -59,6 +65,10 @@ static int p5_allocate_pmc(enum pmc_even
 static int p6_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
     struct pmc_op_pmcallocate *_pmc_config);
 #endif
+#if defined(__amd64__) || defined(__i386__)
+static int tsc_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
+    struct pmc_op_pmcallocate *_pmc_config);
+#endif
 
 #define PMC_CALL(cmd, params)				\
 	syscall(pmc_syscall, PMC_OP_##cmd, (params))
@@ -69,7 +79,6 @@ static int p6_allocate_pmc(enum pmc_even
  * mapped to the appropriate canonical event descriptions using a
  * lookup table.
  */
-
 struct pmc_event_alias {
 	const char	*pm_alias;
 	const char	*pm_spec;
@@ -78,25 +87,145 @@ struct pmc_event_alias {
 static const struct pmc_event_alias *pmc_mdep_event_aliases;
 
 /*
- * The pmc_event_descr table maps symbolic names known to the user
+ * The pmc_event_descr structure maps symbolic names known to the user
  * to integer codes used by the PMC KLD.
  */
-
 struct pmc_event_descr {
 	const char	*pm_ev_name;
 	enum pmc_event	pm_ev_code;
-	enum pmc_class	pm_ev_class;
 };
 
-static const struct pmc_event_descr
-pmc_event_table[] =
+/*
+ * The pmc_class_descr structure maps class name prefixes for
+ * event names to event tables and other PMC class data.
+ */
+struct pmc_class_descr {
+	const char	*pm_evc_name;
+	size_t		pm_evc_name_size;
+	enum pmc_class	pm_evc_class;
+	const struct pmc_event_descr *pm_evc_event_table;
+	size_t		pm_evc_event_table_size;
+	int		(*pm_evc_allocate_pmc)(enum pmc_event _pe,
+			    char *_ctrspec, struct pmc_op_pmcallocate *_pa);
+};
+
+#define	PMC_TABLE_SIZE(N)	(sizeof(N)/sizeof(N[0]))
+#define	PMC_EVENT_TABLE_SIZE(N)	PMC_TABLE_SIZE(N##_event_table)
+
+#undef	__PMC_EV
+#define	__PMC_EV(C,N) { #N, PMC_EV_ ## C ## _ ## N },
+
+/*
+ * PMC_CLASSDEP_TABLE(NAME, CLASS)
+ *
+ * Define a table mapping event names and aliases to HWPMC event IDs.
+ */
+#define	PMC_CLASSDEP_TABLE(N, C)				\
+	static const struct pmc_event_descr N##_event_table[] =	\
+	{							\
+		__PMC_EV_##C()					\
+	}
+
+PMC_CLASSDEP_TABLE(iaf, IAF);
+PMC_CLASSDEP_TABLE(k7, K7);
+PMC_CLASSDEP_TABLE(k8, K8);
+PMC_CLASSDEP_TABLE(p4, P4);
+PMC_CLASSDEP_TABLE(p5, P5);
+PMC_CLASSDEP_TABLE(p6, P6);
+
+#undef	__PMC_EV_ALIAS
+#define	__PMC_EV_ALIAS(N,CODE) 	{ N, PMC_EV_##CODE },
+
+static const struct pmc_event_descr atom_event_table[] =
+{
+	__PMC_EV_ALIAS_ATOM()
+};
+
+static const struct pmc_event_descr core_event_table[] =
 {
-#undef  __PMC_EV
-#define	__PMC_EV(C,N,EV) { #EV, PMC_EV_ ## C ## _ ## N, PMC_CLASS_ ## C },
-	__PMC_EVENTS()
+	__PMC_EV_ALIAS_CORE()
+};
+
+
+static const struct pmc_event_descr core2_event_table[] =
+{
+	__PMC_EV_ALIAS_CORE2()
+};
+
+static const struct pmc_event_descr corei7_event_table[] =
+{
+	__PMC_EV_ALIAS_COREI7()
 };
 
 /*
+ * PMC_MDEP_TABLE(NAME, PRIMARYCLASS, ADDITIONAL_CLASSES...)
+ *
+ * Map a CPU to the PMC classes it supports.
+ */
+#define	PMC_MDEP_TABLE(N,C,...)				\
+	static const enum pmc_class N##_pmc_classes[] = {	\
+		PMC_CLASS_##C, __VA_ARGS__			\
+	}
+
+PMC_MDEP_TABLE(atom, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(core, IAP, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(core2, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(corei7, IAP, PMC_CLASS_IAF, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(k7, K7, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(k8, K8, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(p4, P4, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(p5, P5, PMC_CLASS_TSC);
+PMC_MDEP_TABLE(p6, P6, PMC_CLASS_TSC);
+
+static const struct pmc_event_descr tsc_event_table[] =
+{
+	__PMC_EV_TSC()
+};
+
+#undef	PMC_CLASS_TABLE_DESC
+#define	PMC_CLASS_TABLE_DESC(NAME, CLASS, EVENTS, ALLOCATOR)	\
+static const struct pmc_class_descr NAME##_class_table_descr =	\
+	{							\
+		.pm_evc_name  = #CLASS "-",			\
+		.pm_evc_name_size = sizeof(#CLASS "-") - 1,	\
+		.pm_evc_class = PMC_CLASS_##CLASS ,		\
+		.pm_evc_event_table = EVENTS##_event_table ,	\
+		.pm_evc_event_table_size = 			\
+			PMC_EVENT_TABLE_SIZE(EVENTS),		\
+		.pm_evc_allocate_pmc = ALLOCATOR##_allocate_pmc	\
+	}
+
+#if	defined(__i386__) || defined(__amd64__)
+PMC_CLASS_TABLE_DESC(iaf, IAF, iaf, iaf);
+PMC_CLASS_TABLE_DESC(atom, IAP, atom, iap);
+PMC_CLASS_TABLE_DESC(core, IAP, core, iap);
+PMC_CLASS_TABLE_DESC(core2, IAP, core2, iap);
+PMC_CLASS_TABLE_DESC(corei7, IAP, corei7, iap);
+#endif
+#if	defined(__i386__)
+PMC_CLASS_TABLE_DESC(k7, K7, k7, k7);
+#endif
+#if	defined(__i386__) || defined(__amd64__)
+PMC_CLASS_TABLE_DESC(k8, K8, k8, k8);
+PMC_CLASS_TABLE_DESC(p4, P4, p4, p4);
+#endif
+#if	defined(__i386__)
+PMC_CLASS_TABLE_DESC(p5, P5, p5, p5);
+PMC_CLASS_TABLE_DESC(p6, P6, p6, p6);
+#endif
+#if	defined(__i386__) || defined(__amd64__)
+PMC_CLASS_TABLE_DESC(tsc, TSC, tsc, tsc);
+#endif
+
+#undef	PMC_CLASS_TABLE_DESC
+
+static const struct pmc_class_descr **pmc_class_table;
+#define	PMC_CLASS_TABLE_SIZE	cpu_info.pm_nclass
+
+static const enum pmc_class *pmc_mdep_class_list;
+static size_t pmc_mdep_class_list_size;
+
+/*
  * Mapping tables, mapping enumeration values to human readable
  * strings.
  */
@@ -113,9 +242,14 @@ static const char * pmc_class_names[] = 
 	__PMC_CLASSES()
 };
 
-static const char * pmc_cputype_names[] = {
+struct pmc_cputype_map {
+	enum pmc_class	pm_cputype;
+	const char	*pm_name;
+};
+
+static const struct pmc_cputype_map pmc_cputype_names[] = {
 #undef	__PMC_CPU
-#define	__PMC_CPU(S, D) #S ,
+#define	__PMC_CPU(S, V, D) { .pm_cputype = PMC_CPU_##S, .pm_name = #S } ,
 	__PMC_CPUS()
 };
 
@@ -141,11 +275,6 @@ static int pmc_syscall = -1;		/* filled 
 
 static struct pmc_cpuinfo cpu_info;	/* filled in by pmc_init() */
 
-
-/* Architecture dependent event parsing */
-static int (*pmc_mdep_allocate_pmc)(enum pmc_event _pe, char *_ctrspec,
-    struct pmc_op_pmcallocate *_pmc_config);
-
 /* Event masks for events */
 struct pmc_masks {
 	const char	*pm_name;
@@ -163,20 +292,21 @@ pmc_parse_mask(const struct pmc_masks *p
 	int c;
 
 	if (pmask == NULL)	/* no mask keywords */
-		return -1;
-	q = strchr(p, '='); 	/* skip '=' */
+		return (-1);
+	q = strchr(p, '=');	/* skip '=' */
 	if (*++q == '\0')	/* no more data */
-		return -1;
+		return (-1);
 	c = 0;			/* count of mask keywords seen */
 	while ((r = strsep(&q, "+")) != NULL) {
-		for (pm = pmask; pm->pm_name && strcmp(r, pm->pm_name); pm++)
+		for (pm = pmask; pm->pm_name && strcasecmp(r, pm->pm_name);
+		    pm++)
 			;
 		if (pm->pm_name == NULL) /* not found */
-			return -1;
+			return (-1);
 		*evmask |= pm->pm_value;
 		c++;
 	}
-	return c;
+	return (c);
 }
 #endif
 
@@ -194,7 +324,7 @@ static struct pmc_event_alias k7_aliases
 	EV_ALIAS("branches",		"k7-retired-branches"),
 	EV_ALIAS("branch-mispredicts",	"k7-retired-branches-mispredicted"),
 	EV_ALIAS("cycles",		"tsc"),
-	EV_ALIAS("dc-misses",		"k7-dc-misses,mask=moesi"),
+	EV_ALIAS("dc-misses",		"k7-dc-misses"),
 	EV_ALIAS("ic-misses",		"k7-ic-misses"),
 	EV_ALIAS("instructions",	"k7-retired-instructions"),
 	EV_ALIAS("interrupts",		"k7-hardware-interrupts"),
@@ -212,19 +342,12 @@ static int
 k7_allocate_pmc(enum pmc_event pe, char *ctrspec,
     struct pmc_op_pmcallocate *pmc_config)
 {
-	char 		*e, *p, *q;
-	int 		c, has_unitmask;
+	char		*e, *p, *q;
+	int		c, has_unitmask;
 	uint32_t	count, unitmask;
 
 	pmc_config->pm_md.pm_amd.pm_amd_config = 0;
-	pmc_config->pm_caps |= PMC_CAP_READ;
-
-	if (pe == PMC_EV_TSC_TSC) {
-		/* TSC events must be unqualified. */
-		if (ctrspec && *ctrspec != '\0')
-			return -1;
-		return 0;
-	}
+	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
 
 	if (pe == PMC_EV_K7_DC_REFILLS_FROM_L2 ||
 	    pe == PMC_EV_K7_DC_REFILLS_FROM_SYSTEM ||
@@ -234,17 +357,15 @@ k7_allocate_pmc(enum pmc_event pe, char 
 	} else
 		unitmask = has_unitmask = 0;
 
-	pmc_config->pm_caps |= PMC_CAP_WRITE;
-
 	while ((p = strsep(&ctrspec, ",")) != NULL) {
 		if (KWPREFIXMATCH(p, K7_KW_COUNT "=")) {
 			q = strchr(p, '=');
 			if (*++q == '\0') /* skip '=' */
-				return -1;
+				return (-1);
 
 			count = strtol(q, &e, 0);
 			if (e == q || *e != '\0')
-				return -1;
+				return (-1);
 
 			pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
 			pmc_config->pm_md.pm_amd.pm_amd_config |=
@@ -258,11 +379,11 @@ k7_allocate_pmc(enum pmc_event pe, char 
 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
 		} else if (KWPREFIXMATCH(p, K7_KW_UNITMASK "=")) {
 			if (has_unitmask == 0)
-				return -1;
+				return (-1);
 			unitmask = 0;
 			q = strchr(p, '=');
 			if (*++q == '\0') /* skip '=' */
-				return -1;
+				return (-1);
 
 			while ((c = tolower(*q++)) != 0)
 				if (c == 'm')
@@ -278,15 +399,15 @@ k7_allocate_pmc(enum pmc_event pe, char 
 				else if (c == '+')
 					continue;
 				else
-					return -1;
+					return (-1);
 
 			if (unitmask == 0)
-				return -1;
+				return (-1);
 
 		} else if (KWMATCH(p, K7_KW_USR)) {
 			pmc_config->pm_caps |= PMC_CAP_USER;
 		} else
-			return -1;
+			return (-1);
 	}
 
 	if (has_unitmask) {
@@ -295,7 +416,7 @@ k7_allocate_pmc(enum pmc_event pe, char 
 		    AMD_PMC_TO_UNITMASK(unitmask);
 	}
 
-	return 0;
+	return (0);
 
 }
 
@@ -304,6 +425,240 @@ k7_allocate_pmc(enum pmc_event pe, char 
 #if defined(__amd64__) || defined(__i386__)
 
 /*
+ * Intel Core (Family 6, Model E) PMCs.
+ */
+
+static struct pmc_event_alias core_aliases[] = {
+	EV_ALIAS("branches",		"iap-br-instr-ret"),
+	EV_ALIAS("branch-mispredicts",	"iap-br-mispred-ret"),
+	EV_ALIAS("cycles",		"tsc-tsc"),
+	EV_ALIAS("ic-misses",		"iap-icache-misses"),
+	EV_ALIAS("instructions",	"iap-instr-ret"),
+	EV_ALIAS("interrupts",		"iap-core-hw-int-rx"),
+	EV_ALIAS("unhalted-cycles",	"iap-unhalted-core-cycles"),
+	EV_ALIAS(NULL, NULL)
+};
+
+/*
+ * Intel Core2 (Family 6, Model F), Core2Extreme (Family 6, Model 17H)
+ * and Atom (Family 6, model 1CH) PMCs.
+ */
+
+static struct pmc_event_alias core2_aliases[] = {
+	EV_ALIAS("branches",		"iap-br-inst-retired.any"),
+	EV_ALIAS("branch-mispredicts",	"iap-br-inst-retired.mispred"),
+	EV_ALIAS("cycles",		"tsc-tsc"),
+	EV_ALIAS("ic-misses",		"iap-l1i-misses"),
+	EV_ALIAS("instructions",	"iaf-instr-retired.any"),
+	EV_ALIAS("interrupts",		"iap-hw-int-rcv"),
+	EV_ALIAS("unhalted-cycles",	"iaf-cpu-clk-unhalted.core"),
+	EV_ALIAS(NULL, NULL)
+};
+#define	atom_aliases	core2_aliases
+#define corei7_aliases	core2_aliases
+
+#define	IAF_KW_OS		"os"
+#define	IAF_KW_USR		"usr"
+#define	IAF_KW_ANYTHREAD	"anythread"
+
+/*
+ * Parse an event specifier for Intel fixed function counters.
+ */
+static int
+iaf_allocate_pmc(enum pmc_event pe, char *ctrspec,
+    struct pmc_op_pmcallocate *pmc_config)
+{
+	char *p;
+
+	(void) pe;
+
+	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
+	pmc_config->pm_md.pm_iaf.pm_iaf_flags = 0;
+
+	while ((p = strsep(&ctrspec, ",")) != NULL) {
+		if (KWMATCH(p, IAF_KW_OS))
+			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
+		else if (KWMATCH(p, IAF_KW_USR))
+			pmc_config->pm_caps |= PMC_CAP_USER;
+		else if (KWMATCH(p, IAF_KW_ANYTHREAD))
+			pmc_config->pm_md.pm_iaf.pm_iaf_flags |= IAF_ANY;
+		else
+			return (-1);
+	}
+
+	return (0);
+}
+
+/*
+ * Core/Core2 support.
+ */
+
+#define	IAP_KW_AGENT		"agent"
+#define	IAP_KW_ANYTHREAD	"anythread"
+#define	IAP_KW_CACHESTATE	"cachestate"
+#define	IAP_KW_CMASK		"cmask"
+#define	IAP_KW_CORE		"core"
+#define	IAP_KW_EDGE		"edge"
+#define	IAP_KW_INV		"inv"
+#define	IAP_KW_OS		"os"
+#define	IAP_KW_PREFETCH		"prefetch"
+#define	IAP_KW_SNOOPRESPONSE	"snoopresponse"
+#define	IAP_KW_SNOOPTYPE	"snooptype"
+#define	IAP_KW_TRANSITION	"trans"
+#define	IAP_KW_USR		"usr"
+
+static struct pmc_masks iap_core_mask[] = {
+	PMCMASK(all,	(0x3 << 14)),
+	PMCMASK(this,	(0x1 << 14)),
+	NULLMASK
+};
+
+static struct pmc_masks iap_agent_mask[] = {
+	PMCMASK(this,	0),
+	PMCMASK(any,	(0x1 << 13)),
+	NULLMASK
+};
+
+static struct pmc_masks iap_prefetch_mask[] = {
+	PMCMASK(both,		(0x3 << 12)),
+	PMCMASK(only,		(0x1 << 12)),
+	PMCMASK(exclude,	0),
+	NULLMASK
+};
+
+static struct pmc_masks iap_cachestate_mask[] = {
+	PMCMASK(i,		(1 <<  8)),
+	PMCMASK(s,		(1 <<  9)),
+	PMCMASK(e,		(1 << 10)),
+	PMCMASK(m,		(1 << 11)),
+	NULLMASK
+};
+
+static struct pmc_masks iap_snoopresponse_mask[] = {
+	PMCMASK(clean,		(1 << 8)),
+	PMCMASK(hit,		(1 << 9)),
+	PMCMASK(hitm,		(1 << 11)),
+	NULLMASK
+};
+
+static struct pmc_masks iap_snooptype_mask[] = {
+	PMCMASK(cmp2s,		(1 << 8)),
+	PMCMASK(cmp2i,		(1 << 9)),
+	NULLMASK
+};
+
+static struct pmc_masks iap_transition_mask[] = {
+	PMCMASK(any,		0x00),
+	PMCMASK(frequency,	0x10),
+	NULLMASK
+};
+
+static int
+iap_allocate_pmc(enum pmc_event pe, char *ctrspec,
+    struct pmc_op_pmcallocate *pmc_config)
+{
+	char *e, *p, *q;
+	uint32_t cachestate, evmask;
+	int count, n;
+
+	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE |
+	    PMC_CAP_QUALIFIER);
+	pmc_config->pm_md.pm_iap.pm_iap_config = 0;
+
+	cachestate = evmask = 0;
+
+	/* Parse additional modifiers if present */
+	while ((p = strsep(&ctrspec, ",")) != NULL) {
+
+		n = 0;
+		if (KWPREFIXMATCH(p, IAP_KW_CMASK "=")) {
+			q = strchr(p, '=');
+			if (*++q == '\0') /* skip '=' */
+				return (-1);
+			count = strtol(q, &e, 0);
+			if (e == q || *e != '\0')
+				return (-1);
+			pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
+			pmc_config->pm_md.pm_iap.pm_iap_config |=
+			    IAP_CMASK(count);
+		} else if (KWMATCH(p, IAP_KW_EDGE)) {
+			pmc_config->pm_caps |= PMC_CAP_EDGE;
+		} else if (KWMATCH(p, IAP_KW_INV)) {
+			pmc_config->pm_caps |= PMC_CAP_INVERT;
+		} else if (KWMATCH(p, IAP_KW_OS)) {
+			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
+		} else if (KWMATCH(p, IAP_KW_USR)) {
+			pmc_config->pm_caps |= PMC_CAP_USER;
+		} else if (KWMATCH(p, IAP_KW_ANYTHREAD)) {
+			pmc_config->pm_md.pm_iap.pm_iap_config |= IAP_ANY;
+		} else if (KWMATCH(p, IAP_KW_CORE)) {
+			n = pmc_parse_mask(iap_core_mask, p, &evmask);
+			if (n != 1)
+				return (-1);
+		} else if (KWMATCH(p, IAP_KW_AGENT)) {
+			n = pmc_parse_mask(iap_agent_mask, p, &evmask);
+			if (n != 1)
+				return (-1);
+		} else if (KWMATCH(p, IAP_KW_PREFETCH)) {
+			n = pmc_parse_mask(iap_prefetch_mask, p, &evmask);
+			if (n != 1)
+				return (-1);
+		} else if (KWMATCH(p, IAP_KW_CACHESTATE)) {
+			n = pmc_parse_mask(iap_cachestate_mask, p, &cachestate);
+		} else if (cpu_info.pm_cputype == PMC_CPU_INTEL_CORE &&
+		    KWMATCH(p, IAP_KW_TRANSITION)) {
+			n = pmc_parse_mask(iap_transition_mask, p, &evmask);
+			if (n != 1)
+				return (-1);
+		} else if (cpu_info.pm_cputype == PMC_CPU_INTEL_ATOM ||
+		    cpu_info.pm_cputype == PMC_CPU_INTEL_CORE2 ||
+		    cpu_info.pm_cputype == PMC_CPU_INTEL_CORE2EXTREME ||
+		    cpu_info.pm_cputype == PMC_CPU_INTEL_COREI7) {
+			if (KWMATCH(p, IAP_KW_SNOOPRESPONSE)) {
+				n = pmc_parse_mask(iap_snoopresponse_mask, p,
+				    &evmask);
+			} else if (KWMATCH(p, IAP_KW_SNOOPTYPE)) {
+				n = pmc_parse_mask(iap_snooptype_mask, p,
+				    &evmask);
+			} else
+				return (-1);
+		} else
+			return (-1);
+
+		if (n < 0)	/* Parsing failed. */
+			return (-1);
+	}
+
+	pmc_config->pm_md.pm_iap.pm_iap_config |= evmask;
+
+	/*
+	 * If the event requires a 'cachestate' qualifier but was not
+	 * specified by the user, use a sensible default.
+	 */
+	switch (pe) {
+	case PMC_EV_IAP_EVENT_28H: /* Core, Core2, Atom */
+	case PMC_EV_IAP_EVENT_29H: /* Core, Core2, Atom */
+	case PMC_EV_IAP_EVENT_2AH: /* Core, Core2, Atom */
+	case PMC_EV_IAP_EVENT_2BH: /* Atom, Core2 */
+	case PMC_EV_IAP_EVENT_2EH: /* Core, Core2, Atom */
+	case PMC_EV_IAP_EVENT_30H: /* Core, Core2, Atom */
+	case PMC_EV_IAP_EVENT_32H: /* Core */
+	case PMC_EV_IAP_EVENT_40H: /* Core */
+	case PMC_EV_IAP_EVENT_41H: /* Core */
+	case PMC_EV_IAP_EVENT_42H: /* Core, Core2, Atom */
+	case PMC_EV_IAP_EVENT_77H: /* Core */
+		if (cachestate == 0)
+			cachestate = (0xF << 8);
+	default:
+		break;
+	}
+
+	pmc_config->pm_md.pm_iap.pm_iap_config |= cachestate;
+
+	return (0);
+}
+
+/*
  * AMD K8 PMCs.
  *
  * These are very similar to AMD K7 PMCs, but support more kinds of
@@ -317,7 +672,7 @@ static struct pmc_event_alias k8_aliases
 	EV_ALIAS("cycles",		"tsc"),
 	EV_ALIAS("dc-misses",		"k8-dc-miss"),
 	EV_ALIAS("ic-misses",		"k8-ic-miss"),
-	EV_ALIAS("instructions", 	"k8-fr-retired-x86-instructions"),
+	EV_ALIAS("instructions",	"k8-fr-retired-x86-instructions"),
 	EV_ALIAS("interrupts",		"k8-fr-taken-hardware-interrupts"),
 	EV_ALIAS("unhalted-cycles",	"k8-bu-cpu-clk-unhalted"),
 	EV_ALIAS(NULL, NULL)
@@ -492,7 +847,7 @@ static const struct pmc_masks k8_mask_np
 /* nb hypertransport bus bandwidth */
 static const struct pmc_masks k8_mask_nhbb[] = { /* HT bus bandwidth */
 	__K8MASK(command,	0),
-	__K8MASK(data, 	1),
+	__K8MASK(data,	1),
 	__K8MASK(buffer-release, 2),
 	__K8MASK(nop,	3),
 	NULLMASK
@@ -511,21 +866,14 @@ static int
 k8_allocate_pmc(enum pmc_event pe, char *ctrspec,
     struct pmc_op_pmcallocate *pmc_config)
 {
-	char 		*e, *p, *q;
-	int 		n;
+	char		*e, *p, *q;
+	int		n;
 	uint32_t	count, evmask;
 	const struct pmc_masks	*pm, *pmask;
 
-	pmc_config->pm_caps |= PMC_CAP_READ;
+	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
 	pmc_config->pm_md.pm_amd.pm_amd_config = 0;
 
-	if (pe == PMC_EV_TSC_TSC) {
-		/* TSC events must be unqualified. */
-		if (ctrspec && *ctrspec != '\0')
-			return -1;
-		return 0;
-	}
-
 	pmask = NULL;
 	evmask = 0;
 
@@ -599,17 +947,15 @@ k8_allocate_pmc(enum pmc_event pe, char 
 		break;		/* no options defined */
 	}
 
-	pmc_config->pm_caps |= PMC_CAP_WRITE;
-
 	while ((p = strsep(&ctrspec, ",")) != NULL) {
 		if (KWPREFIXMATCH(p, K8_KW_COUNT "=")) {
 			q = strchr(p, '=');
 			if (*++q == '\0') /* skip '=' */
-				return -1;
+				return (-1);
 
 			count = strtol(q, &e, 0);
 			if (e == q || *e != '\0')
-				return -1;
+				return (-1);
 
 			pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
 			pmc_config->pm_md.pm_amd.pm_amd_config |=
@@ -621,18 +967,17 @@ k8_allocate_pmc(enum pmc_event pe, char 
 			pmc_config->pm_caps |= PMC_CAP_INVERT;
 		} else if (KWPREFIXMATCH(p, K8_KW_MASK "=")) {
 			if ((n = pmc_parse_mask(pmask, p, &evmask)) < 0)
-				return -1;
+				return (-1);
 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
 		} else if (KWMATCH(p, K8_KW_OS)) {
 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
 		} else if (KWMATCH(p, K8_KW_USR)) {
 			pmc_config->pm_caps |= PMC_CAP_USER;
 		} else
-			return -1;
+			return (-1);
 	}
 
 	/* other post processing */
-
 	switch (pe) {
 	case PMC_EV_K8_FP_DISPATCHED_FPU_OPS:
 	case PMC_EV_K8_FP_CYCLES_WITH_NO_FPU_OPS_RETIRED:
@@ -648,7 +993,7 @@ k8_allocate_pmc(enum pmc_event pe, char 
 	case PMC_EV_K8_LS_LOCKED_OPERATION:
 		/* XXX CPU Rev A,B evmask is to be zero */
 		if (evmask & (evmask - 1)) /* > 1 bit set */
-			return -1;
+			return (-1);
 		if (evmask == 0) {
 			evmask = 0x01; /* Rev C and later: #instrs */
 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
@@ -666,7 +1011,7 @@ k8_allocate_pmc(enum pmc_event pe, char 
 		pmc_config->pm_md.pm_amd.pm_amd_config =
 		    AMD_PMC_TO_UNITMASK(evmask);
 
-	return 0;
+	return (0);
 }
 
 #endif
@@ -1008,25 +1353,17 @@ p4_allocate_pmc(enum pmc_event pe, char 
 	uint32_t evmask, cccractivemask;
 	const struct pmc_masks *pm, *pmask;
 
-	pmc_config->pm_caps |= PMC_CAP_READ;
+	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
 	pmc_config->pm_md.pm_p4.pm_p4_cccrconfig =
 	    pmc_config->pm_md.pm_p4.pm_p4_escrconfig = 0;
 
-	if (pe == PMC_EV_TSC_TSC) {
-		/* TSC must not be further qualified */
-		if (ctrspec && *ctrspec != '\0')
-			return -1;
-		return 0;
-	}
-
 	pmask   = NULL;
 	evmask  = 0;
 	cccractivemask = 0x3;
 	has_tag = has_busreqtype = 0;
-	pmc_config->pm_caps |= PMC_CAP_WRITE;
 
 #define	__P4SETMASK(M) do {				\
-	pmask = p4_mask_##M; 				\
+	pmask = p4_mask_##M;				\
 } while (0)
 
 	switch (pe) {
@@ -1159,7 +1496,7 @@ p4_allocate_pmc(enum pmc_event pe, char 
 		__P4SETMASK(machclr);
 		break;
 	default:
-		return -1;
+		return (-1);
 	}
 
 	/* process additional flags */
@@ -1167,30 +1504,30 @@ p4_allocate_pmc(enum pmc_event pe, char 
 		if (KWPREFIXMATCH(p, P4_KW_ACTIVE)) {
 			q = strchr(p, '=');
 			if (*++q == '\0') /* skip '=' */
-				return -1;
+				return (-1);
 
-			if (strcmp(q, P4_KW_ACTIVE_NONE) == 0)
+			if (strcasecmp(q, P4_KW_ACTIVE_NONE) == 0)
 				cccractivemask = 0x0;
-			else if (strcmp(q, P4_KW_ACTIVE_SINGLE) == 0)
+			else if (strcasecmp(q, P4_KW_ACTIVE_SINGLE) == 0)
 				cccractivemask = 0x1;
-			else if (strcmp(q, P4_KW_ACTIVE_BOTH) == 0)
+			else if (strcasecmp(q, P4_KW_ACTIVE_BOTH) == 0)
 				cccractivemask = 0x2;
-			else if (strcmp(q, P4_KW_ACTIVE_ANY) == 0)
+			else if (strcasecmp(q, P4_KW_ACTIVE_ANY) == 0)
 				cccractivemask = 0x3;
 			else
-				return -1;
+				return (-1);
 
 		} else if (KWPREFIXMATCH(p, P4_KW_BUSREQTYPE)) {
 			if (has_busreqtype == 0)
-				return -1;
+				return (-1);
 
 			q = strchr(p, '=');
 			if (*++q == '\0') /* skip '=' */
-				return -1;
+				return (-1);
 
 			count = strtol(q, &e, 0);
 			if (e == q || *e != '\0')
-				return -1;
+				return (-1);
 			evmask = (evmask & ~0x1F) | (count & 0x1F);
 		} else if (KWMATCH(p, P4_KW_CASCADE))
 			pmc_config->pm_caps |= PMC_CAP_CASCADE;
@@ -1200,7 +1537,7 @@ p4_allocate_pmc(enum pmc_event pe, char 
 			pmc_config->pm_caps |= PMC_CAP_INVERT;
 		else if (KWPREFIXMATCH(p, P4_KW_MASK "=")) {
 			if ((n = pmc_parse_mask(pmask, p, &evmask)) < 0)
-				return -1;
+				return (-1);
 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
 		} else if (KWMATCH(p, P4_KW_OS))
 			pmc_config->pm_caps |= PMC_CAP_SYSTEM;
@@ -1208,15 +1545,15 @@ p4_allocate_pmc(enum pmc_event pe, char 
 			pmc_config->pm_caps |= PMC_CAP_PRECISE;
 		else if (KWPREFIXMATCH(p, P4_KW_TAG "=")) {
 			if (has_tag == 0)
-				return -1;
+				return (-1);
 
 			q = strchr(p, '=');
 			if (*++q == '\0') /* skip '=' */
-				return -1;
+				return (-1);
 
 			count = strtol(q, &e, 0);
 			if (e == q || *e != '\0')
-				return -1;
+				return (-1);
 
 			pmc_config->pm_caps |= PMC_CAP_TAGGING;
 			pmc_config->pm_md.pm_p4.pm_p4_escrconfig |=
@@ -1224,11 +1561,11 @@ p4_allocate_pmc(enum pmc_event pe, char 
 		} else if (KWPREFIXMATCH(p, P4_KW_THRESHOLD "=")) {
 			q = strchr(p, '=');
 			if (*++q == '\0') /* skip '=' */
-				return -1;
+				return (-1);
 
 			count = strtol(q, &e, 0);
 			if (e == q || *e != '\0')
-				return -1;
+				return (-1);
 
 			pmc_config->pm_caps |= PMC_CAP_THRESHOLD;
 			pmc_config->pm_md.pm_p4.pm_p4_cccrconfig &=
@@ -1238,7 +1575,7 @@ p4_allocate_pmc(enum pmc_event pe, char 
 		} else if (KWMATCH(p, P4_KW_USR))
 			pmc_config->pm_caps |= PMC_CAP_USER;
 		else
-			return -1;
+			return (-1);
 	}
 
 	/* other post processing */
@@ -1258,16 +1595,16 @@ p4_allocate_pmc(enum pmc_event pe, char 
 	case PMC_EV_P4_FSB_DATA_ACTIVITY:
 		if ((evmask & 0x06) == 0x06 ||
 		    (evmask & 0x18) == 0x18)
-			return -1; /* can't have own+other bits together */
+			return (-1); /* can't have own+other bits together */
 		if (evmask == 0) /* default:drdy-{drv,own}+dbsy{drv,own} */
 			evmask = 0x1D;
 		break;
 	case PMC_EV_P4_MACHINE_CLEAR:
 		/* only one bit is allowed to be set */
 		if ((evmask & (evmask - 1)) != 0)
-			return -1;
+			return (-1);
 		if (evmask == 0) {
-			evmask = 0x1; 	/* 'CLEAR' */
+			evmask = 0x1;	/* 'CLEAR' */
 			pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
 		}
 		break;
@@ -1282,7 +1619,7 @@ p4_allocate_pmc(enum pmc_event pe, char 
 	pmc_config->pm_md.pm_p4.pm_p4_escrconfig =
 	    P4_ESCR_TO_EVENT_MASK(evmask);
 
-	return 0;
+	return (0);
 }
 
 #endif
@@ -1294,7 +1631,14 @@ p4_allocate_pmc(enum pmc_event pe, char 
  */
 
 static struct pmc_event_alias p5_aliases[] = {
-	EV_ALIAS("cycles", "tsc"),
+	EV_ALIAS("branches",		"p5-taken-branches"),
+	EV_ALIAS("cycles",		"tsc"),
+	EV_ALIAS("dc-misses",		"p5-data-read-miss-or-write-miss"),
+	EV_ALIAS("ic-misses",		"p5-code-cache-miss"),
+	EV_ALIAS("instructions",	"p5-instructions-executed"),
+	EV_ALIAS("interrupts",		"p5-hardware-interrupts"),
+	EV_ALIAS("unhalted-cycles",
+	    "p5-number-of-cycles-not-in-halt-state"),
 	EV_ALIAS(NULL, NULL)
 };
 
@@ -1302,7 +1646,7 @@ static int
 p5_allocate_pmc(enum pmc_event pe, char *ctrspec,
     struct pmc_op_pmcallocate *pmc_config)
 {
-	return -1 || pe || ctrspec || pmc_config; /* shut up gcc */
+	return (-1 || pe || ctrspec || pmc_config); /* shut up gcc */
 }
 
 /*
@@ -1438,22 +1782,15 @@ p6_allocate_pmc(enum pmc_event pe, char 
 	int count, n;
 	const struct pmc_masks *pm, *pmask;
 
-	pmc_config->pm_caps |= PMC_CAP_READ;
+	pmc_config->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
 	pmc_config->pm_md.pm_ppro.pm_ppro_config = 0;
 
-	if (pe == PMC_EV_TSC_TSC) {
-		if (ctrspec && *ctrspec != '\0')
-			return -1;
-		return 0;
-	}
-
-	pmc_config->pm_caps |= PMC_CAP_WRITE;
 	evmask = 0;
 
 #define	P6MASKSET(M)	pmask = p6_mask_ ## M
 
 	switch(pe) {
-	case PMC_EV_P6_L2_IFETCH: 	P6MASKSET(mesi); break;
+	case PMC_EV_P6_L2_IFETCH:	P6MASKSET(mesi); break;
 	case PMC_EV_P6_L2_LD:		P6MASKSET(mesi); break;
 	case PMC_EV_P6_L2_ST:		P6MASKSET(mesi); break;
 	case PMC_EV_P6_L2_RQSTS:	P6MASKSET(mesi); break;
@@ -1513,10 +1850,10 @@ p6_allocate_pmc(enum pmc_event pe, char 
 		if (KWPREFIXMATCH(p, P6_KW_CMASK "=")) {
 			q = strchr(p, '=');
 			if (*++q == '\0') /* skip '=' */
-				return -1;
+				return (-1);
 			count = strtol(q, &e, 0);
 			if (e == q || *e != '\0')
-				return -1;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906071000.n57A0Zem089380>