From owner-svn-src-user@FreeBSD.ORG Tue Nov 11 10:21:19 2008 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 655A11065688; Tue, 11 Nov 2008 10:21:19 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 493728FC21; Tue, 11 Nov 2008 10:21:19 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id mABALJvG097184; Tue, 11 Nov 2008 10:21:19 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id mABALJAO097183; Tue, 11 Nov 2008 10:21:19 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <200811111021.mABALJAO097183@svn.freebsd.org> From: Kip Macy Date: Tue, 11 Nov 2008 10:21:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r184838 - user/kmacy/HEAD_fast_multi_xmit/lib/libpmc X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 11 Nov 2008 10:21:19 -0000 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: