svn commit: r184838 - user/kmacy/HEAD_fast_multi_xmit/lib/libpmc
Kip Macy
kmacy at FreeBSD.org
Tue Nov 11 02:21:19 PST 2008
Author: kmacy
Date: Tue Nov 11 10:21:19 2008
New Revision: 184838
URL: http://svn.freebsd.org/changeset/base/184838
Log:
Import libpmc changes required for core2 support
Modified:
user/kmacy/HEAD_fast_multi_xmit/lib/libpmc/libpmc.c
Modified: user/kmacy/HEAD_fast_multi_xmit/lib/libpmc/libpmc.c
==============================================================================
--- user/kmacy/HEAD_fast_multi_xmit/lib/libpmc/libpmc.c Tue Nov 11 09:40:27 2008 (r184837)
+++ user/kmacy/HEAD_fast_multi_xmit/lib/libpmc/libpmc.c Tue Nov 11 10:21:19 2008 (r184838)
@@ -53,7 +53,7 @@ static int k8_allocate_pmc(enum pmc_even
static int p4_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
#endif
-#if defined(__i386__)
+#if defined(__i386__)
static int p5_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
static int p6_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
@@ -62,6 +62,8 @@ static int p6_allocate_pmc(enum pmc_even
#if defined(__amd64__) || defined(__i386__)
static int tsc_allocate_pmc(enum pmc_event _pe, char *_ctrspec,
struct pmc_op_pmcallocate *_pmc_config);
+static int iap2_allocate_pmc(enum pmc_event pe, char *ctrspec,
+ struct pmc_op_pmcallocate *pmc_config);
#endif
#define PMC_CALL(cmd, params) \
@@ -128,6 +130,7 @@ 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);
+PMC_MDEP_TABLE(iap2, IAP2, PMC_CLASS_TSC);
static const struct pmc_event_descr tsc_event_table[] =
{
@@ -159,6 +162,7 @@ static const struct pmc_class_descr pmc_
PMC_CLASS_TABLE_DESC(p6, P6),
#endif
#if defined(__i386__) || defined(__amd64__)
+ PMC_CLASS_TABLE_DESC(iap2, IAP2),
PMC_CLASS_TABLE_DESC(tsc, TSC)
#endif
};
@@ -1336,7 +1340,7 @@ p4_allocate_pmc(enum pmc_event pe, char
#endif
-#if defined(__i386__)
+#if defined(__i386__)
/*
* Pentium style PMCs
@@ -1361,20 +1365,23 @@ p5_allocate_pmc(enum pmc_event pe, char
return (-1 || pe || ctrspec || pmc_config); /* shut up gcc */
}
+#endif
/*
* Pentium Pro style PMCs. These PMCs are found in Pentium II, Pentium III,
* and Pentium M CPUs.
*/
-static struct pmc_event_alias p6_aliases[] = {
- EV_ALIAS("branches", "p6-br-inst-retired"),
- EV_ALIAS("branch-mispredicts", "p6-br-miss-pred-retired"),
+#if defined(__i386__) || defined(__amd64__)
+
+static struct pmc_event_alias iap2_aliases[] = {
+ EV_ALIAS("branches", "iap2-br-inst-retired-any"),
+ EV_ALIAS("branch-mispredicts", "iap2-br-inst-retired-mispred"),
EV_ALIAS("cycles", "tsc"),
- EV_ALIAS("dc-misses", "p6-dcu-lines-in"),
- EV_ALIAS("ic-misses", "p6-ifu-fetch-miss"),
- EV_ALIAS("instructions", "p6-inst-retired"),
- EV_ALIAS("interrupts", "p6-hw-int-rx"),
- EV_ALIAS("unhalted-cycles", "p6-cpu-clk-unhalted"),
+ EV_ALIAS("dc-misses", "iap2-l1d-pend-miss"),
+ EV_ALIAS("ic-misses", "iap2-l1i-misses"),
+ EV_ALIAS("instructions", "iap2-instructions-retired"),
+ EV_ALIAS("interrupts", "iap2-hw-int-rcv"),
+ EV_ALIAS("unhalted-cycles", "iap2-unhalted-core-cycles"),
EV_ALIAS(NULL, NULL)
};
@@ -1384,6 +1391,12 @@ static struct pmc_event_alias p6_aliases
#define P6_KW_OS "os"
#define P6_KW_UMASK "umask"
#define P6_KW_USR "usr"
+#define IPM_KW_CMASK P6_KW_CMASK
+#define IPM_KW_EDGE P6_KW_EDGE
+#define IPM_KW_INV P6_KW_INV
+#define IPM_KW_OS P6_KW_OS
+#define IPM_KW_UMASK P6_KW_UMASK
+#define IPM_KW_USR P6_KW_USR
static struct pmc_masks p6_mask_mesi[] = {
PMCMASK(m, 0x01),
@@ -1392,6 +1405,20 @@ static struct pmc_masks p6_mask_mesi[] =
PMCMASK(i, 0x08),
NULLMASK
};
+#endif
+
+#if defined(__i386__)
+static struct pmc_event_alias p6_aliases[] = {
+ EV_ALIAS("branches", "p6-br-inst-retired"),
+ EV_ALIAS("branch-mispredicts", "p6-br-miss-pred-retired"),
+ EV_ALIAS("cycles", "tsc"),
+ EV_ALIAS("dc-misses", "p6-dcu-lines-in"),
+ EV_ALIAS("ic-misses", "p6-ifu-fetch-miss"),
+ EV_ALIAS("instructions", "p6-inst-retired"),
+ EV_ALIAS("interrupts", "p6-hw-int-rx"),
+ EV_ALIAS("unhalted-cycles", "p6-cpu-clk-unhalted"),
+ EV_ALIAS(NULL, NULL)
+};
static struct pmc_masks p6_mask_mesihw[] = {
PMCMASK(m, 0x01),
@@ -1484,6 +1511,7 @@ static struct pmc_masks p6_mask_esscir[]
NULLMASK
};
+
/* P6 event parser */
static int
p6_allocate_pmc(enum pmc_event pe, char *ctrspec,
@@ -1683,7 +1711,246 @@ p6_allocate_pmc(enum pmc_event pe, char
#endif
+
#if defined(__i386__) || defined(__amd64__)
+
+#define ipm_mask_mesi p6_mask_mesi
+#define ipm_default_mask_mesi 0x0F /* mesi */
+
+static struct pmc_masks ipm_mask_cores[] = {
+ PMCMASK(cself, 0x40),
+ PMCMASK(cany, 0xC0),
+ NULLMASK
+};
+#define ipm_default_mask_cores 0x40 /* this core */
+
+static struct pmc_masks ipm_mask_agents[] = {
+ PMCMASK(aself, 0x00),
+ PMCMASK(aany, 0x20),
+ NULLMASK
+};
+#define ipm_default_mask_agents 0x00 /* this agent */
+
+static struct pmc_masks ipm_mask_cores_and_agents[] = {
+ PMCMASK(cself, 0x40),
+ PMCMASK(cany, 0xC0),
+ PMCMASK(aself, 0x00),
+ PMCMASK(aany, 0x20),
+ NULLMASK
+};
+#define ipm_default_mask_cores_and_agents 0x40 /* this core,this agent */
+
+static struct pmc_masks ipm_mask_cores_and_hw[] = {
+ PMCMASK(cself, 0x40),
+ PMCMASK(cany, 0xC0),
+ PMCMASK(nonhw, 0x00),
+ PMCMASK(hw, 0x10),
+ PMCMASK(both, 0x30),
+ NULLMASK
+};
+#define ipm_default_mask_cores_and_hw 0x70 /* this core,both */
+
+static struct pmc_masks ipm_mask_cores_and_mesi[] = {
+ PMCMASK(cself, 0x40),
+ PMCMASK(cany, 0xC0),
+ PMCMASK(m, 0x01),
+ PMCMASK(e, 0x02),
+ PMCMASK(s, 0x04),
+ PMCMASK(i, 0x08),
+ NULLMASK
+};
+#define ipm_default_mask_cores_and_mesi 0x4F /* this core,mesi */
+
+static struct pmc_masks ipm_mask_cores_and_hw_and_mesi[] = {
+ PMCMASK(cself, 0x40),
+ PMCMASK(cany, 0xC0),
+ PMCMASK(nonhw, 0x00),
+ PMCMASK(hw, 0x10),
+ PMCMASK(both, 0x30),
+ PMCMASK(m, 0x01),
+ PMCMASK(e, 0x02),
+ PMCMASK(s, 0x04),
+ PMCMASK(i, 0x08),
+ NULLMASK
+};
+#define ipm_default_mask_cores_and_hw_and_mesi 0x7F /* this core,both,mesi */
+
+static struct pmc_masks ipm_mask_cores_and_snoop_response[] = {
+ PMCMASK(cself, 0x40),
+ PMCMASK(cany, 0xC0),
+ PMCMASK(clean, 0x01),
+ PMCMASK(hit, 0x02),
+ PMCMASK(hitm, 0x08),
+ NULLMASK
+};
+#define ipm_default_mask_cores_and_snoop_response 0x41 /*this core,clean */
+
+static struct pmc_masks ipm_mask_cores_and_snoop_type[] = {
+ PMCMASK(cself, 0x40),
+ PMCMASK(cany, 0xC0),
+ PMCMASK(cmp2s, 0x01),
+ PMCMASK(cmp2i, 0x02),
+ NULLMASK
+};
+#define ipm_default_mask_cores_and_snoop_type 0x41 /* this core,cmp2s */
+
+/*
+ * Intel Performance Monitoring PMCs event parser
+ */
+static int
+iap2_allocate_pmc(enum pmc_event pe, char *ctrspec,
+ struct pmc_op_pmcallocate *pmc_config)
+{
+ char *e, *p, *q;
+ uint32_t evmask, default_mask = 0;
+ int count, n, masks = 0;
+ const struct pmc_masks *pmask;
+
+ pmc_config->pm_caps |= PMC_CAP_READ;
+
+ if (pe == PMC_EV_TSC_TSC) {
+ if (ctrspec && *ctrspec != '\0')
+ return -1;
+ return 0;
+ }
+
+ pmc_config->pm_caps |= PMC_CAP_WRITE;
+
+ if (pe == PMC_EV_IAF_INSTRUCTIONS_RETIRED ||
+ pe == PMC_EV_IAF_UNHALTED_CORE_CYCLES ||
+ pe == PMC_EV_IAF_UNHALTED_REFERENCE_CYCLES) {
+ while ((p = strsep(&ctrspec, ",")) != NULL) {
+ if (KWMATCH(p, IPM_KW_OS)) {
+ pmc_config->pm_caps |= PMC_CAP_SYSTEM;
+ } else if (KWMATCH(p, IPM_KW_USR)) {
+ pmc_config->pm_caps |= PMC_CAP_USER;
+ } else
+ return -1;
+ }
+ pmc_config->pm_class = PMC_CLASS_IAF;
+ return 0;
+ }
+
+ evmask = 0;
+
+#define IPMMASKSET(M) \
+ do { \
+ pmask = ipm_mask_ ## M; \
+ default_mask = ipm_default_mask_ ## M; \
+ } while(0)
+
+ switch(pe) {
+ case PMC_EV_IAP2_L2_ADS: case PMC_EV_IAP2_L2_DBUS_BUSY_RD:
+ case PMC_EV_IAP2_L2_NO_REQ: case PMC_EV_IAP2_BUS_DATA_RCV:
+ case PMC_EV_IAP2_BUSQ_EMPTY: case PMC_EV_IAP2_BUS_IO_WAIT:
+ case PMC_EV_IAP2_L2_M_LINES_IN:
+ masks = 1;
+ IPMMASKSET(cores);
+ break;
+
+ case PMC_EV_IAP2_BUS_HIT_DRV: case PMC_EV_IAP2_BUS_HITM_DRV:
+ case PMC_EV_IAP2_BUS_BNR_DRV: case PMC_EV_IAP2_BUS_DRDY_CLOCKS:
+ masks = 1;
+ IPMMASKSET(agents);
+ break;
+
+ case PMC_EV_IAP2_L1D_CACHE_LD: case PMC_EV_IAP2_L1D_CACHE_ST:
+ case PMC_EV_IAP2_L1D_CACHE_LOCK:
+ masks = 1;
+ IPMMASKSET(mesi);
+ break;
+
+ case PMC_EV_IAP2_L2_LINES_IN: case PMC_EV_IAP2_L2_LINES_OUT:
+ case PMC_EV_IAP2_L2_M_LINES_OUT:
+ masks = 2;
+ IPMMASKSET(cores_and_hw);
+ break;
+
+ case PMC_EV_IAP2_BUS_TRANS_ANY: case PMC_EV_IAP2_SNOOP_STALL_DRV:
+ case PMC_EV_IAP2_BUS_TRANS_MEM: case PMC_EV_IAP2_BUS_TRANS_BURST:
+ case PMC_EV_IAP2_BUS_TRANS_DEF: case PMC_EV_IAP2_BUS_TRANS_IO:
+ case PMC_EV_IAP2_BUS_TRANS_P: case PMC_EV_IAP2_BUS_TRANS_PWR:
+ case PMC_EV_IAP2_BUS_TRANS_WB: case PMC_EV_IAP2_BUS_TRANS_INVAL:
+ case PMC_EV_IAP2_BUS_TRANS_RFO: case PMC_EV_IAP2_BUS_TRANS_IFETCH:
+ case PMC_EV_IAP2_BUS_TRANS_BRD: case PMC_EV_IAP2_BUS_LOCK_CLOCKS:
+ case PMC_EV_IAP2_BUS_REQUEST_OUTSTANDING:
+ masks = 2;
+ IPMMASKSET(cores_and_agents);
+ break;
+
+ case PMC_EV_IAP2_L2_IFETCH: case PMC_EV_IAP2_L2_ST:
+ case PMC_EV_IAP2_L2_LOCK:
+ masks = 2;
+ IPMMASKSET(cores_and_mesi);
+ break;
+
+ case PMC_EV_IAP2_EXT_SNOOP:
+ masks = 2;
+ IPMMASKSET(cores_and_snoop_response);
+ break;
+
+ case PMC_EV_IAP2_CMP_SNOOP:
+ masks = 2;
+ IPMMASKSET(cores_and_snoop_type);
+ break;
+
+ case PMC_EV_IAP2_L2_LD: case PMC_EV_IAP2_L2_RQSTS:
+ case PMC_EV_IAP2_L2_REJECT_BUSQ:
+ masks = 3;
+ IPMMASKSET(cores_and_hw_and_mesi);
+ break;
+
+ default:
+ pmask = NULL;
+ break;
+ }
+
+ /* Parse additional modifiers if present */
+ while ((p = strsep(&ctrspec, ",")) != NULL) {
+ if (KWPREFIXMATCH(p, IPM_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;
+#if 0
+ pmc_config->pm_md.pm_ppro.pm_ppro_config |=
+ P6_EVSEL_TO_CMASK(count);
+#endif
+ } else if (KWMATCH(p, IPM_KW_EDGE)) {
+ pmc_config->pm_caps |= PMC_CAP_EDGE;
+ } else if (KWMATCH(p, IPM_KW_INV)) {
+ pmc_config->pm_caps |= PMC_CAP_INVERT;
+ } else if (KWMATCH(p, IPM_KW_OS)) {
+ pmc_config->pm_caps |= PMC_CAP_SYSTEM;
+ } else if (KWPREFIXMATCH(p, IPM_KW_UMASK "=")) {
+ evmask = 0;
+ if ((n = pmc_parse_mask(pmask, p, &evmask)) < 0)
+ return -1;
+ if (n > masks)
+ return -1;
+ pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
+ } else if (KWMATCH(p, P6_KW_USR)) {
+ pmc_config->pm_caps |= PMC_CAP_USER;
+ } else
+ return -1;
+ }
+
+ if (evmask == 0 && pmask) {
+ evmask = default_mask;
+ pmc_config->pm_caps |= PMC_CAP_QUALIFIER;
+ }
+
+ if (pmc_config->pm_caps & PMC_CAP_QUALIFIER)
+ pmc_config->pm_md.pm_ipm.pm_ipm_config |=
+ IPM_EVSEL_TO_UMASK(evmask);
+
+ pmc_config->pm_class = PMC_CLASS_IAP2;
+ return 0;
+}
+
static int
tsc_allocate_pmc(enum pmc_event pe, char *ctrspec,
struct pmc_op_pmcallocate *pmc_config)
@@ -2125,6 +2392,10 @@ pmc_init(void)
case PMC_CPU_INTEL_PIV:
PMC_MDEP_INIT(p4);
break;
+ case PMC_CPU_INTEL_CORE:
+ case PMC_CPU_INTEL_CORE2:
+ PMC_MDEP_INIT(iap2);
+ break;
#endif
default:
More information about the svn-src-user
mailing list